67 lines
2.1 KiB
GLSL
67 lines
2.1 KiB
GLSL
#include "Uniforms.glsl"
|
|
#include "Samplers.glsl"
|
|
#include "Transform.glsl"
|
|
#include "ScreenPos.glsl"
|
|
#include "Fog.glsl"
|
|
|
|
#ifndef GL_ES
|
|
varying vec4 vScreenPos;
|
|
varying vec2 vReflectUV;
|
|
varying vec2 vWaterUV;
|
|
varying vec4 vEyeVec;
|
|
#else
|
|
varying highp vec4 vScreenPos;
|
|
varying highp vec2 vReflectUV;
|
|
varying highp vec2 vWaterUV;
|
|
varying highp vec4 vEyeVec;
|
|
#endif
|
|
varying vec3 vNormal;
|
|
|
|
#ifdef COMPILEVS
|
|
uniform vec2 cNoiseSpeed;
|
|
uniform float cNoiseTiling;
|
|
#endif
|
|
#ifdef COMPILEPS
|
|
uniform float cNoiseStrength;
|
|
uniform float cFresnelPower;
|
|
uniform vec3 cWaterTint;
|
|
#endif
|
|
|
|
void VS()
|
|
{
|
|
mat4 modelMatrix = iModelMatrix;
|
|
vec3 worldPos = GetWorldPos(modelMatrix);
|
|
gl_Position = GetClipPos(worldPos);
|
|
vScreenPos = GetScreenPos(gl_Position);
|
|
// GetQuadTexCoord() returns a vec2 that is OK for quad rendering; multiply it with output W
|
|
// coordinate to make it work with arbitrary meshes such as the water plane (perform divide in pixel shader)
|
|
// Also because the quadTexCoord is based on the clip position, and Y is flipped when rendering to a texture
|
|
// on OpenGL, must flip again to cancel it out
|
|
vReflectUV = GetQuadTexCoord(gl_Position);
|
|
vReflectUV.y = 1.0 - vReflectUV.y;
|
|
vReflectUV *= gl_Position.w;
|
|
vWaterUV = iTexCoord * cNoiseTiling + cElapsedTime * cNoiseSpeed;
|
|
vNormal = GetWorldNormal(modelMatrix);
|
|
vEyeVec = vec4(cCameraPos - worldPos, GetDepth(gl_Position));
|
|
}
|
|
|
|
void PS()
|
|
{
|
|
vec2 refractUV = vScreenPos.xy / vScreenPos.w;
|
|
vec2 reflectUV = vReflectUV.xy / vScreenPos.w;
|
|
|
|
vec2 noise = (texture2D(sNormalMap, vWaterUV).rg - 0.5) * cNoiseStrength;
|
|
refractUV += noise;
|
|
// Do not shift reflect UV coordinate upward, because it will reveal the clipping of geometry below water
|
|
if (noise.y < 0.0)
|
|
noise.y = 0.0;
|
|
reflectUV += noise;
|
|
|
|
float fresnel = pow(1.0 - clamp(dot(normalize(vEyeVec.xyz), vNormal), 0.0, 1.0), cFresnelPower);
|
|
vec3 refractColor = texture2D(sEnvMap, refractUV).rgb * cWaterTint;
|
|
vec3 reflectColor = texture2D(sDiffMap, reflectUV).rgb;
|
|
vec3 finalColor = mix(refractColor, reflectColor, fresnel);
|
|
|
|
gl_FragColor = vec4(GetFog(finalColor, GetFogFactor(vEyeVec.w)), 1.0);
|
|
}
|