#230136 - 11/12/07 06:59 AM
improving deferred shading
|
Regular Contributor
Registered: 07/11/05
Posts: 277
Loc: Germany
|
i do the following to restore worldspace position for deferred shading: initial pass, vs: vViewPosition = gl_ModelViewMatrix*gl_Vertex; fs: vViewPosition /= vViewPosition.w;
//then i store (-vViewPosition.z) in the MRT deferred lighting pass, fs: // Depth = (-vViewPosition.z) read from MRT
float invTanHalfFOV = 1.0/tan( radians(FOV*0.5) );
vec3 Ray = vec3( ((gl_FragCoord.xy/vec2(Width, Height))-0.5)*2.0, -invTanHalfFOV );
Ray /= invTanHalfFOV;
vec4 Position = vec4( Ray*(Depth), 1.0 ); this works perfectly fine, but requires a floating-point color attachment to store (-vViewPosition.z), but i guess the same should be possible using a depth attachment. i got it working using some hacks, but lost too much precision. any ideas?
|
|
Top
|
|
|
|
#230138 - 11/12/07 08:37 AM
Re: improving deferred shading
[Re: Vexator]
|
Regular Contributor
   
Registered: 01/30/07
Posts: 171
Loc: germany
|
For both problems you should use the simples solution. To calculate the distance from a Z buffer value you have to calculate two values: http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html
depthparameter.x = zFar / ( zFar - zNear )
depthparameter.y = zFar * zNear / ( zNear - zFar )
Don't to that in the shader and use doubles to preserve the precision. Pass both values as uniform vec2 to the lighting shader:
uniform sampler2DRect g_depth;
uniform vec2 DepthParameter;
....
float Z = DepthParameter.y/(DepthParameter.x - texture2DRect(g_depth,gl_FragCoord.xy).r);
The second problem: Your FOV construct looks crazy. A much simpler and faster possibility is that:
varying vec3 unpro;
....
vec3 ModelView = vec3 (unpro.xy/unpro.z * Z,Z);
unpro is the modelview position of the light bounding volume. That can be calculated in the vertex shader with:
ftransform();
unpro = gl_ModelViewMatrix * gl_Vertex;
Draw always convex volumes around the lights (pointlight: Sphere, Spotlight: Cone). A fullscreen quad for a global light can be drawn by unprojecting the nearplane or simpler by drawing a sphere that intersects all frustum sides. (Same position as the camera and disabled Z test) Sometimes it's recommend or required to draw the lightvolume with Frontface culling and glDepthFunc(GL_GREATER); (required if the nearplane is in the light volume)
|
|
Top
|
|
|
|
#230139 - 11/12/07 08:54 AM
Re: improving deferred shading
[Re: Vexator]
|
Regular Contributor
 
Registered: 05/16/01
Posts: 329
|
Why do you divide view space position by view space W per fragment? You should divide in the vertex shader if you expect Wview != 1. And why these complex calculations in the fragment shader if you could just pass in the point on the Z=1 plane through which the ray passes as interpolated coordinates? varying vec2 rayDir;
position = vec3(rayDir * Depth, Depth); this works perfectly fine, but requires a floating-point color attachment to store (-vViewPosition.z), but i guess the same should be possible using a depth attachment. i got it working using some hacks, but lost too much precision. What exactly did you try? Remember that a depth attachment stores window space Z, i.e. (Zclip / Wclip) scaled and biased by the viewport transform.
|
|
Top
|
|
|
|
#230142 - 11/12/07 09:55 AM
Re: improving deferred shading
[Re: oc2k1]
|
Newbie
Registered: 08/27/03
Posts: 45
|
As we speak of deferred shading: Does anybody have an idea how one would use completely different shaders with a deferred shading approach? For example I have a procedural shader for wood, another one for plastic and another one that does anisotropic metall. The only ideas I came up with so far would be a giant switch-like structure in the deferred shading shader (which probably means breaking the instruction limit) or using multipass rendering, one pass for each material, and blending the results. But this doesn´t sound too good to me either.
Are there other ways to work around this limitation of deferred shading?
|
|
Top
|
|
|
|
#230143 - 11/12/07 10:33 AM
Re: improving deferred shading
[Re: CaseMillennium]
|
Regular Contributor
Registered: 07/11/05
Posts: 277
Loc: Germany
|
thanks for your quick replies!
I've just implemented oc2k1's suggestion, and it almost works. the computed position is still dependent on the camera's position/orientation.
is there a way i can do it using a simple fullscreen quad? i don't want to rely on my light hulls, that'd be one potential error source less.
btw near plane is at 1.0, far plane at 100, in case that matters.
thanks you!
@cm: you could use the stencil buffer to mask out geometry that you want to render with another shader.
|
|
Top
|
|
|
|
#230145 - 11/12/07 12:03 PM
Re: improving deferred shading
[Re: Vexator]
|
OpenGL Pro
 
Registered: 09/16/04
Posts: 1402
Loc: Prombaatu
|
As we speak of deferred shading: Does anybody have an idea how one would use completely different shaders with a deferred shading approach? I'm not exactly sure what you mean but it's clear that DS is not without its share of pitfalls and shortcomings. Certainly not a panacea. There's a great chapter in GPU Gems 3 that describes many of the pros, cons, workarounds, etc given varying hw capabilities and so on. Alpha blending (or lack thereof) figures prominently in the cons column.
|
|
Top
|
|
|
|
#230146 - 11/12/07 12:50 PM
Re: improving deferred shading
[Re: Brolingstanz]
|
Regular Contributor
Registered: 07/11/05
Posts: 277
Loc: Germany
|
ok there's definitly something wrong with the way i try to linearize depth.. the first shader reads the distance from the color attachment the way i did it before (see 1st post): void main()
{
float Depth = texture2D(u_DepthTexture, v_Coordinates).r;
gl_FragData[0] = Depth*0.01;
} the 2nd shader reads from a depth map and linearizes it the way oc2k1 suggested: void main()
{
float Depth = texture2D(u_DepthTexture, v_Coordinates).r;
float Z = DepthParameter.y/( DepthParameter.x-Depth );
gl_FragData[0] = (-Z)*0.01;
} :'(
|
|
Top
|
|
|
|
|
25786 Members
13 Forums
54073 Topics
280436 Posts
Max Online: 482 @ 08/11/08 06:19 PM
|
|
|