fix underwater fog

This commit is contained in:
Xonk 2023-04-26 00:28:18 -04:00
parent b12c2491cf
commit 3b375c2b75
7 changed files with 102 additions and 89 deletions

View File

@ -1091,8 +1091,8 @@ void main() {
float Ambient_Caustics = waterCaustics(mat3(gbufferModelViewInverse) * fragpos + gbufferModelViewInverse[3].xyz + cameraPosition, vec3(0.5, 1.0, 0.5));
// apply caustics to the lightting
DirectLightColor *= 0.5 + max(pow(Direct_caustics*2,2),0.0);
Indirect_lighting *= 0.5 + max(pow(Ambient_Caustics,2),0.0);
DirectLightColor *= 0.5 + max(pow(Direct_caustics*2,2),0.0);
// Indirect_lighting *= 0.5 + max(pow(Ambient_Caustics,2),0.0);
// directLightCol *= Direct_caustics;
// Indirect_lighting *= Ambient_Caustics*0.5+0.5;

View File

@ -120,56 +120,76 @@ vec3 normVec (vec3 vec){
}
void waterVolumetrics(inout vec3 inColor, vec3 rayStart, vec3 rayEnd, float estEyeDepth, float estSunDepth, float rayLength, float dither, vec3 waterCoefs, vec3 scatterCoef, vec3 ambient, vec3 lightSource, float VdotL){
int spCount = 8;
int spCount = 8;
vec3 start = toShadowSpaceProjected(rayStart);
vec3 end = toShadowSpaceProjected(rayEnd);
vec3 dV = (end-start);
//limit ray length at 32 blocks for performance and reducing integration error
//you can't see above this anyway
float maxZ = min(rayLength,32.0)/(1e-8+rayLength);
dV *= maxZ;
vec3 dVWorld = mat3(gbufferModelViewInverse) * (rayEnd - rayStart) * maxZ;
rayLength *= maxZ;
float dY = normalize(mat3(gbufferModelViewInverse) * rayEnd).y * rayLength;
vec3 absorbance = vec3(1.0);
vec3 vL = vec3(0.0);
// float phase = 2*mix(phaseg(VdotL, 0.4),phaseg(VdotL, 0.8),0.5);
float phase = phaseg(VdotL,0.7) * 1.5 + 0.02;
float expFactor = 11.0;
vec3 progressW = gbufferModelViewInverse[3].xyz+cameraPosition;
vec3 WsunVec = mat3(gbufferModelViewInverse) * sunVec * lightCol.a;
float cloudShadow = 1;
for (int i=0;i<spCount;i++) {
float d = (pow(expFactor, float(i+dither)/float(spCount))/expFactor - 1.0/expFactor)/(1-1.0/expFactor); // exponential step position (0-1)
float dd = pow(expFactor, float(i+dither)/float(spCount)) * log(expFactor) / float(spCount)/(expFactor-1.0); //step length (derivative)
vec3 spPos = start.xyz + dV*d;
progressW = gbufferModelViewInverse[3].xyz+cameraPosition + d*dVWorld;
//project into biased shadowmap space
float distortFactor = calcDistort(spPos.xy);
vec3 pos = vec3(spPos.xy*distortFactor, spPos.z);
float sh = 1.0;
if (abs(pos.x) < 1.0-0.5/2048. && abs(pos.y) < 1.0-0.5/2048){
pos = pos*vec3(0.5,0.5,0.5/6.0)+0.5;
sh = shadow2D( shadow, pos).x;
}
vec3 start = toShadowSpaceProjected(rayStart);
vec3 end = toShadowSpaceProjected(rayEnd);
vec3 dV = (end-start);
vec3 p3 = mat3(gbufferModelViewInverse) * rayEnd;
vec3 np3 = normVec(p3);
float ambfogfade = clamp(exp(np3.y*1.5 - 1.5),0.0,1.0) ;
vec3 ambientMul = exp(-max(estEyeDepth - dY * d,0.0) * waterCoefs) + ambfogfade*0.5 ;
vec3 sunMul = exp(-max((estEyeDepth - dY * d) ,0.0)/abs(refractedSunVec.y) * waterCoefs)*cloudShadow;
float sunCaustics = waterCaustics(progressW, WsunVec);
sunCaustics = max(pow(sunCaustics*3,2),0.5);
//limit ray length at 32 blocks for performance and reducing integration error
//you can't see above this anyway
float maxZ = min(rayLength,48.0)/(1e-8+rayLength);
dV *= maxZ;
vec3 dVWorld = mat3(gbufferModelViewInverse) * (rayEnd - rayStart) * maxZ;
rayLength *= maxZ;
float dY = normalize(mat3(gbufferModelViewInverse) * rayEnd).y * rayLength;
vec3 light = (sh * lightSource * phase * sunCaustics * sunMul + (ambient*ambientMul))*scatterCoef;
vL += (light - light * exp(-waterCoefs * dd * rayLength)) / waterCoefs *absorbance;
absorbance *= exp(-dd * rayLength * waterCoefs);
// dVWorld *= maxZ
vec3 progressW = (gbufferModelViewInverse[3].xyz+cameraPosition);
vec3 WsunVec = mat3(gbufferModelViewInverse) * sunVec * lightCol.a;
// vec3 wpos = mat3(gbufferModelViewInverse) * rayStart + gbufferModelViewInverse[3].xyz;
// vec3 dVWorld = (wpos-gbufferModelViewInverse[3].xyz);
vec3 absorbance = vec3(1.0);
vec3 vL = vec3(0.0);
float phase = phaseg(VdotL,0.5) * 1.5 + 0.1;
lightSource *= clamp(abs(WsunVec.y)*5,0.,1.);
float cloudShadow = 1;
float expFactor = 11.0;
for (int i=0;i<spCount;i++) {
float d = (pow(expFactor, float(i+dither)/float(spCount))/expFactor - 1.0/expFactor)/(1-1.0/expFactor); // exponential step position (0-1)
float dd = pow(expFactor, float(i+dither)/float(spCount)) * log(expFactor) / float(spCount)/(expFactor-1.0); //step length (derivative)
vec3 spPos = start.xyz + dV*d;
progressW = gbufferModelViewInverse[3].xyz+cameraPosition + d*dVWorld;
// vec3 progressW = start.xyz+cameraPosition+dVWorld;
//project into biased shadowmap space
float distortFactor = calcDistort(spPos.xy);
vec3 pos = vec3(spPos.xy*distortFactor, spPos.z);
float sh = 1.0;
if (abs(pos.x) < 1.0-0.5/2048. && abs(pos.y) < 1.0-0.5/2048){
pos = pos*vec3(0.5,0.5,0.5/6.0)+0.5;
sh = shadow2D( shadow, pos).x;
}
inColor += vL;
// #ifdef VL_CLOUDS_SHADOWS
// sh *= GetCloudShadow_VLFOG(progressW);
// #endif
vec3 p3 = mat3(gbufferModelViewInverse) * rayEnd;
vec3 np3 = normVec(p3);
float ambfogfade = clamp(exp(np3.y*1.5 - 1.5),0.0,1.0) ;
vec3 ambientMul = exp(-max(estEyeDepth - dY * d,0.0) * waterCoefs) + ambfogfade*0.5 ;
vec3 sunMul = exp(-max((estEyeDepth - dY * d) ,0.0)/abs(refractedSunVec.y) * waterCoefs)*cloudShadow;
float sunCaustics = waterCaustics(progressW, WsunVec);
sunCaustics = max(pow(sunCaustics*3,2),0.5);
vec3 light = (sh * lightSource * phase * sunMul * sunCaustics + (ambient*ambientMul))*scatterCoef;
vL += (light - light * exp(-waterCoefs * dd * rayLength)) / waterCoefs *absorbance;
absorbance *= exp(-dd * rayLength * waterCoefs);
}
inColor += vL;
}
#include "lib/volumetricFog.glsl"
@ -210,7 +230,7 @@ void main() {
#endif
vec3 fragpos = toScreenSpace(vec3(tc/RENDER_SCALE,z));
float noise = R2_dither();
float noise = blueNoise();
vec3 vl = vec3(0.0);
float estEyeDepth = clamp((14.0-eyeBrightnessSmooth.y/255.0*16.0)/14.0,0.,1.0);
estEyeDepth *= estEyeDepth*estEyeDepth*34.0;
@ -218,7 +238,7 @@ void main() {
estEyeDepth = max(Water_Top_Layer - cameraPosition.y,0.0);
waterVolumetrics(vl, vec3(0.0), fragpos, estEyeDepth, estEyeDepth, length(fragpos), noise, totEpsilon, scatterCoef, (ambientUp*8./150./3.*0.5) , lightCol.rgb*8./150./3.0*(1.0-pow(1.0-sunElevation*lightCol.a,5.0)), dot(normalize(fragpos), normalize(sunVec) ));
waterVolumetrics(vl, vec3(0.0), fragpos, estEyeDepth, estEyeDepth, length(fragpos), noise, totEpsilon, scatterCoef, (avgAmbient*8./150./3.*0.5) , lightCol.rgb*8./150./3.0*(1.0-pow(1.0-sunElevation*lightCol.a,5.0)), dot(normalize(fragpos), normalize(sunVec) ));
gl_FragData[0] = clamp(vec4(vl,1.0),0.000001,65000.);
}
}

View File

@ -260,16 +260,14 @@ void main() {
// underwater fog
if (isEyeInWater == 1){
float fogfade = clamp(exp(-length(fragpos) /5. ) ,0.0,1.0);
color.rgb *= fogfade;
vl.a *= fogfade*0.70+0.3 ;
float fogfade = clamp( exp(length(p3) / -10) ,0.0,1.0);
color.rgb = color.rgb * fogfade ;
vl.a *= fogfade*0.7+0.3 ;
}
color *= vl.a;
color += vl.rgb;
float rainDrops = clamp(texture2D(colortex9,texcoord).a, 0.0,1.0); // bloomy rain effect
if(rainDrops > 0.0) vl.a *= clamp(exp2(-rainDrops*5),0.,1.); // bloomy rain effect
gl_FragData[0].r = vl.a;

View File

@ -112,7 +112,7 @@ void main() {
vec3 np3 = normVec(p3);
float Shadows = 0.0;
float Shadows = 1.0;
vec3 p3_shadow = mat3(gbufferModelViewInverse) * fragpos + gbufferModelViewInverse[3].xyz;
vec3 projectedShadowPosition = mat3(shadowModelView) * p3_shadow + shadowModelView[3].xyz;
projectedShadowPosition = diagonal3(shadowProjection) * projectedShadowPosition + shadowProjection[3].xyz;
@ -126,7 +126,7 @@ void main() {
float diffthresh = 0.0002;
projectedShadowPosition = projectedShadowPosition * vec3(0.5,0.5,0.5/6.0) + vec3(0.5,0.5,0.5);
Shadows += shadow2D_bicubic(shadow,vec3(projectedShadowPosition + vec3(0.0,0.0,-diffthresh*1.2)));
Shadows = shadow2D_bicubic(shadow,vec3(projectedShadowPosition + vec3(0.0,0.0,-diffthresh*1.2)));
}
#ifdef CLOUDS_SHADOWS
@ -134,7 +134,7 @@ void main() {
#endif
float lightleakfix = clamp(eyeBrightnessSmooth.y/240.0,0.0,1.0);
float phase = phaseg(clamp(dot(np3, WsunVec),0.0,1.0), 0.7) + 1.0 ;
float phase = phaseg(clamp(dot(np3, WsunVec),0.0,1.0),(1.0-gl_FragData[0].a) * 0.8 + 0.1) + 1.0 ;
vec3 Direct_lighting = DoDirectLighting(lightCol.rgb/80., Shadows, 1.0, 0.0) * phase * lightleakfix;
vec3 Indirect_lighting = DoAmbientLighting(avgAmbient, vec3(TORCH_R,TORCH_G,TORCH_B), lmtexcoord.zw, 5.0);

View File

@ -87,12 +87,12 @@ flat varying int EMISSIVE;
// float interleaved_gradientNoise(){
// return fract(52.9829189*fract(0.06711056*gl_FragCoord.x + 0.00583715*gl_FragCoord.y)+frameTimeCounter*51.9521);
// }
// float interleaved_gradientNoise(){
// vec2 alpha = vec2(0.75487765, 0.56984026);
// vec2 coord = vec2(alpha.x * gl_FragCoord.x,alpha.y * gl_FragCoord.y)+ 1.0/1.6180339887 * frameCounter;
// float noise = fract(52.9829189*fract(0.06711056*coord.x + 0.00583715*coord.y));
// return noise;
// }
float interleaved_gradientNoise_temp(){
vec2 alpha = vec2(0.75487765, 0.56984026);
vec2 coord = vec2(alpha.x * gl_FragCoord.x,alpha.y * gl_FragCoord.y)+ 1.0/1.6180339887 * frameCounter;
float noise = fract(52.9829189*fract(0.06711056*coord.x + 0.00583715*coord.y));
return noise;
}
float interleaved_gradientNoise(){
vec2 coord = gl_FragCoord.xy;
float noise = fract(52.9829189*fract(0.06711056*coord.x + 0.00583715*coord.y));
@ -173,16 +173,18 @@ vec3 toScreenSpace(vec3 p) {
vec3 toClipSpace3(vec3 viewSpacePosition) {
return projMAD(gbufferProjection, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
}
#ifdef POM
vec4 readNormal(in vec2 coord)
{
return texture2DGradARB(normals,fract(coord)*vtexcoordam.pq+vtexcoordam.st,dcdx,dcdy);
}
vec4 readTexture(in vec2 coord)
{
return texture2DGradARB(texture,fract(coord)*vtexcoordam.pq+vtexcoordam.st,dcdx,dcdy);
}
vec4 readNormal(in vec2 coord)
{
return texture2DGradARB(normals,fract(coord)*vtexcoordam.pq+vtexcoordam.st,dcdx,dcdy);
}
vec4 readTexture(in vec2 coord)
{
return texture2DGradARB(texture,fract(coord)*vtexcoordam.pq+vtexcoordam.st,dcdx,dcdy);
}
#endif
float luma(vec3 color) {
return dot(color,vec3(0.21, 0.72, 0.07));
}
@ -299,7 +301,7 @@ void main() {
float used_POM_DEPTH = 1.0;
if ( viewVector.z < 0.0 && depthmap < 0.9999 && depthmap > 0.00001) {
float noise = interleaved_gradientNoise_temp();
#ifdef Adaptive_Step_length
vec3 interval = (viewVector.xyz /-viewVector.z/MAX_OCCLUSION_POINTS * POM_DEPTH) * clamp(1.0-pow(depthmap,2),0.1,1.0) ;
used_POM_DEPTH = 1.0;
@ -308,9 +310,9 @@ void main() {
#endif
vec3 coord = vec3(vtexcoord.st, 1.0);
coord += interval * used_POM_DEPTH;
coord += (interval * noise) * used_POM_DEPTH;
float sumVec = 0.5;
float sumVec = noise;
for (int loopCount = 0; (loopCount < MAX_OCCLUSION_POINTS) && (1.0 - POM_DEPTH + POM_DEPTH * readNormal(coord.st).a ) < coord.p && coord.p >= 0.0; ++loopCount) {
coord = coord+interval * used_POM_DEPTH;
sumVec += 1.0 * used_POM_DEPTH;
@ -336,7 +338,7 @@ void main() {
//////////////////////////////// ALBEDO
////////////////////////////////
vec4 Albedo = texture2DGradARB(texture, adjustedTexCoord.xy,dcdx,dcdy) * color;
vec4 Albedo = texture2DGradARB(texture, adjustedTexCoord.xy, dcdx,dcdy) * color;
#ifdef ENTITIES
if(NameTags == 1) Albedo = texture2D(texture, lmtexcoord.xy, Texture_MipMap_Bias) * color;
@ -453,7 +455,6 @@ void main() {
SpecularTex.r = max(SpecularTex.r, Puddle_shape);
SpecularTex.g = max(SpecularTex.g, Puddle_shape*0.04);
#ifdef ENTITIES
if(NameTags == 1) SpecularTex = vec4(0.0);
#endif

View File

@ -415,20 +415,15 @@ if (gl_FragCoord.x * texelSize.x < RENDER_SCALE.x && gl_FragCoord.y * texelSize
vec2 SpecularTex = texture2D(specular, lmtexcoord.xy, Texture_MipMap_Bias).rg;
// SpecularTex = (iswater > 0.0 && iswater < 0.9) && SpecularTex.r > 0.0 && SpecularTex.g < 0.9 ? SpecularTex : vec2(1.0,0.1);
SpecularTex = (iswater > 0.0 && iswater < 0.9) && SpecularTex.r > 0.0 && SpecularTex.g < 0.9 ? SpecularTex : vec2(1.0,0.1);
float roughness = max(pow(1.0-SpecularTex.r,2.0),0.05);
float f0 = SpecularTex.g;
roughness = iswater > 0.95 ? 0.05 : roughness;
f0 = iswater > 0.95 ? 0.1 : f0;
if (iswater > 0.0 ){
if (iswater > 0.0){
vec3 Reflections_Final = vec3(0.0);
float F0 = f0;
float indoors = clamp((lmtexcoord.w-0.6)*5.0, 0.0,1.0);
vec3 reflectedVector = reflect(normalize(fragpos), normal);
float normalDotEye = dot(normal, normalize(fragpos));
@ -440,9 +435,8 @@ if (gl_FragCoord.x * texelSize.x < RENDER_SCALE.x && gl_FragCoord.y * texelSize
if(isEyeInWater == 1 && physics_iterationsNormal > 0.0) fresnel = clamp( 1.0 - (pow( normalDotEye * 1.66 ,25)),0.02,1.0);
fresnel = mix(F0, 1.0, fresnel);
// fresnel = F0 + (1.0 - F0) * fresnel;
float indoors = clamp((lmtexcoord.w-0.6)*5.0, 0.0,1.0);
fresnel = mix(f0, 1.0, fresnel);
vec3 wrefl = mat3(gbufferModelViewInverse)*reflectedVector;
// SSR, Sky, and Sun reflections

View File

@ -136,7 +136,7 @@
//#define POM
#define mob_SSS
#define misc_block_SSS
#define POM_DEPTH 0.25 // [0.025 0.05 0.075 0.1 0.125 0.15 0.20 0.25 0.30 0.50 0.75 1.0] // IN CENTIMETERS. Increase to increase POM strength.
#define POM_DEPTH 0.25 // [0.025 0.05 0.075 0.1 0.125 0.15 0.20 0.25 0.30 0.50 0.75 1.0] // IN METERS. Vanillaccurate: 0.15-0.25. VNR: 0.20. Patrix: 1.0
#define Adaptive_Step_length // make only used parts of the POM depth get samples, to increase overall quality. DOWNSIDE: at sheer angles, it looks kinda buggy.
#define MAX_ITERATIONS 50 // [5 10 15 20 25 30 40 50 60 70 80 90 100 125 150 200 400] //Improves quality at grazing angles (reduces performance)
#define MAX_DIST 25.0 // [5.0 10.0 15.0 20.0 25.0 30.0 40.0 50.0 60.0 70.0 80.0 90.0 100.0 125.0 150.0 200.0 400.0] //Increases distance at which POM is calculated