- Home /
Mirror reflection & deferred shading
Hi all,
I've been using the MirrorReflection script+shader from Unify, and it worked pretty good until I switched to deferred rendering. Now it seems the objects are not lit anymore (except for the ambient?) in the reflection image. Any idea why? Note that :
- I've force-enabled the "use pixel lights" in the script
- I've got a couple of other render-to-texture which do work with deferred rendering
Thanks,
Ben
Hey, did you ever find a solution for this? I have the same problem and I HAVE TO use Deferred Lighting. Would be great if you answer :)
Answer by Mikkel Gjoel · May 06, 2013 at 02:30 PM
Just to document the technical reason for this issue:
Deferred rendering calculates the world-position as part of lighting the scene. This calculation is based on the depthbuffer of the rendered scene.
The reflection camera uses an oblique projection matrix - skewing the viewfrustum of the reflection-camera in order to create a clipplane at water-level.
As a result, the depth from a reflection cam, is different to the depth of a regular cam, causing wrong positions to be used in the deferred lighting calculations. This causes similar issues with shaders that use the depthbuffer in their rendering as well - e.g. soft-particles, and various post-effects.
A solution would be to use the inverse projection-matrix for depth-reconstruction, but this would make all lighting-calculations in Unity slower.
So far, the best solution is probably to use the forward rendering, and just reduce the number of objects reflected to account for the reduced performance.
Hi. How does the thing with the inverse projection matrix work?
Yes, pretty good but I'd still like to know how the projection matrix works :S
SoBiT - the suggested solution of using the inverse projection-matrix requires modifications to Unity. You could possibly override Internal-PrePassLighting.shader, and set the Inverse Projection $$anonymous$$atrix as a global shader-parameter ( see http://docs.unity3d.com/Documentation/ScriptReference/Shader.SetGlobal$$anonymous$$atrix.html ). $$anonymous$$ind you, I have not really looked into this, let alone tried it, and it would certainly reduce your overall lighting-performance some.
If you need to reconstruct depth during a reflection pass, you can however use the inverse projection matrix for this (probably easiest to just grab Camera.current.cameraToWorld$$anonymous$$atrix ). We have used it to add a post-effect fog, that only adds fog from the water-plane to the reflected objects.
If you need more information about reconstructing the worldspace position from a depthbuffer in general, Google as usual has all the answers: https://www.google.dk/search?q=mjp+worldspace+reconstruction
Answer by ILya84a · Oct 01, 2010 at 02:38 PM
Try this dirty hack:
reflectionCamera.renderingPath = RenderingPath.Forward;
I don't know why there is no way to render reflections with Deferred Lighting ((
I'll have to be carefull with the peformance of that, but at the very least this can be a fallback solution - thanks ILya!
Works for light, but there won't be any shadows in the mirror.
SoBit - forward-shadows can be enabled using the fullforwardshadows keyword (for surface-shaders) - see: http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaders.html . This of course requires using your own shaders.
So I would have to modify all shaders I use in the project?
$$anonymous$$aybe a late answer, but no you only need to put that line for shadows in your mirror shader, so it will draw it over everything it sees in its pass. I was having the same problem while writing my advanced glass shader, I wanted to use differed/forward rendering but altough i adjusted the script, it only worked with ambient, wich sucks balls.