FoxMcCloud
Newcomer
I'm trying to write a Depth of Field shader using circle of confusion-based texture fetches. Here's my code so far (Cg):
I'm running into a problem though - in the code I'm rejecting samples that come from an area that's significantly in front of or below the center point (using the linear screen-space depth stored in the depth texture) - however, I'm seeing "acne":
http://www.flickr.com/photos/59098813@N06/7998075690/
I don't understand it - shouldn't that acne be rejected by my test and have its contribution set to zero? Here's the visualized depth buffer for reference:
http://www.flickr.com/photos/59098813@N06/7998069833/
All buffers are FP16, running on OS X Mountain Lion on a Retina MacBook Pro (Kepler, 650M).
Code:
#define DOF_TAP_COUNT 8
#define DOF_TAP_MAX_COUNT 16
float4 do_dof(in float2 TexCoord,
sampler2D Texture,
sampler2D DepthTexture,
float DepthOfFieldCenter,
float DepthOfFieldMaxDistance,
float CoCMaxSize, float4 CenterColor, float CenterDepth, float Offset)
{
float2 TapOffsets[DOF_TAP_MAX_COUNT];
TapOffsets[0] = float2(0.0f, 0.0f);
TapOffsets[1] = float2(0.527837f, -0.085868f);
TapOffsets[2] = float2(-0.040088f, 0.536087f);
TapOffsets[3] = float2(-0.670445f, -0.179949f);
TapOffsets[4] = float2(-0.419418,-0.616039);
TapOffsets[5] = float2( 0.440453,-0.639399);
TapOffsets[6] = float2(-0.757088, 0.349334);
TapOffsets[7] = float2( 0.574619, 0.685879);
TapOffsets[8] = float2(0.0f, 0.0f);
TapOffsets[9] = float2(0.0f, 0.0f);
TapOffsets[10] = float2(0.0f, 0.0f);
TapOffsets[11] = float2(0.0f, 0.0f);
TapOffsets[12] = float2(0.0f, 0.0f);
TapOffsets[13] = float2(0.0f, 0.0f);
TapOffsets[14] = float2(0.0f, 0.0f);
TapOffsets[15] = float2(0.0f, 0.0f);
float2 tap[DOF_TAP_COUNT];
float4 Color[DOF_TAP_COUNT];
float Depth[DOF_TAP_COUNT];
// Fetch center samples from depth and focus maps
float TotalContribution = 1.0f;
float Contribution;
float CoCSize = CoCMaxSize; // Scale the Circle of Confusion
float DepthDelta = abs(DepthOfFieldCenter - CenterDepth);
if(DepthDelta > DepthOfFieldMaxDistance)
{
DepthDelta = DepthOfFieldMaxDistance;
}
CoCSize = CoCMaxSize * (DepthDelta / DepthOfFieldMaxDistance);
int N = 0;
for(int i=0; i < DOF_TAP_COUNT; i++) // Run through all of the taps
{
// Compute tap locations relative to center tap
tap[i] = TexCoord + (CoCSize * TapOffsets[i]);
Color[i] = tex2D(Texture, tap[i]);
Depth[i] = -tex2D(DepthTexture, tap[i]).z;
// Compute tap's contribution to final color
float Threshold = 1.0f;
if(abs(CenterDepth - Depth[i]) > Threshold)
{
Contribution = 0.0f;
++N;
}
else
{
Contribution = 1.0f;//(Depth[i].x > CenterFocus.x) ? CenterFocus.y : Depth[i].y;
}
CenterColor += Contribution * Color[i];
TotalContribution += Contribution;
}
float4 FinalColor = CenterColor / TotalContribution;
return FinalColor;
}
float4 main(in float2 TexCoord : TEXCOORD0,
uniform sampler2D Texture : TEXUNIT0,
uniform sampler2D DepthTexture : TEXUNIT1,
uniform float DepthOfFieldCenter,
uniform float DepthOfFieldMaxDistance,
uniform float CoCMaxSize) : COLOR
{
/////
float4 CenterColor = tex2D(Texture, TexCoord);
float CenterDepth = -tex2D(DepthTexture, TexCoord).z;
//
return do_dof(TexCoord, Texture, DepthTexture, DepthOfFieldCenter, DepthOfFieldMaxDistance, CoCMaxSize, CenterColor, CenterDepth, 0);
}
I'm running into a problem though - in the code I'm rejecting samples that come from an area that's significantly in front of or below the center point (using the linear screen-space depth stored in the depth texture) - however, I'm seeing "acne":
http://www.flickr.com/photos/59098813@N06/7998075690/
I don't understand it - shouldn't that acne be rejected by my test and have its contribution set to zero? Here's the visualized depth buffer for reference:
http://www.flickr.com/photos/59098813@N06/7998069833/
All buffers are FP16, running on OS X Mountain Lion on a Retina MacBook Pro (Kepler, 650M).