Files
Legacy-Projects/HLSL & GLSL Shaders/Flowing Water (GLSL)/Shader.txt
T
2014-11-24 18:18:24 +01:00

259 lines
8.2 KiB
Plaintext

#version 420
/* Animated Water using Flow Maps
* Shader By: Xaymar
*
* Usage:
* s2FlowMap - FlowMap for the Water, see below on the color components
* s2DiffuseMap - DiffuseMap (Used for <Foam>)
* s2NormalMap - NormalMap (Used for refracting the <Reflection> and <Objects in Water>)
* s2Reflect - Reflection Texture (RGB = Color)
* s2Refract - Refraction Texture (RGB = Color, A = Depth)
* v2Density - Thickness Settings: Density, MinimumDepth
* v3Color - Tinting of Refraction and color of Fog
* v3Animation - Animation Settings: Length, SpeedMul, OffsetMul
* v2ReflectDimensions - Size of 's2Reflect'
* v2RefractDimensions - Size of 's2Refract'
*
* Components of the Flow map:
* Red - X-Direction (Normalized with Y-Direction to create movement Vector)
* Green - Y-Direction (Normalized with X-Direction to create movement Vector)
* Blue - Speed (0.125 = Half, 0.25 = Normal, 0.5 = Double, 1.0 = Quadruple)
*
* NormalMap Color Components:
* RGB - Normal
* Alpha - Height
*/
/* Which Fading technique to use for each Texture.
* Defaults to RGB fading if none is defined.
*/
// YUV based fading
//#define FADE_DIFFUSEMAP_YUV
//#define FADE_NORMALMAP_YUV
// YIQ based fading
//#define FADE_DIFFUSEMAP_YIQ
//#define FADE_NORMALMAP_YIQ
// HSL based fading
//#define FADE_DIFFUSEMAP_HSL
//#define FADE_NORMALMAP_HSL
// HSV based fading
//#define FADE_DIFFUSEMAP_HSV
//#define FADE_NORMALMAP_HSV
/* Enable Debug Modes */
//#define DEBUG_FLOW
//#define DEBUG_TESTDIFFUSE
//#define DEBUG_DIFFUSE
//#define DEBUG_NORMAL
//#define DEBUG_REFRACT
//#define DEBUG_REFLECT
/* Constants */
const float LOG2 = 1.442695;
/* Water Variables */
uniform sampler2D s2DiffuseMap;
uniform sampler2D s2NormalMap;
uniform sampler2D s2FlowMap;
uniform vec2 v2Density;
uniform vec3 v3Color;
uniform vec3 v3Animation;
/* Reflection and Refraction */
uniform sampler2D s2Reflect;
uniform vec2 v2ReflectSize;
uniform sampler2D s2Refract;
uniform vec2 v2RefractSize;
/* Other Things */
uniform float fTime;
uniform float fNormalStrength;
/* Variables from Vertex Program */
in vec2 v2TextureCoord0;
in vec4 v4VertexPosition;
/* Function pre-definitions */
vec3 RGB2YUV(in vec3 RGB);
vec3 YUV2RGB(in vec3 YUV);
vec3 RGB2YIQ(in vec3 RGB);
vec3 YIQ2RGB(in vec3 YIQ);
vec3 RGB2HSL(in vec3 RGB);
vec3 HSL2RGB(in vec3 HSL);
vec3 RGB2HSV(in vec3 RGB);
vec3 HSV2RGB(in vec3 HSV);
// Main Loop
void main(void) {
// Read and convert the flowmap color into useable values.
vec4 v4FlowData = texture(s2FlowMap, v2TextureCoord0);
vec2 v2Offset = normalize(vec2(-1.0 + v4FlowData.r * 2.0, -1.0 + v4FlowData.g * 2.0));
float fSpeed = max(v3Animation.y * (v4FlowData.b * 4.0), 0.00001);
float fTimeOffset = dot(v2Offset, v2TextureCoord0) * v3Animation.z;
// Since the water can flow at different speeds, the same repeat time is not always appropriate.
float fAnimTime = max(v3Animation.x / fSpeed, 0.00001);
float fRealTime = mod(fTime + fTimeOffset, fAnimTime);
float fProgress = fRealTime / fAnimTime;
// Calculate the fade value from how far the time has progressed.
float fFade = sin(radians(fProgress * 90));
// Calculate the new Texture Coords using direction, speed and time.
vec2 v2Coord1 = v2TextureCoord0 + v2Offset * fSpeed * fRealTime;
vec2 v2Coord2 = v2Coord1 - v2Offset * fSpeed * fAnimTime;
// Normal: Gather Texels and combine them.
vec4 v4Normal;
vec4 v4Normal1 = texture(s2NormalMap, v2Coord1);
vec4 v4Normal2 = texture(s2NormalMap, v2Coord2);
// Normal: Fade between Normal1 and Normal2.
#ifdef FADE_NORMALMAP_YUV
v4Normal.rgb = YUV2RGB(mix(RGB2YUV(v4Normal1.rgb), RGB2YUV(v4Normal2.rgb), fFade));
#else
#ifdef FADE_NORMALMAP_YIQ
v4Normal.rgb = YIQ2RGB(mix(RGB2YIQ(v4Normal1.rgb), RGB2YIQ(v4Normal2.rgb), fFade));
#else
#ifdef FADE_NORMALMAP_HSL
v4Normal.rgb = HSL2RGB(mix(RGB2HSL(v4Normal1.rgb), RGB2HSL(v4Normal2.rgb), fFade));
#else
#ifdef FADE_NORMALMAP_HSV
v4Normal.rgb = HSV2RGB(mix(RGB2HSV(v4Normal1.rgb), RGB2HSV(v4Normal2.rgb), fFade));
#else //Default to RGB mixing
v4Normal.rgb = mix(v4Normal1.rgb, v4Normal2.rgb, fFade);
#endif
#endif
#endif
#endif
v4Normal.a = mix(v4Normal1.a, v4Normal2.a, fFade);
// Normal: Adjust XYZ Vector.
v4Normal.xyz = (vec3(-1.0, -1.0, -1.0) + (2.0 * v4Normal.xyz)) * fNormalStrength;
v4Normal.xy *= gl_FragCoord.w;
// Refraction & Reflection: Use Screen Coordinates and Normal map to distort.
vec3 v3RefractColor = texture(s2Refract, (gl_FragCoord.xy / v2RefractSize) + v4Normal.xy).rgb;
vec3 v3ReflectColor = texture(s2Reflect, (gl_FragCoord.xy / v2ReflectSize) + v4Normal.xy).rgb;
// Refraction & Reflection: Visibility is based on Distance to camera and ground.
//@TODO: Visibility using distance to object behind it.
float fDepth = max(length(v4VertexPosition.xyz - gl_ModelViewMatrixInverse[3].xyz) - v2Density.y, 0.0);
float fTransparency = clamp(exp2(-v2Density.x * v2Density.x * fDepth * fDepth * LOG2), 0.0, 1.0);
vec3 v3Output = mix(v3ReflectColor, v3RefractColor * v3Color.rgb, fTransparency);
// Diffuse/Foam: Add foam to the top of the waves.
vec4 v4Diffuse;
vec4 v4Diffuse1 = texture(s2DiffuseMap, v2Coord1);
vec4 v4Diffuse2 = texture(s2DiffuseMap, v2Coord2);
// Diffuse/Foam: Fade between Diffuse1 and Diffuse2.
#ifdef FADE_DIFFUSEMAP_YUV
v4Diffuse.rgb = YUV2RGB(mix(RGB2YUV(v4Diffuse1.rgb), RGB2YUV(v4Diffuse2.rgb), fFade));
#else
#ifdef FADE_DIFFUSEMAP_YIQ
v4Diffuse.rgb = YIQ2RGB(mix(RGB2YIQ(v4Diffuse1.rgb), RGB2YIQ(v4Diffuse2.rgb), fFade));
#else
#ifdef FADE_DIFFUSEMAP_HSL
v4Diffuse.rgb = HSL2RGB(mix(RGB2HSL(v4Diffuse1.rgb), RGB2HSL(v4Diffuse2.rgb), fFade));
#else
#ifdef FADE_DIFFUSEMAP_HSV
v4Diffuse.rgb = HSV2RGB(mix(RGB2HSV(v4Diffuse1.rgb), RGB2HSV(v4Diffuse2.rgb), fFade));
#else //Default to RGB mixing
v4Diffuse.rgb = mix(v4Diffuse1.rgb, v4Diffuse2.rgb, fFade);
#endif
#endif
#endif
#endif
v4Diffuse.a = mix(v4Diffuse1.a, v4Diffuse2.a, fFade);
// Output the result.
#ifdef DEBUG_FLOW
gl_FragColor.rgb = v4FlowData.rgb;
#else
#ifdef DEBUG_DIFFUSE
gl_FragColor.rgb = v4Diffuse.rgb;
#else
#ifdef DEBUG_NORMAL
gl_FragColor.rgb = v3Normal;
#else
#ifdef DEBUG_REFRACT
gl_FragColor.rgb = v3Refract;
#else
#ifdef DEBUG_REFLECT
gl_FragColor.rgb = v3Reflect;
#else
gl_FragColor.rgb = v3Output;
#endif
#endif
#endif
#endif
#endif
}
/* --- --- RGB Conversion Functions --- ---*/
// RGB <-> YUV
const vec3 yuv_Y = vec3(0.299000, 0.587000, 0.114000);
const vec3 yuv_U = vec3(0.595716, -0.274453, -0.321263);
const vec3 yuv_V = vec3(0.211456, -0.522591, 0.311135);
const vec3 yuv_R = vec3(1.0, 0.9562, 0.6210);
const vec3 yuv_G = vec3(1.0, -0.2721, -0.6474);
const vec3 yuv_B = vec3(1.0, -1.1070, 1.7046);
vec3 RGB2YUV(in vec3 RGB) {
return RGB;
}
vec3 YUV2RGB(in vec3 YUV) {
return YUV;
}
// RGB <-> YIQ
const vec3 yiq_Y = vec3(0.299000, 0.587000, 0.114000);
const vec3 yiq_I = vec3(0.595716, -0.274453, -0.321263);
const vec3 yiq_Q = vec3(0.211456, -0.522591, 0.311135);
const vec3 yiq_R = vec3(1.0, 0.9562, 0.6210);
const vec3 yiq_G = vec3(1.0, -0.2721, -0.6474);
const vec3 yiq_B = vec3(1.0, -1.1070, 1.7046);
#define dRGB2YIQ(RGB) vec3(dot(RGB, yiq_Y), dot(RGB, yiq_I), dot(RGB, yiq_Q))
#define dYIQ2RGB(YIQ) vec3(dot(YIQ, yiq_R), dot(YIQ, yiq_G), dot(YIQ, yiq_B))
vec3 RGB2YIQ(in vec3 RGB) {
return vec3(dot(RGB, yiq_Y), dot(RGB, yiq_I), dot(RGB, yiq_Q));
}
vec3 YIQ2RGB(in vec3 YIQ) {
return vec3(dot(YIQ, yiq_R), dot(YIQ, yiq_G), dot(YIQ, yiq_B));
}
// RGB <-> HSL
vec3 RGB2HSL(in vec3 RGB) {
return RGB;
}
vec3 HSL2RGB(in vec3 HSL) {
return HSL;
}
// RGB <-> HSV
const vec4 hsv_From = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
const vec4 hsv_To = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 RGB2HSV(in vec3 RGB) {
vec4 p = mix(vec4(RGB.bg, hsv_From.wz), vec4(RGB.gb, hsv_From.xy), step(RGB.b, RGB.g));
vec4 q = mix(vec4(p.xyw, RGB.r), vec4(RGB.r, p.yzx), step(p.x, RGB.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 HSV2RGB(in vec3 HSV) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(HSV.xxx + hsv_To.xyz) * 6.0 - hsv_To.www);
return HSV.z * mix(hsv_To.xxx, clamp(p - K.xxx, 0.0, 1.0), HSV.y);
}
/* --- --- End Of: RGB Conversion Functions --- --- */