improve TAA very slightly. fix underwater fog sunlight not going away in caves. tweak sky SSS. add noise to POM layers

This commit is contained in:
Xonk
2024-07-06 21:03:31 -04:00
parent d5a92880ac
commit 8143c57fa2
30 changed files with 354 additions and 303 deletions

View File

@ -45,7 +45,7 @@ const bool colortex15Clear = false;
*/
#else
/*
const int colortex5Format = R11F_G11F_B10F; //TAA buffer (everything)
const int colortex5Format = RGBA16F; //TAA buffer (everything)
*/
#endif
@ -65,7 +65,6 @@ uniform sampler2D depthtex1;
uniform vec2 texelSize;
uniform float frameTimeCounter;
uniform int framemod8;
uniform float viewHeight;
uniform float viewWidth;
uniform vec3 previousCameraPosition;
@ -73,13 +72,23 @@ uniform mat4 gbufferPreviousModelView;
uniform int hideGUI;
#ifdef DAMAGE_TAKEN_EFFECT
uniform float CriticalDamageTaken;
#endif
#include "/lib/util.glsl"
#include "/lib/projections.glsl"
uniform int framemod8;
#include "/lib/TAA_jitter.glsl"
vec2 decodeVec2(float a){
const vec2 constant1 = 65535. / vec2( 256., 65536.);
const float constant2 = 256. / 255.;
return fract( a * constant1 ) * constant2 ;
}
float luma(vec3 color) {
return dot(color,vec3(0.21, 0.72, 0.07));
}
@ -98,6 +107,93 @@ vec4 fp10Dither(vec4 color ,float dither){
return vec4(color.rgb + dither*exp2(-mantissaBits)*exp2(exponent), color.a);
}
vec3 toClipSpace3Prev(vec3 viewSpacePosition) {
return projMAD(gbufferPreviousProjection, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
}
vec3 tonemap(vec3 col){
return col/(1+luma(col));
}
vec3 invTonemap(vec3 col){
return col/(1-luma(col));
}
void convertHandDepth(inout float depth) {
float ndcDepth = depth * 2.0 - 1.0;
ndcDepth /= MC_HAND_DEPTH;
depth = ndcDepth * 0.5 + 0.5;
}
float convertHandDepth2( float depth) {
float ndcDepth = depth * 2.0 - 1.0;
ndcDepth /= MC_HAND_DEPTH;
return ndcDepth * 0.5 + 0.5;
}
#ifdef DISTANT_HORIZONS
uniform sampler2D dhDepthTex;
#endif
uniform float near;
uniform float far;
uniform float dhFarPlane;
uniform float dhNearPlane;
#include "/lib/DistantHorizons_projections.glsl"
float ld(float dist) {
return (2.0 * near) / (far + near - dist * (far - near));
}
float DH_ld(float dist) {
return (2.0 * dhNearPlane) / (dhFarPlane + dhNearPlane - dist * (dhFarPlane - dhNearPlane));
}
float DH_inv_ld (float lindepth){
return -((2.0*dhNearPlane/lindepth)-dhFarPlane-dhNearPlane)/(dhFarPlane-dhNearPlane);
}
float linearizeDepthFast(const in float depth, const in float near, const in float far) {
return (near * far) / (depth * (near - far) + far);
}
float invertlinearDepthFast(const in float depth, const in float near, const in float far) {
return ((2.0*near/depth)-far-near)/(far-near);
}
vec3 toClipSpace3Prev_DH( vec3 viewSpacePosition, bool depthCheck ) {
#ifdef DISTANT_HORIZONS
mat4 projectionMatrix = depthCheck ? dhPreviousProjection : gbufferPreviousProjection;
return projMAD(projectionMatrix, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
#else
return projMAD(gbufferPreviousProjection, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
#endif
}
vec3 toScreenSpace_DH_special(vec3 POS, bool depthCheck ) {
vec4 viewPos = vec4(0.0);
vec3 feetPlayerPos = vec3(0.0);
vec4 iProjDiag = vec4(0.0);
#ifdef DISTANT_HORIZONS
if (depthCheck) {
iProjDiag = vec4(dhProjectionInverse[0].x, dhProjectionInverse[1].y, dhProjectionInverse[2].zw);
feetPlayerPos = POS * 2.0 - 1.0;
viewPos = iProjDiag * feetPlayerPos.xyzz + dhProjectionInverse[3];
viewPos.xyz /= viewPos.w;
} else {
#endif
iProjDiag = vec4(gbufferProjectionInverse[0].x, gbufferProjectionInverse[1].y, gbufferProjectionInverse[2].zw);
feetPlayerPos = POS * 2.0 - 1.0;
viewPos = iProjDiag * feetPlayerPos.xyzz + gbufferProjectionInverse[3];
viewPos.xyz /= viewPos.w;
#ifdef DISTANT_HORIZONS
}
#endif
return viewPos.xyz;
}
//Modified texture interpolation from inigo quilez
vec4 smoothfilter(in sampler2D tex, in vec2 uv)
{
@ -143,40 +239,26 @@ vec3 FastCatmulRom(sampler2D colorTex, vec2 texcoord, vec4 rtMetrics, float shar
vec4(centerColor, 1.0) * (w12.x * w12.y) +
vec4(texture2D(colorTex, vec2(tc3.x, tc12.y)).rgb, 1.0) * (w3.x * w12.y) +
vec4(texture2D(colorTex, vec2(tc12.x, tc3.y )).rgb, 1.0) * (w12.x * w3.y );
return color.rgb/color.a;
}
vec3 clip_aabb(vec3 q, vec3 aabb_min, vec3 aabb_max)
{
vec3 p_clip = 0.5 * (aabb_max + aabb_min);
vec3 e_clip = 0.5 * (aabb_max - aabb_min) + 0.00000001;
// vec3 clip_aabb(vec3 q, vec3 aabb_min, vec3 aabb_max)
// {
// vec3 p_clip = 0.5 * (aabb_max + aabb_min);
// vec3 e_clip = 0.5 * (aabb_max - aabb_min) + 0.00000001;
vec3 v_clip = q - vec3(p_clip);
vec3 v_unit = v_clip.xyz / e_clip;
vec3 a_unit = abs(v_unit);
float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z));
// vec3 v_clip = q - vec3(p_clip);
// vec3 v_unit = v_clip.xyz / e_clip;
// vec3 a_unit = abs(v_unit);
// float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z));
if (ma_unit > 1.0)
return vec3(p_clip) + v_clip / ma_unit;
else
return q;
}
vec3 toClipSpace3Prev(vec3 viewSpacePosition) {
return projMAD(gbufferPreviousProjection, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
}
vec3 tonemap(vec3 col){
return col/(1+luma(col));
}
vec3 invTonemap(vec3 col){
return col/(1-luma(col));
}
void convertHandDepth(inout float depth) {
float ndcDepth = depth * 2.0 - 1.0;
ndcDepth /= MC_HAND_DEPTH;
depth = ndcDepth * 0.5 + 0.5;
}
// if (ma_unit > 1.0)
// return vec3(p_clip) + v_clip / ma_unit;
// else
// return q;
// }
vec3 closestToCamera5taps(vec2 texcoord, sampler2D depth, bool hand)
{
@ -248,88 +330,6 @@ vec3 closestToCamera5taps_DH(vec2 texcoord, sampler2D depth, sampler2D dhDepth,
return dmin;
}
#ifdef DISTANT_HORIZONS
uniform sampler2D dhDepthTex;
#endif
uniform float near;
uniform float far;
uniform float dhFarPlane;
uniform float dhNearPlane;
#include "/lib/DistantHorizons_projections.glsl"
float ld(float dist) {
return (2.0 * near) / (far + near - dist * (far - near));
}
float DH_ld(float dist) {
return (2.0 * dhNearPlane) / (dhFarPlane + dhNearPlane - dist * (dhFarPlane - dhNearPlane));
}
float DH_inv_ld (float lindepth){
return -((2.0*dhNearPlane/lindepth)-dhFarPlane-dhNearPlane)/(dhFarPlane-dhNearPlane);
}
float linearizeDepthFast(const in float depth, const in float near, const in float far) {
return (near * far) / (depth * (near - far) + far);
}
float invertlinearDepthFast(const in float depth, const in float near, const in float far) {
return ((2.0*near/depth)-far-near)/(far-near);
}
vec3 toClipSpace3Prev_DH( vec3 viewSpacePosition, bool depthCheck ) {
#ifdef DISTANT_HORIZONS
mat4 projectionMatrix = depthCheck ? dhPreviousProjection : gbufferPreviousProjection;
return projMAD(projectionMatrix, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
#else
return projMAD(gbufferPreviousProjection, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
#endif
}
vec3 toScreenSpace_DH_special(vec3 POS, bool depthCheck ) {
vec4 viewPos = vec4(0.0);
vec3 feetPlayerPos = vec3(0.0);
vec4 iProjDiag = vec4(0.0);
#ifdef DISTANT_HORIZONS
if (depthCheck) {
iProjDiag = vec4(dhProjectionInverse[0].x, dhProjectionInverse[1].y, dhProjectionInverse[2].zw);
feetPlayerPos = POS * 2.0 - 1.0;
viewPos = iProjDiag * feetPlayerPos.xyzz + dhProjectionInverse[3];
viewPos.xyz /= viewPos.w;
} else {
#endif
iProjDiag = vec4(gbufferProjectionInverse[0].x, gbufferProjectionInverse[1].y, gbufferProjectionInverse[2].zw);
feetPlayerPos = POS * 2.0 - 1.0;
viewPos = iProjDiag * feetPlayerPos.xyzz + gbufferProjectionInverse[3];
viewPos.xyz /= viewPos.w;
#ifdef DISTANT_HORIZONS
}
#endif
return viewPos.xyz;
}
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.);
#ifdef DAMAGE_TAKEN_EFFECT
uniform float CriticalDamageTaken;
#endif
vec4 TAA_hq(bool hand){
#ifdef TAA_UPSCALING
@ -338,7 +338,7 @@ vec4 TAA_hq(bool hand){
vec2 adjTC = texcoord;
#endif
vec2 offsets = offsets[framemod8]*texelSize*0.5;
vec2 offsets = offsets[framemod8] * texelSize * 0.5;
#ifdef DISTANT_HORIZONS
bool depthCheck = texture2D(depthtex0,adjTC).x >= 1.0;
@ -414,6 +414,7 @@ vec4 TAA_hq(bool hand){
//Blend current pixel with clamped history, apply fast tonemap beforehand to reduce flickering
vec4 supersampled = vec4(invTonemap(mix(tonemap(finalcAcc), tonemap(albedoCurrent0), clamp(BLEND_FACTOR + movementRejection, 0.0,1.0))), 1.0);
// vec4 supersampled = vec4(invTonemap(mix(tonemap(finalcAcc), tonemap(albedoCurrent0), 0.5)), 1.0);
#ifdef DAMAGE_TAKEN_EFFECT
if(CriticalDamageTaken > 0.01) supersampled.rgb = mix(supersampled.rgb, texture2D(colortex5, adjTC).rgb, sqrt(CriticalDamageTaken)*0.8);
@ -432,17 +433,97 @@ vec4 TAA_hq(bool hand){
#endif
}
vec4 computeTAA(vec2 texcoord, bool hand){
vec2 decodeVec2(float a){
const vec2 constant1 = 65535. / vec2( 256., 65536.);
const float constant2 = 256. / 255.;
return fract( a * constant1 ) * constant2 ;
vec2 jitter = offsets[framemod8]*texelSize*0.5;
vec2 adjTC = clamp(texcoord*RENDER_SCALE, vec2(0.0), RENDER_SCALE - texelSize*2.0);
// get previous frames position stuff for UV
//use velocity from the nearest texel from camera in a 3x3 box in order to improve edge quality in motion
#ifdef DISTANT_HORIZONS
bool depthCheck = texture2D(depthtex0,adjTC).x >= 1.0;
vec3 closestToCamera = closestToCamera5taps_DH(adjTC, depthtex0, dhDepthTex, depthCheck, hand);
vec3 viewPos = toScreenSpace_DH_special(closestToCamera, depthCheck);
#else
vec3 closestToCamera = closestToCamera5taps(adjTC, depthtex0, hand);
vec3 viewPos = toScreenSpace(closestToCamera);
#endif
vec3 playerPos = mat3(gbufferModelViewInverse) * toScreenSpace(closestToCamera) + gbufferModelViewInverse[3].xyz + (cameraPosition - previousCameraPosition);
vec3 previousPosition = mat3(gbufferPreviousModelView) * playerPos + gbufferPreviousModelView[3].xyz;
previousPosition = toClipSpace3Prev(previousPosition);
vec2 velocity = previousPosition.xy - closestToCamera.xy;
previousPosition.xy = texcoord + velocity;
// sample current frame, and make sure it is de-jittered
vec3 currentFrame = smoothfilter(colortex3, adjTC + jitter).rgb;
//reject history if off-screen and early exit
if (previousPosition.x < 0.0 || previousPosition.y < 0.0 || previousPosition.x > 1.0 || previousPosition.y > 1.0) return vec4(currentFrame, 1.0);
#ifdef TAA_UPSCALING
// Interpolating neighboorhood clampling boundaries between pixels
vec3 colMax = texture2D(colortex0, adjTC).rgb;
vec3 colMin = texture2D(colortex6, adjTC).rgb;
#else
//Assuming the history color is a blend of the 3x3 neighborhood, we clamp the history to the min and max of each channel in the 3x3 neighborhood
vec3 col0 = currentFrame; // can use this because its the center sample.
vec3 col1 = texture2D(colortex3, adjTC + vec2( texelSize.x, texelSize.y)).rgb;
vec3 col2 = texture2D(colortex3, adjTC + vec2( texelSize.x, -texelSize.y)).rgb;
vec3 col3 = texture2D(colortex3, adjTC + vec2(-texelSize.x, -texelSize.y)).rgb;
vec3 col4 = texture2D(colortex3, adjTC + vec2(-texelSize.x, texelSize.y)).rgb;
vec3 col5 = texture2D(colortex3, adjTC + vec2( 0.0, texelSize.y)).rgb;
vec3 col6 = texture2D(colortex3, adjTC + vec2( 0.0, -texelSize.y)).rgb;
vec3 col7 = texture2D(colortex3, adjTC + vec2(-texelSize.x, 0.0)).rgb;
vec3 col8 = texture2D(colortex3, adjTC + vec2( texelSize.x, 0.0)).rgb;
vec3 colMax = max(col0,max(col1,max(col2,max(col3, max(col4, max(col5, max(col6, max(col7, col8))))))));
vec3 colMin = min(col0,min(col1,min(col2,min(col3, min(col4, min(col5, min(col6, min(col7, col8))))))));
vec3 colMax5 = max(col0,max(col5,max(col6,max(col7,col8))));
vec3 colMin5 = min(col0,min(col5,min(col6,min(col7,col8))));
colMin = 0.5 * (colMin + colMin5);
colMax = 0.5 * (colMax + colMax5);
#endif
#ifdef DAMAGE_TAKEN_EFFECT
// when this triggers, use current frame UV to sample history, for a funny trailing effect.
if(CriticalDamageTaken > 0.01) previousPosition.xy = adjTC;
#endif
vec3 frameHistory = max(FastCatmulRom(colortex5, previousPosition.xy, vec4(texelSize, 1.0/texelSize), 0.75).xyz,0.0);
vec3 clampedframeHistory = clamp(frameHistory, colMin, colMax);
float blendingFactor = BLEND_FACTOR;
if(hand) blendingFactor = clamp(length(velocity/texelSize),blendingFactor,1.0);
//Increases blending factor when far from AABB, reduces ghosting
blendingFactor = min(blendingFactor + luma(min(max(clampedframeHistory - frameHistory,0.0) / frameHistory, 1.0)),1.0);
// Blend current pixel with clamped history, apply fast tonemap beforehand to reduce flickering
vec3 finalResult = invTonemap(mix(tonemap(clampedframeHistory), tonemap(currentFrame), blendingFactor));
#ifdef DAMAGE_TAKEN_EFFECT
// when this triggers, do a funny trailing effect.
if(CriticalDamageTaken > 0.01) finalResult = mix(finalResult, frameHistory, sqrt(CriticalDamageTaken)*0.8);
#endif
#ifdef SCREENSHOT_MODE
// when this is on, do "infinite frame accumulation "
if (hideGUI == 0) return vec4(finalResult, 1.0);
vec4 superSampledHistory = texture2D(colortex5, previousPosition.xy);
vec3 superSampledResult = superSampledHistory.rgb * superSampledHistory.a + currentFrame;
return vec4(superSampledResult/(superSampledHistory.a+1.0), superSampledHistory.a+1.0);
#endif
return vec4(finalResult, 1.0);
}
void main() {
/* DRAWBUFFERS:5 */
gl_FragData[0].a = 1.0;
#ifdef TAA
@ -451,7 +532,11 @@ void main() {
float dataUnpacked = decodeVec2(texelFetch2D(colortex1,ivec2(gl_FragCoord.xy*RENDER_SCALE),0).w).y;
bool hand = abs(dataUnpacked-0.75) < 0.01 && texture2D(depthtex1,taauTC).x < 1.0;
vec4 color = TAA_hq(hand);
// vec4 color = TAA_hq(hand);
vec4 color = computeTAA(texcoord, hand);
// gl_FragData[0] = clamp(color, 0.0, 65000.0);
#if DEBUG_VIEW == debug_TEMPORAL_REPROJECTION
color.rgb = texture2D(colortex3, taauTC).rgb;