WORKING WATER! (no clipping planes implemented)
This commit is contained in:
parent
d55389dacb
commit
7590e7930e
@ -9,37 +9,38 @@ uniform sampler2D normalMap;
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
uniform float uReflectivity;
|
||||
uniform vec4 uTint;
|
||||
uniform float uDUDVOffset;
|
||||
uniform vec3 uLightColor;
|
||||
uniform vec4 uTint;
|
||||
|
||||
uniform float uShine;
|
||||
uniform float uShineDamper;
|
||||
uniform float uDistortionStrength;
|
||||
|
||||
uniform float uNearPlane;
|
||||
uniform float uFarPlane;
|
||||
|
||||
varying vec2 uv;
|
||||
varying vec3 toCameraVector;
|
||||
varying vec3 fromLightVector;
|
||||
|
||||
const float waterDistortionStrength = 0.02;
|
||||
const float shineDamper = 20.0;
|
||||
const float reflectivity = 0.6;
|
||||
|
||||
const float near = 0.1;
|
||||
const float far = 10000.0;
|
||||
|
||||
void main() {
|
||||
vec2 ndc = (clipSpace.xy / clipSpace.w) / 2.0 + 0.5;
|
||||
vec2 refractTexCoords = vec2(ndc.x, ndc.y);
|
||||
vec2 reflectTexCoords = vec2(ndc.x, -ndc.y);
|
||||
|
||||
float depth = 2.0 * texture2D(depthMap, refractTexCoords).r - 1.0;
|
||||
float floorDistance = 2.0 * near * far / (far + near - depth * (far - near));
|
||||
float floorDistance = 2.0 * uNearPlane * uFarPlane / (uFarPlane + uNearPlane - depth * (uFarPlane - uNearPlane));
|
||||
depth = 2.0 * gl_FragCoord.z - 1.0;
|
||||
float waterDistance = 2.0 * near * far / (far + near - depth * (far - near));
|
||||
float waterDistance = 2.0 * uNearPlane * uFarPlane / (uFarPlane + uNearPlane - depth * (uFarPlane - uNearPlane));
|
||||
float waterDepth = floorDistance - waterDistance;
|
||||
|
||||
vec2 distortedTexCoords = texture2D(dudvMap, vec2(uv.x + uDUDVOffset, uv.y)).rg * 0.1;
|
||||
distortedTexCoords = uv + vec2(distortedTexCoords.x, distortedTexCoords.y + uDUDVOffset);
|
||||
|
||||
// Between -1 and 1
|
||||
vec2 totalDistortion = (texture2D(dudvMap, distortedTexCoords).rg * 2.0 - 1.0) * waterDistortionStrength;
|
||||
float depthDistortionBlend = clamp(waterDepth / 20.0, 0.0, 1.0);
|
||||
vec2 totalDistortion = (texture2D(dudvMap, distortedTexCoords).rg * 2.0 - 1.0) * uDistortionStrength * depthDistortionBlend;
|
||||
|
||||
refractTexCoords += totalDistortion;
|
||||
reflectTexCoords += totalDistortion;
|
||||
@ -61,11 +62,14 @@ void main() {
|
||||
vec3 normal = vec3(normalMapColor.r * 2.0 - 1.0, normalMapColor.b, normalMapColor.g * 2.0 - 1.0);
|
||||
normal = normalize(normal);
|
||||
|
||||
float depthAlpha = clamp(waterDepth / 5.0, 0.0, 1.0);
|
||||
|
||||
vec3 reflectedLight = reflect(normalize(fromLightVector), normal);
|
||||
float specular = max(dot(reflectedLight, viewVector), 0.0);
|
||||
specular = pow(specular, shineDamper);
|
||||
vec3 specularHighlights = uLightColor * specular * reflectivity;
|
||||
specular = pow(specular, uShineDamper);
|
||||
vec3 specularHighlights = uLightColor * specular * uShine * depthAlpha;
|
||||
|
||||
gl_FragColor = mix(reflectColor, refractColor, refractiveFactor);
|
||||
gl_FragColor = mix(gl_FragColor, vec4(uTint.xyz, 1.0), uTint.w) + vec4(specularHighlights, 0.0);
|
||||
gl_FragColor.a = depthAlpha;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 565 KiB After Width: | Height: | Size: 249 KiB |
@ -37,7 +37,7 @@ class WaterFBOs {
|
||||
// create the framebuffer
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer)
|
||||
// indicate that we will always render to color attachment 0
|
||||
gl.drawBuffers.drawBuffersWEBGL([gl.COLOR_ATTACHMENT0])
|
||||
gl.drawBuffers.drawBuffersWEBGL([gl.drawBuffers.COLOR_ATTACHMENT0_WEBGL])
|
||||
return frameBuffer
|
||||
}
|
||||
|
||||
@ -80,6 +80,8 @@ class WaterFBOs {
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null)
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, texture, 0)
|
||||
return texture
|
||||
}
|
||||
@ -94,12 +96,17 @@ class WaterFBOs {
|
||||
}
|
||||
|
||||
class WaterTile extends Node {
|
||||
constructor (pos, scale, reflectivity = 1, tint = [0.0, 0.3, 0.5, 0.2]) {
|
||||
constructor (pos, scale, reflectivity = 0.1, tint = [0.0, 0.3, 0.5, 0.2]) {
|
||||
super(pos, [scale, 0.0, scale])
|
||||
this.fbos = new WaterFBOs()
|
||||
|
||||
this.reflectivity = reflectivity
|
||||
this.tint = tint
|
||||
this.phase = 1.0
|
||||
|
||||
this.shininess = 0.7
|
||||
this.shineDamper = 20.0
|
||||
this.distortionStrength = 0.02
|
||||
}
|
||||
|
||||
initialize (gl) {
|
||||
@ -107,7 +114,7 @@ class WaterTile extends Node {
|
||||
this.fbos.initialize(gl)
|
||||
}
|
||||
|
||||
async useDUDV (gl, file) {
|
||||
async useDUDVMap (gl, file) {
|
||||
this.dudvMap = await Texture.createTexture2D(gl, await Resource.loadImage(file + '.png'), false, gl.LINEAR)
|
||||
}
|
||||
|
||||
@ -136,15 +143,25 @@ class WaterTile extends Node {
|
||||
|
||||
prepare (gl, shader, cam, sun) {
|
||||
const transformLoc = shader.getUniformLocation(gl, 'uModelMatrix')
|
||||
|
||||
const camPosLoc = shader.getUniformLocation(gl, 'uCameraPosition')
|
||||
const refrLoc = shader.getUniformLocation(gl, 'refractionTexture')
|
||||
const reflLoc = shader.getUniformLocation(gl, 'reflectionTexture')
|
||||
const depthLoc = shader.getUniformLocation(gl, 'depthTexture')
|
||||
const depthLoc = shader.getUniformLocation(gl, 'depthMap')
|
||||
const dudvLoc = shader.getUniformLocation(gl, 'dudvMap')
|
||||
const normalLoc = shader.getUniformLocation(gl, 'dudvMap')
|
||||
const normalLoc = shader.getUniformLocation(gl, 'normalMap')
|
||||
|
||||
const reflectivityLoc = shader.getUniformLocation(gl, 'uReflectivity')
|
||||
const tintLoc = shader.getUniformLocation(gl, 'uTint')
|
||||
const phaseLoc = shader.getUniformLocation(gl, 'uDUDVOffset')
|
||||
|
||||
const shininessLoc = shader.getUniformLocation(gl, 'uShine')
|
||||
const damperLoc = shader.getUniformLocation(gl, 'uShineDamper')
|
||||
const distortLoc = shader.getUniformLocation(gl, 'uDistortionStrength')
|
||||
|
||||
const farLoc = shader.getUniformLocation(gl, 'uFarPlane')
|
||||
const nearLoc = shader.getUniformLocation(gl, 'uNearPlane')
|
||||
|
||||
const sunPosLoc = shader.getUniformLocation(gl, 'uLightPosition')
|
||||
const sunColorLoc = shader.getUniformLocation(gl, 'uLightColor')
|
||||
|
||||
@ -154,6 +171,11 @@ class WaterTile extends Node {
|
||||
gl.uniform3fv(sunColorLoc, sun.color)
|
||||
gl.uniform1f(reflectivityLoc, this.reflectivity)
|
||||
gl.uniform1f(phaseLoc, this.phase)
|
||||
gl.uniform1f(shininessLoc, this.shininess)
|
||||
gl.uniform1f(damperLoc, this.shineDamper)
|
||||
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)
|
||||
@ -178,9 +200,19 @@ class WaterTile extends Node {
|
||||
|
||||
this.prepare(gl, shader, cam, sun)
|
||||
|
||||
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)
|
||||
|
||||
gl.disable(gl.BLEND)
|
||||
}
|
||||
|
||||
update (dt) {
|
||||
this.phase += 0.001
|
||||
if (this.phase >= 1) this.phase = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
20
src/index.js
20
src/index.js
@ -28,7 +28,7 @@ async function pipeline () {
|
||||
|
||||
let water = new WaterTile([100.0, 0.0, 100.0], 100.0)
|
||||
water.initialize(game.gl)
|
||||
await water.useDUDV(game.gl, 'dudv')
|
||||
await water.useDUDVMap(game.gl, 'dudv')
|
||||
await water.useNormalMap(game.gl, 'normalmap')
|
||||
|
||||
let arialFont = await Font.fromFile('arial')
|
||||
@ -43,9 +43,8 @@ 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 is example text!\nmulti line!', arialFont, 1.5, new Dim4(0.1, 0.0, -0.1, 0.0), new Dim4(1.0, 0.0, 0.3, 0.0), false))
|
||||
itms[0].children[0].color = [1.0, 0.0, 0.2]
|
||||
itms[0].updateTransform()
|
||||
itms[0].addChild(new GUIText('this project is coded by an idiot', arialFont, 1.5, new Dim4(0.1, 0.0, -0.1, 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
|
||||
let hmap = new SimplexHeightMap(1, 1, 256, 50)
|
||||
@ -76,9 +75,6 @@ async function pipeline () {
|
||||
// Load textures and generate a mesh
|
||||
await skybox.initialize(game.gl)
|
||||
|
||||
itms.push(new GUIImage(water.fbos.reflectionTexture, new Dim4(-0.9, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0)))
|
||||
itms.push(new GUIImage(water.fbos.refractionTexture, new Dim4(-0.3, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0)))
|
||||
|
||||
// Update function for camera and terrain
|
||||
game.addUpdateFunction(function (dt) {
|
||||
if (game.input.isDown('w')) {
|
||||
@ -101,10 +97,16 @@ async function pipeline () {
|
||||
// Update detail levels
|
||||
terrain.update(game.gl, cam)
|
||||
terrain.updateLODMesh(game.gl)
|
||||
|
||||
// Ripple water
|
||||
water.update(dt)
|
||||
})
|
||||
|
||||
function drawEverything (gl) {
|
||||
game.prepare()
|
||||
// Draw the skybox
|
||||
skyboxShader.use(gl)
|
||||
skybox.draw(gl, skyboxShader, cam)
|
||||
|
||||
// Use terrain shader
|
||||
terrainShader.use(gl)
|
||||
@ -121,10 +123,6 @@ async function pipeline () {
|
||||
shader.use(gl)
|
||||
cam.draw(gl, shader)
|
||||
entity.draw(gl, shader)
|
||||
|
||||
// Draw the skybox
|
||||
skyboxShader.use(gl)
|
||||
skybox.draw(gl, skyboxShader, cam)
|
||||
}
|
||||
|
||||
// Render function for the triangle
|
||||
|
Loading…
Reference in New Issue
Block a user