Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/shaders/glsl/water_high.fs
Show First 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | float IntersectBox (in Ray ray, in vec3 minimum, in vec3 maximum) | ||||
vec3 MAX = max ( OMAX, OMIN ); | vec3 MAX = max ( OMAX, OMIN ); | ||||
return min ( MAX.x, min ( MAX.y, MAX.z ) ); | return min ( MAX.x, min ( MAX.y, MAX.z ) ); | ||||
} | } | ||||
vec3 get_fog(vec3 color) | vec3 get_fog(vec3 color) | ||||
{ | { | ||||
float density = fogParams.x; | float density = fogParams.x; | ||||
float maxFog = fogParams.y; | float maxFog = fogParams.y; | ||||
const float LOG2 = 1.442695; | const float LOG2 = 1.442695; | ||||
float z = gl_FragCoord.z / gl_FragCoord.w; | float z = gl_FragCoord.z / gl_FragCoord.w; | ||||
float fogFactor = exp2(-density * density * z * z * LOG2); | float fogFactor = exp2(-density * density * z * z * LOG2); | ||||
fogFactor = fogFactor * (1.0 - maxFog) + maxFog; | fogFactor = fogFactor * (1.0 - maxFog) + maxFog; | ||||
fogFactor = clamp(fogFactor, 0.0, 1.0); | fogFactor = clamp(fogFactor, 0.0, 1.0); | ||||
return mix(fogColor, color, fogFactor); | return mix(fogColor, color, fogFactor); | ||||
} | } | ||||
void main() | void main() | ||||
{ | { | ||||
float fresnel; | float fresnel; | ||||
vec2 reflCoords, refrCoords; | vec2 reflCoords, refrCoords; | ||||
vec3 reflColor, refrColor, specular; | vec3 reflColor, refrColor, specular; | ||||
float losMod, reflMod; | float losMod; | ||||
// Calculate water normals. | // Calculate water normals. | ||||
float wavyEffect = waveParams1.r; | float wavyEffect = waveParams1.r; | ||||
float baseScale = waveParams1.g; | float baseScale = waveParams1.g; | ||||
float flattenism = waveParams1.b; | float flattenism = waveParams1.b; | ||||
float baseBump = waveParams1.a; | float baseBump = waveParams1.a; | ||||
float BigMovement = waveParams2.b; | float BigMovement = waveParams2.b; | ||||
// This method uses 60 animated water frames. We're blending between each two frames | // 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. | // 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 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 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); | vec3 wwInterp = mix(ww1, ww2, moddedTime) - vec3(0.5,0.0,0.5); | ||||
ww1.x = wwInterp.x * WindCosSin.x - wwInterp.z * WindCosSin.y; | ww1.x = wwInterp.x * WindCosSin.x - wwInterp.z * WindCosSin.y; | ||||
ww1.z = wwInterp.x * WindCosSin.y + wwInterp.z * WindCosSin.x; | ww1.z = wwInterp.x * WindCosSin.y + wwInterp.z * WindCosSin.x; | ||||
ww1.y = wwInterp.y; | ww1.y = wwInterp.y; | ||||
// Flatten them based on waviness. | // Flatten them based on waviness. | ||||
vec3 n = normalize(mix(vec3(0.0,1.0,0.0), ww1, clamp(baseBump + fwaviness/flattenism,0.0,1.0))); | vec3 n = normalize(mix(vec3(0.0,1.0,0.0), ww1, clamp(baseBump + fwaviness/flattenism,0.0,1.0))); | ||||
#if USE_FANCY_EFFECTS | #if USE_FANCY_EFFECTS | ||||
vec4 fancyeffects = texture2D(waterEffectsTexNorm, gl_FragCoord.xy/screenSize); | vec4 fancyeffects = texture2D(waterEffectsTexNorm, gl_FragCoord.xy/screenSize); | ||||
n = mix(vec3(0.0,1.0,0.0), n,0.5 + waterInfo.r/2.0); | n = mix(vec3(0.0,1.0,0.0), n,0.5 + waterInfo.r/2.0); | ||||
n.xz = mix(n.xz, fancyeffects.rb,fancyeffects.a/2.0); | n.xz = mix(n.xz, fancyeffects.rb,fancyeffects.a/2.0); | ||||
#else | #else | ||||
n = mix(vec3(0.0,1.0,0.0), n, 0.5 + waterInfo.r/2.0); | n = mix(vec3(0.0,1.0,0.0), n, 0.5 + waterInfo.r/2.0); | ||||
#endif | #endif | ||||
n = vec3(-n.x,n.y,-n.z); // The final wave normal vector. | n = vec3(-n.x,n.y,-n.z); // The final wave normal vector. | ||||
// 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(n, v),0.0,1.0); | float ndotv = clamp(dot(n, v),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 | 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)), 100.0), 0.0, 1.0); | float specIntensity = clamp(pow(abs(dot(specVector, v)), 100.0), 0.0, 1.0); | ||||
specular = specIntensity*1.2 * mix(vec3(1.5), sunColor,0.5); | specular = specIntensity*1.2 * mix(vec3(1.5), sunColor,0.5); | ||||
#if USE_SHADOWS_ON_WATER && USE_SHADOW | |||||
float shadow = get_shadow(vec4(v_shadow.xy, v_shadow.zw)); | |||||
#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". | |||||
// And it looks weird (again, we are not used to seeing water from above). | |||||
float fixedVy = max(v.y,0.01); | |||||
float murky = mix(200.0,0.1,pow(murkiness,0.25)); | |||||
vladislavbelov: Some missing spaces here and above. | |||||
float depth; | float depth; | ||||
#if USE_REAL_DEPTH | #if USE_REAL_DEPTH | ||||
// Don't change these two. They should match the values in the config (TODO: dec uniforms). | // Don't change these two. They should match the values in the config (TODO: dec uniforms). | ||||
float zNear = 2.0; | float zNear = 2.0; | ||||
float zFar = 4096.0; | float zFar = 4096.0; | ||||
// Okay so here it's a tad complicated. I want to distort the depth buffer along the waves for a nice effect. | // Compute real depth at the target point. | ||||
// However this causes a problem around underwater objects (think fishes): on some pixels, the depth will be seen as the same as the fishes' | |||||
// and the color will be grass ( cause I don't distort the refraction coord by exactly the same stuff) | |||||
// Also, things like towers with the feet in water would cause the buffer to see the depth as actually negative in some places. | |||||
// So what I do is first check the undistorted depth, then I compare with the distorted value and fix. | |||||
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; | ||||
float undisto_z_n = 2.0 * undisto_z_b - 1.0; | 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); | float waterDepth_undistorted = (2.0 * zNear * zFar / (zFar + zNear - undisto_z_n * (zFar - zNear)) - waterDBuffer); | ||||
vec2 depthCoord = clamp((gl_FragCoord.xy) / screenSize - n.xz*clamp( waterDepth_undistorted/400.0,0.0,0.05) , 0.001, 0.999); | // Set depth to the depth at the undistorted point. | ||||
depth = waterDepth_undistorted; | |||||
float z_b = texture2D(depthTex, depthCoord).x; | |||||
if (z_b < undisto_z_b) | |||||
z_b = undisto_z_b; | |||||
float z_n = 2.0 * z_b - 1.0; | |||||
depth = (2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)) - waterDBuffer); | |||||
#else | #else | ||||
// 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,v.y)*1.5*min(0.5,v.y)*2.0); | depth = waterDepth / (min(0.5,v.y)*1.5*min(0.5,v.y)*2.0); | ||||
#endif | #endif | ||||
#if USE_FANCY_EFFECTS | #if USE_FANCY_EFFECTS | ||||
depth = max(depth,fancyeffects.a); | depth = max(depth,fancyeffects.a); | ||||
#endif | #endif | ||||
#if USE_SHADOWS_ON_WATER && USE_SHADOW | |||||
float shadow = get_shadow(vec4(v_shadow.xy, v_shadow.zw)); | |||||
#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". | |||||
// And it looks weird (again, we are not used to seeing water from above). | |||||
float fixedVy = max(v.y,0.01); | |||||
float murky = mix(200.0,0.1,pow(murkiness,0.25)); | |||||
#if USE_REFRACTION | #if USE_REFRACTION | ||||
// for refraction we want to distort more as depth goes down. | |||||
// 1) compute a distortion based on depth at the pixel. | |||||
// 2) Re-sample the depth at the target point | |||||
// 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 | |||||
vec2 depthCoord = clamp((gl_FragCoord.xy) / screenSize - n.xz * distoFactor / refractionCoords.z, 0.001, 0.999); | |||||
float z_b = texture2D(depthTex, depthCoord).x; | |||||
float z_n = 2.0 * z_b - 1.0; | |||||
float newDepth = (2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)) - waterDBuffer); | |||||
// try to correct for fish. In general they'd look weirder without this fix. | |||||
if (depth > newDepth + 3.0) | |||||
distoFactor /= 2.0; // this in general will not fall on the fish but still look distorted. | |||||
else | |||||
depth = newDepth; | |||||
#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 - n.xz * distoFactor) / refractionCoords.z + 0.5; | refrCoords = (0.5 * refractionCoords.xy - n.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. | ||||
if (refColor.r > 0.999 && refColor.g < 0.001) | |||||
{ | |||||
refrCoords = (0.5*refractionCoords.xy) / refractionCoords.z + 0.5; | |||||
refColor = texture2D(refractionMap, refrCoords).rgb; | |||||
if (refColor.r > 0.999 && refColor.g < 0.001) | |||||
fresnel = 1.0; | |||||
} | |||||
else | |||||
{ | |||||
// blur the refraction map, distoring using n so that it looks more random than it really is | // blur the refraction map, distoring using n 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(n.x,-0.1,0.1))/refractionCoords.z; | float blur = (0.3+clamp(n.x,-0.1,0.1))/refractionCoords.z; | ||||
vec3 blurColor = texture2D(refractionMap, refrCoords + vec2(blur+n.x, blur+n.z)).rgb; | vec4 blurColor = vec4(refColor, 1.0); | ||||
blurColor += texture2D(refractionMap, refrCoords + vec2(-blur, blur+n.z)).rgb; | |||||
blurColor += texture2D(refractionMap, refrCoords + vec2(-blur, -blur+n.x)).rgb; | vec4 tex = texture2D(refractionMap, refrCoords + vec2(blur+n.x, blur+n.z)); | ||||
blurColor += texture2D(refractionMap, refrCoords + vec2(blur+n.z, -blur)).rgb; | blurColor += vec4(tex.rgb * tex.a, tex.a); | ||||
blurColor /= 4.0; | tex = texture2D(refractionMap, refrCoords + vec2(-blur, blur+n.z)); | ||||
blurColor += vec4(tex.rgb * tex.a, tex.a); | |||||
tex = texture2D(refractionMap, refrCoords + vec2(-blur, -blur+n.x)); | |||||
blurColor += vec4(tex.rgb * tex.a, tex.a); | |||||
tex = texture2D(refractionMap, refrCoords + vec2(blur+n.z, -blur)); | |||||
blurColor += vec4(tex.rgb * tex.a, tex.a); | |||||
blurColor /= blurColor.a; | |||||
float blurFactor = (distoFactor/7.0); | float blurFactor = (distoFactor/7.0); | ||||
refColor = (refColor + blurColor * blurFactor) / (1.0+blurFactor); | refColor = (refColor + blurColor.rgb * blurFactor) / (1.0+blurFactor); | ||||
} | |||||
// Apply water tint and murk color. | // Apply water tint and murk color. | ||||
float extFact = max(0.0,1.0 - (depth*fixedVy/murky)); | float extFact = max(0.0,1.0 - (depth*fixedVy/murky)); | ||||
float ColextFact = 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 colll = mix(refColor*tint,refColor,ColextFact); | ||||
refrColor = mix(color, colll, extFact); | refrColor = mix(color, colll, extFact); | ||||
#else | #else | ||||
// Apply water tint and murk color only. | // Apply water tint and murk color only. | ||||
float extFact = max(0.0,1.0 - (depth*fixedVy/murky)); | float extFact = max(0.0,1.0 - (depth*fixedVy/murky)); | ||||
float ColextFact = max(0.0,1.0 - (depth*fixedVy/murky)); | float ColextFact = max(0.0,1.0 - (depth*fixedVy/murky)); | ||||
vec3 colll = mix(color*tint,color,ColextFact); | vec3 colll = mix(color*tint,color,ColextFact); | ||||
refrColor = mix(color, colll, extFact); | refrColor = mix(color, colll, extFact); | ||||
#endif | #endif | ||||
#if USE_REFLECTION | |||||
// Reflections | // Reflections | ||||
// We use real reflections against the skybox, and distort a texture of objects closer. | // 3 level of settings: | ||||
// -If a player has refraction and reflection disabled, we return a gradient of blue based on the Y component. | |||||
// -If a player has refraction OR reflection, we return a reflection of the actual skybox used. | |||||
// -If a player has reflection enabled, we also return a reflection of actual entities where applicable. | |||||
float reflMod = 0.75; | |||||
vec3 eye = reflect(v,n); | vec3 eye = reflect(v,n); | ||||
#if USE_REFLECTION || USE_REFRACTION | |||||
#if USE_REFLECTION | |||||
float refVY = clamp(v.y*2.0,0.05,1.0); | float refVY = clamp(v.y*2.0,0.05,1.0); | ||||
// Distort the reflection coords based on waves. | // Distort the reflection coords based on waves. | ||||
reflCoords = (0.5*reflectionCoords.xy - 15.0 * n.zx / refVY) / reflectionCoords.z + 0.5; | reflCoords = (0.5*reflectionCoords.xy - 15.0 * n.zx / refVY) / reflectionCoords.z + 0.5; | ||||
vec4 refTex = texture2D(reflectionMap, reflCoords); | vec4 refTex = texture2D(reflectionMap, reflCoords); | ||||
reflColor = refTex.rgb; | reflColor = refTex.rgb; | ||||
if (refTex.a < 0.99) | if (refTex.a < 0.99) | ||||
{ | { | ||||
#endif | |||||
// Calculate where we intersect with the skycube. | // Calculate where we intersect with the skycube. | ||||
Ray myRay = Ray(vec3(worldPos.x/4.0,worldPos.y,worldPos.z/4.0),eye); | Ray myRay = Ray(vec3(worldPos.x/4.0,worldPos.y,worldPos.z/4.0),eye); | ||||
vec3 start = vec3(-1500.0 + mapSize/2.0,-100.0,-1500.0 + mapSize/2.0); | vec3 start = vec3(-1500.0 + mapSize/2.0,-100.0,-1500.0 + mapSize/2.0); | ||||
vec3 end = vec3(1500.0 + mapSize/2.0,500.0,1500.0 + mapSize/2.0); | vec3 end = vec3(1500.0 + mapSize/2.0,500.0,1500.0 + mapSize/2.0); | ||||
float tmin = IntersectBox(myRay,start,end); | float tmin = IntersectBox(myRay,start,end); | ||||
vec4 newpos = vec4(-worldPos.x/4.0,worldPos.y,-worldPos.z/4.0,1.0) + vec4(eye * tmin,0.0) - vec4(-mapSize/2.0,worldPos.y,-mapSize/2.0,0.0); | vec4 newpos = vec4(-worldPos.x/4.0,worldPos.y,-worldPos.z/4.0,1.0) + vec4(eye * tmin,0.0) - vec4(-mapSize/2.0,worldPos.y,-mapSize/2.0,0.0); | ||||
newpos *= skyBoxRot; | newpos *= skyBoxRot; | ||||
newpos.y *= 4.0; | newpos.y *= 4.0; | ||||
#if !USE_REFLECTION | |||||
reflColor = textureCube(skyCube, newpos.rgb).rgb; | |||||
#else | |||||
// Interpolate between the sky color and nearby objects. | // Interpolate between the sky color and nearby objects. | ||||
reflColor = mix(textureCube(skyCube, newpos.rgb).rgb, refTex.rgb, refTex.a); | reflColor = mix(textureCube(skyCube, newpos.rgb).rgb, refTex.rgb, refTex.a); | ||||
} | } | ||||
// reflMod is used to reduce the intensity of sky reflections, which otherwise are too extreme. | // reflMod is used to reduce the intensity of sky reflections, which otherwise are too extreme. | ||||
reflMod = max(refTex.a, 0.75); | reflMod = max(refTex.a, 0.75); | ||||
#endif | |||||
#else | #else | ||||
reflMod = 0.75; | // Simplest case for reflection, return a gradient of blue based on Y component. | ||||
reflColor = vec3(0.15, 0.7, 0.82); | reflColor = mix(vec3(0.76, 0.84, 0.92), vec3(0.24, 0.43, 0.71), -eye.y); | ||||
#endif | #endif | ||||
losMod = texture2D(losMap, losCoords.st).a; | losMod = texture2D(losMap, losCoords.st).a; | ||||
losMod = losMod < 0.03 ? 0.0 : losMod; | losMod = losMod < 0.03 ? 0.0 : losMod; | ||||
vec3 color; | vec3 color; | ||||
#if USE_SHADOWS_ON_WATER && USE_SHADOW | #if USE_SHADOWS_ON_WATER && USE_SHADOW | ||||
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, fresShadow); | color = mix(refrColor, reflColor, fresShadow * reflMod); | ||||
#else | #else | ||||
color = mix(refrColor, reflColor, fresnel * reflMod); | color = mix(refrColor, reflColor, fresnel * reflMod); | ||||
#endif | #endif | ||||
#if USE_SHADOWS_ON_WATER && USE_SHADOW | #if USE_SHADOWS_ON_WATER && USE_SHADOW | ||||
color += shadow*specular; | color += shadow*specular; | ||||
#else | #else | ||||
color += specular; | color += specular; | ||||
#endif | #endif | ||||
#if USE_FOG | #if USE_FOG | ||||
color = get_fog(color); | color = get_fog(color); | ||||
#endif | #endif | ||||
#if USE_FANCY_EFFECTS | #if USE_FANCY_EFFECTS | ||||
vec4 FoamEffects = texture2D(waterEffectsTexOther, gl_FragCoord.xy/screenSize); | vec4 FoamEffects = texture2D(waterEffectsTexOther, gl_FragCoord.xy/screenSize); | ||||
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 = foaminterp.x * WindCosSin.x - foaminterp.z * WindCosSin.y; | foam1.x = foaminterp.x * WindCosSin.x - foaminterp.z * WindCosSin.y; | ||||
color += FoamEffects.r * FoamEffects.a * 0.4 + pow(foam1.x * (5.0 + waviness), 2.6 - waviness / 5.5); | color += FoamEffects.r * FoamEffects.a * 0.4 + pow(foam1.x * (5.0 + waviness), 2.6 - waviness / 5.5); | ||||
#endif | #endif | ||||
float alpha = 1.0; | float alpha = 1.0; | ||||
#if !USE_REFRACTION | #if !USE_REFRACTION | ||||
alpha = 1.4 - extFact; | alpha = 1.4 - extFact; | ||||
#endif | #endif | ||||
#if USE_FANCY_EFFECTS | #if USE_FANCY_EFFECTS | ||||
if (fancyeffects.a < 0.05 && waterDepth < -1.0 ) | if (fancyeffects.a < 0.05 && waterDepth < -1.0 ) | ||||
alpha = 0.0; | alpha = 0.0; | ||||
#endif | #endif | ||||
gl_FragColor = vec4(color * losMod, alpha); | gl_FragColor = vec4(color * losMod, alpha); | ||||
} | } |
Wildfire Games · Phabricator
Some missing spaces here and above.