Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/shaders/glsl/water_high.fs
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
uniform vec4 waveParams2; // Smallintensity, Smallbase, Bigmovement, Smallmovement | uniform vec4 waveParams2; // Smallintensity, Smallbase, Bigmovement, Smallmovement | ||||
#if USE_REFLECTION | #if USE_REFLECTION | ||||
uniform sampler2D reflectionMap; | uniform sampler2D reflectionMap; | ||||
#endif | #endif | ||||
#if USE_REFRACTION | #if USE_REFRACTION | ||||
uniform sampler2D refractionMap; | uniform sampler2D refractionMap; | ||||
#endif | |||||
#if USE_REAL_DEPTH | #if USE_REAL_DEPTH | ||||
uniform sampler2D depthTex; | uniform sampler2D depthTex; | ||||
uniform float zNear; | uniform mat4 projInvTransform; | ||||
uniform float zFar; | uniform mat4 viewInvTransform; | ||||
#endif | |||||
#endif | #endif | ||||
#if USE_SHADOWS_ON_WATER && USE_SHADOW | #if USE_SHADOWS_ON_WATER && USE_SHADOW | ||||
varying vec4 v_shadow; | varying vec4 v_shadow; | ||||
#if USE_SHADOW_SAMPLER | #if USE_SHADOW_SAMPLER | ||||
uniform sampler2DShadow shadowTex; | uniform sampler2DShadow shadowTex; | ||||
#if USE_SHADOW_PCF | #if USE_SHADOW_PCF | ||||
uniform vec4 shadowScale; | uniform vec4 shadowScale; | ||||
▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | |||||
#else // !USE_REFLECTION && !USE_REFRACTION | #else // !USE_REFLECTION && !USE_REFRACTION | ||||
// Simplest case for reflection, return a gradient of blue based on Y component. | // Simplest case for reflection, return a gradient of blue based on Y component. | ||||
vec3 reflColor = mix(vec3(0.76, 0.84, 0.92), vec3(0.24, 0.43, 0.71), -eye.y); | vec3 reflColor = mix(vec3(0.76, 0.84, 0.92), vec3(0.24, 0.43, 0.71), -eye.y); | ||||
#endif | #endif | ||||
return vec4(reflColor, reflMod); | return vec4(reflColor, reflMod); | ||||
} | } | ||||
#if USE_REFRACTION && USE_REAL_DEPTH | |||||
vec3 getWorldPositionFromRefractionDepth(vec2 uv) | |||||
{ | |||||
float depth = texture2D(depthTex, uv).x; | |||||
vec4 viewPosition = projInvTransform * (vec4((uv - vec2(0.5)) * 2.0, depth * 2.0 - 1.0, 1.0)); | |||||
viewPosition /= viewPosition.w; | |||||
vec3 refrWorldPos = (viewInvTransform * viewPosition).xyz; | |||||
// Depth buffer precision errors can give heights above the water. | |||||
refrWorldPos.y = min(refrWorldPos.y, worldPos.y); | |||||
return refrWorldPos; | |||||
} | |||||
#endif | |||||
vec4 getRefraction(vec3 normal, vec3 eyeVec, float depthLimit) | vec4 getRefraction(vec3 normal, vec3 eyeVec, float depthLimit) | ||||
{ | { | ||||
float depth; | #if USE_REFRACTION && USE_REAL_DEPTH | ||||
#if USE_REAL_DEPTH | |||||
// Compute real depth at the target point. | // Compute real depth at the target point. | ||||
float water_b = gl_FragCoord.z; | vec2 coords = (0.5 * refractionCoords.xy) / refractionCoords.z + 0.5; | ||||
float water_n = 2.0 * water_b - 1.0; | vec3 refrWorldPos = getWorldPositionFromRefractionDepth(coords); | ||||
float waterDBuffer = 2.0 * zNear * zFar / (zFar + zNear - water_n * (zFar - zNear)); | |||||
float undisto_z_b = texture2D(depthTex, (gl_FragCoord.xy) / screenSize).x; | |||||
float undisto_z_n = 2.0 * undisto_z_b - 1.0; | |||||
float waterDepth_undistorted = (2.0 * zNear * zFar / (zFar + zNear - undisto_z_n * (zFar - zNear)) - waterDBuffer); | |||||
// Set depth to the depth at the undistorted point. | // Set depth to the depth at the undistorted point. | ||||
depth = waterDepth_undistorted; | float depth = distance(refrWorldPos, worldPos); | ||||
#else | #else | ||||
// fake depth computation: take the value at the vertex, add some if we are looking at a more oblique angle. | // fake depth computation: take the value at the vertex, add some if we are looking at a more oblique angle. | ||||
depth = waterDepth / (min(0.5, eyeVec.y) * 1.5 * min(0.5, eyeVec.y) * 2.0); | float depth = waterDepth / (min(0.5, eyeVec.y) * 1.5 * min(0.5, eyeVec.y) * 2.0); | ||||
#endif | #endif | ||||
#if USE_REFRACTION | #if USE_REFRACTION | ||||
// for refraction we want to distort more as depth goes down. | // for refraction we want to distort more as depth goes down. | ||||
// 1) compute a distortion based on depth at the pixel. | // 1) compute a distortion based on depth at the pixel. | ||||
// 2) Re-sample the depth at the target point | // 2) Re-sample the depth at the target point | ||||
// 3) Sample refraction texture | // 3) Sample refraction texture | ||||
// distoFactor controls the amount of distortion relative to wave normals. | // distoFactor controls the amount of distortion relative to wave normals. | ||||
float distoFactor = 0.5 + clamp(depth / 2.0, 0.0, 7.0); | float distoFactor = 0.5 + clamp(depth / 2.0, 0.0, 7.0); | ||||
#if USE_REAL_DEPTH | #if USE_REAL_DEPTH | ||||
vec2 depthCoord = clamp((gl_FragCoord.xy) / screenSize - normal.xz * distoFactor / refractionCoords.z, 0.001, 0.999); | // Distort the texture coords under where the water is to simulate refraction. | ||||
float z_b = texture2D(depthTex, depthCoord).x; | vec2 shiftedCoords = (0.5 * refractionCoords.xy - normal.xz * distoFactor) / refractionCoords.z + 0.5; | ||||
float z_n = 2.0 * z_b - 1.0; | vec3 refrWorldPos2 = getWorldPositionFromRefractionDepth(shiftedCoords); | ||||
float newDepth = (2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)) - waterDBuffer); | float newDepth = distance(refrWorldPos2, worldPos); | ||||
// try to correct for fish. In general they'd look weirder without this fix. | // try to correct for fish. In general they'd look weirder without this fix. | ||||
if (depth > newDepth + 3.0) | if (depth > newDepth + 3.0) | ||||
distoFactor /= 2.0; // this in general will not fall on the fish but still look distorted. | distoFactor /= 2.0; // this in general will not fall on the fish but still look distorted. | ||||
else | else | ||||
depth = newDepth; | depth = newDepth; | ||||
#endif | #endif | ||||
#if USE_FANCY_EFFECTS | #if USE_FANCY_EFFECTS | ||||
depth = max(depth, depthLimit); | depth = max(depth, depthLimit); | ||||
if (waterDepth < 0.0) | if (waterDepth < 0.0) | ||||
depth = 0.0; | depth = 0.0; | ||||
#endif | #endif | ||||
// Distort the texture coords under where the water is to simulate refraction. | // Distort the texture coords under where the water is to simulate refraction. | ||||
vec2 refrCoords = (0.5 * refractionCoords.xy - normal.xz * distoFactor) / refractionCoords.z + 0.5; | vec2 refrCoords = (0.5 * refractionCoords.xy - normal.xz * distoFactor) / refractionCoords.z + 0.5; | ||||
vec3 refColor = texture2D(refractionMap, refrCoords).rgb; | vec3 refColor = texture2D(refractionMap, refrCoords).rgb; | ||||
// Note, the refraction map is cleared using (255, 0, 0), so pixels outside of the water plane are pure red. | // Note, the refraction map is cleared using (255, 0, 0), so pixels outside of the water plane are pure red. | ||||
// If we get a pure red fragment, use an undistorted/less distorted coord instead. | // If we get a pure red fragment, use an undistorted/less distorted coord instead. | ||||
// blur the refraction map, distoring using normal so that it looks more random than it really is | // blur the refraction map, distoring using normal so that it looks more random than it really is | ||||
// and thus looks much better. | // and thus looks much better. | ||||
float blur = (0.3 + clamp(normal.x, -0.1, 0.1)) / refractionCoords.z; | float blur = (0.1 + clamp(normal.x, -0.1, 0.1)) / refractionCoords.z; | ||||
vec4 blurColor = vec4(refColor, 1.0); | vec4 blurColor = vec4(refColor, 1.0); | ||||
vec4 tex = texture2D(refractionMap, refrCoords + vec2(blur + normal.x, blur + normal.z)); | vec4 tex = texture2D(refractionMap, refrCoords + vec2(blur + normal.x, blur + normal.z)); | ||||
blurColor += vec4(tex.rgb * tex.a, tex.a); | blurColor += vec4(tex.rgb * tex.a, tex.a); | ||||
tex = texture2D(refractionMap, refrCoords + vec2(-blur, blur + normal.z)); | tex = texture2D(refractionMap, refrCoords + vec2(-blur, blur + normal.z)); | ||||
blurColor += vec4(tex.rgb * tex.a, tex.a); | blurColor += vec4(tex.rgb * tex.a, tex.a); | ||||
tex = texture2D(refractionMap, refrCoords + vec2(-blur, -blur + normal.x)); | tex = texture2D(refractionMap, refrCoords + vec2(-blur, -blur + normal.x)); | ||||
▲ Show 20 Lines • Show All 102 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator