Deferred shading position reconstruction change

Started by
5 comments, last by csisy 9 years, 7 months ago

Hi,

The position reconstruction is currently working but I want to change it.

I'm using linear depth, so I can easly get an "eye ray" and use it to recostruct the position.

It works for directional lights and point lights if drawn by a fullscreen quad + scissor test. However I want to change the scissor-test-based point light into sphere geometry drawing.

The main problem is that the directional light pass is still drawn by a fullscreen quad and the two different approaches need two different depth value.

Now I'm storing the depth value as (ViewPos.z / FarPlane). It works perfectly if I'm drawing a fullscreen quad in the following way:

- compute view rays from the 4 corner of the far plane

- in the lighting pass simply get the necessary ray and compute world position:

vec3 wPosition = eyePosition + EyeRay * depthVal;

However, if I'd like to draw point lights with sphere, I cannot use the view rays to the far plane. I can only use the world position of the vertex of the sphere then compute a view ray from it. But it's trivial that the depth required to reconstruct world position is not ViewPos.z. It needs length(ViewPos).

I want to use linear depth so I don't want to reconstruct position using the inverseViewProj matrix.

Why I need geometry? For spot lights also + performance.

sorry for my bad english
Advertisement

If you have access to the cameras front vector, then you can do:


// Compute ray from vertex positions 
vec3 eyeRay = normalize( vertexPosition - eyePosition );

// Ray gets shorter towards edges of the screen (due to camera being at center)
// So we need to correct for this.
// Note: this is scaled by the far plane, but the depth can also be scaled (since both get multiplied onto the eyeRay anyway).
float eyeCorrection = rcp( dot( eyeRay, -cameraFront ) ) * farPlaneDist;
eyeRay *= eyeCorrection;

// Final world position
vec3 wPosition = eyePosition + eyeRay * depthVal;

Thanks, I'll try it. :)

What does the rcp function actually do? Rounding, like floor / ceil in C?

sorry for my bad english

Thanks, I'll try it. smile.png

What does the rcp function actually do? Rounding, like floor / ceil in C?

rcp is the reciprocal ( 1 / x ).

note that in shaders this is often a fast approximation (so faster than actually doing 1.0 / x but less accurate).

Thanks, I'll try it. smile.png

What does the rcp function actually do? Rounding, like floor / ceil in C?

rcp is the reciprocal ( 1 / x ).

note that in shaders this is often a fast approximation (so faster than actually doing 1.0 / x but less accurate).

Oh, I'm stupid, it's trivial... :D

Thanks.:)

sorry for my bad english

Tested, works pretty well, thanks! :)

Can I set "accepted solution" to the topic, or just leave it here?

sorry for my bad english

Thanks, I'll try it. smile.png

What does the rcp function actually do? Rounding, like floor / ceil in C?

rcp is the reciprocal ( 1 / x ).

note that in shaders this is often a fast approximation (so faster than actually doing 1.0 / x but less accurate).

I've found that rcp is not in the standard so I'm not using it. In this case, the equation is:


float eyeCorrection = farPlane / dot(eyeRay, -cameraFront);

Shouldn't we prevent division by zero? If the eyeRay == -cameraFront, the dot product will be zero.

However this probably isn't a problem at all, I'm culling front faces (so rendering back faces only) and the only way it could be true if the camera is facing in exactly the opposite direction. Which means the light is culled and not rendered at all.

sorry for my bad english

This topic is closed to new replies.

Advertisement