We are implementing a feature that requires objects to tag themselves in the GBuffer during the Base Pass.
To achieve this, we modified the BasePassPixelShader.usf to write Primitive.CustomData into GBuffer.CustomData. Our implementation approach is as follows: We introduced a switch (e.g., a material usage flag) to control this behavior. In the shader, we conditionally declare the necessary macro (e.g., WRITES_CUSTOMDATA_TO_GBUFFER) and set
PIXELSHADEROUTPUT_MRT4=1 (or PIXELSHADEROUTPUT_MRT5, depending on GBUFFER_HAS_VELOCITY). We also ensured the correct render target bindings are set in the pass uniforms. Finally, we fetch the CustomData from GBufferD after the BasePass.
This implementation works correctly for all standard shading models. However, it completely fails for the Unlit shading model.
For Unlit materials, the GBuffer.CustomData output is consistently optimized away, resulting in a value of zero. This occurs even though:
- The translated HLSL shader code shows the correct MRT outputs, including the custom data slot.
- RenderDoc confirms that the binding for the CustomData render target exists.
- As shown in the capture in attachment, a Lit material correctly writes data to GBufferD, while an Unlit material does not, under identical conditions. Furthermore, the disassembled shader instructions do not correspond to the expected logic in the source HLSL.
My questions are:
- What is the recommended way to force the Unlit shading model to write to the GBuffer? Is there a specific pipeline or shader file that overrides the standard BasePass behavior for Unlit?
- Why does this restriction not cause any errors during the material translation process, even though the final compiled shader optimizes the write out?