#if TAA_SMOOTHING == 2 float blendMinimum = 0.3; float blendVariable = 0.3; float blendConstant = 0.6; float regularEdge = 10.0; float extraEdgeMult = 2.0; float farEdgeDist = 128.0; #elif TAA_SMOOTHING == 3 float blendMinimum = 0.35; float blendVariable = 0.2; float blendConstant = 0.7; float regularEdge = 6.0; float extraEdgeMult = 3.0; float farEdgeDist = 112.0; #elif TAA_SMOOTHING == 4 float blendMinimum = 0.5; float blendVariable = 0.15; float blendConstant = 0.75; float regularEdge = 4.0; float extraEdgeMult = 3.5; float farEdgeDist = 96.0; #endif #if TAA_MOVEMENT_IMPROVEMENT_FILTER == 1 //Catmull-Rom sampling from Filmic SMAA presentation vec3 textureCatmullRom(sampler2D colortex, vec2 texcoord, vec2 view) { vec2 position = texcoord * view; vec2 centerPosition = floor(position - 0.5) + 0.5; vec2 f = position - centerPosition; vec2 f2 = f * f; vec2 f3 = f * f2; float c = 0.7; vec2 w0 = -c * f3 + 2.0 * c * f2 - c * f; vec2 w1 = (2.0 - c) * f3 - (3.0 - c) * f2 + 1.0; vec2 w2 = -(2.0 - c) * f3 + (3.0 - 2.0 * c) * f2 + c * f; vec2 w3 = c * f3 - c * f2; vec2 w12 = w1 + w2; vec2 tc12 = (centerPosition + w2 / w12) / view; vec2 tc0 = (centerPosition - 1.0) / view; vec2 tc3 = (centerPosition + 2.0) / view; vec4 color = vec4(texture2DLod(colortex, vec2(tc12.x, tc0.y ), 0).rgb, 1.0) * (w12.x * w0.y ) + vec4(texture2DLod(colortex, vec2(tc0.x, tc12.y), 0).rgb, 1.0) * (w0.x * w12.y) + vec4(texture2DLod(colortex, vec2(tc12.x, tc12.y), 0).rgb, 1.0) * (w12.x * w12.y) + vec4(texture2DLod(colortex, vec2(tc3.x, tc12.y), 0).rgb, 1.0) * (w3.x * w12.y) + vec4(texture2DLod(colortex, vec2(tc12.x, tc3.y ), 0).rgb, 1.0) * (w12.x * w3.y ); return color.rgb / color.a; } #endif // Previous frame reprojection from Chocapic13 vec2 Reprojection(vec4 viewPos1) { vec4 pos = gbufferModelViewInverse * viewPos1; vec4 previousPosition = pos + vec4(cameraPosition - previousCameraPosition, 0.0); previousPosition = gbufferPreviousModelView * previousPosition; previousPosition = gbufferPreviousProjection * previousPosition; return previousPosition.xy / previousPosition.w * 0.5 + 0.5; } vec3 ClipAABB(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)); if (ma_unit > 1.0) return vec3(p_clip) + v_clip / ma_unit; else return q; } ivec2 neighbourhoodOffsets[8] = ivec2[8]( ivec2( 1, 1), ivec2( 1,-1), ivec2(-1, 1), ivec2(-1,-1), ivec2( 1, 0), ivec2( 0, 1), ivec2(-1, 0), ivec2( 0,-1) ); void NeighbourhoodClamping(vec3 color, inout vec3 tempColor, float z0, float z1, inout float edge) { vec3 minclr = color; vec3 maxclr = minclr; int cc = 2; ivec2 texelCoordM1 = clamp(texelCoord, ivec2(cc), ivec2(view) - cc); // Fixes screen edges for (int i = 0; i < 8; i++) { ivec2 texelCoordM2 = texelCoordM1 + neighbourhoodOffsets[i]; float z0CheckLinear = GetLinearDepth(texelFetch(depthtex0, texelCoordM2, 0).r); float z1CheckLinear = GetLinearDepth(texelFetch(depthtex1, texelCoordM2, 0).r); float z0Linear = GetLinearDepth(z0); float z1Linear = GetLinearDepth(z1); if (max(abs(z0CheckLinear - z0Linear), abs(z1CheckLinear - z1Linear)) > 0.09) { edge = regularEdge; float approxClosestDist = min(z0CheckLinear, z0Linear) * far; if (approxClosestDist < farEdgeDist) if (int(texelFetch(colortex6, texelCoordM2, 0).g * 255.1) == 253) // Reduced Edge TAA edge *= extraEdgeMult; } vec3 clr = texelFetch(colortex3, texelCoordM2, 0).rgb; minclr = min(minclr, clr); maxclr = max(maxclr, clr); } tempColor = ClipAABB(tempColor, minclr, maxclr); } void DoTAA(inout vec3 color, inout vec3 temp, float z1) { int materialMask = int(texelFetch(colortex6, texelCoord, 0).g * 255.1); vec4 screenPos1 = vec4(texCoord, z1, 1.0); vec4 viewPos1 = gbufferProjectionInverse * (screenPos1 * 2.0 - 1.0); viewPos1 /= viewPos1.w; float lViewPos1 = length(viewPos1); #ifdef ENTITY_TAA_NOISY_CLOUD_FIX float cloudLinearDepth = texture2D(colortex5, texCoord).a; if (pow2(cloudLinearDepth) * renderDistance < min(lViewPos1, renderDistance)) { // Material in question is obstructed by the cloud volume materialMask = 0; } #endif if ( abs(materialMask - 149.5) < 50.0 // Entity Reflection Handling (see common.glsl for details) || materialMask == 254 // No SSAO, No TAA, Reduce Reflection ) { return; } /*if (materialMask == 254) { // No SSAO, No TAA, Reduce Reflection #ifndef CUSTOM_PBR if (z1 <= 0.56) return; // The edge pixel trick doesn't look nice on hand #endif int i = 0; while (i < 4) { int mms = int(texelFetch(colortex6, texelCoord + neighbourhoodOffsets[i], 0).g * 255.1); if (mms != materialMask) break; i++; } // Checking edge-pixels prevents flickering if (i == 4) return; }*/ float z0 = texelFetch(depthtex0, texelCoord, 0).r; vec2 prvCoord = texCoord; if (z1 > 0.56) prvCoord = Reprojection(viewPos1); #if TAA_MOVEMENT_IMPROVEMENT_FILTER == 1 vec3 tempColor = textureCatmullRom(colortex2, prvCoord, view); #else vec3 tempColor = texture2D(colortex2, prvCoord).rgb; #endif if (tempColor == vec3(0.0) || any(isnan(tempColor))) { // Fixes the first frame and nans temp = color; return; } float edge = 0.0; NeighbourhoodClamping(color, tempColor, z0, z1, edge); if (materialMask == 253) // Reduced Edge TAA edge *= extraEdgeMult; #ifdef DISTANT_HORIZONS if (z0 == 1.0) { blendMinimum = 0.75; blendVariable = 0.05; blendConstant = 0.9; edge = 1.0; } #endif vec2 velocity = (texCoord - prvCoord.xy) * view; float blendFactor = float(prvCoord.x > 0.0 && prvCoord.x < 1.0 && prvCoord.y > 0.0 && prvCoord.y < 1.0); float velocityFactor = dot(velocity, velocity) * 10.0; blendFactor *= max(exp(-velocityFactor) * blendVariable + blendConstant - min(length(cameraPosition - previousCameraPosition), 0.05) * edge, blendMinimum); #ifdef RAIN_ATMOSPHERE blendFactor *= 1.0 - isLightningActive(); #endif #ifdef MIRROR_DIMENSION blendFactor = 0.0; #endif color = mix(color, tempColor, blendFactor); temp = color; //if (edge > 0.05) color.rgb = vec3(1.0, 0.0, 1.0); }