You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.1 KiB
GLSL
75 lines
2.1 KiB
GLSL
uniform sampler2D heights;
|
|
uniform sampler2D colors;
|
|
|
|
// This material expects heights to be sorted from lowest to highest.
|
|
|
|
float getHeight(int idx, float invTexSize)
|
|
{
|
|
vec2 uv = vec2((float(idx) + 0.5) * invTexSize, 0.5);
|
|
#ifdef OES_texture_float
|
|
return texture2D(heights, uv).x;
|
|
#else
|
|
return czm_unpackFloat(texture2D(heights, uv));
|
|
#endif
|
|
}
|
|
|
|
czm_material czm_getMaterial(czm_materialInput materialInput)
|
|
{
|
|
czm_material material = czm_getDefaultMaterial(materialInput);
|
|
|
|
float height = materialInput.height;
|
|
float invTexSize = 1.0 / float(heightsDimensions.x);
|
|
|
|
float minHeight = getHeight(0, invTexSize);
|
|
float maxHeight = getHeight(heightsDimensions.x - 1, invTexSize);
|
|
|
|
// early-out when outside the height range
|
|
if (height < minHeight || height > maxHeight) {
|
|
material.diffuse = vec3(0.0);
|
|
material.alpha = 0.0;
|
|
return material;
|
|
}
|
|
|
|
// Binary search to find heights above and below.
|
|
int idxBelow = 0;
|
|
int idxAbove = heightsDimensions.x;
|
|
float heightBelow = minHeight;
|
|
float heightAbove = maxHeight;
|
|
|
|
// while loop not allowed, so use for loop with max iterations.
|
|
// maxIterations of 16 supports a texture size up to 65536 (2^16).
|
|
const int maxIterations = 16;
|
|
for (int i = 0; i < maxIterations; i++) {
|
|
if (idxBelow >= idxAbove - 1) {
|
|
break;
|
|
}
|
|
|
|
int idxMid = (idxBelow + idxAbove) / 2;
|
|
float heightTex = getHeight(idxMid, invTexSize);
|
|
|
|
if (height > heightTex) {
|
|
idxBelow = idxMid;
|
|
heightBelow = heightTex;
|
|
} else {
|
|
idxAbove = idxMid;
|
|
heightAbove = heightTex;
|
|
}
|
|
}
|
|
|
|
float lerper = heightBelow == heightAbove ? 1.0 : (height - heightBelow) / (heightAbove - heightBelow);
|
|
vec2 colorUv = vec2(invTexSize * (float(idxBelow) + 0.5 + lerper), 0.5);
|
|
vec4 color = texture2D(colors, colorUv);
|
|
|
|
// undo preumultiplied alpha
|
|
if (color.a > 0.0)
|
|
{
|
|
color.rgb /= color.a;
|
|
}
|
|
|
|
color.rgb = czm_gammaCorrect(color.rgb);
|
|
|
|
material.diffuse = color.rgb;
|
|
material.alpha = color.a;
|
|
return material;
|
|
}
|