mirror of
https://github.com/X0nk/Bliss-Shader.git
synced 2026-10-10 05:03:04 +08:00
add additional water fog controls, centralize water absorbance into one file
This commit is contained in:
@@ -182,6 +182,7 @@ float convertHandDepth_2(in float depth, bool hand) {
|
||||
#include "/lib/diffuse_lighting.glsl"
|
||||
#include "/lib/end_fog.glsl"
|
||||
#include "/lib/DistantHorizons_projections.glsl"
|
||||
#include "/lib/water_absorbance_effects.glsl"
|
||||
|
||||
float ld(float dist) {
|
||||
return (2.0 * near) / (far + near - dist * (far - near));
|
||||
@@ -912,8 +913,8 @@ void main() {
|
||||
vec3 viewPos = toScreenSpace(vec3(texcoord/RENDER_SCALE - taaJitter*texelSize*0.5, z));
|
||||
#endif
|
||||
|
||||
vec3 feetPlayerPos = mat3(gbufferModelViewInverse) * viewPos;
|
||||
vec3 feetPlayerPos_normalized = normalize(feetPlayerPos);
|
||||
vec3 feetPlayerPos = mat3(gbufferModelViewInverse) * viewPos + gbufferModelViewInverse[3].xyz;
|
||||
vec3 feetPlayerPos_normalized = normalize(feetPlayerPos );
|
||||
|
||||
#ifdef POM
|
||||
#ifdef Horrible_slope_normals
|
||||
@@ -971,95 +972,23 @@ void main() {
|
||||
//////////////////////////////// UNDER WATER SHADING ////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
if ((isEyeInWater == 0 && isWater) || (isEyeInWater == 1 && !isWater)){
|
||||
|
||||
feetPlayerPos += gbufferModelViewInverse[3].xyz;
|
||||
|
||||
#ifdef USING_LOD_MOD
|
||||
vec3 playerPos0 = mat3(gbufferModelViewInverse) * toScreenSpace_DH(texcoord/RENDER_SCALE-taaJitter*texelSize*0.5, z0, DH_depth0) + gbufferModelViewInverse[3].xyz;
|
||||
#else
|
||||
vec3 playerPos0 = mat3(gbufferModelViewInverse) * toScreenSpace(vec3(texcoord/RENDER_SCALE-taaJitter*texelSize*0.5,z0)) + gbufferModelViewInverse[3].xyz;
|
||||
#endif
|
||||
|
||||
float Vdiff = distance(feetPlayerPos, playerPos0);
|
||||
float estimatedDepth = Vdiff* abs(feetPlayerPos_normalized.y);// assuming water plane
|
||||
|
||||
|
||||
// vec3 waterNormal = clamp(normalize(cross(dFdx(playerPos0), dFdy(playerPos0))),-1,1); // it uses depth that has POM written to it.
|
||||
// vec3 absPlayerPosNorm = abs(feetPlayerPos_normalized);
|
||||
// estimatedDepth = mix(estimatedDepth, Vdiff*absPlayerPosNorm.y, max(waterNormal.y,0));
|
||||
// estimatedDepth = mix(estimatedDepth, Vdiff*absPlayerPosNorm.y, max(-waterNormal.y,0));
|
||||
// estimatedDepth = mix(estimatedDepth, Vdiff*absPlayerPosNorm.z, max(waterNormal.z,0));
|
||||
// estimatedDepth = mix(estimatedDepth, Vdiff*absPlayerPosNorm.z, max(-waterNormal.z,0));
|
||||
// estimatedDepth = mix(estimatedDepth, Vdiff*absPlayerPosNorm.x, max(waterNormal.x,0));
|
||||
// estimatedDepth = mix(estimatedDepth, Vdiff*absPlayerPosNorm.x, max(-waterNormal.x,0));
|
||||
|
||||
// force the absorbance to start way closer to the water surface in low light areas, so the water is visible in caves and such.
|
||||
#if MINIMUM_WATER_ABSORBANCE > -1
|
||||
float minimumAbsorbance = MINIMUM_WATER_ABSORBANCE*0.1;
|
||||
#else
|
||||
float minimumAbsorbance = (1.0 - lightLeakFix);
|
||||
#endif
|
||||
|
||||
Absorbtion = exp(-totEpsilon * max(Vdiff, minimumAbsorbance));
|
||||
|
||||
// things to note about sunlight in water
|
||||
// sunlight gets absorbed by water on the way down to the floor, and on the way back up to your eye. im gonna ingore the latter part lol
|
||||
// based on the angle of the sun, sunlight will travel through more/less water to reach the same spot. scale absorbtion depth accordingly
|
||||
vec3 sunlightAbsorbtion = exp(-totEpsilon * (estimatedDepth/abs(WsunVec.y)));
|
||||
float percievedWaterDepth = estimatedDepth;
|
||||
|
||||
|
||||
if (isEyeInWater == 1){
|
||||
|
||||
estimatedDepth = 1.0;
|
||||
|
||||
// viewerWaterDepth = max(0.9-lightmap.y,0.0)*3.0;
|
||||
float distanceFromWaterSurface = -(feetPlayerPos.y + (cameraPosition.y - waterEnteredAltitude));//max(-(feetPlayerPos.y + (cameraPosition.y - waterEnteredAltitude)),0.0) ;
|
||||
|
||||
percievedWaterDepth = distanceFromWaterSurface;
|
||||
|
||||
distanceFromWaterSurface = max(distanceFromWaterSurface,0.0);
|
||||
|
||||
Absorbtion = exp(-totEpsilon * distanceFromWaterSurface);
|
||||
|
||||
sunlightAbsorbtion = exp(-totEpsilon * (distanceFromWaterSurface/abs(WsunVec.y)));
|
||||
|
||||
} else {
|
||||
// use hardcoded gradient position if the water surface normal does not face upwards.
|
||||
// vec3 waterNormal = clamp(normalize(cross(dFdx(playerPos0), dFdy(playerPos0))),0,1); // it uses depth that has POM written to it.
|
||||
// percievedWaterDepth = mix( -(feetPlayerPos.y + cameraPosition.y),percievedWaterDepth, waterNormal.y);
|
||||
|
||||
// artifacts too obvious unfortunately, go back to hardcoded
|
||||
percievedWaterDepth = -(feetPlayerPos.y + cameraPosition.y);
|
||||
}
|
||||
|
||||
DirectLightColor *= sunlightAbsorbtion;
|
||||
|
||||
if( nightVision > 0.0 ) Absorbtion += exp(-totEpsilon * 25.0) * nightVision;
|
||||
|
||||
// apply caustics to the lighting, and make sure they dont look weird
|
||||
vec3 pos = feetPlayerPos + cameraPosition;
|
||||
vec2 causticPos = pos.xz;
|
||||
causticPos = mix(causticPos, pos.xz, max(FlatNormals.y,0));
|
||||
// causticPos = mix(causticPos, pos.xy, max(-FlatNormals.y,0));
|
||||
causticPos = mix(causticPos, pos.zy, max(FlatNormals.x,0));
|
||||
causticPos = mix(causticPos, pos.xy, max(-FlatNormals.z,0));
|
||||
// causticPos = mix(causticPos, pos.xy, max(FlatNormals.x,0));
|
||||
// causticPos = mix(causticPos, pos.xy, max(-FlatNormals.x,0));
|
||||
|
||||
|
||||
DirectLightColor *= pow(mix(1.0, waterCaustics(feetPlayerPos + cameraPosition, WsunVec, percievedWaterDepth)*WATER_CAUSTICS_BRIGHTNESS, clamp(estimatedDepth,0,1)), WATER_CAUSTICS_POWER);
|
||||
|
||||
underWaterAbsorbance_outsidePOV(
|
||||
playerPos0, feetPlayerPos , feetPlayerPos_normalized,
|
||||
WsunVec, // (normalize(cross(dFdx(feetPlayerPos ), dFdy(feetPlayerPos ))).y > 0.01 ? 1.0 : 0.0),
|
||||
totEpsilon, Absorbtion, DirectLightColor, lightLeakFix
|
||||
);
|
||||
}
|
||||
|
||||
// albedo *= waterCaustics(feetPlayerPos + cameraPosition, WsunVec);
|
||||
|
||||
if (swappedDepth < 1.0) {
|
||||
|
||||
// idk why this do
|
||||
feetPlayerPos += gbufferModelViewInverse[3].xyz;
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////// FILTER STUFF //////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -227,6 +227,7 @@ uniform sampler2D colortex4;
|
||||
#ifdef END_SHADER
|
||||
uniform sampler2D colortex4;
|
||||
#include "/lib/end_fog.glsl"
|
||||
// #include "/lib/end_volumetrics.glsl"
|
||||
#endif
|
||||
|
||||
#define fsign(a) (clamp((a)*1e35,0.,1.)*2.-1.)
|
||||
@@ -350,8 +351,8 @@ vec4 waterVolumetrics_insidePOV(vec3 rayStart, vec3 rayEnd, float rayLength, vec
|
||||
float bubble = exp2(-10.0 * clamp(1.0 - length(d*dVWorld) / 16.0, 0.0,1.0));
|
||||
float caustics = max(max(waterCaustics(progressW, WsunVec, -(progressW.y - waterEnteredAltitude)), phase*0.5) * mix(0.5, 1.5, bubble), phase);
|
||||
|
||||
vec3 sunAbsorbance = exp(-waterCoefs * (distanceFromWaterSurface/abs(WsunVec.y)));
|
||||
vec3 WaterAbsorbance = exp(-waterCoefs * (distanceFromWaterSurface + thing));
|
||||
vec3 sunAbsorbance = exp(-waterCoefs * (distanceFromWaterSurface/abs(WsunVec.y)) * WATER_DEPTH_FREQUENCY_DIRECTLIGHT);
|
||||
vec3 WaterAbsorbance = exp(-waterCoefs * (distanceFromWaterSurface + thing) * WATER_DEPTH_FREQUENCY_INDIRECTLIGHT);
|
||||
|
||||
vec3 Directlight = lightSource * sh * phase * caustics * sunAbsorbance;
|
||||
vec3 Indirectlight = ambient * WaterAbsorbance;
|
||||
@@ -445,8 +446,8 @@ vec4 waterVolumetrics_outsidePOV( vec3 rayStart, vec3 rayEnd, float estEndDepth,
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 sunAbsorbance = exp(-waterCoefs * estSunDepth * d);
|
||||
vec3 ambientAbsorbance = exp(-waterCoefs * (estEndDepth * d + thing));
|
||||
vec3 sunAbsorbance = exp(-waterCoefs * estSunDepth * d * WATER_DEPTH_FREQUENCY_DIRECTLIGHT);
|
||||
vec3 ambientAbsorbance = exp(-waterCoefs * (estEndDepth * d + thing) * WATER_DEPTH_FREQUENCY_INDIRECTLIGHT);
|
||||
|
||||
vec3 Directlight = lightSource * sh * cloudShadow * phase * sunAbsorbance;
|
||||
vec3 Indirectlight = ambient * ambientAbsorbance;
|
||||
|
||||
@@ -77,6 +77,7 @@ uniform float eyeAltitude;
|
||||
#endif
|
||||
|
||||
#include "/lib/sky_gradient.glsl"
|
||||
#include "/lib/water_absorbance_effects.glsl"
|
||||
|
||||
#define diagonal3(m) vec3((m)[0].x, (m)[1].y, m[2].z)
|
||||
#define projMAD(m, v) (diagonal3(m) * (v) + (m)[3].xyz)
|
||||
@@ -385,22 +386,8 @@ void blendAllFogTypes( inout vec3 color, inout float bloomyFogMult, vec4 volumet
|
||||
#endif
|
||||
|
||||
/// water absorption; it is completed when volumetrics are blended.
|
||||
if(isEyeInWater == 1){
|
||||
vec3 totEpsilon = vec3(Water_Absorb_R, Water_Absorb_G, Water_Absorb_B);
|
||||
vec3 scatterCoef = Dirt_Amount * vec3(Dirt_Scatter_R, Dirt_Scatter_G, Dirt_Scatter_B) / 3.14;
|
||||
if(isEyeInWater == 1) underWaterAbsorbance_insidePOV(linearDistance, color, bloomyFogMult);
|
||||
|
||||
float distanceFromWaterSurface = playerPos.y + 1.0 + (cameraPosition.y - waterEnteredAltitude)/waterEnteredAltitude;
|
||||
distanceFromWaterSurface = clamp(distanceFromWaterSurface,0,1);
|
||||
|
||||
vec3 transmittance = exp(-totEpsilon * linearDistance);
|
||||
color.rgb *= transmittance;
|
||||
|
||||
vec3 transmittance2 = exp(-totEpsilon * 50.0);
|
||||
float fogfade = 1.0 - max((1.0 - linearDistance / min(far, 16.0*7.0) ),0);
|
||||
color.rgb += (transmittance2 * scatterCoef) * fogfade;
|
||||
|
||||
bloomyFogMult *= dot(transmittance,vec3(0.3333))*0.75 + 0.25;
|
||||
}
|
||||
/// blend volumetrics
|
||||
color = color * volumetrics.a + volumetrics.rgb;
|
||||
|
||||
|
||||
@@ -195,6 +195,12 @@
|
||||
#define PATCHY_WAVE_BLEND 1.0 // [0.0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.2 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.3 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.4 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.5 0.51 0.52 0.53 0.54 0.55 0.56 0.57 0.58 0.59 0.6 0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69 0.7 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.8 0.81 0.82 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.9 0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.0]
|
||||
#define WAVES_A_RADIUS 1.0 // [0.0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.2 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.3 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.4 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.5 0.51 0.52 0.53 0.54 0.55 0.56 0.57 0.58 0.59 0.6 0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69 0.7 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.8 0.81 0.82 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.9 0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.0 2.0 3.0 4.0 5.0]
|
||||
#define WAVES_B_RADIUS 0.15 // [0.0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.2 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.3 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.4 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.5 0.51 0.52 0.53 0.54 0.55 0.56 0.57 0.58 0.59 0.6 0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69 0.7 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.8 0.81 0.82 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.9 0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.0 2.0 3.0 4.0 5.0]
|
||||
|
||||
#define WATER_DEPTH_FREQUENCY_DIRECTLIGHT 1.0 // [0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0]
|
||||
#define WATER_DEPTH_FREQUENCY_INDIRECTLIGHT 1.0 // [0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0]
|
||||
#define WATER_DEPTH_FREQUENCY_ALL_LIGHT 1.0 // [0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0]
|
||||
|
||||
#define MINIMUM_UNDERWATER_FOG_BRIGHTNESS 1.0 // [0.0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.2 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.3 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.4 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.5 0.51 0.52 0.53 0.54 0.55 0.56 0.57 0.58 0.59 0.6 0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69 0.7 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.8 0.81 0.82 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.9 0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 50.0 100.0]
|
||||
#endif
|
||||
|
||||
#if defined EXPOSURE_RELATED_SETTINGS
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
void underWaterAbsorbance_outsidePOV(
|
||||
in vec3 playerPos_depthtex0, in vec3 playerPos_depthtex1, in vec3 playerPos_n,
|
||||
in vec3 sunVector,
|
||||
in vec3 totEpsilon,
|
||||
inout vec3 absorbance, inout vec3 directLightColor, in float lightLeakFix
|
||||
){
|
||||
// theres 2 absorbances being done here.
|
||||
// absorbance for the cameras POV into the water
|
||||
// absorbance for the sunlight itself as it travels through the volume to the point it hits a surface, and then the former absorbance is applied on top of that.
|
||||
|
||||
// force the absorbance to start way closer to the water surface in low light areas, so the water is visible in caves and such.
|
||||
#if MINIMUM_WATER_ABSORBANCE > -1
|
||||
float minimumAbsorbance = MINIMUM_WATER_ABSORBANCE*0.1;
|
||||
#else
|
||||
float minimumAbsorbance = 1.0 - lightLeakFix;
|
||||
#endif
|
||||
|
||||
// get the difference of playerpos with depthtex0 and depthtex1, to get the distance starting at the water surface.
|
||||
float distanceDiff = distance(playerPos_depthtex1, playerPos_depthtex0);
|
||||
|
||||
// fix the gradient to be perfectly vertical in meters.
|
||||
float estimatedWaterDepth = distanceDiff * abs(playerPos_n.y);
|
||||
|
||||
// the distance the sunlight has travelled through water.
|
||||
float travelledWaterDepth = estimatedWaterDepth;
|
||||
|
||||
if (isEyeInWater == 1){
|
||||
minimumAbsorbance = 0.0;
|
||||
estimatedWaterDepth = 1.0;
|
||||
travelledWaterDepth = -(playerPos_depthtex1.y + (cameraPosition.y - waterEnteredAltitude));
|
||||
}
|
||||
|
||||
absorbance = exp(-totEpsilon * max(distanceDiff, minimumAbsorbance) * WATER_DEPTH_FREQUENCY_ALL_LIGHT);
|
||||
if( nightVision > 0.0 ) absorbance += exp(-totEpsilon * 25.0) * nightVision;
|
||||
|
||||
// things to note about sunlight in water
|
||||
// sunlight gets absorbed by water on the way down to the floor, and on the way back up to your eye. im gonna ingore the latter part lol
|
||||
// based on the angle of the sun, sunlight will travel through more/less water to reach the same spot. scale absorbtion depth accordingly
|
||||
vec3 directLightAbsorbance = exp(-totEpsilon * (max(travelledWaterDepth,0.0)/abs(sunVector.y)) * WATER_DEPTH_FREQUENCY_DIRECTLIGHT);
|
||||
|
||||
// this is a quick fix for the water depth offset for projecting caustics. the sides of water have unsable water depth info (its the wrong angle) for this usecase, so fallback to a hardcoded height gradient
|
||||
if (isEyeInWater == 0) travelledWaterDepth = -(playerPos_depthtex1.y + (cameraPosition.y - 63.0));
|
||||
|
||||
float waterCaustics = waterCaustics(playerPos_depthtex1 + cameraPosition, sunVector, travelledWaterDepth);
|
||||
waterCaustics *= WATER_CAUSTICS_BRIGHTNESS;
|
||||
waterCaustics = mix(1.0, waterCaustics, clamp(estimatedWaterDepth,0.0,1.0));
|
||||
waterCaustics = pow(waterCaustics, WATER_CAUSTICS_POWER);
|
||||
|
||||
directLightColor *= directLightAbsorbance * waterCaustics;
|
||||
}
|
||||
|
||||
void underWaterAbsorbance_insidePOV(
|
||||
in float linearDistance,
|
||||
inout vec3 sceneColor, inout float bloomyFogMult
|
||||
){
|
||||
vec3 totEpsilon = vec3(Water_Absorb_R, Water_Absorb_G, Water_Absorb_B);
|
||||
vec3 scatterCoef = Dirt_Amount * vec3(Dirt_Scatter_R, Dirt_Scatter_G, Dirt_Scatter_B) / 3.14;
|
||||
|
||||
vec3 transmittance = exp(-totEpsilon * linearDistance * WATER_DEPTH_FREQUENCY_ALL_LIGHT);
|
||||
vec3 transmittance2 = exp(-totEpsilon * 50.0);
|
||||
float fogfade = 1.0 - max((1.0 - linearDistance / min(far, 16.0*7.0) ),0);
|
||||
|
||||
sceneColor *= transmittance;
|
||||
sceneColor += (transmittance2 * scatterCoef) * fogfade * MINIMUM_UNDERWATER_FOG_BRIGHTNESS;
|
||||
|
||||
bloomyFogMult *= dot(transmittance,vec3(0.3333))*0.75 + 0.25;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user