Files
2025-11-18 08:49:24 +01:00

288 lines
8.7 KiB
GLSL

#version 120
#extension GL_ARB_shader_texture_lod : enable
const bool gaux1MipmapEnabled = true;
/* DRAWBUFFERS:3 */
#define composite2
#define composite1
#define lightingColors
#include "/shaders.settings"
varying vec2 texcoord;
uniform sampler2D composite;
uniform sampler2D gaux1;
uniform sampler2D depthtex0;
uniform sampler2D depthtex1;
uniform sampler2D colortex0;
uniform sampler2D colortex1;
uniform sampler2D colortex2;
uniform sampler2D gdepth;
uniform sampler2D noisetex;
uniform sampler2D gaux3;
uniform sampler2D gaux2;
uniform vec3 cameraPosition;
uniform mat4 gbufferProjection;
uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferModelViewInverse;
uniform int isEyeInWater;
uniform float near;
uniform float far;
uniform float screenBrightness;
uniform float frameTimeCounter;
uniform float blindness;
#if MC_VERSION >= 11900
uniform float darknessFactor;
uniform float darknessLightFactor;
#endif
/*------------------------------------------*/
float comp = 1.0-near/far/far;
#if defined waterRefl || defined iceRefl
const int maxf = 3; //number of refinements
const float ref = 0.11; //refinement multiplier
const float inc = 3.0; //increasement factor at each step
vec3 nvec3(vec4 pos) {
return pos.xyz/pos.w;
}
vec4 nvec4(vec3 pos) {
return vec4(pos.xyz, 1.0);
}
float cdist(vec2 coord) {
return max(abs(coord.s-0.5),abs(coord.t-0.5))*2.0;
}
vec4 raytrace(vec3 fragpos, vec3 skycolor, vec3 rvector) {
vec4 color = vec4(0.0);
vec3 start = fragpos;
rvector *= 1.2;
fragpos += rvector;
vec3 tvector = rvector;
int sr = 0;
for(int i=0;i<25;i++){
vec3 pos = nvec3(gbufferProjection * nvec4(fragpos)) * 0.5 + 0.5;
if(pos.x < 0 || pos.x > 1 || pos.y < 0 || pos.y > 1 || pos.z < 0 || pos.z > 1.0) break;
vec3 fragpos0 = vec3(pos.st, texture2D(depthtex1, pos.st).r);
fragpos0 = nvec3(gbufferProjectionInverse * nvec4(fragpos0 * 2.0 - 1.0));
float err = distance(fragpos,fragpos0);
if(err < pow(length(rvector),1.175)){ //if(err < pow(length(rvector)*1.85,1.15)){ <- old, adjusted error check to reduce banding issues/glitches
sr++;
if(sr >= maxf){
bool land = texture2D(depthtex1, pos.st).r < comp;
color = pow(texture2DLod(gaux1, pos.st, 1),vec4(2.2))*257.0;
if (isEyeInWater == 0) color.rgb = land ? mix(color.rgb,skycolor,0.5) : skycolor; //reflections color, blend it with fake sky color.
color.a = clamp(1.0 - pow(cdist(pos.st), 20.0), 0.0, 1.0);
break;
}
tvector -= rvector;
rvector *= ref;
}
rvector *= inc;
tvector += rvector;
fragpos = start + tvector;
}
return color;
}
#endif
#ifdef Refraction
mat2 rmatrix(float rad){
return mat2(vec2(cos(rad), -sin(rad)), vec2(sin(rad), cos(rad)));
}
float calcWaves(vec2 coord){
vec2 movement = abs(vec2(0.0, -frameTimeCounter * 0.5));
coord *= 0.4;
vec2 coord0 = coord * rmatrix(1.0) - movement * 4.5;
coord0.y *= 3.0;
vec2 coord1 = coord * rmatrix(0.5) - movement * 1.5;
coord1.y *= 3.0;
vec2 coord2 = coord * frameTimeCounter * 0.02;
coord0 *= waveSize;
coord1 *= (waveSize-0.5); //create an offset for smaller waves
float wave = texture2D(noisetex,coord0 * 0.005).x * 10.0; //big waves
wave -= texture2D(noisetex,coord1 * 0.010416).x * 7.0; //small waves
wave += 1.0-sqrt(texture2D(noisetex,coord2 * 0.0416).x * 6.5) * 1.33; //noise texture
wave *= 0.0157;
return wave;
}
vec2 calcBump(vec2 coord){
const vec2 deltaPos = vec2(0.25, 0.0);
float h0 = calcWaves(coord);
float h1 = calcWaves(coord + deltaPos.xy);
float h2 = calcWaves(coord - deltaPos.xy);
float h3 = calcWaves(coord + deltaPos.yx);
float h4 = calcWaves(coord - deltaPos.yx);
float xDelta = ((h1-h0)+(h0-h2));
float yDelta = ((h3-h0)+(h0-h4));
return vec2(xDelta,yDelta)*0.05;
}
#endif
vec3 decode (vec2 enc){
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4.0);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
void main() {
vec3 c = pow(texture2D(gaux1,texcoord).xyz,vec3(2.2))*257.;
//Depth and fragpos
float depth0 = texture2D(depthtex0, texcoord).x;
vec4 fragpos0 = gbufferProjectionInverse * (vec4(texcoord, depth0, 1.0) * 2.0 - 1.0);
fragpos0 /= fragpos0.w;
vec3 normalfragpos0 = normalize(fragpos0.xyz);
float depth1 = texture2D(depthtex1, texcoord).x;
vec4 fragpos1 = gbufferProjectionInverse * (vec4(texcoord, depth1, 1.0) * 2.0 - 1.0);
fragpos1 /= fragpos1.w;
vec3 normalfragpos1 = normalize(fragpos1.xyz);
/*--------------------------------------------------------------------------------------------*/
vec4 trp = texture2D(gaux3,texcoord.xy);
bool transparency = dot(trp.xyz,trp.xyz) > 0.000001;
#ifdef Refraction
if (texture2D(colortex2, texcoord).z < 0.2499 && dot(texture2D(colortex2,texcoord).xyz,texture2D(colortex2,texcoord).xyz) > 0.0 || isEyeInWater == 1.0) { //reflective water
vec2 wpos = (gbufferModelViewInverse*fragpos0).xz+cameraPosition.xz;
vec2 refraction = texcoord.xy + calcBump(wpos);
c = pow(texture2D(gaux1, refraction).xyz, vec3(2.2))*257.0;
//remove underwater tint, not needed in end
}
#endif
//Draw fog
vec3 fogC = vec3(0.001, 0.0, 0.002);
//float fogF = calcFog(fragpos0.xyz);
//Render before transparency
float mats = texture2D(colortex0,texcoord).b;
bool isMetallic = mats > 0.39 && mats < 0.41;
bool isPolished = mats > 0.49 && mats < 0.51;
#ifndef polishedRefl
isPolished = false;
#endif
#ifndef metallicRefl
isMetallic = false;
#endif
#if defined metallicRefl || defined polishedRefl
if (isMetallic || isPolished) {
vec3 relfNormal = decode(texture2D(colortex1,texcoord).xy);
vec3 reflectedVector = reflect(normalfragpos0, relfNormal);
float normalDotEye = dot(relfNormal, normalfragpos0);
float fresnel = pow(clamp(1.0 + normalDotEye,0.0,1.0), 4.0);
fresnel = mix(0.09,1.0,fresnel); //F0
vec3 sky_c = fogC*metallicSky;
vec4 reflection = raytrace(fragpos0.xyz, sky_c, reflectedVector);
reflection.rgb = mix(sky_c, reflection.rgb, reflection.a)*0.5;
c = mix(c,reflection.rgb,fresnel*metalStrength);
}
#endif
if (transparency) {
vec3 normal = texture2D(colortex2,texcoord).xyz;
float sky = normal.z;
bool reflectiveWater = sky < 0.2499 && dot(normal,normal) > 0.0;
bool reflectiveIce = sky > 0.2499 && sky < 0.4999 && dot(normal,normal) > 0.0;
bool iswater = sky < 0.2499;
bool isice = sky > 0.2499 && sky < 0.4999;
if (iswater) sky *= 4.0;
if (isice) sky = (sky - 0.25)*4.0;
if (!iswater && !isice) sky = (sky - 0.5)*4.0;
sky = clamp(sky*1.2-2./16.0*1.2,0.,1.0);
sky *= sky;
normal = decode(normal.xy);
normal = normalize(normal);
//draw fog for transparency
float iswater2 = float(iswater);
//c = mix(c, fogC, 1.0-exp(-length(fragpos1.xyz)*(0.0075+(screenBrightness*0.001))));
if(depth1 < comp)c = mix(fogC, c, exp(-exp2(length(fragpos1.xyz) / far * 16.0 - 14.0)));
//Draw transparency
vec3 finalAc = texture2D(gaux2, texcoord.xy).rgb;
float alphaT = clamp(length(trp.rgb)*1.02,0.0,1.0);
c = mix(c,c*(trp.rgb*0.9999+0.0001)*1.732,alphaT)*(1.0-alphaT) + finalAc;
/*-----------------------------------------------------------------------------------------*/
//Reflections
if (reflectiveWater || reflectiveIce) {
vec3 reflectedVector = reflect(normalfragpos1, normal);
vec3 hV= normalize(reflectedVector - normalfragpos1);
float normalDotEye = dot(hV, normalfragpos1);
float F0 = 0.09;
float fresnel = pow(clamp(1.0 + normalDotEye,0.0,1.0), 4.0) ;
fresnel = fresnel+F0*(1.0-fresnel);
vec3 sky_c = fogC*0.5; //Use fogC as our custom sky reflections
#if defined waterRefl || defined iceRefl
vec4 reflection = raytrace(fragpos0.xyz, sky_c, reflectedVector);
#else
vec4 reflection = vec4(0.0);
fresnel *= 0.5;
#endif
reflection.rgb = mix(sky_c, reflection.rgb, reflection.a)*0.5;
#ifdef IceGlassReflections
fresnel *= 0.5*float(isice) + 0.5*iswater2;
#else
fresnel *= 1.0*iswater2;
#endif
c = mix(c,reflection.rgb,fresnel*1.5);
}
}
#ifdef Fog
if(depth0 < comp)c = mix(c, fogC*(1.0-isEyeInWater), 1.0-exp(-length(fragpos0.xyz)*(0.0075+(screenBrightness*0.001)))); //scale with screenbrightness
if(depth0 < comp)c = mix(fogC, c, exp(-exp2(length(fragpos0.xyz) / far * 16.0 - 14.0)));
#endif
#ifdef Underwater_Fog
vec3 ufogC = vec3(0.0, 0.005, 0.0125);
if (isEyeInWater == 1.0) c = mix(c, ufogC, 1.0-exp(-length(fragpos0.xyz)/uFogDensity));
#endif
if (isEyeInWater == 2.0) c = mix(c, vec3(1.0, 0.0125, 0.0), 1.0-exp(-length(fragpos0.xyz))); //lava fog
if(blindness > 0.9) c = mix(c, vec3(0.0), 1.0-exp(-length(fragpos1.xyz)*1.125)); //blindness fog
#if MC_VERSION >= 11900
if(darknessFactor > 0.9) c = mix(c, vec3(0.0), 1.0-exp(-length(fragpos1.xyz)*0.125)) * (1.0-darknessLightFactor*2.0); //Darkness fog, adjust for end.
#endif
c *= 0.142;
gl_FragData[0] = vec4(c,1.0);
}