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() |