Sky from atmosphere! Fix normalization
This commit is contained in:
parent
ba2bc1a43c
commit
46026ab9b9
@ -30,35 +30,50 @@ uniform mat4 uModelMatrix;
|
||||
uniform mat4 uViewMatrix;
|
||||
uniform mat4 uProjectionMatrix;
|
||||
|
||||
float scale(float fCos)
|
||||
{
|
||||
float scale(float fCos) {
|
||||
float x = 1.0 - fCos;
|
||||
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
||||
}
|
||||
void main(void)
|
||||
{
|
||||
|
||||
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 v3Ray = aVertexPosition - v3CameraPosition;
|
||||
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 B = 2.0 * dot(v3CameraPosition, v3Ray);
|
||||
float C = fCameraHeight2 - fOuterRadius2;
|
||||
float fDet = max(0.0, B*B - 4.0 * C);
|
||||
float fNear = 0.5 * (-B - sqrt(fDet));
|
||||
// Calculate the ray's starting position, then calculate its scattering offset
|
||||
vec3 v3Start = v3CameraPosition + v3Ray * fNear;
|
||||
fFar -= fNear;
|
||||
float fStartAngle = dot(v3Ray, v3Start) / fOuterRadius;
|
||||
float fStartDepth = exp(-1.0 / fScaleDepth);
|
||||
float fStartOffset = fStartDepth * scale(fStartAngle);
|
||||
//c0 = vec3(1.0, 0, 0) * fStartAngle;
|
||||
|
||||
vec3 v3Start;
|
||||
float fStartAngle;
|
||||
float fStartDepth;
|
||||
float fStartOffset;
|
||||
|
||||
if (fCameraHeight > fOuterRadius) {
|
||||
// Sky from space
|
||||
// Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere)
|
||||
float B = 2.0 * dot(v3CameraPosition, v3Ray);
|
||||
float C = fCameraHeight2 - fOuterRadius2;
|
||||
float fDet = max(0.0, B*B - 4.0 * C);
|
||||
float fNear = 0.5 * (-B - sqrt(fDet));
|
||||
|
||||
// Calculate the ray's starting position, then calculate its scattering offset
|
||||
v3Start = v3CameraPosition + v3Ray * fNear;
|
||||
fFar -= fNear;
|
||||
fStartAngle = dot(v3Ray, v3Start) / fOuterRadius;
|
||||
fStartDepth = exp(-1.0 / fScaleDepth);
|
||||
fStartOffset = fStartDepth * scale(fStartAngle);
|
||||
} else {
|
||||
// Sky from within the atmosphere
|
||||
v3Start = v3CameraPosition;
|
||||
fStartDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fCameraHeight));
|
||||
fStartAngle = dot(v3Ray, v3Start) / length(v3Start);
|
||||
fStartOffset = fStartDepth*scale(fStartAngle);
|
||||
}
|
||||
|
||||
// Initialize the scattering loop variables
|
||||
float fSampleLength = fFar / fSamples;
|
||||
float fScaledLength = fSampleLength * fScale;
|
||||
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
// Now loop through the sample rays
|
||||
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||
for(int i=0; i<nSamples; i++)
|
||||
@ -72,6 +87,7 @@ void main(void)
|
||||
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 = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aVertexPosition,1);
|
||||
c0 = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||
|
@ -11,7 +11,7 @@ class Atmosphere extends MeshInstance {
|
||||
this.wavelength = wavelength
|
||||
|
||||
this.Kr = 0.0025
|
||||
this.Km = 0.0010
|
||||
this.Km = 0.0020
|
||||
this.ESun = 20.0
|
||||
this.g = -0.950
|
||||
this.scaleDepth = 0.25
|
||||
@ -23,9 +23,10 @@ class Atmosphere extends MeshInstance {
|
||||
gl.uniformMatrix4fv(shader.getUniformLocation(gl, 'uModelMatrix'), false, this.transform)
|
||||
|
||||
const camHeight = vec3.length(subv3(camera.pos, this.pos))
|
||||
const invWavelength = [1 / Math.pow(this.wavelength[0], 4), 1 / Math.pow(this.wavelength[1], 4), 1 / Math.pow(this.wavelength[2], 4)]
|
||||
gl.uniform3fv(shader.getUniformLocation(gl, 'v3CameraPosition'), camera.pos)
|
||||
gl.uniform3fv(shader.getUniformLocation(gl, 'v3LightPosition'), normalv3(sun.pos.slice()))
|
||||
gl.uniform3f(shader.getUniformLocation(gl, 'v3InvWavelength'), 1 / Math.pow(this.wavelength[0], 4), 1 / Math.pow(this.wavelength[1], 4), 1 / Math.pow(this.wavelength[2], 4))
|
||||
gl.uniform3fv(shader.getUniformLocation(gl, 'v3LightPosition'), normalv3(sun.pos))
|
||||
gl.uniform3fv(shader.getUniformLocation(gl, 'v3InvWavelength'), invWavelength)
|
||||
gl.uniform1f(shader.getUniformLocation(gl, 'fCameraHeight'), camHeight)
|
||||
gl.uniform1f(shader.getUniformLocation(gl, 'fCameraHeight2'), camHeight * camHeight)
|
||||
gl.uniform1f(shader.getUniformLocation(gl, 'fInnerRadius'), this.innerRadius)
|
||||
|
@ -57,7 +57,7 @@ export function divv3 (one, two) {
|
||||
}
|
||||
|
||||
export function normalv3 (vec) {
|
||||
const res = vec
|
||||
const res = []
|
||||
vec3.normalize(res, vec)
|
||||
return res
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user