VR4Medical/ICI/Library/PackageCache/com.unity.render-pipelines.universal@2b88762731f8/ShaderLibrary/GBufferOutput.hlsl
2025-07-29 13:45:50 +03:00

132 lines
5.5 KiB
HLSL

// This file contains functionality for writing contents of URP GBuffers.
// The functionality provided here is intended to be used during in the material GBuffer pass.
#ifndef UNIVERSAL_GBUFFEROUTPUT_INCLUDED
#define UNIVERSAL_GBUFFEROUTPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#define DECL_SV_TARGET(idx) SV_Target##idx
#define DECL_OPT_GBUFFER_TARGET(type, name, idx) type name : DECL_SV_TARGET(GBUFFER_IDX_AFTER(idx))
// URP GBuffer pass fragment shader output struct.
struct GBufferFragOutput
{
half4 gBuffer0 : SV_Target0;
half4 gBuffer1 : SV_Target1;
half4 gBuffer2 : SV_Target2;
half4 color : SV_Target3; // Camera color attachment, used for GI during GBuffer laydown
#if defined(GBUFFER_FEATURE_DEPTH)
DECL_OPT_GBUFFER_TARGET(float, depth, GBUFFER_IDX_R_DEPTH);
#endif
#if defined(GBUFFER_FEATURE_SHADOWMASK)
DECL_OPT_GBUFFER_TARGET(half4, shadowMask, GBUFFER_IDX_RGBA_SHADOWMASK);
#endif
#if defined(GBUFFER_FEATURE_RENDERING_LAYERS)
DECL_OPT_GBUFFER_TARGET(half4, meshRenderingLayers, GBUFFER_IDX_R_RENDERING_LAYERS);
#endif
};
#undef DECL_SV_TARGET
#undef DECL_OPT_GBUFFER_TARGET
// Pack SurfaceData into GBuffers.
GBufferFragOutput PackGBuffersSurfaceData(SurfaceData surfaceData, InputData inputData, half3 globalIllumination)
{
half3 packedNormalWS = PackGBufferNormal(inputData.normalWS);
uint materialFlags = 0;
// SimpleLit does not use _SPECULARHIGHLIGHTS_OFF to disable specular highlights.
#ifdef _RECEIVE_SHADOWS_OFF
materialFlags |= kMaterialFlagReceiveShadowsOff;
#endif
#if defined(LIGHTMAP_ON) && defined(_MIXED_LIGHTING_SUBTRACTIVE)
materialFlags |= kMaterialFlagSubtractiveMixedLighting;
#endif
GBufferFragOutput output;
output.gBuffer0 = half4(surfaceData.albedo.rgb, PackGBufferMaterialFlags(materialFlags)); // albedo albedo albedo materialFlags (sRGB rendertarget)
output.gBuffer1 = half4(surfaceData.specular.rgb, surfaceData.occlusion); // specular specular specular occlusion
output.gBuffer2 = half4(packedNormalWS, surfaceData.smoothness); // encoded-normal encoded-normal encoded-normal smoothness
output.color = half4(globalIllumination, 1); // GI GI GI unused (lighting buffer)
#if defined(GBUFFER_FEATURE_DEPTH)
output.depth = inputData.positionCS.z;
#endif
#if defined(GBUFFER_FEATURE_SHADOWMASK)
output.shadowMask = inputData.shadowMask; // will have unity_ProbesOcclusion value if subtractive lighting is used (baked)
#endif
#if defined(GBUFFER_FEATURE_RENDERING_LAYERS)
uint renderingLayers = GetMeshRenderingLayer();
output.meshRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0.0, 0.0, 0.0);
#endif
return output;
}
// Pack BRDFData into GBuffers.
GBufferFragOutput PackGBuffersBRDFData(BRDFData brdfData, InputData inputData, half smoothness, half3 globalIllumination, half occlusion = 1.0)
{
half3 packedNormalWS = PackGBufferNormal(inputData.normalWS);
uint materialFlags = 0;
#ifdef _RECEIVE_SHADOWS_OFF
materialFlags |= kMaterialFlagReceiveShadowsOff;
#endif
half3 packedSpecular;
#ifdef _SPECULAR_SETUP
materialFlags |= kMaterialFlagSpecularSetup;
packedSpecular = brdfData.specular.rgb;
#else
packedSpecular.r = brdfData.reflectivity;
packedSpecular.gb = 0.0;
#endif
#ifdef _SPECULARHIGHLIGHTS_OFF
// During the next deferred shading pass, we don't use a shader variant to disable specular calculations.
// Instead, we can either silence specular contribution when writing the gbuffer, and/or reserve a bit in the gbuffer
// and use this during shading to skip computations via dynamic branching. Fastest option depends on platforms.
materialFlags |= kMaterialFlagSpecularHighlightsOff;
packedSpecular = 0.0.xxx;
#endif
#if defined(LIGHTMAP_ON) && defined(_MIXED_LIGHTING_SUBTRACTIVE)
materialFlags |= kMaterialFlagSubtractiveMixedLighting;
#endif
GBufferFragOutput output;
output.gBuffer0 = half4(brdfData.albedo.rgb, PackGBufferMaterialFlags(materialFlags)); // diffuse diffuse diffuse materialFlags (sRGB rendertarget)
output.gBuffer1 = half4(packedSpecular, occlusion); // metallic/specular specular specular occlusion
output.gBuffer2 = half4(packedNormalWS, smoothness); // encoded-normal encoded-normal encoded-normal smoothness
output.color = half4(globalIllumination, 1); // GI GI GI unused (lighting buffer)
#if defined(GBUFFER_FEATURE_DEPTH)
output.depth = inputData.positionCS.z;
#endif
#if defined(GBUFFER_FEATURE_SHADOWMASK)
output.shadowMask = inputData.shadowMask; // will have unity_ProbesOcclusion value if subtractive lighting is used (baked)
#endif
#if defined(GBUFFER_FEATURE_RENDERING_LAYERS)
uint renderingLayers = GetMeshRenderingLayer();
output.meshRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0.0, 0.0, 0.0);
#endif
return output;
}
#endif // UNIVERSAL_GBUFFERUTIL_INCLUDED