Deferred Engine Playground - download

Just some nice recources useful for deferred shaders and shading I’ve recently came across again

I have been thinking about large performance optimizations and an obvious one would be to switch to view space normals and lighting.

Right now I’m using z/w depth and world space normals and lighting. This leads to a lot of unnecessary math inside the pixel shaders but is cheaper for the GBuffer setup and CPU.

The way World Space calculations work in a deferred renderer are:

  • transform vertex position with our WorldViewProjection matrix, transform normal with World matrix, save depth from position
  • store world space normals, store z/w depth
  • per light
    +pass the light position and info to shader
    +reconstruct the world position of the current pixel by construcing the ViewProjection Position with the Screen position and the depth from our depth buffer. Then multiply by the inverse viewProjection and end up with world position.
  • calculate vector from light to the world position,
  • this gives us the distance and the direction which we can compare with our Normal (we just read it from the normal buffer)
  • calculate Diffuse/Spec/NdL

The way View Space calculations work in a deferred renderer are:

  • transform vertex position with our WorldViewProjection matrix, transform normal with WorldView matrix, transform vertex position with WorldView and save depth (-> transform the position twice)
  • store world space normals, store depth / farClip (-> linear depth)
  • per light
    +transform the light position to WorldView position
    +pass the light position and info to shader
    +reconstruct the View position of the current pixel by construcing the ViewProjection Position with the Screen position and the depth from our depth buffer. With a ray into the frustum plane at the far end we can get the correct depth.
  • calculate vector from light to the view position,
  • this gives us the distance and the direction which we can compare with our Normal (we just read it from the normal buffer)
  • calculate Diffuse/Spec/NdL

So I’m using the first one.
That’s fine for lighting still, in fact, the precomputation and the savings in the Pixel shader per light average each other out at 1000 lights.

But the inverse Matrix projection for each pixel is not really good when I have a lot of lights.

PLUS

With this approach I have a real linear depth buffer, so screen space ray marching should in theory be easier to realize and understand.
And I could use a 2 component normal buffer, but right now I don’t know what the extra slot would be useful for, so I’d rather avoid the additional encoding/decoding cost.

It would be a pretty big undertaking to switch to view space lighting, basically every shader has to be changed to accomodate for that and the ray marching stuff changes a lot potentially.

Not sure what to do, especially since it works right now, just not hyper fast.

@willmotil
You asked about mesh warping - > check this out

1 Like