forked from BilalY/Rasagar
307 lines
15 KiB
C#
307 lines
15 KiB
C#
|
using UnityEngine;
|
||
|
using UnityEngine.Rendering;
|
||
|
using UnityEngine.Rendering.HighDefinition;
|
||
|
|
||
|
namespace UnityEditor.Rendering.HighDefinition
|
||
|
{
|
||
|
// The common shader stripper function
|
||
|
class CommonShaderPreprocessor : BaseShaderPreprocessor
|
||
|
{
|
||
|
public override int Priority => 100;
|
||
|
private HDRenderPipelineRuntimeShaders m_ShaderResources;
|
||
|
private HDRenderPipelineRuntimeMaterials m_MaterialResources;
|
||
|
|
||
|
public CommonShaderPreprocessor()
|
||
|
{
|
||
|
m_ShaderResources = HDRPBuildData.instance.runtimeShaders;
|
||
|
m_MaterialResources = HDRPBuildData.instance.materialResources;
|
||
|
}
|
||
|
|
||
|
protected override bool DoShadersStripper(HDRenderPipelineAsset hdrpAsset, Shader shader, ShaderSnippetData snippet, ShaderCompilerData inputData)
|
||
|
{
|
||
|
bool stripDebugVariants = HDRPBuildData.instance.stripDebugVariants;
|
||
|
|
||
|
// CAUTION: Pass Name and Lightmode name must match in master node and .shader.
|
||
|
// HDRP use LightMode to do drawRenderer and pass name is use here for stripping!
|
||
|
var settings = hdrpAsset.currentPlatformRenderPipelineSettings;
|
||
|
|
||
|
// Remove water if disabled
|
||
|
if (!settings.supportWater)
|
||
|
{
|
||
|
if (shader == m_ShaderResources.opaqueAtmosphericScatteringPS)
|
||
|
{
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_SupportWater) ||
|
||
|
inputData.shaderKeywordSet.IsEnabled(m_SupportWaterCaustics) ||
|
||
|
inputData.shaderKeywordSet.IsEnabled(m_SupportWaterCausticsShadow))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_SupportWaterAbsorption))
|
||
|
return true;
|
||
|
|
||
|
if (stripDebugVariants && snippet.passName.StartsWith(WaterSystem.k_WaterDebugPass))
|
||
|
return true;
|
||
|
}
|
||
|
if (HDRPBuildData.instance.waterDecalMaskAndCurrent)
|
||
|
{
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_WaterDecalPartial))
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_WaterDecalComplete))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// If Screen Space Lens Flare is disabled, strip all the shaders
|
||
|
if (!settings.supportScreenSpaceLensFlare)
|
||
|
{
|
||
|
if (shader == m_ShaderResources.lensFlareScreenSpacePS)
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// If Data Driven Lens Flare is disabled, strip all the shaders (the preview shader LensFlareDataDrivenPreview.shader in Core will not be stripped)
|
||
|
if (!settings.supportDataDrivenLensFlare)
|
||
|
{
|
||
|
if (shader == m_ShaderResources.lensFlareDataDrivenPS)
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// Remove editor only pass
|
||
|
bool isSceneSelectionPass = snippet.passName == "SceneSelectionPass";
|
||
|
bool isScenePickingPass = snippet.passName == "ScenePickingPass";
|
||
|
bool metaPassUnused = (snippet.passName == "META") && (SupportedRenderingFeatures.active.enlighten == false ||
|
||
|
((int)SupportedRenderingFeatures.active.lightmapBakeTypes | (int)LightmapBakeType.Realtime) == 0);
|
||
|
bool editorVisualization = inputData.shaderKeywordSet.IsEnabled(m_EditorVisualization);
|
||
|
if (isSceneSelectionPass || isScenePickingPass || metaPassUnused || editorVisualization)
|
||
|
return true;
|
||
|
|
||
|
// CAUTION: We can't identify transparent material in the stripped in a general way.
|
||
|
// Shader Graph don't produce any keyword - However it will only generate the pass that are required, so it already handle transparent (Note that shader Graph still define _SURFACE_TYPE_TRANSPARENT but as a #define)
|
||
|
// For inspector version of shader, we identify transparent with a shader feature _SURFACE_TYPE_TRANSPARENT.
|
||
|
// Only our Lit (and inherited) shader use _SURFACE_TYPE_TRANSPARENT, so the specific stripping based on this keyword is in LitShadePreprocessor.
|
||
|
// Here we can't strip based on opaque or transparent but we will strip based on HDRP Asset configuration.
|
||
|
|
||
|
bool isMotionPass = snippet.passName == "MotionVectors";
|
||
|
if (isMotionPass && !settings.supportMotionVectors)
|
||
|
return true;
|
||
|
|
||
|
bool isDistortionPass = snippet.passName == "DistortionVectors";
|
||
|
if (isDistortionPass && !settings.supportDistortion)
|
||
|
return true;
|
||
|
|
||
|
bool isTransparentBackface = snippet.passName == "TransparentBackface";
|
||
|
if (isTransparentBackface && !settings.supportTransparentBackface)
|
||
|
return true;
|
||
|
|
||
|
bool isTransparentPrepass = snippet.passName == "TransparentDepthPrepass";
|
||
|
if (isTransparentPrepass && !settings.supportTransparentDepthPrepass)
|
||
|
return true;
|
||
|
|
||
|
bool isTransparentPostpass = snippet.passName == "TransparentDepthPostpass";
|
||
|
if (isTransparentPostpass && !settings.supportTransparentDepthPostpass)
|
||
|
return true;
|
||
|
|
||
|
bool isRayTracingPrepass = snippet.passName == "RayTracingPrepass";
|
||
|
if (isRayTracingPrepass && !settings.supportRayTracing)
|
||
|
return true;
|
||
|
|
||
|
// If requested by the render pipeline settings, or if we are in a release build,
|
||
|
// don't compile fullscreen debug display variant
|
||
|
bool isFullScreenDebugPass = snippet.passName == "FullScreenDebug";
|
||
|
if (isFullScreenDebugPass && stripDebugVariants)
|
||
|
return true;
|
||
|
|
||
|
// Debug Display shader is currently the longest shader to compile, so we allow users to disable it at runtime.
|
||
|
// We also don't want it in release build.
|
||
|
// However our AOV API rely on several debug display shader. In case AOV API is requested at runtime (like for the Graphics Compositor)
|
||
|
// we allow user to make explicit request for it and it bypass other request
|
||
|
if (stripDebugVariants && !settings.supportRuntimeAOVAPI)
|
||
|
{
|
||
|
if (shader == m_ShaderResources.debugDisplayLatlongPS ||
|
||
|
shader == m_ShaderResources.debugViewMaterialGBufferPS ||
|
||
|
shader == m_ShaderResources.debugViewTilesPS ||
|
||
|
shader == m_ShaderResources.debugFullScreenPS ||
|
||
|
shader == m_ShaderResources.debugColorPickerPS ||
|
||
|
shader == m_ShaderResources.debugExposurePS ||
|
||
|
shader == m_ShaderResources.debugHDRPS ||
|
||
|
shader == m_ShaderResources.debugLightVolumePS ||
|
||
|
shader == m_ShaderResources.debugBlitQuad ||
|
||
|
shader == m_ShaderResources.debugViewVirtualTexturingBlit ||
|
||
|
shader == m_ShaderResources.debugWaveformPS ||
|
||
|
shader == m_ShaderResources.debugVectorscopePS ||
|
||
|
shader == m_ShaderResources.debugLocalVolumetricFogAtlasPS)
|
||
|
return true;
|
||
|
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_DebugDisplay))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_WriteMSAADepth) && (settings.supportedLitShaderMode == RenderPipelineSettings.SupportedLitShaderMode.DeferredOnly))
|
||
|
return true;
|
||
|
|
||
|
if (!settings.supportSubsurfaceScattering)
|
||
|
{
|
||
|
if (shader == m_ShaderResources.combineLightingPS)
|
||
|
return true;
|
||
|
// Note that this is only going to affect the deferred shader and for a debug case, so it won't save much.
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_SubsurfaceScattering))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (!settings.lightLoopSettings.supportFabricConvolution)
|
||
|
{
|
||
|
if (shader == m_ShaderResources.charlieConvolvePS)
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_Transparent))
|
||
|
{
|
||
|
// If transparent we don't need the depth only pass
|
||
|
bool isDepthOnlyPass = snippet.passName == "DepthForwardOnly";
|
||
|
if (isDepthOnlyPass)
|
||
|
return true;
|
||
|
|
||
|
// If transparent we don't need the motion vector pass
|
||
|
if (isMotionPass)
|
||
|
return true;
|
||
|
|
||
|
// If we are transparent we use cluster lighting and not tile lighting
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_TileLighting))
|
||
|
return true;
|
||
|
}
|
||
|
else // Opaque
|
||
|
{
|
||
|
// If opaque, we never need transparent specific passes (even in forward only mode)
|
||
|
bool isTransparentForwardPass = isTransparentPostpass || isTransparentBackface || isTransparentPrepass || isDistortionPass;
|
||
|
if (isTransparentForwardPass)
|
||
|
return true;
|
||
|
|
||
|
// TODO: Should we remove Cluster version if we know MSAA is disabled ? This prevent to manipulate LightLoop Settings (useFPTL option)
|
||
|
// For now comment following code
|
||
|
// if (inputData.shaderKeywordSet.IsEnabled(m_ClusterLighting) && !hdrpAsset.currentPlatformRenderPipelineSettings.supportMSAA)
|
||
|
// return true;
|
||
|
}
|
||
|
|
||
|
// SHADOW
|
||
|
|
||
|
// Strip every useless shadow configs
|
||
|
var shadowInitParams = settings.hdShadowInitParams;
|
||
|
|
||
|
foreach (var shadowVariant in m_ShadowKeywords.PunctualShadowVariants)
|
||
|
{
|
||
|
if (shadowVariant.Key != shadowInitParams.punctualShadowFilteringQuality)
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(shadowVariant.Value))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
foreach (var shadowVariant in m_ShadowKeywords.DirectionalShadowVariants)
|
||
|
{
|
||
|
if (shadowVariant.Key != shadowInitParams.directionalShadowFilteringQuality)
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(shadowVariant.Value))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
foreach (var areaShadowVariant in m_ShadowKeywords.AreaShadowVariants)
|
||
|
{
|
||
|
if (areaShadowVariant.Key != shadowInitParams.areaShadowFilteringQuality)
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(areaShadowVariant.Value))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (!shadowInitParams.supportScreenSpaceShadows && shader == m_ShaderResources.screenSpaceShadowPS)
|
||
|
return true;
|
||
|
|
||
|
// Screen space shadow variant is exclusive, either we have a variant with dynamic if that support screen space shadow or not
|
||
|
// either we have a variant that don't support at all. We can't have both at the same time.
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_ScreenSpaceShadowOFFKeywords) && shadowInitParams.supportScreenSpaceShadows)
|
||
|
return true;
|
||
|
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_ScreenSpaceShadowONKeywords) && !shadowInitParams.supportScreenSpaceShadows)
|
||
|
return true;
|
||
|
|
||
|
// DECAL
|
||
|
|
||
|
// Rendering layers and decal layers output to the same buffer
|
||
|
// Difference is that decal layers need also geometric normals, and rendering layers ignore _DISABLE_DECALS
|
||
|
// To reduce variants, we assume that enabling rendering layers will always enable decal layers, so we have 3 modes:
|
||
|
// - All off
|
||
|
// - Output layers and normal for relevant materials
|
||
|
// - Output layers and normals for everyone. (But if decal are disabled, buffer is only 16 bits so we don't write normals)
|
||
|
if (settings.renderingLayerMaskBuffer)
|
||
|
{
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_WriteDecalBuffer))
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_WriteRenderingLayer))
|
||
|
return true;
|
||
|
// If we don't require the rendering layers, strip the decal prepass variant when decals are disabled
|
||
|
if ((inputData.shaderKeywordSet.IsEnabled(m_WriteDecalBuffer) || inputData.shaderKeywordSet.IsEnabled(m_WriteDecalBufferAndRenderingLayer)) &&
|
||
|
!(settings.supportDecals && settings.supportDecalLayers))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// If decal support, remove unused variant
|
||
|
if (settings.supportDecals)
|
||
|
{
|
||
|
// Remove the no decal case
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_DecalsOFF))
|
||
|
return true;
|
||
|
|
||
|
// If decal but with 4RT remove 3RT variant and vice versa for both Material and Decal Material
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_Decals3RT) && settings.decalSettings.perChannelMask)
|
||
|
return true;
|
||
|
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_Decals4RT) && !settings.decalSettings.perChannelMask)
|
||
|
return true;
|
||
|
|
||
|
// Remove the surface gradient blending if not enabled
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_DecalSurfaceGradient) && !settings.supportSurfaceGradient)
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Strip if it is a decal pass
|
||
|
bool isDBufferMesh = snippet.passName == "DBufferMesh";
|
||
|
bool isDecalMeshForwardEmissive = snippet.passName == "DecalMeshForwardEmissive";
|
||
|
bool isDBufferProjector = snippet.passName == "DBufferProjector";
|
||
|
bool isDecalProjectorForwardEmissive = snippet.passName == "DecalProjectorForwardEmissive";
|
||
|
bool isAtlasProjector = snippet.passName == "AtlasProjector";
|
||
|
if (isDBufferMesh || isDecalMeshForwardEmissive || isDBufferProjector || isDecalProjectorForwardEmissive || isAtlasProjector)
|
||
|
return true;
|
||
|
|
||
|
// If no decal support, remove decal variant
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_Decals3RT) || inputData.shaderKeywordSet.IsEnabled(m_Decals4RT))
|
||
|
return true;
|
||
|
|
||
|
// Remove the surface gradient blending
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_DecalSurfaceGradient))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// Global Illumination
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_ProbeVolumesL1) &&
|
||
|
(!settings.supportProbeVolume || settings.probeVolumeSHBands != ProbeVolumeSHBands.SphericalHarmonicsL1))
|
||
|
return true;
|
||
|
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_ProbeVolumesL2) &&
|
||
|
(!settings.supportProbeVolume || settings.probeVolumeSHBands != ProbeVolumeSHBands.SphericalHarmonicsL2))
|
||
|
return true;
|
||
|
|
||
|
#if !ENABLE_SENSOR_SDK
|
||
|
// If the SensorSDK package is not present, make sure that all code related to it is stripped away
|
||
|
if (inputData.shaderKeywordSet.IsEnabled(m_SensorEnableLidar) || inputData.shaderKeywordSet.IsEnabled(m_SensorOverrideReflectance))
|
||
|
return true;
|
||
|
#endif
|
||
|
|
||
|
// HDR Output
|
||
|
if (!HDROutputUtils.IsShaderVariantValid(inputData.shaderKeywordSet, PlayerSettings.allowHDRDisplaySupport))
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|