Sorry to bother you again...
I think i got the depth normal pass working and went on to the actual algorithm,
but theres weired stuff happening again...
This is how i generate normals and positions:
struct VS_INPUT
{
float3 position : POSITION;
float3 normal : NORMAL;
};
struct PS_INPUT
{
float4 position : SV_Position;
float4 viewpos : POSITION;
float3 normal : NORMAL;
};
PS_INPUT VSMAIN (in VS_INPUT input)
{
PS_INPUT Out;
Out.viewpos = mul (float4 (input.position, 1.0f), WorldMatrix);
Out.viewpos = mul (Out.viewpos, ViewMatrix);
Out.position = mul (Out.viewpos, ProjMatrix);
float3 viewSpaceNormal = mul (input.normal, (float3x3)WorldMatrix);
Out.normal = mul (viewSpaceNormal, (float3x3)ViewMatrix);
return Out;
}
struct PS_OUTPUT
{
float4 normal : SV_Target0;
float4 viewpos : SV_Target1;
};
PS_OUTPUT PSMAIN (in PS_INPUT In)
{
PS_OUTPUT Out;
Out.normal = float4(normalize(In.normal) * 0.5f + 0.5f, 1.0f);
Out.viewpos = In.viewpos;
return Out;
}
This is what i got so far, it is pretty much like the article from here: http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/a-simple-and-practical-approach-to-ssao-r2753
The Ambien Occlusion shader here is applied to a full screen triangle
float3 getPosition (in float2 uv)
{
return PositionBuffer.Sample (LinearSampler, uv).xyz;
}
float3 getNormal (in float2 uv)
{
return DepthNormalBuffer.Sample (LinearSampler, uv).xyz;
}
float2 getRandom (in float2 uv)
{
return normalize (RandomTexture.Sample (LinearSampler, uv).xy * 2.0f - 1.0f);
}
float doAmbientOcclusion (in float2 tcoord, in float2 occluder, in float3 p, in float3 cnorm)
{
// vector v from the occludee to the occluder
float3 diff = getPosition (tcoord + occluder) - p;
const float3 v = normalize (diff);
// distance between occluder and occludee
const float d = length (diff);
return max (0.0, dot (cnorm,v)) * (1.0 / (1.0 + d));
}
float PSMAIN (in PS_INPUT In) : SV_Target
{
const float2 vec[4] = {
float2 (1,0), float2 (-1,0),
float2 (0,1), float2 (0,-1)
};
float3 p = getPosition (In.tex);
float3 n = getNormal (In.tex);
float2 rand = getRandom(In.tex);
float ao = 0.0f;
float rad = 0.125 / p.z;
int iterations = 4;
for (int j = 0; j < iterations; ++j)
{
float2 coord1 = reflect(vec[j], rand) * rad;
float2 coord2 = float2 (coord1.x*0.707 - coord1.y*0.707,
coord1.x*0.707 + coord1.y*0.707);
ao += doAmbientOcclusion (In.tex, coord1*0.25, p, n);
ao += doAmbientOcclusion (In.tex, coord2*0.5, p, n);
ao += doAmbientOcclusion (In.tex, coord1*0.75, p, n);
ao += doAmbientOcclusion (In.tex, coord2, p, n);
}
ao /= (float)iterations*4.0;
return ao;
}
after that I render the scene again and modulate the output by using this occlusion buffer
how ever theese are the images it produces:
I dont't know how that soapy screen effect is produced but i think it has something to do with the randomTexture.
I can't get the image look right to me (aside from the soap screen) by tweaking the parameters.
For example: If I look 45° to the left the front faces grow dark (why?).
Another thing is, that if I normalize the random normals the frame rate drops to a tenth.