#define EARTH varying vec3 vViewPosition; varying vec3 vLightDirection; varying vec2 vUv; varying vec3 vEyeNormal; #include #include uniform vec3 light; uniform vec3 invWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels uniform float outerRadius; // The outer (atmosphere) radius uniform float innerRadius; // The inner (planetary) radius uniform float ESun; // Sun exposure uniform float Km; // Mie coefficient uniform float Kr; // Rayleigh coefficient uniform float scale; // 1 / (outerRadius - innerRadius) uniform float scaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found) const int nSamples = 2; const float fSamples = 1.0; varying vec3 v3Direction; varying vec3 c0; varying vec3 c1; float dscale(float fCos) { float x = 1.0 - fCos; return scaleDepth * exp(-0.00287 + x * (0.459 + x * (3.83 + x * (-6.80 + x * 5.25)))); } float calculateNearScatter(vec3 v3CameraPosition, vec3 v3Ray, float fCameraHeight, float fOuterRadius) { float B = 2.0 * dot(v3CameraPosition, v3Ray); float C = pow(fCameraHeight, 2.0) - pow(fOuterRadius, 2.0); float fDet = max(0.0, B * B - 4.0 * C); return 0.5 * (-B - sqrt(fDet)); } void main() { #include #include #include #include #include vLightDirection = (viewMatrix * vec4(light, 0.)).xyz; vec3 modelPosition = (modelMatrix * vec4(position, 1.0)).xyz; float cameraHeight = length(vec3(0.0, 0.0, 0.0) - cameraPosition); float KmESun = Km * ESun; float KrESun = Kr * ESun; float Kr4PI = Kr * 4.0 * PI; float Km4PI = Km * 4.0 * PI; float scaleOverScaleDepth = scale / scaleDepth; // Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere) vec3 v3Ray = modelPosition - cameraPosition; float fFar = length(v3Ray); v3Ray /= fFar; // Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere) float fNear = calculateNearScatter(cameraPosition, v3Ray, cameraHeight, outerRadius); // Calculate the ray's starting position, then calculate its scattering offset vec3 v3Start = cameraPosition + v3Ray * fNear; fFar -= fNear; float fDepth = exp((innerRadius - outerRadius) / scaleDepth); float fCameraAngle = dot(-v3Ray, modelPosition) / length(modelPosition); float fLightAngle = dot(normalize(light), modelPosition) / length(modelPosition); float fCameraScale = dscale(fCameraAngle); float fLightScale = dscale(fLightAngle); float fCameraOffset = fDepth*fCameraScale; float fTemp = (fLightScale + fCameraScale); // Initialize the scattering loop variables float fSampleLength = fFar / fSamples; float fScaledLength = fSampleLength * scale; vec3 v3SampleRay = v3Ray * fSampleLength; vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5; // Now loop through the sample rays vec3 v3FrontColor = vec3(0.0, 0.0, 0.0); vec3 v3Attenuate; for(int i=0; i