288 lines
8.7 KiB
GLSL
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);
|
|
}
|