| NAMESPACE_ENTER(OFX) |
| #include OFX_SETTINGS_DEF |
| #if USE_DEPTHHAZE |
| /////////////////////////////////////////////////////////////////// |
| // Based on default old DoF. The old DoF was original programmed by: |
| // Matso, gp65cj042, MartyMcFly |
| // |
| // This effect works like a one-side DoF for distance haze, which slightly |
| // blurs far away elements. A normal DoF has a focus point and blurs using |
| // two planes. |
| // |
| // This effect blurs from the near threshold to infinity (1.0f), using 0 |
| // as blur strength at the near threshold to the max blur strength at infinity. |
| /////////////////////////////////////////////////////////////////// |
| floatCalculateCoC(float2 texcoord) |
| { |
| float scenedepth = tex2D(RFX_depthTexColor, texcoord).r; |
| float toReturn = 0.0f; |
| if(scenedepth > DEH_NEARPLANE) |
| { |
| float depthdiff = abs(scenedepth-DEH_NEARPLANE); |
| float power = pow(depthdiff, DEH_FARBLURCURVE); |
| toReturn = saturate(power); |
| } |
| return toReturn; |
| } |
| float4 GetDoF(sampler tex, float2 coords, float blur) |
| { |
| const float3 lumCoef = float3(0.212656, 0.715158, 0.072186); |
| float4 colDF = tex2Dlod(tex, float4(coords,0,0)); |
| float lum = dot(colDF.xyz, lumCoef); |
| float thresh = max((lum - DEH_RingDOFThreshold) * DEH_RingDOFGain, 0.0); |
| float3 nullcol = float3(0,0,0); |
| colDF.xyz +=max(0, lerp(nullcol.xyz, colDF.xyz, thresh * blur)); |
| return colDF; |
| } |
| voidPS_OFX_DEH_RingDOF(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 hdr2R : SV_Target0) |
| { |
| float origCoC = CalculateCoC(texcoord.xy); |
| float2 discRadius = DEH_BLURRADIUS * float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) * origCoC / DEH_RingDOFRings; |
| float4 col = tex2D(RFX_backbufferColor, texcoord.xy); |
| if(discRadius.x/BUFFER_RCP_WIDTH > 0.25) |
| { |
| float s = 1.0; |
| int ringsamples; |
| [loop] |
| for (int g = 1; g <= DEH_RingDOFRings; g += 1) |
| { |
| ringsamples = g * DEH_RingDOFSamples; |
| [loop] |
| for (int j = 0 ; j < ringsamples ; j += 1) |
| { |
| float step = 3.1415972*2.0 / ringsamples; |
| float2 sampleoffset = discRadius.xy * float2(cos(j*step)*g, sin(j*step)*g); |
| float sampleCoC = CalculateCoC(float2(texcoord.xy + sampleoffset)); |
| if(sampleCoC<origCoC) |
| { |
| sampleoffset = sampleoffset / origCoC * sampleCoC; |
| } |
| col.xyz += GetDoF(RFX_backbufferColor, texcoord.xy + sampleoffset, origCoC).xyz * lerp(1.0, g /DEH_RingDOFRings, DEH_RingDOFBias); |
| s += 1.0*lerp(1.0,g/ DEH_RingDOFRings, DEH_RingDOFBias); |
| } |
| } |
| col = col/s; |
| } |
| hdr2R = col; |
| } |
| technique OFX_DEH_Tech <bool enabled = false; int toggle = DEH_ToggleKey; > |
| { |
| // single pass, simply calculate CoC (which is straight forward) on the fly, write directly back into backbuffer. |
| pass OFX_DEH_RingDOF |
| { |
| VertexShader = RFX_VS_PostProcess; |
| PixelShader = PS_OFX_DEH_RingDOF; |
| } |
| } |
| #endif |
| #include OFX_SETTINGS_UNDEF |
| NAMESPACE_LEAVE() |