ElevationBandMaterial.glsl 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. uniform sampler2D heights;
  2. uniform sampler2D colors;
  3. // This material expects heights to be sorted from lowest to highest.
  4. float getHeight(int idx, float invTexSize)
  5. {
  6. vec2 uv = vec2((float(idx) + 0.5) * invTexSize, 0.5);
  7. #ifdef OES_texture_float
  8. return texture(heights, uv).x;
  9. #else
  10. return czm_unpackFloat(texture(heights, uv));
  11. #endif
  12. }
  13. czm_material czm_getMaterial(czm_materialInput materialInput)
  14. {
  15. czm_material material = czm_getDefaultMaterial(materialInput);
  16. float height = materialInput.height;
  17. float invTexSize = 1.0 / float(heightsDimensions.x);
  18. float minHeight = getHeight(0, invTexSize);
  19. float maxHeight = getHeight(heightsDimensions.x - 1, invTexSize);
  20. // early-out when outside the height range
  21. if (height < minHeight || height > maxHeight) {
  22. material.diffuse = vec3(0.0);
  23. material.alpha = 0.0;
  24. return material;
  25. }
  26. // Binary search to find heights above and below.
  27. int idxBelow = 0;
  28. int idxAbove = heightsDimensions.x;
  29. float heightBelow = minHeight;
  30. float heightAbove = maxHeight;
  31. // while loop not allowed, so use for loop with max iterations.
  32. // maxIterations of 16 supports a texture size up to 65536 (2^16).
  33. const int maxIterations = 16;
  34. for (int i = 0; i < maxIterations; i++) {
  35. if (idxBelow >= idxAbove - 1) {
  36. break;
  37. }
  38. int idxMid = (idxBelow + idxAbove) / 2;
  39. float heightTex = getHeight(idxMid, invTexSize);
  40. if (height > heightTex) {
  41. idxBelow = idxMid;
  42. heightBelow = heightTex;
  43. } else {
  44. idxAbove = idxMid;
  45. heightAbove = heightTex;
  46. }
  47. }
  48. float lerper = heightBelow == heightAbove ? 1.0 : (height - heightBelow) / (heightAbove - heightBelow);
  49. vec2 colorUv = vec2(invTexSize * (float(idxBelow) + 0.5 + lerper), 0.5);
  50. vec4 color = texture(colors, colorUv);
  51. // undo preumultiplied alpha
  52. if (color.a > 0.0)
  53. {
  54. color.rgb /= color.a;
  55. }
  56. color.rgb = czm_gammaCorrect(color.rgb);
  57. material.diffuse = color.rgb;
  58. material.alpha = color.a;
  59. return material;
  60. }