GIF89a; %PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY
Server IP : 134.29.175.74 / Your IP : 216.73.216.160 Web Server : nginx/1.10.2 System : Windows NT CST-WEBSERVER 10.0 build 19045 (Windows 10) i586 User : Administrator ( 0) PHP Version : 7.1.0 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Program Files/NVIDIA Corporation/Ansel/ShaderMod/ |
Upload File : |
//------------------------------------------------------------------ // Shader file for NVIDIA Ansel //------------------------------------------------------------------ //------------------------------------------------------------------ // Constants //------------------------------------------------------------------ #define DepthParameters float4(1.0,1000.0,-999.0f,0.0) //x = near plane, y = far plane, z = -(y-x), w = unused #define PixelSize float2(1.0 / screenSize.x, 1.0 / screenSize.y) //x = Pixel width, y = Pixel height #define Aspect (screenSize.x / screenSize.y) //Aspect ratio cbuffer globalParams { float2 screenSize; //x = screen width, y = screen height int captureState; //unused, my math works without using specific cases float4 tileUV; //xy - top left tile coordinate, zw - bottom right tile coordinate } cbuffer controlBuf { float ui_fFocusDepth; //focus plane distance, in code ^4 to make adjustments for low value ranges easier, where ui-center-mapping doesn't cut it float ui_fFarBlurCurve; //buildup curve of blur behind focus plane float ui_fNearBlurCurve; //buildup curve of blur in front of focus plane float ui_fShapeRadius; //blur radius where CoC is max #define ui_iShapeVertices 6 //float ui_iShapeVertices; //bokeh shape vertices, 5 == pentagon, 6 == hexagon ... #define ui_fShapeRoundness 1//float ui_fShapeRoundness; //deforms polygon to circle, 0 == polygon, 1 == circle #define ui_fBokehIntensity 0.7//float ui_fBokehIntensity; //intensity of bokeh highlighting bool g_sldInvert; } struct VSOut { float4 position : SV_POSITION; float2 txcoord : TEXCOORD; }; //------------------------------------------------------------------ // Textures, Samplers //------------------------------------------------------------------ Texture2D texOriginalColor; Texture2D texOriginalDepth; Texture2D texColorCoC; //------------------------------------------------------------------ SamplerState SamplerLinear; SamplerState SamplerPoint; //------------------------------------------------------------------ // Functions //------------------------------------------------------------------ /* linearizes depth value so distance from camera ~ depth value */ float GetLinearDepth(float2 texcoord) { float depth = texOriginalDepth.SampleLevel(SamplerLinear, texcoord.xy,0).x; if(!g_sldInvert) depth = 1.0 - depth; depth *= rcp(DepthParameters.y + depth * DepthParameters.z); return saturate(depth); } //------------------------------------------------------------------ /* calculates out-of-focus value for given depth and focus plane distance. where 0 means pixel is in focus, 1 means focus is entirely out of focus. Aggressive leak reduction basically shifts depth to minimum of neighbour pixels to completely eradicate color leaking of main bokeh pass. This introduces a sharp border around sharp objects, which gets removed by gaussian blur after bokeh filter which uses CoC without leak reduction.*/ float CircleOfConfusion(float2 texcoord, bool aggressiveLeakReduction) { float2 depthdata; //x - linear scene depth, y - linear scene focus float scenecoc; //blur value, signed by position relative to focus plane depthdata.x = GetLinearDepth(texcoord.xy); [branch] if(aggressiveLeakReduction) { float3 neighbourOffsets = float3(PixelSize.xy, 0); //sadly, flipped depth buffers etc don't allow for gather or linearizing in batch float4 neighbourDepths = float4(GetLinearDepth(texcoord.xy - neighbourOffsets.xz), //left GetLinearDepth(texcoord.xy + neighbourOffsets.xz), //right GetLinearDepth(texcoord.xy - neighbourOffsets.zy), //top GetLinearDepth(texcoord.xy + neighbourOffsets.zy));//bottom float neighbourMin = min(min(neighbourDepths.x,neighbourDepths.y),min(neighbourDepths.z,neighbourDepths.w)); depthdata.x = lerp(min(neighbourMin, depthdata.x), depthdata.x, 0.001); } depthdata.y = ui_fFocusDepth*ui_fFocusDepth*ui_fFocusDepth; [branch] if(depthdata.x < depthdata.y) { scenecoc = depthdata.x / depthdata.y - 1.0; scenecoc = ldexp(scenecoc, -0.5*ui_fNearBlurCurve*ui_fNearBlurCurve*10*10); } else { scenecoc = (depthdata.x - depthdata.y)/(ldexp(depthdata.y, pow(ui_fFarBlurCurve * 10, 1.5)) - depthdata.y); scenecoc = saturate(scenecoc); } return abs(scenecoc); } //------------------------------------------------------------------ // Pixel Shaders //------------------------------------------------------------------ /* writes CoC to alpha channel. Early firefly reduction with depth masking to prevent color leaking in main bokeh pass.*/ float4 PS_CoC2Alpha( VSOut IN ): SV_Target { float4 color = texOriginalColor.Sample(SamplerLinear, IN.txcoord.xy); static const float2 sampleOffsets[4] = {float2( 1.5, 0.5) * PixelSize.xy, float2( 0.5,-1.5) * PixelSize.xy, float2(-1.5,-0.5) * PixelSize.xy, float2(-0.5, 1.5) * PixelSize.xy}; float centerDepth = GetLinearDepth(IN.txcoord.xy); float2 sampleCoord = 0.0; float3 neighbourOffsets = float3(PixelSize.xy, 0); float4 coccolor = 0.0; [loop] for(int i=0; i<4; i++) { sampleCoord.xy = IN.txcoord.xy + sampleOffsets[i]; float3 sampleColor = texOriginalColor.SampleLevel(SamplerLinear, sampleCoord, 0).rgb; float4 sampleDepths = float4(GetLinearDepth(sampleCoord.xy + neighbourOffsets.xz), //right GetLinearDepth(sampleCoord.xy - neighbourOffsets.xz), //left GetLinearDepth(sampleCoord.xy + neighbourOffsets.zy), //bottom GetLinearDepth(sampleCoord.xy - neighbourOffsets.zy)); //top float sampleDepthMin = min(min(sampleDepths.x,sampleDepths.y),min(sampleDepths.z,sampleDepths.w)); sampleColor /= 1.0 + max(max(sampleColor.r, sampleColor.g), sampleColor.b); float sampleWeight = saturate(sampleDepthMin * rcp(centerDepth + 1e-6) + 1e-3); coccolor += float4(sampleColor.rgb * sampleWeight, sampleWeight); } coccolor.rgb /= coccolor.a; coccolor.rgb /= 1.0 - max(coccolor.r, max(coccolor.g, coccolor.b)); color.rgb = lerp(color.rgb, coccolor.rgb, saturate(coccolor.w * 8.0)); color.w = CircleOfConfusion(IN.txcoord.xy, 1); color.w = saturate(color.w * 0.5 + 0.5); return color; } //------------------------------------------------------------------ /* main bokeh blur pass.*/ float4 PS_Bokeh( VSOut IN ): SV_Target { static const float2 PixelSizeScaled = PixelSize.xy * float2(rcp(tileUV.z-tileUV.x),rcp(tileUV.w-tileUV.y)); float4 BokehSum, BokehMax; BokehMax = texColorCoC.Sample(SamplerLinear, IN.txcoord.xy); BokehSum = BokehMax; float weightSum = 1.0; float CoC = abs(BokehSum.w * 2.0 - 1.0); float2 bokehRadiusScaled = CoC * ui_fShapeRadius * 25; float nRings = round(bokehRadiusScaled*rcp(tileUV.z-tileUV.x)*0.2) + 2 + (dot(IN.position.xy,1) % 2) * 0.5; bokehRadiusScaled /= nRings; bokehRadiusScaled *= PixelSizeScaled; CoC /= nRings; float2 currentVertex,nextVertex,matrixVector; sincos(radians(10.0), currentVertex.y,currentVertex.x); sincos(radians(360.0 / round(ui_iShapeVertices)),matrixVector.x,matrixVector.y); float2x2 rotMatrix = float2x2(matrixVector.y,-matrixVector.x,matrixVector.x,matrixVector.y); [fastopt] for (int iVertices = 0; iVertices < ui_iShapeVertices; iVertices++) { nextVertex = mul(currentVertex.xy, rotMatrix); [fastopt] for(float iRings = 1; iRings <= nRings; iRings++) { [fastopt] for(float iSamplesPerRing = 0; iSamplesPerRing < iRings; iSamplesPerRing++) { float2 sampleOffset = lerp(currentVertex,nextVertex,iSamplesPerRing/iRings); //sampleOffset *= (1.0-ui_fShapeRoundness) + rsqrt(dot(sampleOffset,sampleOffset))*ui_fShapeRoundness; sampleOffset *= rsqrt(dot(sampleOffset,sampleOffset)); float4 sampleBokeh = texColorCoC.SampleLevel(SamplerLinear, IN.txcoord.xy + sampleOffset.xy * bokehRadiusScaled * iRings,0); float sampleWeight = saturate(1e6 * (abs(sampleBokeh.a * 2.0 - 1.0) - CoC * (float)iRings) + 1.0); sampleBokeh.rgb *= sampleWeight; weightSum += sampleWeight; BokehSum += sampleBokeh; BokehMax = max(BokehMax,sampleBokeh); } } currentVertex = nextVertex; } //scale bokeh intensity by blur level to make transition from sharp to blurred area less apparent return lerp(BokehSum / weightSum, BokehMax, ui_fBokehIntensity * saturate(CoC*nRings*4.0)); } /* combines blurred bokeh output with sharp original texture. Calculate CoC a second time because gaussian blur is not prone to obvious color leaking. */ float4 PS_Combine( VSOut IN ): SV_Target { float4 blurredColor = texColorCoC.Sample(SamplerLinear, IN.txcoord.xy); float4 originalColor = texOriginalColor.Sample(SamplerLinear, IN.txcoord.xy); float CoC = CircleOfConfusion(IN.txcoord.xy, 0); float2 bokehRadiusScaled = CoC * ui_fShapeRadius * 25; #define linearstep(a,b,x) saturate((x-a)/(b-a)) float blendWeight = linearstep(0.25, 1.0, bokehRadiusScaled.x); blendWeight = sqrt(blendWeight); float4 color; color.rgb = lerp(originalColor.rgb, blurredColor.rgb, blendWeight); color.a = saturate(CoC * 2.0) * 0.5 + 0.5; return color; } /* blur color (and blur radius) to solve common DoF technique issue of having sharp transitions in blurred regions because of blurred color vs sharp depth info*/ float4 PS_Gauss1( VSOut IN ): SV_Target { float4 centerTap = texColorCoC.Sample(SamplerLinear, IN.txcoord.xy); float CoC = abs(centerTap.a * 2.0 - 1.0); float nSteps = floor(CoC * (2.0)); float expCoeff = -2.0 * rcp(nSteps * nSteps + 1e-3); //sigma adjusted for blur width static const float2 blurAxisScaled = float2(1,0) * PixelSize.xy; float4 gaussianSum = 0.0; float gaussianSumWeight = 1e-3; for(float iStep = -nSteps; iStep <= nSteps; iStep++) { float currentWeight = exp(iStep * iStep * expCoeff); float currentOffset = 2.0 * iStep - 0.5; //Sample between texels to double blur width at no cost float4 currentTap = texColorCoC.SampleLevel(SamplerLinear, IN.txcoord.xy + blurAxisScaled.xy * currentOffset, 0); currentWeight *= saturate(abs(currentTap.a * 2.0 - 1.0) - CoC * 0.25); //bleed fix gaussianSum += currentTap * currentWeight; gaussianSumWeight += currentWeight; } gaussianSum /= gaussianSumWeight; float4 color; color.rgb = lerp(centerTap.rgb, gaussianSum.rgb, saturate(gaussianSumWeight)); color.a = centerTap.a; return color; } float4 PS_Gauss2( VSOut IN ): SV_Target { float4 centerTap = texColorCoC.Sample(SamplerLinear, IN.txcoord.xy); float CoC = abs(centerTap.a * 2.0 - 1.0); float nSteps = floor(CoC * (2.0)); float expCoeff = -2.0 * rcp(nSteps * nSteps + 1e-3); //sigma adjusted for blur width static const float2 blurAxisScaled = float2(0,1) * PixelSize.xy; float4 gaussianSum = 0.0; float gaussianSumWeight = 1e-3; for(float iStep = -nSteps; iStep <= nSteps; iStep++) { float currentWeight = exp(iStep * iStep * expCoeff); float currentOffset = 2.0 * iStep - 0.5; //Sample between texels to double blur width at no cost float4 currentTap = texColorCoC.SampleLevel(SamplerLinear, IN.txcoord.xy + blurAxisScaled.xy * currentOffset, 0); currentWeight *= saturate(abs(currentTap.a * 2.0 - 1.0) - CoC * 0.25); //bleed fix gaussianSum += currentTap * currentWeight; gaussianSumWeight += currentWeight; } gaussianSum /= gaussianSumWeight; float4 color; color.rgb = lerp(centerTap.rgb, gaussianSum.rgb, saturate(gaussianSumWeight)); color.a = centerTap.a; return color; }