ich versuche jetzt schon einige Zeit eine vernünftige SSAO Implementierung hinzubekommen aber scheitere immer wieder. Anbei der Code von meinem letzten Versuch(nach http://john-chapman-graphics.blogspot.d ... orial.html). Die Eingabedaten sind im World Space:
Code: Alles auswählen
struct VS_OUTPUT
{
float4 position : SV_Position;
float2 tex0 : TEXCOORD0;
float3 pos : TEXCOORD1;
float3 norm : TEXCOORD2;
float3 color : TEXCOORD3;
};
struct PS_OUTPUT
{
float4 RGBColor : SV_Target;
};
cbuffer MATRIXBUFFER
{
matrix CAMERA_MATRIX;
matrix DEVICE_MATRIX;
matrix INVERT_CAMERA_MATRIX;
matrix INVERT_DEVICE_MATRIX;
};
cbuffer APPLICATIONBUFFER
{
float4 APPLICATION_MATERIAL;
};
Texture2D<float4> RENDERTARGET_1;
Texture2D<float4> RENDERTARGET_2;
Texture2D<float4> RENDERTARGET_3;
Texture2DMS<float,8> ZBUFFER;
Texture2D<float4> RANDOM;
SamplerState g_samPoint
{
Filter = MIN_MAG_MIP_POINT;
AddressU = MIRROR;
AddressV = MIRROR;
AddressW = MIRROR;
};
float SampleDepth(float2 uv)
{
int2 size = int2(1344,730);
int2 index = int2(uv.x*size.x,uv.y*size.y);
return ZBUFFER.Load(int3(index, 0), 0 );
}
float3 SampleNormal(float2 uv)
{
return normalize(RENDERTARGET_2.Sample(g_samPoint,uv.xy).xyz);
}
float3 SamplePos(float2 uv)
{
return RENDERTARGET_3.Sample(g_samPoint,uv.xy);
//Alternative aber mit gleichem Ergebniss
float3 screenPos;
float2 uvPos=uv;
uvPos.y = 1-uvPos.y;
uvPos = uvPos*2.0-1.0;
screenPos = float3(uv, SampleDepth(uv));
float4 worldPos = mul(float4(screenPos, 1.0f), INVERT_DEVICE_MATRIX);
worldPos = mul(float4(screenPos, 1.0f), INVERT_CAMERA_MATRIX);
worldPos.xyz /= worldPos.w;
return worldPos.xyz;
}
float3 SampleColor(float2 uv)
{
return RENDERTARGET_1.Sample(g_samPoint,uv.xy);
}
float3 SampleRandom(float2 uv)
{
return normalize(RANDOM.Sample(g_samPoint,uv*float2(1344.0,730.0)*1.0/64).xyz*2.0 - float3(1.0,1.0,1.0));
}
float SSAO3(float2 uv)
{
float SSAORad=1.0*APPLICATION_MATERIAL.x;
float3 samples[16] = {
float3(-0.0182121,0.197594,0.232228),
float3(0.293952,-0.0652266,0.250021),
float3(-0.104782,-0.463961,0.511148),
float3(0.12743,0.0689862,0.118884),
float3(0.0883658,1.01601,0.897755),
float3(-0.0711823,0.0184628,0.0630255),
float3(0.399123,-0.0238302,0.260211),
float3(0.246834,-0.400789,0.305677),
float3(-0.965089,-1.07855,1.23738),
float3(-0.114554,-0.124242,0.146548),
float3(0.619386,-0.564064,0.434935),
float3(0.739393,0.396969,0.642246),
float3(-0.0852846,-0.327954,0.153502),
float3(0.209668,-0.237002,0.0298241),
float3(0.00607007,0.0817364,0.160404),
float3(0.00546413,0.00826584,0.00676915)
};
float3 random = SampleRandom(uv);
float3 currentPixelNormal = SampleNormal(uv);
float3 currentPixelPos = SamplePos(uv);
float3 rvec = normalize(float3(random.xy,0.0));
float3 tangent = normalize(rvec - currentPixelNormal * dot(rvec, currentPixelNormal));
float3 bitangent = cross(currentPixelNormal, tangent);
float3x3 tbn = float3x3(tangent, bitangent, currentPixelNormal);
int iterations = 16;
float ao = 0.0;
for (int i = 0; i < iterations; ++i) {
// get sample position:
float3 sample = mul(samples[i],tbn);
sample = sample * SSAORad + currentPixelPos;
// project sample position:
float4 offset = float4(sample, 1.0);
offset = mul(offset,CAMERA_MATRIX);
offset = mul(offset,DEVICE_MATRIX);
offset.xy /= offset.w;
offset.xy = offset.xy * 0.5 + 0.5;
// get sample depth:
float sampleDepth = SamplePos(uv).z;
// range check & accumulate:
float rangeCheck= abs(currentPixelPos.z - sampleDepth) < SSAORad ? 1.0 : 0.0;
ao += (sampleDepth <= sample.z ? 1.0 : 0.0) * rangeCheck;
}
return ao = (ao / iterations);
}
float4 main(VS_OUTPUT frag) : SV_Target
{
float depth = SampleDepth(frag.tex0);
float3 norm = SampleNormal(frag.tex0);
float ao=SSAO3(frag.tex0);
return float4(ao,ao,ao,1.0);
//return float4(SampleNormal(frag.tex0),1.0);
//return float4(SampleColor(frag.tex0)-ao,1.0);
}
Und so sieht das ganze aus:
<a%20href="http://www.imgbox.de/"%20title="Bilder% ... er="0"></a>
Hatt jemand eine Idee was ich falsch mache?
PS: Ich habe mal SamplePos umgeschrieben das da immer 0 oder ein konstanter Vektor rauskommt aber das ändert gar nix am Ergebnis :shock: