Created
August 2, 2012 17:46
-
-
Save bzgeb/3239074 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////////////////////////////////////////////////// | |
// ATMOSPHERIC SCATTERING | |
// Viewing the sky from within the atmosphere. | |
// | |
// Based on OGRE Forum user HexiDave's Atmospheric Scattering demo | |
// http://www.ogre3d.org/forums/viewtopic.php?t=37072 | |
/////////////////////////////////////////////////////////////////////////////// | |
/////////////////////////////////////////////////////////////////////////////// | |
// VARIABLES FROM OGRE | |
/////////////////////////////////////////////////////////////////////////////// | |
// automatic from OGRE | |
uniform vec3 g_cameraPosition; | |
uniform vec4 g_lightPosition; | |
// manual from application | |
uniform vec3 g_invWavelengths; | |
uniform float g_globeRadius; | |
uniform float g_atmosphereRadius; | |
uniform float g_atmosphereRadiusSq; | |
uniform float g_Kr4PI; | |
uniform float g_Km4PI; | |
uniform float g_KrESun; | |
uniform float g_KmESun; | |
uniform float g_scale; | |
uniform float g_scaleDepth; | |
uniform float g_invScaleDepth; | |
uniform float g_scaleOverScaleDepth; | |
/////////////////////////////////////////////////////////////////////////////// | |
// VARYINGS | |
/////////////////////////////////////////////////////////////////////////////// | |
varying vec4 v_rayleighColour; | |
varying vec4 v_mieColour; | |
/////////////////////////////////////////////////////////////////////////////// | |
// HELPERS | |
/////////////////////////////////////////////////////////////////////////////// | |
// Returns the near intersection point of a line and a sphere | |
float getNearIntersection(vec3 v3Pos, vec3 v3Ray, float fDistance2, float fRadius2) { | |
float B = 2.0 * dot(v3Pos, v3Ray); | |
float C = fDistance2 - fRadius2; | |
float fDet = max(0.0, B*B - 4.0 * C); | |
return 0.5 * (-B - sqrt(fDet)); | |
} | |
// The scale equation calculated by Vernier's Graphical Analysis | |
float scale(float fCos) { | |
float x = 1.0 - fCos; | |
return g_scaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); | |
} | |
void main(void) { | |
// 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 v3Pos = (gl_Vertex.xyz); | |
vec3 v3Ray = v3Pos - g_cameraPosition; | |
float fFar = length(v3Ray); | |
v3Ray /= fFar; | |
// Calculate the ray's starting position, then calculate its scattering offset | |
vec3 v3Start = g_cameraPosition; | |
float fDepth = exp((g_globeRadius - g_atmosphereRadius) * g_invScaleDepth); | |
float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos); | |
float fLightAngle = dot(g_lightPosition, v3Pos) / length(v3Pos); | |
float fCameraScale = scale(fCameraAngle); | |
float fLightScale = scale(fLightAngle); | |
float fCameraOffset = fDepth*fCameraScale; | |
float fTemp = (fLightScale + fCameraScale); | |
// initialize the scattering loop variables | |
float fSampleLength = fFar / 3.0; | |
float fScaledLength = fSampleLength * g_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<3; i++) { | |
float fHeight = length(v3SamplePoint); | |
float fDepth = exp(g_scaleOverScaleDepth * (g_globeRadius - fHeight)); | |
float fScatter = fDepth * fTemp - fCameraOffset; | |
v3Attenuate = exp(-fScatter * (g_invWavelengths * g_Kr4PI + g_Km4PI)); | |
v3FrontColor += v3Attenuate * (fDepth * fScaledLength); | |
v3SamplePoint += v3SampleRay; | |
} | |
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader | |
gl_Position = ftransform(); | |
v_rayleighColour = vec4(v3FrontColor * (g_invWavelengths * g_KrESun + g_KmESun), 1.0); | |
v_mieColour = vec4(v3Attenuate, 1.0); | |
gl_TexCoord[0].xyz = g_cameraPosition.xyz - v3Pos.xyz; | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment