Seite 1 von 1

SSAO Probleme

Verfasst: 08.09.2013, 17:53
von MadMax
Hallo zusammen,

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:

Bild

<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:

Re: SSAO Probleme

Verfasst: 08.09.2013, 17:55
von Schrompf
Das Bild wird leider nicht angezeigt.

Re: SSAO Probleme

Verfasst: 08.09.2013, 17:58
von MadMax
Jetzt aber :-)

Re: SSAO Probleme

Verfasst: 08.09.2013, 18:19
von CodingCat
Deine Zufallstextur wird schonmal nicht wiederholt, wie auf dem Bild unschwer zu erkennen. Also entsprechenden Sampler State auf Repeat stellen. Die Angaben im HLSL-Sampler-Block sind ausserhalb des fuer deprecated erklaerten Effects11-Frameworks wirkungslos, d.h. du musst haendisch einen entsprechenden Sampler State Block mittels PSSetSamplers in den richtigen Slot setzen. Es ist uebrigens ratsam, die Zufallstextur exakt pixelweise auf den Bildschirm abzubilden.

Ansonsten einfach mal mittels Farbkodierung debuggen, wo da was rauskommt, und wieso bestimmte Dinge sich nicht oder falsch aufs Ergebnis auswirken.

Re: SSAO Probleme

Verfasst: 15.09.2013, 14:25
von MadMax
Danke! Das mit dem Sampler States hatte ich so noch nicht gewusst. Was die RND-Textur angeht verwende ich jetzt einen in der gleichen Größe wie mein Bildschirm ich denke das hast du mit exakt Pixelweise gemein oder?

Ich habe noch einige kleine Fehler gefixed aber es sieht immer noch völlig falsch aus:

Im View Space
Bild

Im World Space
Bild

Neuer Code:

Code: Alles auswählen

float SSAO3(float2 uv)
{
	float SSAORad=1.0*APPLICATION_MATERIAL.x;
	

	float3 samples[36] = {
		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(0.0266294,0.0466458,0.0651193),  float3(-0.00876011,0.491309,0.315298),float3(-0.410571,-0.862981,0.896798),   float3(-0.169266,0.428677,0.164507),
		float3(0.011676,0.167468,0.100763),     float3(0.128002,0.0476439,0.527884),  float3(0.452763,-0.00383817,0.276509),  float3(-0.609517,0.434583,0.679426),
		float3(-0.00927132,0.0164443,0.0726412),float3(-0.0419945,0.144547,0.219946), float3(0.628496,0.612039,0.0667422),    float3(0.0205594,0.010582,0.0135621),
		float3(-0.034159,-0.0483252,0.0285935), float3(0.372881,-0.237748,0.247605),  float3(-0.0245225,0.00747819,0.0225939),float3(-0.0931879,0.239895,0.100817),
		float3(0.219383,0.210142,0.170228),     float3(0.115573,0.0519275,0.011864),  float3(0.105376,0.0526046,0.261525),    float3(-0.150244,-0.045597,0.153778)
};


	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 = 36;

	float ao = 0.0;
	for (int i = 0; i < iterations; i+=1) {
		// 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(offset).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);   
}

Re: SSAO Probleme

Verfasst: 15.09.2013, 14:45
von MadMax
Ach ja so sample ich meine RND-Vectoren:

float3 SampleRandom(float2 uv)
{

float sizeX=1344.0;
float sizeY=730.0;
float bit=255.0;

float2 uvR=uv;
uvR.x *= 1344.0/sizeX;
uvR.y *= 730.0/sizeY;

float3 rand=RANDOM.Sample(PointSamplerWrap,uvR).xyz*(1.0/bit); //RAND VEC [0..1]
rand=float3(rand.xy,0.0); //RAND VEC Z=0
rand=rand*2.0-float3(1.0,1.0,0.0); //RAND VEC [-1..1]

return normalize(rand);
}

Sobald ich bit auf 1.0 setze bekomme ich das folgende Bild:
Bild

Re: SSAO Probleme

Verfasst: 15.09.2013, 15:55
von CodingCat
MadMax hat geschrieben:Danke! Das mit dem Sampler States hatte ich so noch nicht gewusst. Was die RND-Textur angeht verwende ich jetzt einen in der gleichen Größe wie mein Bildschirm ich denke das hast du mit exakt Pixelweise gemein oder?
Nein, ich meinte nur, dass du die Zufallstextur genau so oft wiederholen solltest, dass ein Pixel in der Zufallstextur genauso groß ist wie ein Bildschirmpixel. Mit bildschirmfuellenden Noise-Texturen habe ich keine guten Erfahrungen gemacht. Insbesondere wenn die Verteilung nicht optimal ist, laesst sich das Rauschen hinterher kaum noch rausglätten. Lieber eine wiederholte Noise-Textur im Rahmen der Größe des Glättungskernels.

Dass du mit Skalierung 1/255 nichts siehst, ist kein Wunder, weil dir Sample() ziemlich sicher Werte zwischen 0 und 1 liefert. Das verrauschte Ergebnis ist aber in der Tat immer noch weit von plausibler Ambient Occlusion weg, weiter debuggen! ;)

Re: SSAO Probleme

Verfasst: 15.09.2013, 17:55
von MadMax
die Skalierung ist jetzt weg :-)

Re: SSAO Probleme

Verfasst: 16.09.2013, 09:28
von MadMax
So habe mal als debbuged:

Noise:
Bild

Noise abs:
Bild

World Color:
Bild

World Normal:
Bild

World Position:
Bild

World AO:
Bild

View Color:
Bild

View Normal:
Bild

View Position:
Bild

View AO:
Bild

Re: SSAO Probleme

Verfasst: 16.09.2013, 15:58
von Blue Cobold
Die Normals sehen merkwürdig aus, speziell an den glatten Wand-Teilen über den Säulen.

Re: SSAO Probleme

Verfasst: 16.09.2013, 16:57
von MadMax
Ja dachte ich auch zuerst liegt aber denke ich an der Datei.

Andere Szene:
Bild

Ich habe eher das Gefühl das es irgendwo an den Koordinatensystemen liegt. Ich verwende übrigens ein linkshändiges. Kann mir jemand sagen ob ich dazu die Schritte im Tutorial irgendwie anpassen muss? Habe zwar schon ein bisschen rumprobiert aber das Ergebnis wird nicht besser.

Re: SSAO Probleme

Verfasst: 16.09.2013, 20:31
von MadMax
Wichtiger Bugfix:

//project sample position:
float4 offset = float4(sample, 1.0);
if(APPLICATION_MATERIAL.z == 1.0){
offset = mul(offset,CAMERA_MATRIX);}
offset = mul(offset,DEVICE_MATRIX);
offset.y *= -1.0;
offset.xy /= offset.w;
offset.xy = offset.xy * 0.5 + 0.5;

Im Viewspace sieht das ganze jetzt schon etwas besser aus:

Bild

Re: SSAO Probleme

Verfasst: 17.09.2013, 20:18
von MadMax
So langsam wirds:

ohne SSAO
Bild

mit SSAO
Bild

Re: SSAO Probleme

Verfasst: 17.09.2013, 20:53
von TGGC
Ich glaube auch, das in der anderen Szene die Normalen falsch berechnet werden. Als waere alles in einer Smoothgroup.