deferred render concepts, questions

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
kaos
Posts: 155
Joined: Tue Aug 12, 2008 8:25 pm
Location: Spain

deferred render concepts, questions

Post by kaos »

I'm testing and this is my very very simple deferred render without light acumulation pass(first steps).

http://rapidshare.com/files/439331303/shader.zip

I have tried to reconstruct vertex position form depth in view space

http://mynameismjp.wordpress.com/2010/0 ... m-depth-3/

but I don't get the same information that the rtt where I save the vertex position.

¿How can I to pass the light world postion to view space postion? If I put the light like child of cam work, but them.... I put lightpos x matview but not is correct.

Other thing, In light acumulation pass ¿How can I render the light volumen with front face cullin true and them back face cullin true for depth comparison? ¿I need two steps?

Image
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

I've been explaining this to entity...
to get ViewSpace position you just need to simply interpolate the view space frustum corners

You need 4 corners of the far plane of the frustum... during the gbuffer render you only save depth of the pixels in range 0-1 LINEARLY (in floating point RTT)

With a simple method you use just the XY texture coords to interpolate between the 4 corners to get a point on the far plane that a ray passing through the pixel from the camera would intersect... then you interpolate that point with the camera position (which just happens to be 0,0,0 in view space, meaning this time you can just scale the point) using the 0-1 depth.

However please fill me in (with some paper reference) on what Light Accumulation pass is?

I can tell you a simple method of how to render light volumes.....
First you have got to be familiar with attenuation in lighting shaders, linear and quadratic (we can skip constant).
the attenuation for a lightsource is give like this 1.f/(distanceToLight*linear+distanceToLightSQ*quadratic)
obviously this means that the light volume is theoretically infinite, but in reality it means that light doesnt contribute to the scene if the attenuation < 1/256.f
We can imagine that the light volume is a sphere and a ray from each pixel passes through the sphere or not. Now depending on the length of the ray through the sphere we will attenuate the brightness of the light volume. First we need the radius for each light volume, we need to solve this equation to get the distance after which no light is added, ofc we dont want the volume bleeding through the walls or being to large. The actual raidus is going to be scaled at least 50 smaller, but with my approach the size of the light volume doesnt impact performance but only the number of volumes does. The equation is

1.f/256.f = 1.f/(x*linear+x^2*quadratic)

x^2*quadratic/256.f+x*linear/256.f-1.f=0

which is a simple quadratic equation.....

x = (-linear/256.f+sqrt(linear^2/256^2+4*quadratic/256))*256.f/(2*quadratic)

or something like that :) that x will equal the radius for each light (r)

obviously for each ray from pixel

(x-lightPos.X)^2+(y-lightPos.Y)^2+(z-lightPos.Z)^2=radiusOfLightVolume

obviously you will need to rearrage this equation 3 times in terms of x,y, and z

then using some simultaneous equations you will need to solve intersection of sphere with a ray in the shader. which again turns out to be a quadratic expression, thus returning two intersections. The distance between the two intersections will be the ray length inside the sphere, this distance can be plugged back into the equation

distance*linear+distance*distance*quadratic

which will give an more intense light volume as the ray passes nearer the center of the sphere.



I am not handling spot lights with this equation, a totally different intersection model would be needed.

Also if you plan for SSAO, you should render light volumes AFTER the AO.
kaos
Posts: 155
Joined: Tue Aug 12, 2008 8:25 pm
Location: Spain

Post by kaos »

