terrain-gen/shaders/water.frag

79 lines
2.7 KiB
GLSL

#version 420 core
layout(location = 0) out vec4 out_color;
layout(location = 1) out vec4 out_position;
layout(location = 2) out vec4 out_normal;
in vec4 worldSpacePosition;
in vec3 normalWorldSpace;
in vec3 tangentWorldSpace;
in vec3 binormalWorldSpace;
in vec4 landPosition;
flat in mat4 projectionViewMat;
uniform mat4 u_view;
uniform mat4 u_depthVP;
uniform int u_time;
uniform sampler2D reflectionTexture;
uniform sampler2D refractionTexture;
uniform sampler2D waterDepthTexture;
uniform sampler2D shadowMapTexture;
uniform mat3 u_normalMatrix;
uniform float u_dayNightFactor;
uniform vec3 u_cameraPosition;
uniform vec4 u_lightPos;
#include "noise.glsl"
#include "commonlighting.glsl"
float noise(vec3 pos) {
float total = singlePerlin(8657, pos) +
singlePerlin(8657, pos * 2) * 0.5 +
singlePerlin(8657, pos * 3) * 0.25;
return total / 1.75;
}
void main() {
vec3 tint = vec3(0.19, 0.42, 0.92);
vec3 wavesNoisePosition = worldSpacePosition.xyz;
wavesNoisePosition.y = float(u_time) / 2000;
float du = noise(wavesNoisePosition);
float dv = noise(wavesNoisePosition + vec3(6542, -7519, 452));
vec2 distortion = vec2(du, dv);
mat3 tbn = mat3(tangentWorldSpace, binormalWorldSpace, normalWorldSpace);
vec3 waveNormal = normalize(tbn * vec3(du, dv, 1.0));
vec4 screenCoord = projectionViewMat * worldSpacePosition;
vec2 normalizedScreenCoord = screenCoord.xy / screenCoord.w;
vec2 texCoord = vec2(0.5, 0.5) + 0.5 * normalizedScreenCoord;
vec3 eyeVector = normalize(u_cameraPosition - worldSpacePosition.xyz);
vec3 reflectedLightDirection = reflect(-u_lightPos.xyz, waveNormal);
float specularLight = 0;
float shadow = shadow(worldSpacePosition, waveNormal);
float visibility = visibility(shadow) * 0.5 + 0.5;
if (shadow < 0.5) {
specularLight = pow(clamp(dot(eyeVector, reflectedLightDirection), 0.0, 1.0), 100);
}
float diffuseLight = diffuse(waveNormal) * mix(0.2, 1.0, u_dayNightFactor);
float distortionForce = min(-landPosition.y, 1) * 2;
vec4 distortedScreenCoord = projectionViewMat * (worldSpacePosition + (vec4(distortion.x, 0.0, distortion.y, 0.0) * distortionForce));
vec2 distortedCoord = distortedScreenCoord.xy / distortedScreenCoord.w;
vec2 distortedTexCoord = vec2(0.5, 0.5) + 0.5 * distortedCoord;
vec3 color = 0.2 * tint
+ 0.5 * texture2D(reflectionTexture, distortedTexCoord).rgb
+ 0.3 * texture2D(refractionTexture, distortedTexCoord).rgb * texture2D(waterDepthTexture, distortedTexCoord).r;
out_color = vec4(clamp(color * (0.7 + 0.2 * diffuseLight + specularLight) * visibility, 0.0, 1.0), 1.0);
out_position = worldSpacePosition;
out_normal = vec4(waveNormal, 1);
}