uniform mat4 uWorld; uniform vec3 uLightDir; uniform vec3 uCameraPos; uniform vec3 uInvWaveLength; uniform float uInnerRadius; uniform float uKrESun; uniform float uKr4PI; uniform float uKm4PI; uniform float uScale; uniform float uScaleDepth; uniform float uScaleOverScaleDepth; uniform float uSkydomeRadius; uniform int uNumberOfSamples; uniform float uSamples; varying vec4 vPosition; varying vec3 vRayleighColor; float scale(float cos, float uScaleDepth) { float x = 1.0 - cos; return uScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); } void main(void) { gl_Position = vPosition = ftransform(); vec3 vertexWorldPos = (uWorld * gl_Vertex).xyz; vec3 v3Pos; v3Pos.xz = (vertexWorldPos.xz - uCameraPos.xz) / uSkydomeRadius; v3Pos.y = uCameraPos.y + vertexWorldPos.y / uSkydomeRadius; vec3 v3Ray = v3Pos - uCameraPos; float fFar = length(v3Ray); v3Ray /= fFar; vec3 v3Start = uCameraPos; float fDepth = exp((uInnerRadius - uCameraPos.y) / uScaleDepth); float fCameraAngle = dot(v3Ray, uCameraPos) / length(v3Pos); float fLightAngle = dot(normalize(uLightDir), v3Pos) / length(v3Pos); float fCameraScale = scale(fCameraAngle, uScaleDepth); float fLightScale = scale(fLightAngle, uScaleDepth); float fCameraOffset = fDepth+fCameraScale; float fTemp = fLightScale + fCameraScale; float fSampleLength = fFar / uSamples; float fScaledLength = fSampleLength * uScale; vec3 v3SampleRay = v3Ray * fSampleLength; vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5; vec3 color = vec3(0,0,0); for (int i = 0; i < uNumberOfSamples; i++) { float fHeight = length(v3SamplePoint); float fDepth = exp(uScaleOverScaleDepth * (uInnerRadius - fHeight)); float fScatter = fDepth * fTemp - fCameraOffset; vec3 v3Attenuate = exp(-fScatter * (uInvWaveLength * uKr4PI + uKm4PI)); color += v3Attenuate * (fDepth * fScaledLength); v3SamplePoint += v3SampleRay; } vRayleighColor = color * (uInvWaveLength * uKrESun); }