1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- 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 texture(heights, uv).x;
- #else
- return czm_unpackFloat(texture(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 = texture(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;
- }
|