Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]
GameDev.Net Discussion Forums Image of the Day  SSAO
Send Topic To a Friend | View Forum FAQ | Track this topic | View Forum

 Last Image Next Image 
 SSAO
 Page:    «« 1 2 3 4
Post Reply 
I am looking at Inigo's GLSL code and was wondering if someone could clarify a couple of things. I'm not sure I understand, certain things.

First, the uniforms.

uniform vec4 fk3f[32];
uniform vec4 fres;
uniform sampler2D tex0;
uniform sampler2D tex1;


Questions:
is tex0 the zbuffer "as-is", meaning that is no special shader was used to modify the resulting depth and the zbuffer was passed to the SSAO shader as a normal floating point texture?

is tex1 a texture containing normalized, random vectors?

is fres suppose to be the resolution of the random texture?

Next, accessing the textures:

vec4 zbu = texture2D( tex0, gl_Color.xy );
vec3 ep = zbu.x*gl_TexCoord[0].xyz/gl_TexCoord[0].z;


Questions:
What is gl_Color.xy suppose to be equal to? Obviously this was set by the vertex shader, could someone clarify what this vertex shader is?

why divide by .z in the line gl_TexCoord[0].xyz/gl_TexCoord[0].z? I thought gl_TexCoord was simply holding the current pixel's screen XY coordinate.

Any help is appreciated.

f.






Hello there,
I 've just published a screenshot from my AO implementation

The effect isn't finished-optimized yet, but I think its really fast and gives nice results, that dont change as you rotate the scene. In a few days I am going to publish details on the implementation. In the follow link you can find a short description and the computer's specification
-> Ambient Occlusion



Quote:
Original post by Hurp
Quote:
Original post by dams32
I try to improve my SSAO algorithm. Actually, I use the depth buffer and a normal buffer obtained from a pass with rgb shader.


Why do you use a normal buffer pass?


Because without using the normal the result will less accurate with dark glows around everything. If you use the normal you can avoid that and get really nice looking results without dark edge glows and it also opens up for some other interesting techniques. For instance radiosity color bleeding, which I've successfully implemented in my software only SSAO for 3dsmax with no noticeable overhead. Has been used in many of our rendering productions. Fast, cheap and scanline renderer based making the base render faster aswell.

One day I'll write a blog post about it on my blog. For now there is only the software psuedo-code without the 3dsmax G-buffer layer handling and other nice 3dsmax bonuses (www.malmer.nu).


This thread has helped me conceive a concept for my own SSAO.

I just recently finished writing a SSAO and here's the results:
on vimeo (better quality):
http://vimeo.com/2716403
on youtube:
http://www.youtube.com/watch?v=RY_lfHzQrAQ

There is no pre-computation or baked textures, it is all done in real time and running at fast speed. At a resolution of 800x600 with RT shadows and skybox, I get around 90fps with SSAO and 108fps without SSAO (I know ur gonna say I should test with ms instead of fps but its easier to describe on layman terms)



I wrote a simple version of ssao that looks good and is easy to implement, since it is completely a "2D" postproccess, no projections. For all those people who are having trouble with ssao (most common trouble i see is lack of "depth", everything looks flat).

it needs a randomly colorized texture for the random sampling(not tangent space normal, just random colors) and a depth texture, preferably linear. I use a gaussian function to create a shadow falloff, because it allows you to tweak it precisely.

uniform sampler2D som; //depth 
uniform sampler2D rand; //random colors

//unpack vector for linear depth
const vec3 unpack = vec3( 255.0/256, 255.0/(256*256), 255.0/(256*256*256) );

//sampling positions:
const vec2 points[8] = {
vec2(-1,1),vec2(0,1),vec2(1,1),vec2(1,0),vec2(1,-1),vec2(0,-1),vec2(-1,-1),vec2(-1,0)
};

