智慧水务管理系统 - 精河县供水工程综合管理平台

ComputeRadianceMapFS.glsl 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. precision highp float;
  2. in vec2 v_textureCoordinates;
  3. uniform vec3 u_faceDirection; // Current cubemap face
  4. uniform vec3 u_positionWC;
  5. uniform mat4 u_enuToFixedFrame;
  6. uniform vec4 u_brightnessSaturationGammaIntensity;
  7. uniform vec4 u_groundColor; // alpha component represent albedo
  8. vec4 getCubeMapDirection(vec2 uv, vec3 faceDir) {
  9. vec2 scaledUV = uv * 2.0 - 1.0;
  10. if (faceDir.x != 0.0) {
  11. return vec4(faceDir.x, scaledUV.x * faceDir.x, -scaledUV.y, 0.0);
  12. } else if (faceDir.y != 0.0) {
  13. return vec4(scaledUV.x, -scaledUV.y * faceDir.y, faceDir.y, 0.0);
  14. } else {
  15. return vec4(scaledUV.x * faceDir.z, -faceDir.z, -scaledUV.y, 0.0);
  16. }
  17. }
  18. void main() {
  19. float height = length(u_positionWC);
  20. float atmosphereInnerRadius = u_radiiAndDynamicAtmosphereColor.y;
  21. float ellipsoidHeight = max(height - atmosphereInnerRadius, 0.0);
  22. // Scale the position to ensure the sky color is present, even when underground.
  23. vec3 positionWC = u_positionWC / height * (ellipsoidHeight + atmosphereInnerRadius);
  24. float atmosphereOuterRadius = u_radiiAndDynamicAtmosphereColor.x;
  25. float atmosphereHeight = atmosphereOuterRadius - atmosphereInnerRadius;
  26. vec3 direction = (u_enuToFixedFrame * getCubeMapDirection(v_textureCoordinates, u_faceDirection)).xyz;
  27. vec3 normalizedDirection = normalize(direction);
  28. czm_ray ray = czm_ray(positionWC, normalizedDirection);
  29. czm_raySegment intersection = czm_raySphereIntersectionInterval(ray, vec3(0.0), atmosphereInnerRadius);
  30. if (!czm_isEmpty(intersection)) {
  31. intersection = czm_rayEllipsoidIntersectionInterval(ray, vec3(0.0), czm_ellipsoidInverseRadii);
  32. }
  33. bool onEllipsoid = intersection.start >= 0.0;
  34. float rayLength = czm_branchFreeTernary(onEllipsoid, intersection.start, atmosphereOuterRadius);
  35. // Compute sky color for each position on a sphere at radius centered around the provided position's origin
  36. vec3 skyPositionWC = positionWC + normalizedDirection * rayLength;
  37. float lightEnum = u_radiiAndDynamicAtmosphereColor.z;
  38. vec3 lightDirectionWC = normalize(czm_getDynamicAtmosphereLightDirection(skyPositionWC, lightEnum));
  39. vec3 mieColor;
  40. vec3 rayleighColor;
  41. float opacity;
  42. czm_computeScattering(
  43. ray,
  44. rayLength,
  45. lightDirectionWC,
  46. atmosphereInnerRadius,
  47. rayleighColor,
  48. mieColor,
  49. opacity
  50. );
  51. vec4 atmopshereColor = czm_computeAtmosphereColor(ray, lightDirectionWC, rayleighColor, mieColor, opacity);
  52. #ifdef ATMOSPHERE_COLOR_CORRECT
  53. const bool ignoreBlackPixels = true;
  54. atmopshereColor.rgb = czm_applyHSBShift(atmopshereColor.rgb, czm_atmosphereHsbShift, ignoreBlackPixels);
  55. #endif
  56. vec3 lookupDirection = -normalizedDirection;
  57. // Flipping the X vector is a cheap way to get the inverse of czm_temeToPseudoFixed, since that's a rotation about Z.
  58. lookupDirection.x = -lookupDirection.x;
  59. lookupDirection = -normalize(czm_temeToPseudoFixed * lookupDirection);
  60. lookupDirection.x = -lookupDirection.x;
  61. // Values outside the atmopshere are rendered as black, when they should be treated as transparent
  62. float skyAlpha = clamp((1.0 - ellipsoidHeight / atmosphereHeight) * atmopshereColor.a, 0.0, 1.0);
  63. skyAlpha = czm_branchFreeTernary(length(atmopshereColor.rgb) <= czm_epsilon7, 0.0, skyAlpha); // Treat black as transparent
  64. // Blend starmap with atmopshere scattering
  65. float intensity = u_brightnessSaturationGammaIntensity.w;
  66. vec4 sceneSkyBoxColor = czm_textureCube(czm_environmentMap, lookupDirection);
  67. vec3 skyBackgroundColor = mix(czm_backgroundColor.rgb, sceneSkyBoxColor.rgb, sceneSkyBoxColor.a);
  68. vec4 combinedSkyColor = vec4(mix(skyBackgroundColor, atmopshereColor.rgb * intensity, skyAlpha), 1.0);
  69. // Compute ground color based on amount of reflected light, then blend it with ground atmosphere based on height
  70. vec3 up = normalize(positionWC);
  71. float occlusion = max(dot(lightDirectionWC, up), 0.05);
  72. vec4 groundColor = vec4(u_groundColor.rgb * u_groundColor.a * (vec3(intensity * occlusion) + atmopshereColor.rgb), 1.0);
  73. vec4 blendedGroundColor = mix(groundColor, atmopshereColor, clamp(ellipsoidHeight / atmosphereHeight, 0.0, 1.0));
  74. vec4 color = czm_branchFreeTernary(onEllipsoid, blendedGroundColor, combinedSkyColor);
  75. float brightness = u_brightnessSaturationGammaIntensity.x;
  76. float saturation = u_brightnessSaturationGammaIntensity.y;
  77. float gamma = u_brightnessSaturationGammaIntensity.z;
  78. #ifdef ENVIRONMENT_COLOR_CORRECT
  79. color.rgb = mix(vec3(0.0), color.rgb, brightness);
  80. color.rgb = czm_saturation(color.rgb, saturation);
  81. #endif
  82. color.rgb = pow(color.rgb, vec3(gamma)); // Normally this would be in the ifdef above, but there is a precision issue with the atmopshere scattering transmittance (alpha). Having this line is a workaround for that issue, even when gamma is 1.0.
  83. color.rgb = czm_gammaCorrect(color.rgb);
  84. out_FragColor = color;
  85. }