reorganize water renderer
This commit is contained in:
parent
14bc83125c
commit
e56adeeb10
@ -2,7 +2,6 @@ import { Node } from '../'
|
|||||||
import { Mesh } from '../../mesh'
|
import { Mesh } from '../../mesh'
|
||||||
import { Texture } from '../../mesh/material'
|
import { Texture } from '../../mesh/material'
|
||||||
import Screen from '../../screen'
|
import Screen from '../../screen'
|
||||||
import Resource from '../../resource'
|
|
||||||
|
|
||||||
class WaterFBOs {
|
class WaterFBOs {
|
||||||
constructor (reflectionWidth = 320, reflectionHeight = 180, refractionWidth = 1280, refractionHeight = 720) {
|
constructor (reflectionWidth = 320, reflectionHeight = 180, refractionWidth = 1280, refractionHeight = 720) {
|
||||||
@ -96,8 +95,13 @@ class WaterFBOs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class WaterTile extends Node {
|
class WaterTile extends Node {
|
||||||
constructor (pos, scale, reflectivity = 0.1, tint = [0.0, 0.3, 0.5, 0.2]) {
|
constructor (pos, scale) {
|
||||||
super(pos, [scale, 0.0, scale])
|
super(pos, [scale, 0.0, scale])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WaterRenderer {
|
||||||
|
constructor (reflectivity = 0.1, tint = [0.0, 0.3, 0.5, 0.2]) {
|
||||||
this.fbos = new WaterFBOs()
|
this.fbos = new WaterFBOs()
|
||||||
|
|
||||||
this.reflectivity = reflectivity
|
this.reflectivity = reflectivity
|
||||||
@ -107,11 +111,7 @@ class WaterTile extends Node {
|
|||||||
this.shininess = 0.7
|
this.shininess = 0.7
|
||||||
this.shineDamper = 20.0
|
this.shineDamper = 20.0
|
||||||
this.distortionStrength = 0.02
|
this.distortionStrength = 0.02
|
||||||
}
|
this.waveSpeed = 0.001
|
||||||
|
|
||||||
initialize (gl) {
|
|
||||||
this.mesh = Mesh.constructFromVertices(gl, [-1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1], 2)
|
|
||||||
this.fbos.initialize(gl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async useDUDVMap (gl, file) {
|
async useDUDVMap (gl, file) {
|
||||||
@ -124,7 +124,7 @@ class WaterTile extends Node {
|
|||||||
|
|
||||||
reflect (gl, cam, render) {
|
reflect (gl, cam, render) {
|
||||||
this.fbos.bindReflectionFrameBuffer(gl)
|
this.fbos.bindReflectionFrameBuffer(gl)
|
||||||
let dist = 2 * (cam.pos[1] - this.pos[1])
|
let dist = 2 * cam.pos[1]
|
||||||
cam.pos[1] -= dist
|
cam.pos[1] -= dist
|
||||||
cam.rotation[1] *= -1
|
cam.rotation[1] *= -1
|
||||||
cam.updateTransform()
|
cam.updateTransform()
|
||||||
@ -141,31 +141,35 @@ class WaterTile extends Node {
|
|||||||
this.fbos.unbindFrameBuffer(gl)
|
this.fbos.unbindFrameBuffer(gl)
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare (gl, shader, cam, sun) {
|
async initialize (game) {
|
||||||
const transformLoc = shader.getUniformLocation(gl, 'uModelMatrix')
|
this.shader = await game.shaders.createShaderFromFiles(game.gl, 'water', false)
|
||||||
|
this.mesh = Mesh.constructFromVertices(game.gl, [-1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1], 2)
|
||||||
|
this.fbos.initialize(game.gl)
|
||||||
|
}
|
||||||
|
|
||||||
const camPosLoc = shader.getUniformLocation(gl, 'uCameraPosition')
|
prepare (gl, cam, sun) {
|
||||||
const refrLoc = shader.getUniformLocation(gl, 'refractionTexture')
|
const camPosLoc = this.shader.getUniformLocation(gl, 'uCameraPosition')
|
||||||
const reflLoc = shader.getUniformLocation(gl, 'reflectionTexture')
|
const refrLoc = this.shader.getUniformLocation(gl, 'refractionTexture')
|
||||||
const depthLoc = shader.getUniformLocation(gl, 'depthMap')
|
const reflLoc = this.shader.getUniformLocation(gl, 'reflectionTexture')
|
||||||
const dudvLoc = shader.getUniformLocation(gl, 'dudvMap')
|
const depthLoc = this.shader.getUniformLocation(gl, 'depthMap')
|
||||||
const normalLoc = shader.getUniformLocation(gl, 'normalMap')
|
const dudvLoc = this.shader.getUniformLocation(gl, 'dudvMap')
|
||||||
|
const normalLoc = this.shader.getUniformLocation(gl, 'normalMap')
|
||||||
|
|
||||||
const reflectivityLoc = shader.getUniformLocation(gl, 'uReflectivity')
|
const reflectivityLoc = this.shader.getUniformLocation(gl, 'uReflectivity')
|
||||||
const tintLoc = shader.getUniformLocation(gl, 'uTint')
|
const tintLoc = this.shader.getUniformLocation(gl, 'uTint')
|
||||||
const phaseLoc = shader.getUniformLocation(gl, 'uDUDVOffset')
|
const phaseLoc = this.shader.getUniformLocation(gl, 'uDUDVOffset')
|
||||||
|
|
||||||
const shininessLoc = shader.getUniformLocation(gl, 'uShine')
|
const shininessLoc = this.shader.getUniformLocation(gl, 'uShine')
|
||||||
const damperLoc = shader.getUniformLocation(gl, 'uShineDamper')
|
const damperLoc = this.shader.getUniformLocation(gl, 'uShineDamper')
|
||||||
const distortLoc = shader.getUniformLocation(gl, 'uDistortionStrength')
|
const distortLoc = this.shader.getUniformLocation(gl, 'uDistortionStrength')
|
||||||
|
|
||||||
const farLoc = shader.getUniformLocation(gl, 'uFarPlane')
|
const farLoc = this.shader.getUniformLocation(gl, 'uFarPlane')
|
||||||
const nearLoc = shader.getUniformLocation(gl, 'uNearPlane')
|
const nearLoc = this.shader.getUniformLocation(gl, 'uNearPlane')
|
||||||
|
|
||||||
const sunPosLoc = shader.getUniformLocation(gl, 'uLightPosition')
|
const sunPosLoc = this.shader.getUniformLocation(gl, 'uLightPosition')
|
||||||
const sunColorLoc = shader.getUniformLocation(gl, 'uLightColor')
|
const sunColorLoc = this.shader.getUniformLocation(gl, 'uLightColor')
|
||||||
|
|
||||||
gl.uniformMatrix4fv(transformLoc, false, this.transform)
|
gl.uniform4fv(tintLoc, this.tint)
|
||||||
gl.uniform3fv(camPosLoc, cam.pos)
|
gl.uniform3fv(camPosLoc, cam.pos)
|
||||||
gl.uniform3fv(sunPosLoc, sun.pos)
|
gl.uniform3fv(sunPosLoc, sun.pos)
|
||||||
gl.uniform3fv(sunColorLoc, sun.color)
|
gl.uniform3fv(sunColorLoc, sun.color)
|
||||||
@ -176,7 +180,6 @@ class WaterTile extends Node {
|
|||||||
gl.uniform1f(distortLoc, this.distortionStrength)
|
gl.uniform1f(distortLoc, this.distortionStrength)
|
||||||
gl.uniform1f(nearLoc, cam.nearPlane)
|
gl.uniform1f(nearLoc, cam.nearPlane)
|
||||||
gl.uniform1f(farLoc, cam.farPlane)
|
gl.uniform1f(farLoc, cam.farPlane)
|
||||||
gl.uniform4fv(tintLoc, this.tint)
|
|
||||||
gl.uniform1i(reflLoc, 0)
|
gl.uniform1i(reflLoc, 0)
|
||||||
gl.uniform1i(refrLoc, 1)
|
gl.uniform1i(refrLoc, 1)
|
||||||
gl.uniform1i(dudvLoc, 2)
|
gl.uniform1i(dudvLoc, 2)
|
||||||
@ -195,25 +198,35 @@ class WaterTile extends Node {
|
|||||||
gl.bindTexture(gl.TEXTURE_2D, this.fbos.refractionDepthTexture)
|
gl.bindTexture(gl.TEXTURE_2D, this.fbos.refractionDepthTexture)
|
||||||
}
|
}
|
||||||
|
|
||||||
draw (gl, shader, cam, sun) {
|
draw (gl, waters, cam, sun) {
|
||||||
super.draw(gl, shader)
|
this.shader.use(gl)
|
||||||
|
|
||||||
this.prepare(gl, shader, cam, sun)
|
|
||||||
|
|
||||||
gl.enable(gl.BLEND)
|
gl.enable(gl.BLEND)
|
||||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
||||||
|
|
||||||
this.mesh.prepare(gl, shader)
|
// Send camera matrices to the shader
|
||||||
this.mesh.draw(gl, shader)
|
cam.draw(gl, this.shader)
|
||||||
this.mesh.postdraw(gl, shader)
|
|
||||||
|
// Bind uniforms and textures
|
||||||
|
this.prepare(gl, cam, sun)
|
||||||
|
|
||||||
|
// Render a mesh at every tile location
|
||||||
|
this.mesh.prepare(gl, this.shader)
|
||||||
|
for (let i in waters) {
|
||||||
|
const transformLoc = this.shader.getUniformLocation(gl, 'uModelMatrix')
|
||||||
|
gl.uniformMatrix4fv(transformLoc, false, waters[i].transform)
|
||||||
|
|
||||||
|
this.mesh.draw(gl, this.shader)
|
||||||
|
}
|
||||||
|
this.mesh.postdraw(gl, this.shader)
|
||||||
|
|
||||||
gl.disable(gl.BLEND)
|
gl.disable(gl.BLEND)
|
||||||
}
|
}
|
||||||
|
|
||||||
update (dt) {
|
update (dt) {
|
||||||
this.phase += 0.001
|
this.phase += this.waveSpeed
|
||||||
if (this.phase >= 1) this.phase = 0
|
if (this.phase >= 1) this.phase = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { WaterTile, WaterFBOs }
|
export { WaterRenderer, WaterTile }
|
||||||
|
@ -373,6 +373,7 @@ class GUIText extends Node2D {
|
|||||||
draw (gl, shader) {
|
draw (gl, shader) {
|
||||||
// Let only the font shader be used to render text
|
// Let only the font shader be used to render text
|
||||||
if (shader.name !== 'font') return super.draw(gl, shader)
|
if (shader.name !== 'font') return super.draw(gl, shader)
|
||||||
|
if (!this.text) return
|
||||||
const transformLocation = shader.getUniformLocation(gl, 'uTransformation')
|
const transformLocation = shader.getUniformLocation(gl, 'uTransformation')
|
||||||
const cLocation = shader.getUniformLocation(gl, 'uColor')
|
const cLocation = shader.getUniformLocation(gl, 'uColor')
|
||||||
const wLocation = shader.getUniformLocation(gl, 'uWidth')
|
const wLocation = shader.getUniformLocation(gl, 'uWidth')
|
||||||
|
32
src/index.js
32
src/index.js
@ -7,7 +7,7 @@ import { randomInt } from './engine/utility'
|
|||||||
import { Environment } from './engine/environment'
|
import { Environment } from './engine/environment'
|
||||||
import { LODTerrain } from './engine/components/terrain/lod'
|
import { LODTerrain } from './engine/components/terrain/lod'
|
||||||
import { Skybox } from './engine/components/skybox'
|
import { Skybox } from './engine/components/skybox'
|
||||||
import { WaterTile } from './engine/components/water'
|
import { WaterRenderer, WaterTile } from './engine/components/water'
|
||||||
import { Particle, ParticleTexture, ParticleSystem, ParticleRenderer } from './engine/components/particles'
|
import { Particle, ParticleTexture, ParticleSystem, ParticleRenderer } from './engine/components/particles'
|
||||||
import { SimplexHeightMap } from './engine/components/terrain/heightmap'
|
import { SimplexHeightMap } from './engine/components/terrain/heightmap'
|
||||||
import { Material, Texture } from './engine/mesh/material'
|
import { Material, Texture } from './engine/mesh/material'
|
||||||
@ -22,17 +22,17 @@ let prt = new ParticleRenderer()
|
|||||||
|
|
||||||
async function pipeline () {
|
async function pipeline () {
|
||||||
let entity = await loadMesh(game.gl, 'test')
|
let entity = await loadMesh(game.gl, 'test')
|
||||||
let shader = await game.shaders.createShaderFromFiles(game.gl, 'basic', false)
|
|
||||||
let terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
|
let terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
|
||||||
let skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
|
let skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
|
||||||
let waterShader = await game.shaders.createShaderFromFiles(game.gl, 'water', false)
|
|
||||||
|
|
||||||
entity.setRotation([0.0, 0.0, -90.0])
|
entity.setRotation([0.0, 0.0, -90.0])
|
||||||
|
|
||||||
|
// Initialize water
|
||||||
|
let waterRenderer = new WaterRenderer()
|
||||||
let water = new WaterTile([100.0, 0.0, 100.0], 100.0)
|
let water = new WaterTile([100.0, 0.0, 100.0], 100.0)
|
||||||
water.initialize(game.gl)
|
await waterRenderer.initialize(game)
|
||||||
await water.useDUDVMap(game.gl, 'dudv')
|
await waterRenderer.useDUDVMap(game.gl, 'dudv')
|
||||||
await water.useNormalMap(game.gl, 'normalmap')
|
await waterRenderer.useNormalMap(game.gl, 'normalmap')
|
||||||
|
|
||||||
let arialFont = await Font.fromFile('arial')
|
let arialFont = await Font.fromFile('arial')
|
||||||
await arialFont.loadTextures(game.gl)
|
await arialFont.loadTextures(game.gl)
|
||||||
@ -53,7 +53,7 @@ async function pipeline () {
|
|||||||
new Dim4(-0.9, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0))
|
new Dim4(-0.9, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0))
|
||||||
]
|
]
|
||||||
// Nesting test
|
// Nesting test
|
||||||
itms[0].addChild(new GUIText('this project is coded by an idiot', arialFont, 0.8, new Dim4(0.2, 0.0, 0.0, 0.0), new Dim4(1.0, 0.0, 0.3, 0.0), false))
|
itms[0].addChild(new GUIText('', arialFont, 0.8, new Dim4(0.2, 0.0, 0.0, 0.0), new Dim4(1.0, 0.0, 0.3, 0.0), false))
|
||||||
itms[0].children[0].color = [0.0, 0.2, 1.0]
|
itms[0].children[0].color = [0.0, 0.2, 1.0]
|
||||||
|
|
||||||
// Create a height map based on OpenSimplex noise
|
// Create a height map based on OpenSimplex noise
|
||||||
@ -123,7 +123,7 @@ async function pipeline () {
|
|||||||
terrain.updateLODMesh(game.gl)
|
terrain.updateLODMesh(game.gl)
|
||||||
|
|
||||||
// Ripple water
|
// Ripple water
|
||||||
water.update(dt)
|
waterRenderer.update(dt)
|
||||||
|
|
||||||
// Set text to FPS
|
// Set text to FPS
|
||||||
fpsTimer++
|
fpsTimer++
|
||||||
@ -135,37 +135,31 @@ async function pipeline () {
|
|||||||
|
|
||||||
function drawEverything (gl) {
|
function drawEverything (gl) {
|
||||||
game.prepare()
|
game.prepare()
|
||||||
|
|
||||||
// Draw the skybox
|
// Draw the skybox
|
||||||
skyboxShader.use(gl)
|
skyboxShader.use(gl)
|
||||||
skybox.draw(gl, skyboxShader, cam)
|
skybox.draw(gl, skyboxShader, cam)
|
||||||
|
|
||||||
// Use terrain shader
|
// Use terrain shader
|
||||||
terrainShader.use(gl)
|
terrainShader.use(gl)
|
||||||
|
|
||||||
// Set environment variables in shader
|
// Set environment variables in shader
|
||||||
env.draw(gl, terrainShader)
|
env.draw(gl, terrainShader)
|
||||||
|
|
||||||
// Set the viewport uniforms
|
// Set the viewport uniforms
|
||||||
cam.draw(gl, terrainShader)
|
cam.draw(gl, terrainShader)
|
||||||
|
|
||||||
// Draw terrain
|
// Draw terrain
|
||||||
terrain.draw(gl, terrainShader)
|
terrain.draw(gl, terrainShader)
|
||||||
|
|
||||||
shader.use(gl)
|
entity.draw(gl, terrainShader)
|
||||||
cam.draw(gl, shader)
|
|
||||||
entity.draw(gl, shader)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render function for the triangle
|
// Render function for the triangle
|
||||||
game.addRenderFunction(function (gl) {
|
game.addRenderFunction(function (gl) {
|
||||||
water.reflect(gl, cam, drawEverything)
|
waterRenderer.reflect(gl, cam, drawEverything)
|
||||||
water.refract(gl, cam, drawEverything)
|
waterRenderer.refract(gl, cam, drawEverything)
|
||||||
|
|
||||||
drawEverything(gl)
|
drawEverything(gl)
|
||||||
|
|
||||||
waterShader.use(gl)
|
waterRenderer.draw(gl, [water], cam, env.sun)
|
||||||
cam.draw(gl, waterShader)
|
|
||||||
water.draw(gl, waterShader, cam, env.sun)
|
|
||||||
|
|
||||||
// Draw particles
|
// Draw particles
|
||||||
particleSystem.draw(gl, cam)
|
particleSystem.draw(gl, cam)
|
||||||
|
Loading…
Reference in New Issue
Block a user