60 lines
2.7 KiB
JavaScript
60 lines
2.7 KiB
JavaScript
import { MeshInstance } from '../'
|
|
import Sphere from '../../mesh/geometry/sphere'
|
|
import { vec3 } from 'gl-matrix'
|
|
import { subv3, normalv3 } from '../../utility'
|
|
|
|
class Atmosphere extends MeshInstance {
|
|
constructor (pos, innerRadius, outerRadius, wavelength = [0.650, 0.570, 0.475]) {
|
|
super(Sphere.new(outerRadius, 200, 200), pos)
|
|
this.outerRadius = outerRadius
|
|
this.innerRadius = innerRadius
|
|
this.wavelength = wavelength
|
|
|
|
this.Kr = 0.0025
|
|
this.Km = 0.0020
|
|
this.ESun = 20.0
|
|
this.g = -0.950
|
|
this.scaleDepth = 0.25
|
|
this.mieScaleDepth = 0.1
|
|
}
|
|
|
|
draw (gl, shader, camera, sun, sky) {
|
|
// Set model transform matrix uniform
|
|
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))
|
|
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)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fInnerRadius2'), this.innerRadius * this.innerRadius)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fOuterRadius'), this.outerRadius)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fOuterRadius2'), this.outerRadius * this.outerRadius)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fKrESun'), this.Kr * this.ESun)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fKmESun'), this.Km * this.ESun)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fKr4PI'), this.Kr * 4 * Math.PI)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fKm4PI'), this.Km * 4 * Math.PI)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fScale'), 1 / (this.outerRadius - this.innerRadius))
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fScaleDepth'), this.scaleDepth)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'fScaleOverScaleDepth'), 1 / (this.outerRadius - this.innerRadius) / this.scaleDepth)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'g'), this.g)
|
|
gl.uniform1f(shader.getUniformLocation(gl, 'g2'), this.g * this.g)
|
|
|
|
// Draw the mesh
|
|
gl.enable(gl.BLEND)
|
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
|
gl.cullFace(gl.FRONT)
|
|
|
|
this.mesh.prepare(gl, shader)
|
|
this.mesh.draw(gl, shader)
|
|
this.mesh.postdraw(gl, shader)
|
|
|
|
gl.disable(gl.BLEND)
|
|
}
|
|
}
|
|
|
|
export default Atmosphere
|