//-----------------------------------------
// Vertex Shader Input
//-----------------------------------------
struct VS_IN
{
float3 PosL : POSITION;
float2 Tex : TEXCOORD;
};
//-----------------------------------------
// Vertex Shader Output/Pixel Shader Input
//-----------------------------------------
struct VS_OUT
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float2 Tex : TEXCOORD;
float3 vView: TEXCOORD1;
};
//========================================================================================================================
// Vertex Shader
//========================================================================================================================
VS_OUT VS(VS_IN vIn)
{
VS_OUT vOut;
//Leave as NDC
vOut.PosH = float4(vIn.PosL, 1.0f);
//Transform to world space
vOut.PosW = mul(float4(vIn.PosL, 1.0f), mWorld);
//Transform to view space
vOut.Tex = vIn.Tex;//(float2(vIn.Tex.x, -vIn.Tex.y) + float2(1.0f, 1.0f)) * 0.5f;
//Calculate the View Ray
vOut.vView = normalize(mul(float4((vCamPos - vOut.PosW), 1.0f), mView));
//float fFarY = tan(3.14159f/3.0f/2.0f) * 100.0f;
//float fFarX = fFarY *(gvScreenDims.x/gvScreenDims.y);
//vOut.vView = normalize(mul(float4(float3(-fFarX * vIn.PosL.x, fFarY * vIn.PosL.y, 100.0f), 1.0f), mView));
return vOut;
}
//=======================================================================================================================
// Pixel Shader
//=======================================================================================================================
float4 PS(VS_OUT pIn) : SV_Target
{
//Sample the linear depth at this pixel
float fDepth = gNormalMap.Sample(gTriLinearSam, pIn.Tex).a;
//Get the normal for this pixel
float3 vNorm = gNormalMap.Sample(gTriLinearSam, pIn.Tex).rgb;
//Determine pixel dimensions use this to sample surrounding pixels
float2 vPixDims = float2(1.0f/gvScreenDims.x, 1.0f/gvScreenDims.y);
float3 vEye = pIn.vView * fDepth/pIn.vView.z;
//Comparison Sample Pixels
float4 vSamples[12] =
{
float4(-0.87866, 0.157139, -0.115167, 0.0 ),
float4(0.140679, -0.475516, -0.0639818, 0.0 ),
float4(-0.0796121, 0.158842, -0.677075, 0.0 ),
float4(-0.0759516, -0.101676, -0.483625, 0.0 ),
float4(0.12493, -0.0223423, -0.483625, 0.0 ),
float4(-0.0720074, 0.243395, -0.967251, 0.0 ),
float4(-0.207641, 0.414286, 0.187755, 0.0 ),
float4(-0.277332, -0.371262, 0.187755, 0.0 ),
float4(0.63864, -0.114214, 0.262857, 0.0 ),
float4(-0.184051, 0.622119, 0.262857, 0.0 ),
float4(0.110007, -0.219486, 0.435574, 0.0 ),
float4(0.235085, 0.314707, 0.696918, 0.0 )
};
//Generate a random normal
float3 vRandNorm = normalize(gRandomMap.Sample(gTriLinearSam, pIn.Tex.yx));
//The final occlusion factor
float fOcclusion = 0.0f;
for(int i=0; i<gnSamples; ++i)
{
//Reflect samples with a random normal to remove banding effects.
//Make sure it is projected within the sphere
float3 vRay = vEye + reflect(vSamples, vRandNorm) * gfRadius;
//Transform to screen space
float4 vSample = float4(vRay, 1.0f);
vSample = mul(vSample, mProj);
//Convert from NDC to texture space
float2 vSampleTex = 0.5f * vSample.xy/vSample.w + 0.5;
//Scale up the Tex Coords to give a blurry effect
vSampleTex.x += 1.0/gvScreenDims.x * 2.0f;
vSampleTex.y += 1.0/gvScreenDims.y * 2.0f;
//Sample the depth at the offset pixels
float4 vSampleDepth = gNormalMap.Sample(gTriLinearSam, vSampleTex);
//Use the difference in normals as a weighting
float fDeltaNorm = (1.0 - dot(vSampleDepth.rgb, vNorm));
float fDeltaDepth = max(fDepth - vSampleDepth.a, 0.0f);
//Calculate fade-off (1/ZD^2)
float fAttenuation = 1.0f/(1.0f + fDeltaDepth * fDeltaDepth);
//Accumulate the occlusion
fOcclusion += fAttenuation * fDeltaNorm;
}
//The final output colour: Average the occlusion factor and scale to get desired contrast
float fAO = (1 - (fOcclusion/gnSamples)) * gfContrast;
//Pack the normal back in to use in final pass and for blurring
return float4(vNorm, fAO);
}
SSAO - Again!
I know there are hundreds of docs and posts about screen space AO (believe me I've been through a lot) but I never got round to using this technique when everyone was doing it a year ago so I thought I'd try it now. The problem is that my SSAO looks waaaay too much like an edge detection algorithm, and if the camera goes too close to the model the light and dark bits swap and flicker
I am not sure if my space transforms are wrong or what. If anyone has time could they look at the HLSL code and give me some hints.
Thanks.
Hey dont know how to embed images.
Heres a link to the to pics though
thanks.
[Edited by - Downie on September 12, 2009 6:37:34 PM]
Heres a link to the to pics though
thanks.
[Edited by - Downie on September 12, 2009 6:37:34 PM]
Quote:Original post by DownieNot to be pedantic or anything, but SSAO *is* an edge detection algorithm - albeit only concave edges.
The problem is that my SSAO looks waaaay too much like an edge detection algorithm
Quote:I am not sure if my space transforms are wrong or what. If anyone has time could they look at the HLSL code and give me some hints.I don't see anything wrong in your code from a brief inspection. I do however find it is a little simpler if one performs all calculations in view space - might be worth considering.
Quote:Hey dont know how to embed images.Use the HTML <img src="http://www.example.com" /> tag.
Quote:Not to be pedantic or anything, but SSAO *is* an edge detection algorithm - albeit only concave edges.
I know it is similar but even with a blur pass the edges are too well defined, and it looks nothing like other SSAO screenshots. See what you think from the pics
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement