reorganize water renderer

This commit is contained in:
Evert Prants 2020-01-01 01:39:40 +02:00
parent 14bc83125c
commit e56adeeb10
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
3 changed files with 64 additions and 56 deletions

View File

@ -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 }

View File

@ -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')

View File

@ -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)