thanks devsh. I have many problems with 3d reconstruction from depth in view-space. I thought that it was more easy. I must do more tests, I save the x,y,z postion in view-space in a rtt for compare with my reconstruction position but I can`t get the same result. The same problems with the position light in world-space to view-space.

The acumulation light pass that I want to make is that:

I build 3 scenemanagers:

smgr1 -> objets
smgr2 -> lights with front face culling true ( back face culling false )
smgr3 -> same lights with front face culling false

so depth-object <= depth-light-smgr2 && depth-object >= depth-light-smgr3

I need 2 pass for render the light acumulation(there are other method?). What is better ?

pd: In this moment ssao is very dificult for me. ;)
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Post by Mel »

kaos wrote:pd: In this moment ssao is very dificult for me. ;)
Using the normals and the position, SSAO can be done as a postprocessing routine :)
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
kaos
Posts: 155
Joined: Tue Aug 12, 2008 8:25 pm
Location: Spain

Post by kaos »

I know, but the first thing is reconstruct the position, And I can't get it ¡¡¡¡ I'm idiot.

for light position I write:

WorldViewmat = view * world;
WorldViewmat.makeInverse();
TIWorldViewmat = WorldViewmat.getTranspose();
TIWorldViewmat.transformVect(vLightPosition);

but the vLightPosition not change, I don't know what thing to do bad

pd: happy new YEAR
kaos
Posts: 155
Joined: Tue Aug 12, 2008 8:25 pm
Location: Spain

Post by kaos »

Code: Select all

    fru = camera->getViewFrustum()->getFarRightUp();
    right = fru.X;
    top   = fru.Y;
in the shader

Code: Select all


	// normalize to [-1,1] screen coord
	IN.coord.x = ( IN.coord.x * 2.0 ) /  screen.width - 1.0;
	IN.coord.y = ( IN.coord.y * 2.0 ) / screen.height - 1.0;

	// view-space.z = depth
	view-space.z = depth;

	//normalize depth
	epth = depth / ( far - near );

	//reconstruct position
	view-space.x = IN.coord.x * ( view-space.z / (far-near) ) * right;
	view-space.y = IN.coord.y * ( view-space.z / (far-near) ) * top;

what is wrong?
kaos
Posts: 155
Joined: Tue Aug 12, 2008 8:25 pm
Location: Spain

Post by kaos »

ok, this is my progress but not work, I think that the solution is near. But... ufff

Code: Select all


HFarClip = 2 * tan( fov / 2 ) / far;
WFarClip = HFarClip * aspectratio;

float3 viewray;
IN.coord.x = ( IN.coord.x * 2.0 ) / screeWidth – 1.0;
IN.coord.y = ( IN.coord.y * 2.0 ) / screenHeight – 1.0;
viewray.x =  IN.coord.x * ( WFarClip / 2.0 );
viewray.y = -IN.coord.y * ( HFarClip / 2.0 );
viewray.z = Far;
viewray = normalize(viewray); // normalize viewray
// vertex_position.xyz = a * viewray.xyz; 
// a = vertex_position.z(store in gbuffer) / eye.z
vertex_position.x = ( vertex_position.z / viewray.z ) * viewray.x;
vertex_position.y = ( vertex_position.z / viewray.z ) * viewray.y;

kaos
Posts: 155
Joined: Tue Aug 12, 2008 8:25 pm
Location: Spain

Post by kaos »

Ok, I got it, work fine with 16 bit textures

Code: Select all

	vertex_position.x = depth * WidthFarClip / 2.0 * Coordn.x;
	vertex_position.y = depth * HeightFarClip / 2.0 * Coordn.y;
	vertex_position.z = depth * Far;
Now the problem is with 8 bit textures.

If I store the depth in a8r8g8b8 like 32 bit number

Code: Select all

    mrt.rt2.x = depth;
    mrt.rt2.y = frac( 256.0 * depth );
    mrt.rt2.z = frac( 256.0 * mrt.rt2.y );
    mrt.rt2.w = frac( 256.0 * mrt.rt2.z );

Code: Select all

float4 f = tex2D(position_map,IN.Texcoord1);
float depth = f.x + ( f.y / 256.0 ) + ( f.z / 65536.0 ) + ( f.w / 16777216.0 );
this is the result with the same code

Image

the next code not work

Code: Select all

	vertex_position.x = depth * WidthFarClip / 2.0 * Coordn.x;
	vertex_position.y = depth * HeightFarClip / 2.0 * Coordn.y;
	vertex_position.z = depth * Far;
¿why? With 16 bit texture work fine(store the depth in red(16bit [0,1])), with 32 bit not work .
devsh
Competition winner
Posts: 2049
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

A) because your encoding is wrong
B) because you are storing a floating point value as a 32 bit integer? a 16bit float will be more accurate than a 32 bit integer in some respects
C) You will get worse precision
Post Reply