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