Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/shaders/glsl/water_high.fs
Show First 20 Lines • Show All 166 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); | ||||||||
} | } | ||||||||
void main() | vec4 getRefraction(vec3 normal, float depthLimit) | ||||||||
{ | { | ||||||||
float fresnel; | |||||||||
vec2 refrCoords; | |||||||||
vec3 refrColor; | |||||||||
// Calculate water normals. | |||||||||
float wavyEffect = waveParams1.r; | |||||||||
float baseScale = waveParams1.g; | |||||||||
float flattenism = waveParams1.b; | |||||||||
float baseBump = waveParams1.a; | |||||||||
float BigMovement = waveParams2.b; | |||||||||
// This method uses 60 animated water frames. We're blending between each two frames | |||||||||
// Scale the normal textures by waviness so that big waviness means bigger waves. | |||||||||
vec3 ww1 = texture2D(normalMap, (normalCoords.st + normalCoords.zw * BigMovement * waviness / 10.0) * (baseScale - waviness / wavyEffect)).xzy; | |||||||||
vec3 ww2 = texture2D(normalMap2, (normalCoords.st + normalCoords.zw * BigMovement * waviness / 10.0) * (baseScale - waviness / wavyEffect)).xzy; | |||||||||
vec3 wwInterp = mix(ww1, ww2, moddedTime) - vec3(0.5, 0.0, 0.5); | |||||||||
ww1.x = wwInterp.x * WindCosSin.x - wwInterp.z * WindCosSin.y; | |||||||||
ww1.z = wwInterp.x * WindCosSin.y + wwInterp.z * WindCosSin.x; | |||||||||
ww1.y = wwInterp.y; | |||||||||
// Flatten them based on waviness. | |||||||||
vec3 normal = normalize(mix(vec3(0.0, 1.0, 0.0), ww1, clamp(baseBump + fwaviness / flattenism, 0.0, 1.0))); | |||||||||
#if USE_FANCY_EFFECTS | |||||||||
vec4 fancyeffects = texture2D(waterEffectsTex, gl_FragCoord.xy / screenSize); | |||||||||
normal = mix(vec3(0.0, 1.0, 0.0), normal, 0.5 + waterInfo.r / 2.0); | |||||||||
normal.xz = mix(normal.xz, fancyeffects.rb, fancyeffects.a / 2.0); | |||||||||
#else | |||||||||
normal = mix(vec3(0.0, 1.0, 0.0), normal, 0.5 + waterInfo.r / 2.0); | |||||||||
#endif | |||||||||
normal = vec3(-normal.x, normal.y, -normal.z); // The final wave normal vector. | |||||||||
float depth; | float depth; | ||||||||
#if 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; | float water_b = gl_FragCoord.z; | ||||||||
float water_n = 2.0 * water_b - 1.0; | float water_n = 2.0 * water_b - 1.0; | ||||||||
float waterDBuffer = 2.0 * zNear * zFar / (zFar + zNear - water_n * (zFar - zNear)); | 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_b = texture2D(depthTex, (gl_FragCoord.xy) / screenSize).x; | ||||||||
Show All 25 Lines | #if USE_REAL_DEPTH | ||||||||
// 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, fancyeffects.a); | 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. | ||||||||
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.3 + clamp(normal.x, -0.1, 0.1)) / refractionCoords.z; | ||||||||
Show All 9 Lines | #endif | ||||||||
blurColor += vec4(tex.rgb * tex.a, tex.a); | blurColor += vec4(tex.rgb * tex.a, tex.a); | ||||||||
blurColor /= blurColor.a; | blurColor /= blurColor.a; | ||||||||
float blurFactor = (distoFactor / 7.0); | float blurFactor = (distoFactor / 7.0); | ||||||||
refColor = (refColor + blurColor.rgb * blurFactor) / (1.0 + blurFactor); | refColor = (refColor + blurColor.rgb * blurFactor) / (1.0 + blurFactor); | ||||||||
#else // !USE_REFRACTION | #else // !USE_REFRACTION | ||||||||
#if USE_FANCY_EFFECTS | #if USE_FANCY_EFFECTS | ||||||||
depth = max(depth, fancyeffects.a); | depth = max(depth, depthLimit); | ||||||||
#endif | #endif | ||||||||
vec3 refColor = color; | vec3 refColor = color; | ||||||||
#endif | #endif | ||||||||
// for refraction, we want to adjust the value by v.y slightly otherwise it gets too different between "from above" and "from the sides". | // for refraction, we want to adjust the value by v.y slightly otherwise it gets too different between "from above" and "from the sides". | ||||||||
// And it looks weird (again, we are not used to seeing water from above). | // And it looks weird (again, we are not used to seeing water from above). | ||||||||
float fixedVy = max(v_eyeVec.y, 0.01); | float fixedVy = max(v_eyeVec.y, 0.01); | ||||||||
float murky = mix(200.0, 0.1, pow(murkiness, 0.25)); | float murky = mix(200.0, 0.1, pow(murkiness, 0.25)); | ||||||||
// Apply water tint and murk color. | |||||||||
float extFact = max(0.0, 1.0 - (depth * fixedVy / murky)); | |||||||||
float ColextFact = max(0.0, 1.0 - (depth * fixedVy / murky)); | |||||||||
vec3 colll = mix(refColor * tint, refColor, ColextFact); | |||||||||
vec3 refrColor = mix(color, colll, extFact); | |||||||||
float alpha = clamp(depth, 0.0, 1.0); | |||||||||
#if !USE_REFRACTION | |||||||||
alpha = (1.4 - extFact) * alpha; | |||||||||
#endif | |||||||||
return vec4(refrColor, alpha); | |||||||||
} | |||||||||
void main() | |||||||||
{ | |||||||||
// Calculate water normals. | |||||||||
float wavyEffect = waveParams1.r; | |||||||||
float baseScale = waveParams1.g; | |||||||||
float flattenism = waveParams1.b; | |||||||||
float baseBump = waveParams1.a; | |||||||||
float BigMovement = waveParams2.b; | |||||||||
// This method uses 60 animated water frames. We're blending between each two frames | |||||||||
// Scale the normal textures by waviness so that big waviness means bigger waves. | |||||||||
vec3 ww1 = texture2D(normalMap, (normalCoords.st + normalCoords.zw * BigMovement * waviness / 10.0) * (baseScale - waviness / wavyEffect)).xzy; | |||||||||
vec3 ww2 = texture2D(normalMap2, (normalCoords.st + normalCoords.zw * BigMovement * waviness / 10.0) * (baseScale - waviness / wavyEffect)).xzy; | |||||||||
vec3 wwInterp = mix(ww1, ww2, moddedTime) - vec3(0.5, 0.0, 0.5); | |||||||||
ww1.x = wwInterp.x * WindCosSin.x - wwInterp.z * WindCosSin.y; | |||||||||
ww1.z = wwInterp.x * WindCosSin.y + wwInterp.z * WindCosSin.x; | |||||||||
ww1.y = wwInterp.y; | |||||||||
// Flatten them based on waviness. | |||||||||
vec3 normal = normalize(mix(vec3(0.0, 1.0, 0.0), ww1, clamp(baseBump + fwaviness / flattenism, 0.0, 1.0))); | |||||||||
#if USE_FANCY_EFFECTS | |||||||||
vec4 fancyeffects = texture2D(waterEffectsTex, gl_FragCoord.xy / screenSize); | |||||||||
normal = mix(vec3(0.0, 1.0, 0.0), normal, 0.5 + waterInfo.r / 2.0); | |||||||||
normal.xz = mix(normal.xz, fancyeffects.rb, fancyeffects.a / 2.0); | |||||||||
#else | |||||||||
normal = mix(vec3(0.0, 1.0, 0.0), normal, 0.5 + waterInfo.r / 2.0); | |||||||||
#endif | |||||||||
normal = vec3(-normal.x, normal.y, -normal.z); // The final wave normal vector. | |||||||||
#if USE_FANCY_EFFECTS | |||||||||
Stan: Needs `USE_REFRACTION`too no ? | |||||||||
vladislavbelovAuthorUnsubmitted Done Inline ActionsNo, since it's accounted in getRefraction. We have kind of "refraction" in any case, USE_REFRACTION just "regulates" quality. vladislavbelov: No, since it's accounted in `getRefraction`. We have kind of "refraction" in any case… | |||||||||
vec4 refrColor = getRefraction(normal, fancyeffects.a); | |||||||||
#else | |||||||||
vec4 refrColor = getRefraction(normal, 0.0); | |||||||||
#endif | |||||||||
vec4 reflColor = getReflection(normal); | |||||||||
// How perpendicular to the normal our view is. Used for fresnel. | // How perpendicular to the normal our view is. Used for fresnel. | ||||||||
float ndotv = clamp(dot(normal, v_eyeVec), 0.0, 1.0); | float ndotv = clamp(dot(normal, v_eyeVec), 0.0, 1.0); | ||||||||
// Fresnel for "how much reflection vs how much refraction". | // Fresnel for "how much reflection vs how much refraction". | ||||||||
fresnel = clamp(((pow(1.1 - ndotv, 2.0)) * 1.5), 0.1, 0.75); // Approximation. I'm using 1.1 and not 1.0 because it causes artifacts, see #1714 | float fresnel = clamp(((pow(1.1 - ndotv, 2.0)) * 1.5), 0.1, 0.75); // Approximation. I'm using 1.1 and not 1.0 because it causes artifacts, see #1714 | ||||||||
// Specular lighting vectors | // Specular lighting vectors | ||||||||
vec3 specVector = reflect(sunDir, ww1); | vec3 specVector = reflect(sunDir, ww1); | ||||||||
// pow is undefined for null or negative values, except on intel it seems. | // pow is undefined for null or negative values, except on intel it seems. | ||||||||
float specIntensity = clamp(pow(abs(dot(specVector, v_eyeVec)), 100.0), 0.0, 1.0); | float specIntensity = clamp(pow(abs(dot(specVector, v_eyeVec)), 100.0), 0.0, 1.0); | ||||||||
vec3 specular = specIntensity * 1.2 * mix(vec3(1.5), sunColor, 0.5); | vec3 specular = specIntensity * 1.2 * mix(vec3(1.5), sunColor, 0.5); | ||||||||
// Apply water tint and murk color. | |||||||||
float extFact = max(0.0, 1.0 - (depth * fixedVy / murky)); | |||||||||
float ColextFact = max(0.0, 1.0 - (depth * fixedVy / murky)); | |||||||||
vec3 colll = mix(refColor * tint, refColor, ColextFact); | |||||||||
refrColor = mix(color, colll, extFact); | |||||||||
vec4 reflColor = getReflection(normal); | |||||||||
vec3 color; | vec3 color; | ||||||||
#if USE_SHADOWS_ON_WATER && USE_SHADOW | #if USE_SHADOWS_ON_WATER && USE_SHADOW | ||||||||
float shadow = get_shadow(vec4(v_shadow.xy, v_shadow.zw)); | float shadow = get_shadow(vec4(v_shadow.xy, v_shadow.zw)); | ||||||||
float fresShadow = mix(fresnel, fresnel * shadow, 0.05 + murkiness * 0.2); | float fresShadow = mix(fresnel, fresnel * shadow, 0.05 + murkiness * 0.2); | ||||||||
color = mix(refrColor, reflColor.rgb, fresShadow * reflColor.a); | color = mix(refrColor.rgb, reflColor.rgb, fresShadow * reflColor.a); | ||||||||
color += shadow * specular; | color += shadow * specular; | ||||||||
#else | #else | ||||||||
color = mix(refrColor, reflColor.rgb, fresnel * reflColor.a); | color = mix(refrColor.rgb, reflColor.rgb, fresnel * reflColor.a); | ||||||||
color += specular; | color += specular; | ||||||||
#endif | #endif | ||||||||
#if USE_FANCY_EFFECTS | #if USE_FANCY_EFFECTS | ||||||||
vec3 foam1 = texture2D(normalMap, (normalCoords.st + normalCoords.zw * BigMovement * waviness / 10.0) * (baseScale - waviness / wavyEffect)).aaa; | vec3 foam1 = texture2D(normalMap, (normalCoords.st + normalCoords.zw * BigMovement * waviness / 10.0) * (baseScale - waviness / wavyEffect)).aaa; | ||||||||
vec3 foam2 = texture2D(normalMap2, (normalCoords.st + normalCoords.zw * BigMovement * waviness / 10.0) * (baseScale - waviness / wavyEffect)).aaa; | vec3 foam2 = texture2D(normalMap2, (normalCoords.st + normalCoords.zw * BigMovement * waviness / 10.0) * (baseScale - waviness / wavyEffect)).aaa; | ||||||||
vec3 foam3 = texture2D(normalMap, normalCoords.st / 6.0 - normalCoords.zw * 0.02).aaa; | vec3 foam3 = texture2D(normalMap, normalCoords.st / 6.0 - normalCoords.zw * 0.02).aaa; | ||||||||
vec3 foam4 = texture2D(normalMap2, normalCoords.st / 6.0 - normalCoords.zw * 0.02).aaa; | vec3 foam4 = texture2D(normalMap2, normalCoords.st / 6.0 - normalCoords.zw * 0.02).aaa; | ||||||||
vec3 foaminterp = mix(foam1, foam2, moddedTime); | vec3 foaminterp = mix(foam1, foam2, moddedTime); | ||||||||
foaminterp *= mix(foam3, foam4, moddedTime); | foaminterp *= mix(foam3, foam4, moddedTime); | ||||||||
foam1.x = abs(foaminterp.x * WindCosSin.x) + abs(foaminterp.z * WindCosSin.y); | foam1.x = abs(foaminterp.x * WindCosSin.x) + abs(foaminterp.z * WindCosSin.y); | ||||||||
color += fancyeffects.g + pow(foam1.x * (3.0 + waviness), 2.6 - waviness / 5.5); | color += fancyeffects.g + pow(foam1.x * (3.0 + waviness), 2.6 - waviness / 5.5); | ||||||||
#endif | #endif | ||||||||
#if USE_FOG | #if USE_FOG | ||||||||
color = get_fog(color); | color = get_fog(color); | ||||||||
#endif | #endif | ||||||||
FreagarachUnsubmitted Not Done Inline Actions
Freagarach: | |||||||||
float alpha = clamp(depth, 0.0, 1.0); | float alpha = refrColor.a; | ||||||||
#if !USE_REFRACTION | |||||||||
alpha = (1.4 - extFact) * alpha; | |||||||||
#endif | |||||||||
float losMod = texture2D(losMap, losCoords.st).a; | float losMod = texture2D(losMap, losCoords.st).a; | ||||||||
losMod = losMod < 0.03 ? 0.0 : losMod; | losMod = losMod < 0.03 ? 0.0 : losMod; | ||||||||
gl_FragColor = vec4(color * losMod, alpha); | gl_FragColor = vec4(color * losMod, alpha); | ||||||||
} | } |
Wildfire Games · Phabricator
Needs USE_REFRACTIONtoo no ?