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 { Texture } from '../../mesh/material'
import Screen from '../../screen'
import Resource from '../../resource'
class WaterFBOs {
constructor (reflectionWidth = 320, reflectionHeight = 180, refractionWidth = 1280, refractionHeight = 720) {
@ -96,8 +95,13 @@ class WaterFBOs {
}
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])
}
}
class WaterRenderer {
constructor (reflectivity = 0.1, tint = [0.0, 0.3, 0.5, 0.2]) {
this.fbos = new WaterFBOs()
this.reflectivity = reflectivity
@ -107,11 +111,7 @@ class WaterTile extends Node {
this.shininess = 0.7
this.shineDamper = 20.0
this.distortionStrength = 0.02
}
initialize (gl) {
this.mesh = Mesh.constructFromVertices(gl, [-1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1], 2)
this.fbos.initialize(gl)
this.waveSpeed = 0.001
}
async useDUDVMap (gl, file) {
@ -124,7 +124,7 @@ class WaterTile extends Node {
reflect (gl, cam, render) {
this.fbos.bindReflectionFrameBuffer(gl)
let dist = 2 * (cam.pos[1] - this.pos[1])
let dist = 2 * cam.pos[1]
cam.pos[1] -= dist
cam.rotation[1] *= -1
cam.updateTransform()
@ -141,31 +141,35 @@ class WaterTile extends Node {
this.fbos.unbindFrameBuffer(gl)
}
prepare (gl, shader, cam, sun) {
const transformLoc = shader.getUniformLocation(gl, 'uModelMatrix')
async initialize (game) {
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')
const refrLoc = shader.getUniformLocation(gl, 'refractionTexture')
const reflLoc = shader.getUniformLocation(gl, 'reflectionTexture')
const depthLoc = shader.getUniformLocation(gl, 'depthMap')
const dudvLoc = shader.getUniformLocation(gl, 'dudvMap')
const normalLoc = shader.getUniformLocation(gl, 'normalMap')
prepare (gl, cam, sun) {
const camPosLoc = this.shader.getUniformLocation(gl, 'uCameraPosition')
const refrLoc = this.shader.getUniformLocation(gl, 'refractionTexture')
const reflLoc = this.shader.getUniformLocation(gl, 'reflectionTexture')
const depthLoc = this.shader.getUniformLocation(gl, 'depthMap')
const dudvLoc = this.shader.getUniformLocation(gl, 'dudvMap')
const normalLoc = this.shader.getUniformLocation(gl, 'normalMap')
const reflectivityLoc = shader.getUniformLocation(gl, 'uReflectivity')
const tintLoc = shader.getUniformLocation(gl, 'uTint')
const phaseLoc = shader.getUniformLocation(gl, 'uDUDVOffset')
const reflectivityLoc = this.shader.getUniformLocation(gl, 'uReflectivity')
const tintLoc = this.shader.getUniformLocation(gl, 'uTint')
const phaseLoc = this.shader.getUniformLocation(gl, 'uDUDVOffset')
const shininessLoc = shader.getUniformLocation(gl, 'uShine')
const damperLoc = shader.getUniformLocation(gl, 'uShineDamper')
const distortLoc = shader.getUniformLocation(gl, 'uDistortionStrength')
const shininessLoc = this.shader.getUniformLocation(gl, 'uShine')
const damperLoc = this.shader.getUniformLocation(gl, 'uShineDamper')
const distortLoc = this.shader.getUniformLocation(gl, 'uDistortionStrength')
const farLoc = shader.getUniformLocation(gl, 'uFarPlane')
const nearLoc = shader.getUniformLocation(gl, 'uNearPlane')
const farLoc = this.shader.getUniformLocation(gl, 'uFarPlane')
const nearLoc = this.shader.getUniformLocation(gl, 'uNearPlane')
const sunPosLoc = shader.getUniformLocation(gl, 'uLightPosition')
const sunColorLoc = shader.getUniformLocation(gl, 'uLightColor')
const sunPosLoc = this.shader.getUniformLocation(gl, 'uLightPosition')
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(sunPosLoc, sun.pos)
gl.uniform3fv(sunColorLoc, sun.color)
@ -176,7 +180,6 @@ class WaterTile extends Node {
gl.uniform1f(distortLoc, this.distortionStrength)
gl.uniform1f(nearLoc, cam.nearPlane)
gl.uniform1f(farLoc, cam.farPlane)
gl.uniform4fv(tintLoc, this.tint)
gl.uniform1i(reflLoc, 0)
gl.uniform1i(refrLoc, 1)
gl.uniform1i(dudvLoc, 2)
@ -195,25 +198,35 @@ class WaterTile extends Node {
gl.bindTexture(gl.TEXTURE_2D, this.fbos.refractionDepthTexture)
}
draw (gl, shader, cam, sun) {
super.draw(gl, shader)
this.prepare(gl, shader, cam, sun)
draw (gl, waters, cam, sun) {
this.shader.use(gl)
gl.enable(gl.BLEND)
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
this.mesh.prepare(gl, shader)
this.mesh.draw(gl, shader)
this.mesh.postdraw(gl, shader)
// Send camera matrices to the shader
cam.draw(gl, this.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)
}
update (dt) {
this.phase += 0.001
this.phase += this.waveSpeed
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) {
// Let only the font shader be used to render text
if (shader.name !== 'font') return super.draw(gl, shader)
if (!this.text) return
const transformLocation = shader.getUniformLocation(gl, 'uTransformation')
const cLocation = shader.getUniformLocation(gl, 'uColor')
const wLocation = shader.getUniformLocation(gl, 'uWidth')

View File

@ -7,7 +7,7 @@ import { randomInt } from './engine/utility'
import { Environment } from './engine/environment'
import { LODTerrain } from './engine/components/terrain/lod'
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 { SimplexHeightMap } from './engine/components/terrain/heightmap'
import { Material, Texture } from './engine/mesh/material'
@ -22,17 +22,17 @@ let prt = new ParticleRenderer()
async function pipeline () {
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 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])
// Initialize water
let waterRenderer = new WaterRenderer()
let water = new WaterTile([100.0, 0.0, 100.0], 100.0)
water.initialize(game.gl)
await water.useDUDVMap(game.gl, 'dudv')
await water.useNormalMap(game.gl, 'normalmap')
await waterRenderer.initialize(game)
await waterRenderer.useDUDVMap(game.gl, 'dudv')
await waterRenderer.useNormalMap(game.gl, 'normalmap')
let arialFont = await Font.fromFile('arial')
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))
]
// 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]
// Create a height map based on OpenSimplex noise
@ -123,7 +123,7 @@ async function pipeline () {
terrain.updateLODMesh(game.gl)
// Ripple water
water.update(dt)
waterRenderer.update(dt)
// Set text to FPS
fpsTimer++
@ -135,37 +135,31 @@ async function pipeline () {
function drawEverything (gl) {
game.prepare()
// Draw the skybox
skyboxShader.use(gl)
skybox.draw(gl, skyboxShader, cam)
// Use terrain shader
terrainShader.use(gl)
// Set environment variables in shader
env.draw(gl, terrainShader)
// Set the viewport uniforms
cam.draw(gl, terrainShader)
// Draw terrain
terrain.draw(gl, terrainShader)
shader.use(gl)
cam.draw(gl, shader)
entity.draw(gl, shader)
entity.draw(gl, terrainShader)
}
// Render function for the triangle
game.addRenderFunction(function (gl) {
water.reflect(gl, cam, drawEverything)
water.refract(gl, cam, drawEverything)
waterRenderer.reflect(gl, cam, drawEverything)
waterRenderer.refract(gl, cam, drawEverything)
drawEverything(gl)
waterShader.use(gl)
cam.draw(gl, waterShader)
water.draw(gl, waterShader, cam, env.sun)
waterRenderer.draw(gl, [water], cam, env.sun)
// Draw particles
particleSystem.draw(gl, cam)