3dexperiments/src/engine/components/planet/atmosphere.js

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