void main()
{    
float sum = 0.0;
float prof = dot(texture2D(som, gl_TexCoord[0].st).xyz,unpack);//I unpack the rgb encoded depth, remove the dot product if you use a standard zbuffer.
//with a non-linear buffer, results are a lot uglier so try to avoid using it.

vec2 fres = vec2(60,60);//tiling of the random texture across screen.
vec3 random = texture2D(rand, gl_TexCoord[0].st*fres.xy);
random = random-vec4(0.5); //we obtain the difference (color-gray) so that there are negative values also.

//calculate sampling rates:
float radx = (1.0/800.0)*1; //800x600 resolution
float rady = (1.0/600.0)*1;

for (int i = 0;i<8;i++){

      vec2 point = vec2(points[i].x*radx,points[i].y*rady)+random.xy*0.06;
      vec2 sp = gl_TexCoord[0].xy+point/prof; //divide by the depth value so that the sampling area gets smaller with depth.
      
      float prof2 = dot(texture2D(som, sp).xyz,unpack);

      float zd = max(prof-prof2,0.0)*50; //depth difference*50
      float gauss = pow(2.7182,-2*zd*zd); //gaussian falloff
      sum += zd*gauss*2; //depth difference*gaussian fallof (so that big differences contribute less, this avoids "flatness")
}

float occ = (1.0-sum/8.0); //white-occlusion
gl_FragColor = vec4(occ,occ,occ,1.0);
}




It looks like this, youŽll need to blur it afterwards, like usual:


If anyone wants a linear depth shader i have one, ask for it and iŽll post it.

[Edited by - ArKano22 on January 11, 2009 5:53:11 AM]


sorry to bring this back,

I'd like that linear shader if possible, the engine I use doesn't use deferred shading :)

- ZeroX aka Chosker My Online Portfolio


im using iq's code to try AO but im only getting a grey screen. i was hoping anyone could take a quick look at the code below and see if you can spot the problem?? i believe its the camera ray, but im not sure.

depthSampler is my depthbuffer. its linear. i compute it as:
float3 viewSpacePos = mul( matView, IN.worldSpacePos ); // done in vertex
float depth = length(IN.viewSpacePos) / farPlane; // done in pixelshader
float4 color = float4( depth, depth, depth, 1 );


as for the camera ray i tried several ways. for example:

float3 ViewVec = CameraTarget-CameraPos; // both in world space
OUT.cameraRay = ViewVec;
-----
float3 ViewVec = WorldSpacePosition-CameraPos; // world space
OUT.cameraRay = ViewVec;
-----
float3 ViewVec = WorldSpacePosition-CameraPos;
float3 ViewVec = mul( matView, ViewVec ).xyz; // vector in viewspace
OUT.cameraRay = ViewVec;
-----
float3 ViewVec = mul( matView, ViewVec ).xyz; // ViewVec is in worldspace and gets transformed to viewspace
OUT.cameraRay = ViewVec;



This is my vertex/pixel shader code. just converted from glsl to Cg


//
// VERTEX SHADER
//

VS_OUTPUT VS_SSAO( in VS_INPUT IN )
{
    VS_OUTPUT Out = (VS_OUTPUT)0;

    //Out.pos = IN.Position;	// for some weird reason passing direct screen coords doesnt work ?!? need to transform by WVP
	Out.pos = mul( worldViewProj, IN.Position ); 

	IN.Position.xy = sign( IN.Position.xy );
    Out.TexCoord = (float2(IN.Position.x, -IN.Position.y) + float2( 1.0f, 1.0f )) * 0.5f;

	float4 pos = IN.Position;
	float3 worldPos = mul( matWorld, pos ).xyz;

	float3 eyevec = worldPos - cameraPos;

	float3 eyeview = mul( matView, float4(eyevec, 1) ).xyz;
	normalize( eyeview );

	Out.viewDirection = eyeview;

    return Out;
}



//
// PIXEL SHADER
//

