292 lines
9.7 KiB
GLSL
292 lines
9.7 KiB
GLSL
#version 120
|
|
/* DRAWBUFFERS:34 */
|
|
|
|
#define gbuffers_shadows
|
|
#define composite0
|
|
#define composite2
|
|
#define lightingColors
|
|
#include "/shaders.settings"
|
|
|
|
#ifdef HandLight
|
|
uniform int heldBlockLightValue;
|
|
uniform int heldBlockLightValue2;
|
|
#endif
|
|
|
|
varying vec2 texcoord;
|
|
varying vec3 sunVec;
|
|
varying vec3 upVec;
|
|
varying vec3 sunlight;
|
|
varying float tr;
|
|
varying float sunVisibility;
|
|
varying float moonVisibility;
|
|
|
|
uniform sampler2D depthtex0;
|
|
uniform sampler2D depthtex1;
|
|
uniform sampler2D colortex0;
|
|
uniform sampler2D colortex1;
|
|
uniform sampler2D colortex2;
|
|
uniform sampler2D composite;
|
|
|
|
uniform mat4 gbufferProjectionInverse;
|
|
|
|
uniform int isEyeInWater;
|
|
uniform float aspectRatio;
|
|
uniform float near;
|
|
uniform float far;
|
|
uniform float viewWidth;
|
|
uniform float viewHeight;
|
|
uniform float rainStrength;
|
|
uniform float nightVision;
|
|
uniform float screenBrightness;
|
|
|
|
float comp = 1.0-near/far/far; //distance above that are considered as sky
|
|
|
|
const vec2 check_offsets[25] = vec2[25](vec2(-0.4894566f,-0.3586783f),
|
|
vec2(-0.1717194f,0.6272162f),
|
|
vec2(-0.4709477f,-0.01774091f),
|
|
vec2(-0.9910634f,0.03831699f),
|
|
vec2(-0.2101292f,0.2034733f),
|
|
vec2(-0.7889516f,-0.5671548f),
|
|
vec2(-0.1037751f,-0.1583221f),
|
|
vec2(-0.5728408f,0.3416965f),
|
|
vec2(-0.1863332f,0.5697952f),
|
|
vec2(0.3561834f,0.007138769f),
|
|
vec2(0.2868255f,-0.5463203f),
|
|
vec2(-0.4640967f,-0.8804076f),
|
|
vec2(0.1969438f,0.6236954f),
|
|
vec2(0.6999109f,0.6357007f),
|
|
vec2(-0.3462536f,0.8966291f),
|
|
vec2(0.172607f,0.2832828f),
|
|
vec2(0.4149241f,0.8816f),
|
|
vec2(0.136898f,-0.9716249f),
|
|
vec2(-0.6272043f,0.6721309f),
|
|
vec2(-0.8974028f,0.4271871f),
|
|
vec2(0.5551881f,0.324069f),
|
|
vec2(0.9487136f,0.2605085f),
|
|
vec2(0.7140148f,-0.312601f),
|
|
vec2(0.0440252f,0.9363738f),
|
|
vec2(0.620311f,-0.6673451f)
|
|
);
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
vec3 YCoCg2RGB(vec3 c){
|
|
c.y-=0.5;
|
|
c.z-=0.5;
|
|
return vec3(c.r+c.g-c.b, c.r + c.b, c.r - c.g - c.b);
|
|
}
|
|
|
|
#ifdef Celshading
|
|
float edepth(vec2 coord) {
|
|
return texture2D(depthtex1,coord).x;
|
|
}
|
|
|
|
vec3 celshade(vec3 clrr) {
|
|
//edge detect
|
|
float dtresh = 1.0/(far-near) / (5000.0*Celradius);
|
|
vec4 dc = vec4(edepth(texcoord.xy));
|
|
vec3 border = vec3(1.0/viewWidth, 1.0/viewHeight, 0.0)*Celborder;
|
|
vec4 sa = vec4(edepth(texcoord.xy + vec2(-border.x,-border.y)),
|
|
edepth(texcoord.xy + vec2(border.x,-border.y)),
|
|
edepth(texcoord.xy + vec2(-border.x,border.z)),
|
|
edepth(texcoord.xy + vec2(border.z,border.y)));
|
|
|
|
//opposite side samples
|
|
vec4 sb = vec4(edepth(texcoord.xy + vec2(border.x,border.y)),
|
|
edepth(texcoord.xy + vec2(-border.x,border.y)),
|
|
edepth(texcoord.xy + vec2(border.x,border.z)),
|
|
edepth(texcoord.xy + vec2(border.z,-border.y)));
|
|
|
|
vec4 dd = abs(2.0* dc - sa - sb) - dtresh;
|
|
dd = step(dd.xyzw, vec4(0.0));
|
|
|
|
float e = clamp(dot(dd,vec4(0.25f)),0.0,1.0);
|
|
return clrr*e;
|
|
}
|
|
#endif
|
|
|
|
#ifdef TAA
|
|
vec2 texelSize = vec2(1.0/viewWidth,1.0/viewHeight);
|
|
uniform int framemod8;
|
|
const vec2[8] offsets = vec2[8](vec2(1./8.,-3./8.),
|
|
vec2(-1.,3.)/8.,
|
|
vec2(5.0,1.)/8.,
|
|
vec2(-3,-5.)/8.,
|
|
vec2(-5.,5.)/8.,
|
|
vec2(-7.,-1.)/8.,
|
|
vec2(3,7.)/8.,
|
|
vec2(7.,-7.)/8.);
|
|
|
|
#endif
|
|
|
|
vec3 toScreenSpace(vec3 p) {
|
|
vec4 iProjDiag = vec4(gbufferProjectionInverse[0].x, gbufferProjectionInverse[1].y, gbufferProjectionInverse[2].zw);
|
|
vec3 p3 = p * 2.0 - 1.0;
|
|
vec4 fragposition = iProjDiag * p3.xyzz + gbufferProjectionInverse[3];
|
|
return fragposition.xyz / fragposition.w;
|
|
}
|
|
|
|
#ifdef SSDO
|
|
uniform float frameTimeCounter;
|
|
//modified version of Yuriy O'Donnell's SSDO (License MIT -> https://github.com/kayru/dssdo)
|
|
float calcSSDO(vec3 fragpos, vec3 normal){
|
|
float finalAO = 0.0;
|
|
|
|
float radius = 0.05 / (fragpos.z);
|
|
const float attenuation_angle_threshold = 0.1;
|
|
const int num_samples = 16;
|
|
const float ao_weight = 1.0;
|
|
#ifdef TAA
|
|
float noise = fract(0.75487765 * gl_FragCoord.x + 0.56984026 * gl_FragCoord.y);
|
|
noise = fract(frameTimeCounter * 2.0 + noise);
|
|
#else
|
|
float noise = 1.0;
|
|
#endif
|
|
|
|
for( int i=0; i<num_samples; ++i ){
|
|
vec2 texOffset = pow(length(check_offsets[i].xy),0.5)*radius*vec2(1.0,aspectRatio)*normalize(check_offsets[i].xy);
|
|
vec2 newTC = texcoord+texOffset*noise;
|
|
#ifdef TAA
|
|
vec3 t0 = toScreenSpace(vec3(newTC-offsets[framemod8]*texelSize*0.5, texture2D(depthtex1, newTC).x));
|
|
#else
|
|
vec3 t0 = toScreenSpace(vec3(newTC, texture2D(depthtex1, newTC).x));
|
|
#endif
|
|
vec3 center_to_sample = t0.xyz - fragpos.xyz;
|
|
|
|
float dist = length(center_to_sample);
|
|
|
|
vec3 center_to_sample_normalized = center_to_sample / dist;
|
|
float attenuation = 1.0-clamp(dist/6.0,0.0,1.0);
|
|
float dp = dot(normal, center_to_sample_normalized);
|
|
|
|
attenuation = sqrt(max(dp,0.0))*attenuation*attenuation * step(attenuation_angle_threshold, dp);
|
|
finalAO += attenuation * (ao_weight / num_samples);
|
|
}
|
|
return finalAO;
|
|
}
|
|
#endif
|
|
|
|
vec2 decodeVec2(float a){
|
|
const vec2 constant1 = 65535. / vec2( 256., 65536.);
|
|
const float constant2 = 256. / 255.;
|
|
return fract( a * constant1 ) * constant2 ;
|
|
}
|
|
|
|
uniform mat4 gbufferModelViewInverse;
|
|
|
|
void main() {
|
|
|
|
//Setup depth
|
|
float depth0 = texture2D(depthtex0, texcoord).x; //everything
|
|
float depth1 = texture2D(depthtex1, texcoord).x; //transparency
|
|
|
|
bool sky = (depth1 >= 1.0);
|
|
|
|
vec4 albedo = texture2D(colortex0,texcoord);
|
|
vec3 normal = decode(texture2D(colortex1, texcoord).xy);
|
|
vec2 lightmap = texture2D(colortex1, texcoord.xy).zw;
|
|
bool translucent = albedo.b > 0.69 && albedo.b < 0.71;
|
|
bool emissive = albedo.b > 0.59 && albedo.b < 0.61;
|
|
vec3 color = vec3(albedo.rg,0.0);
|
|
|
|
vec2 a0 = texture2D(colortex0,texcoord + vec2(1.0/viewWidth,0.0)).rg;
|
|
vec2 a1 = texture2D(colortex0,texcoord - vec2(1.0/viewWidth,0.0)).rg;
|
|
vec2 a2 = texture2D(colortex0,texcoord + vec2(0.0,1.0/viewHeight)).rg;
|
|
vec2 a3 = texture2D(colortex0,texcoord - vec2(0.0,1.0/viewHeight)).rg;
|
|
vec4 lumas = vec4(a0.x,a1.x,a2.x,a3.x);
|
|
vec4 chromas = vec4(a0.y,a1.y,a2.y,a3.y);
|
|
|
|
vec4 w = 1.0-step(0.1176, abs(lumas - color.x));
|
|
float W = dot(w,vec4(1.0));
|
|
w.x = (W==0.0)? 1.0:w.x; W = (W==0.0)? 1.0:W;
|
|
|
|
bool pattern = (mod(gl_FragCoord.x,2.0)==mod(gl_FragCoord.y,2.0));
|
|
color.b= dot(w,chromas)/W;
|
|
color.rgb = (pattern)?color.rbg:color.rgb;
|
|
color.rgb = YCoCg2RGB(color.rgb);
|
|
color = pow(color,vec3(2.2));
|
|
|
|
if (!sky){
|
|
//Water and Ice
|
|
vec3 Wnormal = texture2D(colortex2,texcoord).xyz;
|
|
bool iswater = Wnormal.z < 0.2499 && dot(Wnormal,Wnormal) > 0.0;
|
|
bool isice = Wnormal.z > 0.2499 && Wnormal.z < 0.4999 && dot(Wnormal,Wnormal) > 0.0;
|
|
bool isnsun = (iswater||isice) || ((!iswater||!isice) && isEyeInWater == 1);
|
|
/*--------------------------------------------------------------------------------------*/
|
|
|
|
#ifdef TAA
|
|
vec2 newTC = gl_FragCoord.xy*texelSize;
|
|
vec3 TAAfragpos = toScreenSpace(vec3(newTC-offsets[framemod8]*texelSize*0.5, texture2D(depthtex1, newTC).x));
|
|
#else
|
|
vec3 TAAfragpos = toScreenSpace(vec3(texcoord,depth1)); //was depth0 before, might cause issues
|
|
#endif
|
|
|
|
#ifdef Whiteworld
|
|
color += vec3(1.5);
|
|
#endif
|
|
|
|
#ifdef Celshading
|
|
color = celshade(color);
|
|
#endif
|
|
|
|
float ao = 1.0;
|
|
#ifdef SSDO
|
|
float occlusion = calcSSDO(TAAfragpos, normal);
|
|
if(!iswater)ao = pow(1.0-occlusion, ao_strength);
|
|
#endif
|
|
|
|
//Emissive blocks lighting and colors
|
|
#ifdef HandLight
|
|
bool underwaterlava = (isEyeInWater == 1.0 || isEyeInWater == 2.0);
|
|
if(!underwaterlava) lightmap.x = max(lightmap.x, max(max(float(heldBlockLightValue), float(heldBlockLightValue2)) - 1.0 - length(TAAfragpos), 0.0) / 15.0);
|
|
#endif
|
|
float torch_lightmap = 16.0-min(15.0,(lightmap.x-0.5/16.0)*16.0*16.0/15.0);
|
|
float fallof1 = clamp(1.0 - pow(torch_lightmap/16.0,4.0),0.0,1.0);
|
|
torch_lightmap = fallof1*fallof1/(torch_lightmap*torch_lightmap+1.0);
|
|
float c_emitted = dot((color.rgb),vec3(1.0,0.6,0.4))/2.0;
|
|
float emitted = emissive? clamp(c_emitted*c_emitted,0.0,1.0)*torch_lightmap : 0.0;
|
|
vec3 emissiveLightC = vec3(emissive_R,emissive_G,emissive_B);
|
|
/*------------------------------------------------------------------------------------------*/
|
|
|
|
//Lighting and colors
|
|
float NdotL = dot(normal,sunVec);
|
|
float NdotU = dot(normal,upVec);
|
|
|
|
const vec3 moonlight = vec3(0.5, 0.9, 1.8) * Moonlight;
|
|
|
|
vec2 visibility = vec2(sunVisibility,moonVisibility);
|
|
|
|
float skyL = max(lightmap.y-2./16.0,0.0)*1.14285714286;
|
|
float SkyL2 = skyL*skyL;
|
|
float skyc2 = mix(1.0,SkyL2,skyL);
|
|
|
|
vec4 bounced = vec4(NdotL,NdotL,NdotL,NdotU) * vec4(-0.14*skyL*skyL,0.33,0.7,0.1) + vec4(0.6,0.66,0.7,0.25);
|
|
bounced *= vec4(skyc2,skyc2,visibility.x-tr*visibility.x,0.8);
|
|
|
|
vec3 sun_ambient = bounced.w * (vec3(0.1, 0.5, 1.1)*2.4+rainStrength*2.3*vec3(0.05,-0.33,-0.9))+ 1.6*sunlight*(sqrt(bounced.w)*bounced.x*2.4 + bounced.z)*(1.0-rainStrength*0.99);
|
|
vec3 moon_ambient = (moonlight*0.7 + moonlight*bounced.y)*4.0;
|
|
|
|
vec3 amb1 = (sun_ambient*visibility.x + moon_ambient*visibility.y)*SkyL2*(0.03*0.65+tr*0.17*0.65);
|
|
float finalminlight = (nightVision > 0.01)? 0.15 : (minlight+0.006)+(screenBrightness*0.0125); //add nightvision support but make sure minlight is still adjustable.
|
|
vec3 ambientC = ao*amb1 + emissiveLightC*(emitted*15.*color + torch_lightmap*ao)*0.66 + ao*finalminlight*min(skyL+6/16.,9/16.)*normalize(amb1+0.0001);
|
|
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
color *= (ambientC*(isnsun?1.0/(SkyL2*skyL*0.5+0.5):1.0)*1.4)*0.63;
|
|
}
|
|
|
|
//Draw skytexture from gbuffers_skytextured
|
|
if (sky)color = pow(texture2D(composite, texcoord.xy).rgb,vec3(2.2));
|
|
|
|
gl_FragData[0] = vec4(0.0); //used by custom skycolor, godrays and VL not needed in end dimension
|
|
gl_FragData[1] = vec4(pow(color/257.0,vec3(0.454)), 1.0);
|
|
}
|