@@ -102,16 +102,58 @@ void calculateRayScatteringFromGround(in vec3 positionWC, in vec3 ray, in float
102
102
startOffset = depth* scale(startAngle);
103
103
}
104
104
105
- void calculateMieColorAndRayleighColor( vec3 positionWC , vec3 outerPosition , vec3 lightDirection, bool intersectsEllipsoid, out vec3 mieColor, out vec3 rayleighColor )
105
+ czm_raySegment rayEllipsoidIntersection(czm_ray ray , vec3 ellipsoid_center , vec3 ellipsoid_inverseRadii )
106
106
{
107
- float cameraHeight = length (positionWC);
107
+ vec3 o = ellipsoid_inverseRadii * (czm_inverseModelView * vec4 (ray.origin, 1.0 )).xyz;
108
+ vec3 d = ellipsoid_inverseRadii * (czm_inverseModelView * vec4 (ray.direction, 0.0 )).xyz;
109
+
110
+ float a = dot (d, d);
111
+ float b = dot (d, o);
112
+ float c = dot (o, o) - 1.0 ;
113
+ float discriminant = b * b - a * c;
114
+ if (discriminant < 0.0 )
115
+ {
116
+ return czm_emptyRaySegment;
117
+ }
118
+ discriminant = sqrt (discriminant);
119
+ float t1 = (- b + (- discriminant)) / a;
120
+ float t2 = (- b + (discriminant)) / a;
121
+
122
+ if (t1 < 0.0 && t2 < 0.0 )
123
+ {
124
+ return czm_emptyRaySegment;
125
+ }
126
+
127
+ if (t1 < 0.0 && t2 >= 0.0 )
128
+ {
129
+ t1 = 0.0 ;
130
+ }
131
+
132
+ return czm_raySegment(t1, t2);
133
+ }
134
+
135
+ void calculateMieColorAndRayleighColor(vec3 outerPositionWC, float ellipsoidScaleFactor, out vec3 mieColor, out vec3 rayleighColor)
136
+ {
137
+ vec3 directionWC = normalize (outerPositionWC - czm_viewerPositionWC);
138
+ vec3 directionEC = czm_viewRotation * directionWC;
139
+ czm_ray viewRay = czm_ray(vec3 (0.0 ), directionEC);
140
+ czm_raySegment raySegment = rayEllipsoidIntersection(viewRay, vec3 (czm_view[3 ]), czm_ellipsoidInverseRadii * ellipsoidScaleFactor);
141
+ bool intersectsEllipsoid = raySegment.start >= 0.0 ;
142
+
143
+ vec3 startPositionWC = czm_viewerPositionWC;
144
+ if (intersectsEllipsoid)
145
+ {
146
+ startPositionWC = czm_viewerPositionWC + raySegment.stop * directionWC;
147
+ }
148
+
149
+ vec3 lightDirection = getLightDirection(startPositionWC);
108
150
109
151
// Unpack attributes
110
152
float outerRadius = u_radiiAndDynamicAtmosphereColor.x;
111
153
float innerRadius = u_radiiAndDynamicAtmosphereColor.y;
112
154
113
155
// Get the ray from the start position to the outer position and its length (which is the far point of the ray passing through the atmosphere)
114
- vec3 ray = outerPosition - positionWC ;
156
+ vec3 ray = outerPositionWC - startPositionWC ;
115
157
float far = length (ray);
116
158
ray /= far;
117
159
float atmosphereScale = 1.0 / (outerRadius - innerRadius);
@@ -122,14 +164,14 @@ void calculateMieColorAndRayleighColor(vec3 positionWC, vec3 outerPosition, vec3
122
164
#ifdef SKY_FROM_SPACE
123
165
if (intersectsEllipsoid)
124
166
{
125
- calculateRayScatteringFromGround(positionWC , ray, atmosphereScale, innerRadius, start, startOffset);
167
+ calculateRayScatteringFromGround(startPositionWC , ray, atmosphereScale, innerRadius, start, startOffset);
126
168
}
127
169
else
128
170
{
129
- calculateRayScatteringFromSpace(positionWC , ray, outerRadius, far, start, startOffset);
171
+ calculateRayScatteringFromSpace(startPositionWC , ray, outerRadius, far, start, startOffset);
130
172
}
131
173
#else
132
- calculateRayScatteringFromGround(positionWC , ray, atmosphereScale, innerRadius, start, startOffset);
174
+ calculateRayScatteringFromGround(startPositionWC , ray, atmosphereScale, innerRadius, start, startOffset);
133
175
#endif
134
176
135
177
// Initialize the scattering loop variables
@@ -167,12 +209,6 @@ vec4 calculateFinalColor(vec3 positionWC, vec3 toCamera, vec3 lightDirection, ve
167
209
168
210
vec3 rgb = rayleighPhase * rayleighColor + miePhase * mieColor;
169
211
170
- if (rgb.b > 1000000.0 )
171
- {
172
- // Discard colors that exceed some large number value to prevent against NaN's from the exponent calculation below
173
- return vec4 (0.0 );
174
- }
175
-
176
212
const float exposure = 2.0 ;
177
213
vec3 rgbExposure = vec3 (1.0 ) - exp (- exposure * rgb);
178
214
0 commit comments