2022-12-11 10:31:34 +00:00
|
|
|
#define EARTH
|
2023-03-30 08:09:07 +00:00
|
|
|
#include <common>
|
|
|
|
#include <normal_pars_vertex>
|
|
|
|
|
2022-12-11 10:31:34 +00:00
|
|
|
varying vec3 vViewPosition;
|
|
|
|
varying vec3 vLightDirection;
|
|
|
|
varying vec2 vUv;
|
|
|
|
varying vec3 vEyeNormal;
|
2023-03-30 08:09:07 +00:00
|
|
|
|
|
|
|
varying vec3 v3Direction;
|
|
|
|
varying vec3 c0;
|
|
|
|
varying vec3 c1;
|
|
|
|
|
2022-12-11 10:31:34 +00:00
|
|
|
uniform vec3 light;
|
2022-12-11 11:41:30 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2022-12-11 10:31:34 +00:00
|
|
|
void main() {
|
|
|
|
#include <beginnormal_vertex>
|
|
|
|
#include <defaultnormal_vertex>
|
|
|
|
#include <normal_vertex>
|
|
|
|
#include <begin_vertex>
|
|
|
|
#include <project_vertex>
|
2022-12-11 11:41:30 +00:00
|
|
|
|
|
|
|
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<nSamples; i++)
|
|
|
|
{
|
|
|
|
float fHeight = length(v3SamplePoint);
|
|
|
|
float fDepth = exp(scaleOverScaleDepth * (innerRadius - fHeight));
|
|
|
|
float fScatter = fDepth*fTemp - fCameraOffset;
|
|
|
|
v3Attenuate = exp(-fScatter * (invWavelength * Kr4PI + Km4PI));
|
|
|
|
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
|
|
|
v3SamplePoint += v3SampleRay;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate the attenuation factor for the ground
|
|
|
|
c0 = v3Attenuate;
|
|
|
|
c1 = v3FrontColor * (invWavelength * KrESun + KmESun);
|
2022-12-11 10:31:34 +00:00
|
|
|
|
|
|
|
vViewPosition = - mvPosition.xyz;
|
|
|
|
vec4 viewPos = modelViewMatrix * vec4(position, 1.0);
|
|
|
|
vEyeNormal = (modelViewMatrix * vec4(normal, 0.)).xyz;
|
|
|
|
|
|
|
|
vUv = uv;
|
|
|
|
}
|