#version 120 /* DRAWBUFFERS:3 */ /* Sildur's Enhanced Default: https://www.patreon.com/Sildur https://sildurs-shaders.github.io/ https://twitter.com/Sildurs_shaders https://www.curseforge.com/minecraft/customization/sildurs-enhanced-default Permissions: You are not allowed to edit, copy code or share my shaderpack under a different name or claim it as yours. */ #define composite1 #include "shaders.settings" /* Temporal anti-aliasing (TAA) and adaptive sharpening implementation based on Chocapic13, all credits belong to him: https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/1293898-1-14-chocapic13s-shaders */ varying vec2 texcoord; uniform sampler2D colortex0; //everything #ifdef TAA const bool colortex3Clear = false; uniform sampler2D colortex3; //TAA mixed with everything uniform sampler2D depthtex0; uniform float viewHeight; uniform float viewWidth; vec2 texelSize = vec2(1.0/viewWidth,1.0/viewHeight); uniform mat4 gbufferProjectionInverse; uniform mat4 gbufferModelViewInverse; uniform mat4 gbufferPreviousProjection; uniform mat4 gbufferPreviousModelView; uniform vec3 cameraPosition; uniform vec3 previousCameraPosition; #define BLEND_FACTOR 0.1 //[0.01 0.02 0.03 0.04 0.05 0.06 0.08 0.1 0.12 0.14 0.16] higher values = more flickering but sharper image, lower values = less flickering but the image will be blurrier #define MOTION_REJECTION 1.0 //[0.0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.5] //Higher values=sharper image in motion at the cost of flickering #define ANTI_GHOSTING 0.0 //[0.0 0.25 0.5 0.75 1.0] High values reduce ghosting but may create flickering #define FLICKER_REDUCTION 1.0 //[0.0 0.25 0.5 0.75 1.0] High values reduce flickering but may reduce sharpness #define diagonal3(m) vec3((m)[0].x, (m)[1].y, m[2].z) #define projMAD(m, v) (diagonal3(m) * (v) + (m)[3].xyz) vec3 toClipSpace3Prev(vec3 viewSpacePosition) { return projMAD(gbufferPreviousProjection, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5; } 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; } //returns the projected coordinates of the closest point to the camera in the 3x3 neighborhood vec3 closestToCamera5taps(vec2 texcoord){ vec2 du = vec2(texelSize.x*2., 0.0); vec2 dv = vec2(0.0, texelSize.y*2.); vec3 dtl = vec3(texcoord,0.) + vec3(-texelSize, texture2D(depthtex0, texcoord - dv - du).x); vec3 dtr = vec3(texcoord,0.) + vec3( texelSize.x, -texelSize.y, texture2D(depthtex0, texcoord - dv + du).x); vec3 dmc = vec3(texcoord,0.) + vec3( 0.0, 0.0, texture2D(depthtex0, texcoord).x); vec3 dbl = vec3(texcoord,0.) + vec3(-texelSize.x, texelSize.y, texture2D(depthtex0, texcoord + dv - du).x); vec3 dbr = vec3(texcoord,0.) + vec3( texelSize.x, texelSize.y, texture2D(depthtex0, texcoord + dv + du).x); vec3 dmin = dmc; dmin = dmin.z > dtr.z? dtr : dmin; dmin = dmin.z > dtl.z? dtl : dmin; dmin = dmin.z > dbl.z? dbl : dmin; dmin = dmin.z > dbr.z? dbr : dmin; return dmin; } //approximation from SMAA presentation from siggraph 2016 vec3 FastCatmulRom(sampler2D colorTex, vec2 texcoord, vec4 rtMetrics, float sharpenAmount){ vec2 position = rtMetrics.zw * texcoord; vec2 centerPosition = floor(position - 0.5) + 0.5; vec2 f = position - centerPosition; vec2 f2 = f * f; vec2 f3 = f * f2; float c = sharpenAmount; 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 = rtMetrics.xy * (centerPosition + w2 / w12); vec3 centerColor = texture2D(colorTex, vec2(tc12.x, tc12.y)).rgb; vec2 tc0 = rtMetrics.xy * (centerPosition - 1.0); vec2 tc3 = rtMetrics.xy * (centerPosition + 2.0); vec4 color = vec4(texture2D(colorTex, vec2(tc12.x, tc0.y )).rgb, 1.0) * (w12.x * w0.y ) + vec4(texture2D(colorTex, vec2(tc0.x, tc12.y)).rgb, 1.0) * (w0.x * w12.y) + 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 calcTAA(){ //reproject previous frame vec3 closestToCamera = closestToCamera5taps(texcoord); vec3 fragposition = toScreenSpace(closestToCamera); fragposition = mat3(gbufferModelViewInverse) * fragposition + gbufferModelViewInverse[3].xyz + (cameraPosition - previousCameraPosition); vec3 previousPosition = mat3(gbufferPreviousModelView) * fragposition + gbufferPreviousModelView[3].xyz; previousPosition = toClipSpace3Prev(previousPosition); previousPosition.xy = texcoord + (previousPosition.xy - closestToCamera.xy); //to reduce error propagation caused by interpolation during history resampling, we will introduce back some aliasing in motion vec2 d = 0.5-abs(fract(previousPosition.xy*vec2(viewWidth,viewHeight)-texcoord*vec2(viewWidth,viewHeight))-0.5); float rej = dot(d,d)*MOTION_REJECTION; //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 texture2D(colortex0, texcoord).rgb; //Samples current frame 3x3 neighboorhood vec3 albedoCurrent0 = texture2D(colortex0, texcoord).rgb; vec3 albedoCurrent1 = texture2D(colortex0, texcoord + vec2(texelSize.x,texelSize.y)).rgb; vec3 albedoCurrent2 = texture2D(colortex0, texcoord + vec2(texelSize.x,-texelSize.y)).rgb; vec3 albedoCurrent3 = texture2D(colortex0, texcoord + vec2(-texelSize.x,-texelSize.y)).rgb; vec3 albedoCurrent4 = texture2D(colortex0, texcoord + vec2(-texelSize.x,texelSize.y)).rgb; vec3 albedoCurrent5 = texture2D(colortex0, texcoord + vec2(0.0,texelSize.y)).rgb; vec3 albedoCurrent6 = texture2D(colortex0, texcoord + vec2(0.0,-texelSize.y)).rgb; vec3 albedoCurrent7 = texture2D(colortex0, texcoord + vec2(-texelSize.x,0.0)).rgb; vec3 albedoCurrent8 = texture2D(colortex0, texcoord + vec2(texelSize.x,0.0)).rgb; if(TAA_sharpness > 0.0){ //turn sharpening off if set to 0.0 vec3 m1 = (albedoCurrent0 + albedoCurrent1 + albedoCurrent2 + albedoCurrent3 + albedoCurrent4 + albedoCurrent5 + albedoCurrent6 + albedoCurrent7 + albedoCurrent8)/9.0; vec3 std = abs(albedoCurrent0 - m1) + abs(albedoCurrent1 - m1) + abs(albedoCurrent2 - m1) + abs(albedoCurrent3 - m1) + abs(albedoCurrent3 - m1) + abs(albedoCurrent4 - m1) + abs(albedoCurrent5 - m1) + abs(albedoCurrent6 - m1) + abs(albedoCurrent7 - m1) + abs(albedoCurrent8 - m1); float contrast = 1.0 - dot(std,vec3(0.299, 0.587, 0.114))/9.0; albedoCurrent0 = albedoCurrent0*(1.0+TAA_sharpness*contrast)-(albedoCurrent5+albedoCurrent6+albedoCurrent7+albedoCurrent8+(albedoCurrent1 + albedoCurrent2 + albedoCurrent3 + albedoCurrent4)/2.0)/6.0*TAA_sharpness*contrast; } //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 cMax = max(max(max(albedoCurrent0,albedoCurrent1),albedoCurrent2),max(albedoCurrent3,max(albedoCurrent4,max(albedoCurrent5,max(albedoCurrent6,max(albedoCurrent7,albedoCurrent8)))))); vec3 cMin = min(min(min(albedoCurrent0,albedoCurrent1),albedoCurrent2),min(albedoCurrent3,min(albedoCurrent4,min(albedoCurrent5,min(albedoCurrent6,min(albedoCurrent7,albedoCurrent8)))))); vec3 albedoPrev = FastCatmulRom(colortex3, previousPosition.xy,vec4(texelSize, 1.0/texelSize), 0.82).xyz; vec3 finalcAcc = clamp(albedoPrev,cMin,cMax); //increases blending factor if history is far away from aabb, reduces ghosting at the cost of some flickering float luma = dot(albedoPrev,vec3(0.21, 0.72, 0.07)); float isclamped = distance(albedoPrev,finalcAcc)/luma; //reduces blending factor if current texel is far from history, reduces flickering float lumDiff2 = distance(albedoPrev,albedoCurrent0)/luma; lumDiff2 = 1.0-clamp(lumDiff2*lumDiff2,0.0,1.0)*FLICKER_REDUCTION; //Blend current pixel with clamped history return mix(finalcAcc,albedoCurrent0,clamp(BLEND_FACTOR*lumDiff2+rej+isclamped*ANTI_GHOSTING+0.01,0.0,1.0)); } #endif void main() { #ifdef TAA gl_FragData[0] = vec4(calcTAA(), 1.0); #else gl_FragData[0] = texture2D(colortex0, texcoord); //if TAA is disabled just passthrough data from composite0, previous buffer. #endif }