mirror of
https://github.com/Merlin1809/Eclipse-Shader.git
synced 2026-10-10 04:53:07 +08:00
600 lines
22 KiB
GLSL
600 lines
22 KiB
GLSL
#include "/lib/settings.glsl"
|
|
|
|
#include "/lib/SSBOs.glsl"
|
|
|
|
#ifdef OVERWORLD_SHADER
|
|
in DATA {
|
|
flat vec3 WsunVec;
|
|
};
|
|
#endif
|
|
|
|
#define DEFERRED_SPECULAR
|
|
#define DEFERRED_SSR_QUALITY 30 // [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 200 300 400 500]
|
|
|
|
uniform sampler2D noisetex;
|
|
uniform sampler2D depthtex0;
|
|
uniform sampler2D depthtex1;
|
|
|
|
#ifdef DISTANT_HORIZONS
|
|
uniform sampler2D dhDepthTex;
|
|
uniform sampler2D dhDepthTex1;
|
|
#define dhVoxyDepthTex dhDepthTex
|
|
#define dhVoxyDepthTex1 dhDepthTex1
|
|
#endif
|
|
|
|
#ifdef VOXY
|
|
uniform sampler2D vxDepthTexOpaque;
|
|
uniform sampler2D vxDepthTexTrans;
|
|
#define dhVoxyDepthTex vxDepthTexTrans
|
|
#define dhVoxyDepthTex1 vxDepthTexOpaque
|
|
#endif
|
|
|
|
uniform sampler2D colortex0;
|
|
uniform sampler2D colortex1;
|
|
uniform sampler2D colortex2;
|
|
uniform sampler2D colortex3;
|
|
uniform sampler2D colortex4;
|
|
uniform sampler2D colortex5;
|
|
uniform sampler2D colortex6;
|
|
uniform sampler2D colortex7;
|
|
uniform sampler2D colortex8;
|
|
uniform sampler2D colortex9;
|
|
uniform sampler2D colortex10;
|
|
uniform sampler2D colortex11;
|
|
uniform sampler2D colortex12;
|
|
uniform sampler2D colortex13;
|
|
uniform sampler2D colortex14;
|
|
uniform sampler2D colortex15;
|
|
uniform vec2 texelSize;
|
|
|
|
uniform float viewHeight;
|
|
uniform float viewWidth;
|
|
uniform float nightVision;
|
|
uniform float fogEnd;
|
|
uniform vec3 fogColor;
|
|
uniform vec3 sunVec;
|
|
uniform float frameTimeCounter;
|
|
uniform int frameCounter;
|
|
uniform float far;
|
|
uniform float near;
|
|
uniform float farPlane;
|
|
uniform float dhVoxyNearPlane;
|
|
uniform float dhVoxyFarPlane;
|
|
|
|
uniform mat4 gbufferModelViewInverse;
|
|
uniform mat4 gbufferModelView;
|
|
uniform mat4 gbufferPreviousModelView;
|
|
uniform mat4 gbufferProjectionInverse;
|
|
uniform mat4 gbufferProjection;
|
|
uniform mat4 gbufferPreviousProjection;
|
|
uniform vec3 cameraPosition;
|
|
uniform vec3 previousCameraPosition;
|
|
|
|
uniform int hideGUI;
|
|
uniform int dhVoxyRenderDistance;
|
|
uniform int isEyeInWater;
|
|
uniform ivec2 eyeBrightnessSmooth;
|
|
uniform ivec2 eyeBrightness;
|
|
uniform float rainStrength;
|
|
uniform float blindness;
|
|
uniform float darknessFactor;
|
|
uniform float darknessLightFactor;
|
|
uniform float caveDetection;
|
|
uniform float sunElevation;
|
|
|
|
#include "/lib/res_params.glsl"
|
|
|
|
#define diagonal3(m) vec3((m)[0].x, (m)[1].y, m[2].z)
|
|
#define projMAD(m, v) (diagonal3(m) * (v) + (m)[3].xyz)
|
|
vec3 toScreenSpace(vec3 p) {
|
|
vec4 iProjDiag = vec4(gbufferProjectionInverse[0].x, gbufferProjectionInverse[1].y, gbufferProjectionInverse[2].zw);
|
|
vec3 p3 = p * 2. - 1.;
|
|
vec4 fragposition = iProjDiag * p3.xyzz + gbufferProjectionInverse[3];
|
|
return fragposition.xyz / fragposition.w;
|
|
}
|
|
|
|
float linearize(float dist) {
|
|
return (2.0 * near) / (far + near - dist * (far - near));
|
|
}
|
|
|
|
vec3 toClipSpace3Prev(vec3 viewSpacePosition) {
|
|
return projMAD(gbufferPreviousProjection, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
|
|
}
|
|
|
|
vec3 bilateralUpsample2(vec2 fragcoord, sampler2D colortex, out float outerEdgeResults, float referenceDepth, sampler2D depth, bool hand){
|
|
|
|
vec3 colorSum = vec3(0.0);
|
|
float edgeSum = 0.0;
|
|
|
|
const float threshold = 0.005;
|
|
|
|
|
|
const int samples = 5;
|
|
|
|
vec2 coord = fragcoord - 1.5;
|
|
|
|
vec2 UV = coord;
|
|
const ivec2 SCALE = ivec2(1.0);
|
|
ivec2 UV_COLOR = ivec2(UV);
|
|
ivec2 UV_NOISE = ivec2(gl_FragCoord.xy*texelSize + 1);
|
|
|
|
const ivec2 OFFSET[5] = ivec2[5](
|
|
ivec2(-1,-1),
|
|
ivec2( 1, 1),
|
|
ivec2(-1, 1),
|
|
ivec2( 1,-1),
|
|
ivec2( 0, 0)
|
|
// ,ivec2( 0, 1),
|
|
// ivec2( 0,-1),
|
|
// ivec2( 1, 0),
|
|
// ivec2(-1, 0)
|
|
);
|
|
|
|
for(int i = 0; i < samples; i++) {
|
|
float offsetDepth = linearize(texelFetch(depth, UV_COLOR + (OFFSET[i] + UV_NOISE), 0).r);
|
|
|
|
float edgeDiff = abs(offsetDepth - referenceDepth) < threshold ? 1.0 : 1e-7;
|
|
outerEdgeResults = max(outerEdgeResults, abs(referenceDepth - offsetDepth));
|
|
|
|
vec3 offsetColor = texelFetch(colortex, UV_COLOR + OFFSET[i] + UV_NOISE, 0).rgb;
|
|
colorSum += offsetColor*edgeDiff;
|
|
edgeSum += edgeDiff;
|
|
|
|
}
|
|
|
|
outerEdgeResults = outerEdgeResults > (hand ? 0.005 : referenceDepth*0.05 + 0.1) ? 1.0 : 0.0;
|
|
|
|
return colorSum / edgeSum;
|
|
}
|
|
|
|
vec3 VLTemporalFiltering2(vec2 texcoord, vec3 playerPosIn, in float referenceDepth, sampler2D depth, bool hand, vec3 currentFrame, float roughness){
|
|
// get previous frames position stuff for UV
|
|
vec3 playerPos = playerPosIn + (cameraPosition - previousCameraPosition);
|
|
vec3 previousPosition = mat3(gbufferPreviousModelView) * playerPos + gbufferPreviousModelView[3].xyz;
|
|
previousPosition = toClipSpace3Prev(previousPosition);
|
|
|
|
vec2 velocity = previousPosition.xy - texcoord;
|
|
previousPosition.xy = texcoord + velocity;
|
|
|
|
// return vec4(outerEdgeResults,0,0,1);
|
|
// return upsampledCurrentFrame;
|
|
|
|
if (previousPosition.x < 0.0 || previousPosition.y < 0.0 || previousPosition.x > 1.0 || previousPosition.y > 1.0 || hand) return currentFrame.rgb;
|
|
|
|
// to fill pixel gaps in geometry edges, do a bilateral upsample.
|
|
// pass a mask to only show upsampled color around the edges of blocks. this is so it doesnt blur reprojected results.
|
|
float outerEdgeResults = 0.0;
|
|
vec3 upsampledCurrentFrame = bilateralUpsample2(gl_FragCoord.xy , colortex0, outerEdgeResults, referenceDepth, depth, hand);
|
|
//return currentFrame;
|
|
// vec4 upsampledCurrentFrame = BilateralUpscale(colortex0, depth, gl_FragCoord.xy - 1.5, referenceDepth);
|
|
// /*
|
|
|
|
vec4 frameHistoryTex = texture(colortex12, previousPosition.xy*RENDER_SCALE);
|
|
float prevDepth = frameHistoryTex.a;
|
|
float linPrevDepth = linearize(previousPosition.z);
|
|
|
|
vec3 frameHistory = frameHistoryTex.rgb;
|
|
|
|
vec3 reprojectFrame = currentFrame.rgb;
|
|
|
|
if(!(frameHistory.r == 0.0 && frameHistory.g == 0.0 && frameHistory.b == 0.0) && (abs(prevDepth-linPrevDepth) < max(linPrevDepth * 0.02, 0.001))) {
|
|
vec3 col1 = texture(colortex0, texcoord + vec2( texelSize.x, texelSize.y)).rgb;
|
|
vec3 col2 = texture(colortex0, texcoord + vec2( texelSize.x, -texelSize.y)).rgb;
|
|
vec3 col3 = texture(colortex0, texcoord + vec2(-texelSize.x, -texelSize.y)).rgb;
|
|
vec3 col4 = texture(colortex0, texcoord + vec2(-texelSize.x, texelSize.y)).rgb;
|
|
vec3 col5 = texture(colortex0, texcoord + vec2( 0.0, texelSize.y)).rgb;
|
|
vec3 col6 = texture(colortex0, texcoord + vec2( 0.0, -texelSize.y)).rgb;
|
|
vec3 col7 = texture(colortex0, texcoord + vec2(-texelSize.x, 0.0)).rgb;
|
|
vec3 col8 = texture(colortex0, texcoord + vec2( texelSize.x, 0.0)).rgb;
|
|
|
|
vec3 colMax = max(currentFrame.rgb,max(col1,max(col2,max(col3, max(col4, max(col5, max(col6, max(col7, col8))))))));
|
|
vec3 colMin = min(currentFrame.rgb,min(col1,min(col2,min(col3, min(col4, min(col5, min(col6, min(col7, col8))))))));
|
|
|
|
vec3 clampedFrameHistory = clamp(frameHistory, colMin, colMax);
|
|
|
|
float blendingFactor = mix(0.025, 1.0, smoothstep(0.05, 0.25, length(cameraPosition-previousCameraPosition)));
|
|
blendingFactor = mix(1.0, blendingFactor, smoothstep(0.0, 0.1, roughness));
|
|
reprojectFrame = mix(clampedFrameHistory, currentFrame.rgb, blendingFactor);
|
|
}
|
|
|
|
// return clamp(reprojectFrame,0.0,65000.0);
|
|
return clamp(mix(reprojectFrame, upsampledCurrentFrame, outerEdgeResults),0.0,65000.0);
|
|
// */
|
|
|
|
}
|
|
|
|
float blueNoise(){
|
|
#ifdef TAA
|
|
return fract(texelFetch(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887 * frameCounter);
|
|
#else
|
|
return fract(texelFetch(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887);
|
|
#endif
|
|
}
|
|
|
|
float interleaved_gradientNoise_temporal(){
|
|
// #ifdef TAA
|
|
// return fract(52.9829189*fract(0.06711056*gl_FragCoord.x + 0.00583715*gl_FragCoord.y ) + 1.0/1.6180339887 * frameCounter);
|
|
// #else
|
|
// return fract(52.9829189*fract(0.06711056*gl_FragCoord.x + 0.00583715*gl_FragCoord.y ) + 1.0/1.6180339887);
|
|
// #endif
|
|
|
|
vec2 coord = gl_FragCoord.xy;
|
|
#ifdef TAA
|
|
coord += (frameCounter%40000) * 2.0;
|
|
#endif
|
|
|
|
return fract(52.9829189*fract(0.06711056*coord.x + 0.00583715*coord.y ) + 1.0/1.6180339887);
|
|
}
|
|
|
|
vec2 decodeVec2(float a){
|
|
const vec2 constant1 = 65535. / vec2( 256., 65536.);
|
|
const float constant2 = 256. / 255.;
|
|
return fract( a * constant1 ) * constant2 ;
|
|
}
|
|
|
|
vec3 decode (vec2 encn){
|
|
vec3 n = vec3(0.0);
|
|
encn = encn * 2.0 - 1.0;
|
|
n.xy = abs(encn);
|
|
n.z = 1.0 - n.x - n.y;
|
|
n.xy = n.z <= 0.0 ? (1.0 - n.yx) * sign(encn) : encn;
|
|
return clamp(normalize(n.xyz),-1.0,1.0);
|
|
}
|
|
|
|
vec3 toLinear(vec3 sRGB){
|
|
return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);
|
|
}
|
|
|
|
float shlickFresnelRoughness(float XdotN, float roughness){
|
|
|
|
float shlickFresnel = clamp(1.0 + XdotN,0.0,1.0);
|
|
|
|
float curves = exp(-4.0*pow(1.0-(roughness),2.5));
|
|
float brightness = exp(-3.0*pow(1.0-sqrt(roughness),3.50));
|
|
|
|
shlickFresnel = pow(1.0-pow(1.0-shlickFresnel, mix(1.0, 1.9, curves)),mix(5.0, 2.6, curves));
|
|
shlickFresnel = mix(0.0, mix(1.0,0.065, brightness) , clamp(shlickFresnel,0.0,1.0));
|
|
|
|
return shlickFresnel;
|
|
}
|
|
|
|
void frisvad(in vec3 n, out vec3 f, out vec3 r){
|
|
if(n.z < -0.9) {
|
|
f = vec3(0.,-1,0);
|
|
r = vec3(-1, 0, 0);
|
|
} else {
|
|
float a = 1./(1.+n.z);
|
|
float b = -n.x*n.y*a;
|
|
f = vec3(1. - n.x*n.x*a, b, -n.x) ;
|
|
r = vec3(b, 1. - n.y*n.y*a , -n.y);
|
|
}
|
|
}
|
|
|
|
mat3 CoordBase(vec3 n){
|
|
vec3 x,y;
|
|
frisvad(n,x,y);
|
|
return mat3(x,y,n);
|
|
}
|
|
|
|
vec3 GGX(vec3 n, vec3 v, vec3 l, float r, vec3 f0, vec3 metalAlbedoTint) {
|
|
r = max(pow(r,2.5), 0.0001);
|
|
|
|
vec3 h = normalize(l + v);
|
|
float hn = inversesqrt(dot(h, h));
|
|
|
|
float dotLH = clamp(dot(h,l)*hn,0.,1.);
|
|
float dotNH = clamp(dot(h,n)*hn,0.,1.) ;
|
|
float dotNL = clamp(dot(n,l),0.,1.);
|
|
float dotNHsq = dotNH*dotNH;
|
|
|
|
float denom = dotNHsq * r - dotNHsq + 1.;
|
|
float D = r / (3.141592653589793 * denom * denom);
|
|
|
|
vec3 F = (f0 + (1. - f0) * exp2((-5.55473*dotLH-6.98316)*dotLH)) * metalAlbedoTint;
|
|
float k2 = .25 * r;
|
|
|
|
return dotNL * D * F / (dotLH*dotLH*(1.0-k2)+k2);
|
|
}
|
|
|
|
#ifdef IEXT_ENABLED
|
|
uniform bool IEXT_KEY_0;
|
|
#endif
|
|
|
|
vec4 calculateFlashlightData(in vec3 viewPos, bool hand){
|
|
#ifdef IEXT_ENABLED
|
|
if(IEXT_KEY_0) return vec4(0.0);
|
|
#endif
|
|
|
|
vec4 flashLightSpecularData = vec4(0.0);
|
|
if(hand){
|
|
return flashLightSpecularData;
|
|
}
|
|
|
|
// vec3 shiftedViewPos = viewPos + vec3(-0.25, 0.2, 0.0);
|
|
// vec3 shiftedPlayerPos = mat3(gbufferModelViewInverse) * shiftedViewPos + gbufferModelViewInverse[3].xyz + (cameraPosition - previousCameraPosition) * 3.0;
|
|
// shiftedViewPos = mat3(gbufferPreviousModelView) * shiftedPlayerPos + gbufferPreviousModelView[3].xyz;
|
|
vec3 shiftedViewPos;
|
|
vec3 shiftedPlayerPos;
|
|
float forwardOffset;
|
|
|
|
#ifdef VIVECRAFT
|
|
if (vivecraftIsVR) {
|
|
forwardOffset = 0.0;
|
|
shiftedPlayerPos = mat3(gbufferModelViewInverse) * viewPos + gbufferModelViewInverse[3].xyz + vivecraftRelativeMainHandPos;
|
|
shiftedViewPos = shiftedPlayerPos * mat3(vivecraftRelativeMainHandRot);
|
|
} else
|
|
#endif
|
|
{
|
|
forwardOffset = 0.5;
|
|
shiftedViewPos = viewPos + vec3(-0.25, 0.2, 0.0);
|
|
shiftedPlayerPos = mat3(gbufferModelViewInverse) * shiftedViewPos + gbufferModelViewInverse[3].xyz + (cameraPosition - previousCameraPosition) * 3.0;
|
|
shiftedViewPos = mat3(gbufferPreviousModelView) * shiftedPlayerPos + gbufferPreviousModelView[3].xyz;
|
|
}
|
|
|
|
|
|
|
|
vec2 scaledViewPos = shiftedViewPos.xy / max(-shiftedViewPos.z - forwardOffset, 1e-7);
|
|
float linearDistance = length(shiftedPlayerPos);
|
|
float shiftedLinearDistance = length(scaledViewPos);
|
|
|
|
float lightFalloff = 1.0 - clamp(1.0-linearDistance/FLASHLIGHT_RANGE, -0.999,1.0);
|
|
lightFalloff = max(exp(-10.0 * FLASHLIGHT_BRIGHTNESS_FALLOFF_MULT * lightFalloff),0.0);
|
|
|
|
float flashLightSpecular = lightFalloff * exp2(-7.0*shiftedLinearDistance*shiftedLinearDistance) * FLASHLIGHT_BRIGHTNESS_MULT;
|
|
flashLightSpecularData = vec4(normalize(shiftedPlayerPos), flashLightSpecular);
|
|
|
|
return flashLightSpecularData;
|
|
}
|
|
|
|
#if defined IS_LPV_ENABLED || defined PHOTONICS && defined PHOTONICS && !defined PH_ENABLE_HANDHELD_LIGHT
|
|
uniform bool firstPersonCamera;
|
|
uniform vec3 relativeEyePosition;
|
|
uniform int heldItemId;
|
|
uniform int heldItemId2;
|
|
|
|
uniform sampler3D texLpv1;
|
|
uniform sampler3D texLpv2;
|
|
|
|
#include "/lib/util.glsl"
|
|
#include "/lib/hsv.glsl"
|
|
#include "/lib/lpv_common.glsl"
|
|
#include "/lib/lpv_render.glsl"
|
|
#include "/lib/blocks.glsl"
|
|
#include "/lib/lpv_blocks.glsl"
|
|
|
|
vec3 GetHandLight(const in int itemId, const in vec3 playerPos, inout float lightRange) {
|
|
vec3 lightFinal = vec3(0.0);
|
|
|
|
uint blockData = imageLoad(imgBlockData, itemId).r;
|
|
vec4 lightColorRange = unpackUnorm4x8(blockData);
|
|
lightRange = lightColorRange.a * 255.0;
|
|
|
|
if (lightRange > 0.0) {
|
|
vec3 lightColor = srgbToLinear(lightColorRange.rgb);
|
|
float lightDist = length(playerPos+relativeEyePosition)*0.7;
|
|
float falloff = pow(1.0 - lightDist / lightRange, 3.0);
|
|
lightFinal = lightColor * max(falloff, 0.0);
|
|
}
|
|
|
|
return lightFinal;
|
|
}
|
|
|
|
#ifdef BELTBORNE_LANTERNS
|
|
uniform int IEXT_beltborne_lanterns_Id;
|
|
#endif
|
|
#endif
|
|
|
|
float getReflectionVisibility(float f0, float roughness){
|
|
|
|
// the goal is to determine if the reflection is even visible.
|
|
// if it reaches a point in smoothness or reflectance where it is not visible, allow it to interpolate to diffuse lighting.
|
|
#if ROUGHNESS_THRESHOLD < 1
|
|
return 0.0;
|
|
#else
|
|
float thresholdValue = ROUGHNESS_THRESHOLD/100.0;
|
|
|
|
// the visibility gradient should only happen for dialectric materials. because metal is always shiny i guess or something
|
|
float dialectrics = max(f0*255.0 - 26.0,0.0)/229.0;
|
|
float value = 0.35; // so to a value you think is good enough.
|
|
float thresholdA = min(max( (1.0-dialectrics) - value, 0.0)/value, 1.0);
|
|
|
|
// use perceptual smoothness instead of linear roughness. it just works better i guess
|
|
float smoothness = 1.0-sqrt(roughness);
|
|
value = thresholdValue; // this one is typically want you want to scale.
|
|
float thresholdB = min(max(smoothness - value, 0.0)/value, 1.0);
|
|
|
|
// preserve super smooth reflections. if thresholdB's value is really high, then fully smooth, low f0 materials would be removed (like water).
|
|
value = 0.1; // super low so only the smoothest of materials are includes.
|
|
float thresholdC = 1.0-min(max(value - (1.0-smoothness), 0.0)/value, 1.0);
|
|
|
|
float visibilityGradient = max(thresholdA*thresholdC - thresholdB,0.0);
|
|
|
|
// a curve to make the gradient look smooth/nonlinear. just preference
|
|
visibilityGradient = 1.0-visibilityGradient;
|
|
visibilityGradient *=visibilityGradient;
|
|
visibilityGradient = 1.0-visibilityGradient;
|
|
visibilityGradient *=visibilityGradient;
|
|
|
|
return visibilityGradient;
|
|
#endif
|
|
}
|
|
|
|
/* RENDERTARGETS:12,3 */
|
|
|
|
void main() {
|
|
|
|
vec2 texcoord = gl_FragCoord.xy*texelSize;
|
|
float depth = texelFetch(depthtex1, ivec2(gl_FragCoord.xy),0).x;
|
|
// bool hand = depth < 0.56;
|
|
float z = depth;
|
|
|
|
#if defined DISTANT_HORIZONS || defined VOXY
|
|
float DH_depth1 = 1.0;
|
|
float swappedDepth;
|
|
if(z >= 1.0) {
|
|
DH_depth1 = texelFetch(dhVoxyDepthTex1,ivec2(gl_FragCoord.xy),0).x;
|
|
swappedDepth = DH_depth1;
|
|
} else {
|
|
swappedDepth = z;
|
|
}
|
|
#else
|
|
float DH_depth1 = 1.0;
|
|
float swappedDepth = z;
|
|
#endif
|
|
|
|
bool isSky = swappedDepth >= 1.0;
|
|
|
|
gl_FragData[0] = vec4(0.0);
|
|
vec3 FINAL_COLOR = texture(colortex3, texcoord).rgb;
|
|
if(!isSky) {
|
|
|
|
float frDepth = linearize(z);
|
|
gl_FragData[0].a = frDepth;
|
|
|
|
vec4 data = texelFetch(colortex1, ivec2(gl_FragCoord.xy), 0);
|
|
|
|
vec4 dataUnpacked0 = vec4(decodeVec2(data.x),decodeVec2(data.y)); // albedo, masks
|
|
vec4 dataUnpacked1 = vec4(decodeVec2(data.z),decodeVec2(data.w)); // normals, lightmaps
|
|
|
|
float opaqueMasks = dataUnpacked1.w;
|
|
bool hand = abs(opaqueMasks-0.75) < 0.01;
|
|
bool entities = abs(opaqueMasks-0.45) < 0.01;
|
|
bool opaqueParticles = abs(opaqueMasks-0.85) <0.01;
|
|
#ifdef SHADER_GRASS
|
|
bool isShaderGrass = abs(opaqueMasks-0.80) < 0.01;
|
|
#else
|
|
const bool isShaderGrass = false;
|
|
#endif
|
|
|
|
vec3 viewPos = toScreenSpace(vec3(texcoord/RENDER_SCALE, z));
|
|
|
|
vec3 playerPos = mat3(gbufferModelViewInverse) * viewPos;
|
|
vec3 NplayerPos = normalize(playerPos);
|
|
playerPos += gbufferModelViewInverse[3].xyz;
|
|
|
|
|
|
// derived from N and K from labPBR wiki https://shaderlabs.org/wiki/LabPBR_Material_Standard
|
|
// using ((1.0 - N)^2 + K^2) / ((1.0 + N)^2 + K^2)
|
|
const vec3 HCM_F0 [8] = vec3[8](
|
|
vec3(0.531228825312, 0.51235724246, 0.495828545714),// iron
|
|
vec3(0.944229966045, 0.77610211732, 0.373402004593),// gold
|
|
vec3(0.912298031535, 0.91385063144, 0.919680580954),// Aluminum
|
|
vec3(0.55559681715, 0.55453707574, 0.554779427513),// Chrome
|
|
vec3(0.925952196272, 0.72090163805, 0.504154241735),// Copper
|
|
vec3(0.632483812932, 0.62593707362, 0.641478899539),// Lead
|
|
vec3(0.678849234658, 0.64240055565, 0.588409633571),// Platinum
|
|
vec3(0.961999998804, 0.94946811207, 0.922115710997) // Silver
|
|
);
|
|
|
|
vec3 albedo = toLinear(vec3(dataUnpacked0.xz,dataUnpacked1.x));
|
|
vec2 lightmap = dataUnpacked1.yz;
|
|
|
|
vec4 stuff = texelFetch(colortex8, ivec2(gl_FragCoord.xy), 0);
|
|
vec3 normal = normalize(decode(stuff.xy));
|
|
vec2 speculars = stuff.zw;
|
|
|
|
float roughness = speculars.r;
|
|
float f0 = speculars.g;
|
|
roughness = 1.0 - roughness;
|
|
roughness *= roughness;
|
|
|
|
f0 = f0 == 0.0 ? 0.02 : f0;
|
|
|
|
bool isMetal = f0 > 229.5/255.0;
|
|
|
|
// get reflected vector
|
|
mat3 basis = CoordBase(normal);
|
|
vec3 viewDir = -NplayerPos*basis;
|
|
viewDir.z = abs(viewDir.z);
|
|
|
|
float VdotN = dot(-normalize(viewDir), vec3(0.0,0.0,1.0));
|
|
float shlickFresnel = shlickFresnelRoughness(VdotN, roughness);
|
|
|
|
// F0 < 230 dialectrics
|
|
// F0 >= 230 hardcoded metal f0
|
|
// F0 == 255 use albedo for f0
|
|
albedo = f0 == 1.0 ? sqrt(albedo) : albedo;
|
|
vec3 metalAlbedoTint = isMetal ? albedo : vec3(1.0);
|
|
// get F0 values for hardcoded metals.
|
|
vec3 hardCodedMetalsF0 = f0 == 1.0 ? albedo : HCM_F0[int(clamp(f0*255.0 - 229.5,0.0,7.0))];
|
|
vec3 reflectance = isMetal ? hardCodedMetalsF0 : vec3(f0);
|
|
vec3 F0 = (reflectance + (1.0-reflectance) * shlickFresnel) * metalAlbedoTint;
|
|
|
|
vec4 currentFrame = texture(colortex0, texcoord);
|
|
float alpha = getReflectionVisibility(f0, roughness);
|
|
|
|
vec3 denoisedReflections = currentFrame.rgb;
|
|
|
|
if(roughness > 0.005 && alpha < 0.9999 && !hand && !entities && !opaqueParticles
|
|
#if defined DISTANT_HORIZONS || defined VOXY
|
|
&& z < 1.0
|
|
#endif
|
|
) {
|
|
denoisedReflections = VLTemporalFiltering2(texcoord, playerPos, frDepth, depthtex1, hand, currentFrame.rgb, roughness);
|
|
|
|
gl_FragData[0].rgb = denoisedReflections;
|
|
}
|
|
|
|
denoisedReflections.rgb = mix(FINAL_COLOR, denoisedReflections.rgb, F0);
|
|
FINAL_COLOR = mix(denoisedReflections.rgb, FINAL_COLOR, alpha);
|
|
|
|
#if defined OVERWORLD_SHADER && SUN_SPECULAR_MULT > 0
|
|
vec3 lightSourceReflection = SUN_SPECULAR_MULT * texture(colortex15, texcoord).rgb * GGX(normal, -NplayerPos, WsunVec, roughness, reflectance, metalAlbedoTint);
|
|
FINAL_COLOR += lightSourceReflection;
|
|
#endif
|
|
|
|
#if defined FLASHLIGHT_SPECULAR && (defined DEFERRED_SPECULAR || defined FORWARD_SPECULAR)
|
|
vec4 flashlightData = calculateFlashlightData(viewPos, hand);
|
|
vec3 flashLightReflection = vec3(FLASHLIGHT_R,FLASHLIGHT_G,FLASHLIGHT_B) * flashlightData.a * GGX(normal, -flashlightData.xyz, -flashlightData.xyz, roughness, reflectance, metalAlbedoTint);
|
|
FINAL_COLOR += flashLightReflection;
|
|
#endif
|
|
|
|
#if defined Hand_Held_lights && defined IS_LPV_ENABLED && HANDHELD_LIGHT_REFLECTIONS > 0
|
|
if(!hand && firstPersonCamera && !isShaderGrass) {
|
|
if (heldItemId > 0){
|
|
vec3 shiftedViewPos = viewPos + vec3(-0.25, 0.2, 0.0);
|
|
vec3 shiftedPlayerPos = mat3(gbufferModelViewInverse) * shiftedViewPos + gbufferModelViewInverse[3].xyz + (cameraPosition - previousCameraPosition);
|
|
|
|
float lightRange = 0.0;
|
|
vec3 handLightCol = GetHandLight(heldItemId, shiftedPlayerPos, lightRange);
|
|
|
|
if(lightRange > 0.0) {
|
|
vec3 handheldReflection = handLightCol * GGX(normal, -shiftedPlayerPos, -shiftedPlayerPos, roughness, reflectance, metalAlbedoTint);
|
|
FINAL_COLOR += handheldReflection*HANDHELD_LIGHT_REFLECTIONS*0.005;
|
|
}
|
|
}
|
|
|
|
if (heldItemId2 > 0){
|
|
vec3 shiftedViewPos = viewPos + vec3(0.25, 0.2, 0.0);
|
|
vec3 shiftedPlayerPos = mat3(gbufferModelViewInverse) * shiftedViewPos + gbufferModelViewInverse[3].xyz + (cameraPosition - previousCameraPosition);
|
|
|
|
float lightRange = 0.0;
|
|
vec3 handLightCol = GetHandLight(heldItemId2, shiftedPlayerPos, lightRange);
|
|
|
|
if(lightRange > 0.0) {
|
|
vec3 handheldReflection = handLightCol * GGX(normal, -shiftedPlayerPos, -shiftedPlayerPos, roughness, reflectance, metalAlbedoTint);
|
|
FINAL_COLOR += handheldReflection*HANDHELD_LIGHT_REFLECTIONS*0.005;
|
|
}
|
|
}
|
|
|
|
#ifdef BELTBORNE_LANTERNS
|
|
if (IEXT_beltborne_lanterns_Id > 0){
|
|
vec3 shiftedViewPos = viewPos + vec3(0.15, 0.2, 0.0);
|
|
vec3 shiftedPlayerPos = mat3(gbufferModelViewInverse) * shiftedViewPos + gbufferModelViewInverse[3].xyz + (cameraPosition - previousCameraPosition);
|
|
|
|
float lightRange = 0.0;
|
|
vec3 handLightCol = GetHandLight(IEXT_beltborne_lanterns_Id, shiftedPlayerPos, lightRange);
|
|
|
|
if(lightRange > 0.0) {
|
|
vec3 handheldReflection = handLightCol * GGX(normal, -shiftedPlayerPos, -shiftedPlayerPos, roughness, reflectance, metalAlbedoTint);
|
|
FINAL_COLOR += handheldReflection*HANDHELD_LIGHT_REFLECTIONS*0.005;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
gl_FragData[1].rgb = FINAL_COLOR;
|
|
} |