float4 PS_SSAO( in VS_OUTPUT IN ) : COLOR
{
	float4 samples[16] =
	{
		float4(0.355512, 	-0.709318, 	-0.102371,	0.0 ),
		float4(0.534186, 	0.71511, 	-0.115167,	0.0 ),
		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 ),
		float4(-0.290012, 	0.0518654, 	0.522688,	0.0 ),
		float4(0.0975089, 	-0.329594, 	0.609803,	0.0 )
	};

	float depth = tex2D( depthSampler, IN.TexCoord ).r;

	float3 se = (depth * IN.viewDirection.xyz) / IN.viewDirection.z;

	//float3 viewnormal = tex2D(depthSampler, IN.TexCoord).rgb;

	float3 randNormal = tex2D( randSampler, IN.TexCoord * 200 ).rgb;
	//randNormal = randNormal - float3(0.5);
	randNormal = randNormal * 2 - 1.0;

	float finalColor = 0.0f;
	for( int i=0; i<16; i++ )
	{
		float3 ray = se + sampleRadius * reflect(samples[i].xyz, randNormal);

		float2 ss = (ray.xy/ray.z) * float2( 0.75, 1.0 );
        float2 sn = ss*.5 + float2(0.5);
        float sz = tex2D( depthSampler, sn ).r;

        float zd = 50.0*max( ray.z-sz, 0.0 );
        finalColor += 1.0 / (1.0+zd*zd);
	}

	return float4( finalColor/16, finalColor/16, finalColor/16, 1.0f );
}




Quote:
Original post by paulmelamed
I dont understand why those points need to be generated in 3d, since in the end there is a lookup into the pre-rendered z texture and they have to be projected back to 2d... So all your samples end up in a 2d circular area centered around current pixel. Could the precomputed random 2d offsets be stored in something like a volume texture instead?


I dont understand the 3D projection and back to 2D step either.



I even have these noticeable line effects if the surface normal points torwards the camera due to the depth comparison even when testing, and still got those artefacts when setting the Rendermonkey RenderToTexture to a A32F value (GLSL). (I don't see any visual difference between A8 or A32F)

http://img515.imageshack.us/img515/950/gamedevssaopostimgmy9.png

Or does this feature not work in Rendermonkey anyone knows ?, right now I reduce it by clamping the difference value.

Even when I copied ArKano22's version 2 posts above I have these line effects.


How do you link pictures and stuff?

I have an image I'd like feedback on. My version is coming along nicely, but theres some areas I need to check with you guys on.


I just put up a tutorial, with all relevant source, on how I did my effect that I'm pretty pleased with. It runs fast and has no bad artefact problems afaia.

It's at www.rubicondev.com in the "For Developers" section.


Hi guys,

I plan to implement this technique for my demo. Iam not that skilled, but I hope I can get this working. I have some questions though.

Shaders making SSAO are working with depth values, right ? So what I need is to pass depth buffer into my shader.

How do I do that ? I had an idea to use depth texture of my FBO and pass it via some texture unit. Will this work ?

And to note that this texture is rectangle texture, not ordinary squared texture. How should I get texture coordinates for this texture ? To load correct depth value for my fragment ?

Does someone have an demo example with source code that I can study ? (it has always been best for me to look at someone others code, than to code something from scratch)


thomas3711: this is how I did SSAO: http://www.gamerendering.com/2009/01/14/ssao/

djmj: If I remember correctly, float textures doesn't work with GLSL in Rendermonkey. Try packing the values into 0..1 range and save in a none floating point texture with 32bit resolution per channel instead. With HLSL, float textures works fine.

Game Rendering


Haladria: thanks a lot for link, I've actually seen it, but tried different shaders...which was not a good idea because all the previous ones (I've tried 4 of them) were not working as I've expected them. Yours gives me very good results.

But I have problems with it's performance, when I turn it on my FPS drops from 160 to 16 :) and that is not good...I think this might because I use GL_EXTURE_RECTANGLE, instead of GL_TEXTURE_2D, or maybe something esle. I just wanted to ask how much does your shader drops from FPS in your engine ?


Page:    «« 1 2 3 4
All times are ET (US)

Post Reply
 Last Image Next Image 
Forum Rules:
You may not post new threads
You may not post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: