I try to really understand the deferred shading pipeline and its implementation.
The manual says:
G-buffer Pass: objects are rendered to produce screen-space buffers with diffuse color, specular color, smoothness, world space normal, emission and depth.
Lighting pass: the previously generated buffers are used to add lighting into emission buffer.
I was browsing the source code for the standard shader and found the deferred pass, where all the buffers are filled (UnityStandardCore.cginc):
void fragDeferred (
VertexOutputDeferred i,
out half4 outDiffuse : SV_Target0,
out half4 outSpecSmoothness : SV_Target1,
out half4 outNormal : SV_Target2,
out half4 outEmission : SV_Target3
)
{
// etc.
I don’t understand BDRF too much so I can’t say much about it, but I do know that the data needed for the reflections is view-dependent, which means you need to know from what direction you are looking at the surface. this view direction needs to be calculated per-pixel, which is why you see it in the fragment shader, but it does not need to be calculated per light, so it would be a waste to calculate it in the lighting pass.
The lighting pass seems to be done in the “Internal-DeferredShading.shader”. World position (which can be used to calculate the eye vector) is calculated here:
// read depth and reconstruct world position
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
depth = Linear01Depth (depth);
float4 vpos = float4(i.ray * depth,1);
float3 wpos = mul (_CameraToWorld, vpos).xyz;