I want to modify G-Buffer Albedo, but it seems not working like I’m expected, and I can’t get why it works like that.
I started to simplify my code, and now I have a minimal code for reproducing a problem.
My simple code is just clearing G-Buffer Albedo to yellow color.
The core of the code:
In my example, I have a cube with an albedo texture of white dots.
When I turn on my script, I expect to see just yellow cube without any dots because I overwrite albedo to yellow. There is no information in G-Buffer about dots.
But what I see, there is a yellow cube with dots. How is it possible? Is there another one pass after lighting pass or what?
Well, albedo color is also used to compute ambient lighting. Ambient lighting is computed before individual lights are processed. That’s likely what is happening there. Try to set ambient color to black (Window->Lighting->Ambient Source). Or you can try to clear the lighting buffer (GBuffer 3 according to docs). It is logarithmically encoded, so you want to clear it to white to get rid of ambient lighting (and lightmaps/light probes etc).
Thank you. You are right. It’s ambient. Both solutions are working. The second solution (clear GBuffer3) works only if a camera is not HDR.
I want to have deferred decals that overwrite albedo in some places. I do want ambient color is working too. Black ambient is not a solution in this case. How should I handle this?
I’m not very familiar with the way deferred rendering is implemented in Unity. At least not with the details. But generally speaking you have to override all relevant parts of the gbuffer when rendering deferred decals. That means you shouldn’t modify only albedo but also the lighting buffer, normals, specular, roughness etc. Depending on your specific needs. Lighting buffer in Unity contains ambient light, lightmaps, emission etc. Download Standard shader source code from here if you want to know what exactly it contains and how Unity computes it.
I would also used CameraEvent.AfterGBuffer to render your decals, so that all subsequent passes are using final gbuffer.
Thanks for helping, Michal.
I will try to look inside Unity shaders to figure out how it works. Maybe Render Doc could help me also in understanding the render pipeline.
It would be great to hear some words from Unity Tech. graphics engineers.
It doesn’t matter what kind of Camera you use. HDR or not you still have Emission RT. Just little bit different information contains in this RT.
If we look inside of BRDF1_Unity_PBS:
It means we should do something like this for the “yellow” pass to have correct data in RT3. Also, we have UNITY_BRDF_GI…
It’s just craziness to repeat the same things before lighting pass.
Unfortunately, I don’t see a good way to have deferred decals without big render modifications.
Of course, If we want to close eyes on correctness, we could have it.
Thanks. I’ll read that thread.
Deferred Decals from the Unity blog have the same problem as I have. It’s hard to see the problem there because it’s a simple scene and no textures on objects.
So what you’re missing is in that bit of code you posted earlier, and you followed a bit of a red herring following the code as you missed a snippet of code a few lines earlier in that function.
// no analytic lights in this pass
UnityLight dummyLight = DummyLight (s.normalWorld);
half atten = 1;
The result of setting that dummy light, which has a color of zero, is the call to UNITY_BRDF_PBS basically does nothing in most cases and just returns black. So why include it at all? Because in the case of directional specular lightmaps it actually decodes a light direction and color and passes that to the BRDF.
The next line, UNITY_BRDF_GI, then does any additional ambient lighting, like realtime precomputed GI or just light probes depending on the object and your lighting settings.
So the final result is the value “color”, and thus “outEmission” is actually the output of the albedo & specular from the ambient or baked lighting. After the gbuffers have been filled the render target for outEmission remains as the main target for the deferred lights.
So, when you apply your yellow deferred decal, the spots remain as they were already rendered out with the ambient lighting pre-applied to the render texture that ends up being what is rendered to the screen.
You might want to try the frame debugger to see what’s happening better as the scene view dropdown isn’t giving you the “full picture” as it were.