132 lines
5.5 KiB
HLSL
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
|