testss
This commit is contained in:
@@ -0,0 +1,489 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UnityEditor.Rendering.Universal
|
||||
{
|
||||
[Flags]
|
||||
enum ShaderFeatures
|
||||
{
|
||||
MainLight = (1 << 0),
|
||||
MainLightShadows = (1 << 1),
|
||||
AdditionalLights = (1 << 2),
|
||||
AdditionalLightShadows = (1 << 3),
|
||||
VertexLighting = (1 << 4),
|
||||
SoftShadows = (1 << 5),
|
||||
MixedLighting = (1 << 6),
|
||||
TerrainHoles = (1 << 7),
|
||||
DeferredShading = (1 << 8), // DeferredRenderer is in the list of renderer
|
||||
DeferredWithAccurateGbufferNormals = (1 << 9),
|
||||
DeferredWithoutAccurateGbufferNormals = (1 << 10),
|
||||
ScreenSpaceOcclusion = (1 << 11),
|
||||
ScreenSpaceShadows = (1 << 12),
|
||||
UseFastSRGBLinearConversion = (1 << 13)
|
||||
}
|
||||
|
||||
internal class ShaderPreprocessor : IPreprocessShaders
|
||||
{
|
||||
public static readonly string kPassNameGBuffer = "GBuffer";
|
||||
public static readonly string kTerrainShaderName = "Universal Render Pipeline/Terrain/Lit";
|
||||
#if PROFILE_BUILD
|
||||
private const string k_ProcessShaderTag = "OnProcessShader";
|
||||
#endif
|
||||
// Event callback to report shader stripping info. Form:
|
||||
// ReportShaderStrippingData(Shader shader, ShaderSnippetData data, int currentVariantCount, double strippingTime)
|
||||
internal static event Action<Shader, ShaderSnippetData, int, double> shaderPreprocessed;
|
||||
private static readonly System.Diagnostics.Stopwatch m_stripTimer = new System.Diagnostics.Stopwatch();
|
||||
|
||||
ShaderKeyword m_MainLightShadows = new ShaderKeyword(ShaderKeywordStrings.MainLightShadows);
|
||||
ShaderKeyword m_MainLightShadowsCascades = new ShaderKeyword(ShaderKeywordStrings.MainLightShadowCascades);
|
||||
ShaderKeyword m_MainLightShadowsScreen = new ShaderKeyword(ShaderKeywordStrings.MainLightShadowScreen);
|
||||
ShaderKeyword m_AdditionalLightsVertex = new ShaderKeyword(ShaderKeywordStrings.AdditionalLightsVertex);
|
||||
ShaderKeyword m_AdditionalLightsPixel = new ShaderKeyword(ShaderKeywordStrings.AdditionalLightsPixel);
|
||||
ShaderKeyword m_AdditionalLightShadows = new ShaderKeyword(ShaderKeywordStrings.AdditionalLightShadows);
|
||||
ShaderKeyword m_DeferredAdditionalLightShadows = new ShaderKeyword(ShaderKeywordStrings._DEFERRED_ADDITIONAL_LIGHT_SHADOWS);
|
||||
ShaderKeyword m_CastingPunctualLightShadow = new ShaderKeyword(ShaderKeywordStrings.CastingPunctualLightShadow);
|
||||
ShaderKeyword m_SoftShadows = new ShaderKeyword(ShaderKeywordStrings.SoftShadows);
|
||||
ShaderKeyword m_MixedLightingSubtractive = new ShaderKeyword(ShaderKeywordStrings.MixedLightingSubtractive);
|
||||
ShaderKeyword m_LightmapShadowMixing = new ShaderKeyword(ShaderKeywordStrings.LightmapShadowMixing);
|
||||
ShaderKeyword m_ShadowsShadowMask = new ShaderKeyword(ShaderKeywordStrings.ShadowsShadowMask);
|
||||
ShaderKeyword m_Lightmap = new ShaderKeyword(ShaderKeywordStrings.LIGHTMAP_ON);
|
||||
ShaderKeyword m_DirectionalLightmap = new ShaderKeyword(ShaderKeywordStrings.DIRLIGHTMAP_COMBINED);
|
||||
ShaderKeyword m_AlphaTestOn = new ShaderKeyword(ShaderKeywordStrings._ALPHATEST_ON);
|
||||
ShaderKeyword m_GbufferNormalsOct = new ShaderKeyword(ShaderKeywordStrings._GBUFFER_NORMALS_OCT);
|
||||
ShaderKeyword m_UseDrawProcedural = new ShaderKeyword(ShaderKeywordStrings.UseDrawProcedural);
|
||||
ShaderKeyword m_ScreenSpaceOcclusion = new ShaderKeyword(ShaderKeywordStrings.ScreenSpaceOcclusion);
|
||||
ShaderKeyword m_UseFastSRGBLinearConversion = new ShaderKeyword(ShaderKeywordStrings.UseFastSRGBLinearConversion);
|
||||
|
||||
ShaderKeyword m_LocalDetailMulx2;
|
||||
ShaderKeyword m_LocalDetailScaled;
|
||||
ShaderKeyword m_LocalClearCoat;
|
||||
ShaderKeyword m_LocalClearCoatMap;
|
||||
|
||||
int m_TotalVariantsInputCount;
|
||||
int m_TotalVariantsOutputCount;
|
||||
|
||||
// Multiple callback may be implemented.
|
||||
// The first one executed is the one where callbackOrder is returning the smallest number.
|
||||
public int callbackOrder { get { return 0; } }
|
||||
|
||||
void InitializeLocalShaderKeywords(Shader shader)
|
||||
{
|
||||
m_LocalDetailMulx2 = new ShaderKeyword(shader, ShaderKeywordStrings._DETAIL_MULX2);
|
||||
m_LocalDetailScaled = new ShaderKeyword(shader, ShaderKeywordStrings._DETAIL_SCALED);
|
||||
m_LocalClearCoat = new ShaderKeyword(shader, ShaderKeywordStrings._CLEARCOAT);
|
||||
m_LocalClearCoatMap = new ShaderKeyword(shader, ShaderKeywordStrings._CLEARCOATMAP);
|
||||
}
|
||||
|
||||
bool IsFeatureEnabled(ShaderFeatures featureMask, ShaderFeatures feature)
|
||||
{
|
||||
return (featureMask & feature) != 0;
|
||||
}
|
||||
|
||||
bool StripUnusedPass(ShaderFeatures features, ShaderSnippetData snippetData)
|
||||
{
|
||||
if (snippetData.passType == PassType.Meta)
|
||||
return true;
|
||||
|
||||
if (snippetData.passType == PassType.ShadowCaster)
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.MainLightShadows) && !IsFeatureEnabled(features, ShaderFeatures.AdditionalLightShadows))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StripUnusedFeatures(ShaderFeatures features, Shader shader, ShaderSnippetData snippetData, ShaderCompilerData compilerData)
|
||||
{
|
||||
// strip main light shadows, cascade and screen variants
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.MainLightShadows))
|
||||
{
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadows))
|
||||
return true;
|
||||
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsCascades))
|
||||
return true;
|
||||
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsScreen))
|
||||
return true;
|
||||
|
||||
if (snippetData.passType == PassType.ShadowCaster && !compilerData.shaderKeywordSet.IsEnabled(m_CastingPunctualLightShadow))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.SoftShadows) &&
|
||||
compilerData.shaderKeywordSet.IsEnabled(m_SoftShadows))
|
||||
return true;
|
||||
|
||||
// Left for backward compatibility
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_MixedLightingSubtractive) &&
|
||||
!IsFeatureEnabled(features, ShaderFeatures.MixedLighting))
|
||||
return true;
|
||||
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_UseFastSRGBLinearConversion) &&
|
||||
!IsFeatureEnabled(features, ShaderFeatures.UseFastSRGBLinearConversion))
|
||||
return true;
|
||||
|
||||
// Strip here only if mixed lighting is disabled
|
||||
// No need to check here if actually used by scenes as this taken care by builtin stripper
|
||||
if ((compilerData.shaderKeywordSet.IsEnabled(m_LightmapShadowMixing) ||
|
||||
compilerData.shaderKeywordSet.IsEnabled(m_ShadowsShadowMask)) &&
|
||||
!IsFeatureEnabled(features, ShaderFeatures.MixedLighting))
|
||||
return true;
|
||||
|
||||
|
||||
// No additional light shadows
|
||||
bool isAdditionalLightShadow = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightShadows);
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.AdditionalLightShadows) && isAdditionalLightShadow)
|
||||
return true;
|
||||
|
||||
bool isPunctualLightShadowCasterPass = (snippetData.passType == PassType.ShadowCaster) && compilerData.shaderKeywordSet.IsEnabled(m_CastingPunctualLightShadow);
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.AdditionalLightShadows) && isPunctualLightShadowCasterPass)
|
||||
if (compilerData.shaderCompilerPlatform != ShaderCompilerPlatform.GLES3x) // [Work-around] We do not strip this variant on GLES3 because it could make some scenes crash current Unity GLES3 AndroidPlayer on OnePlus6T - TODO: remove this line once https://issuetracker.unity3d.com/product/unity/issues/guid/1293454/ is fixed
|
||||
return true;
|
||||
|
||||
bool isDeferredAdditionalShadow = compilerData.shaderKeywordSet.IsEnabled(m_DeferredAdditionalLightShadows);
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.AdditionalLightShadows) && isDeferredAdditionalShadow)
|
||||
return true;
|
||||
|
||||
// Additional light are shaded per-vertex or per-pixel.
|
||||
bool isFeaturePerPixelLightingEnabled = IsFeatureEnabled(features, ShaderFeatures.AdditionalLights);
|
||||
bool isFeaturePerVertexLightingEnabled = IsFeatureEnabled(features, ShaderFeatures.VertexLighting);
|
||||
bool isAdditionalLightPerPixel = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsPixel);
|
||||
bool isAdditionalLightPerVertex = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsVertex);
|
||||
|
||||
// Strip if Per-Pixel lighting is NOT used in the project and the
|
||||
// Per-Pixel (_ADDITIONAL_LIGHTS) or additional shadows (_ADDITIONAL_LIGHT_SHADOWS)
|
||||
// variants are enabled in the shader.
|
||||
if (!isFeaturePerPixelLightingEnabled && (isAdditionalLightPerPixel || isAdditionalLightShadow))
|
||||
return true;
|
||||
|
||||
// Strip if Per-Vertex lighting is NOT used in the project and the
|
||||
// Per-Vertex (_ADDITIONAL_LIGHTS_VERTEX) variant is enabled in the shader.
|
||||
if (!isFeaturePerVertexLightingEnabled && isAdditionalLightPerVertex)
|
||||
return true;
|
||||
|
||||
// Screen Space Shadows
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.ScreenSpaceShadows) &&
|
||||
compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsScreen))
|
||||
return true;
|
||||
|
||||
// Screen Space Occlusion
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.ScreenSpaceOcclusion) &&
|
||||
compilerData.shaderKeywordSet.IsEnabled(m_ScreenSpaceOcclusion))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StripUnsupportedVariants(ShaderCompilerData compilerData)
|
||||
{
|
||||
// Dynamic GI is not supported so we can strip variants that have directional lightmap
|
||||
// enabled but not baked lightmap.
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_DirectionalLightmap) &&
|
||||
!compilerData.shaderKeywordSet.IsEnabled(m_Lightmap))
|
||||
return true;
|
||||
|
||||
// As GLES2 has low amount of registers, we strip:
|
||||
if (compilerData.shaderCompilerPlatform == ShaderCompilerPlatform.GLES20)
|
||||
{
|
||||
// VertexID - as GLES2 does not support VertexID that is required for full screen draw procedural pass;
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_UseDrawProcedural))
|
||||
return true;
|
||||
|
||||
// Cascade shadows
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsCascades))
|
||||
return true;
|
||||
|
||||
// Screen space shadows
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsScreen))
|
||||
return true;
|
||||
|
||||
// Detail
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_LocalDetailMulx2) || compilerData.shaderKeywordSet.IsEnabled(m_LocalDetailScaled))
|
||||
return true;
|
||||
|
||||
// Clear Coat
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_LocalClearCoat) || compilerData.shaderKeywordSet.IsEnabled(m_LocalClearCoatMap))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StripInvalidVariants(ShaderCompilerData compilerData)
|
||||
{
|
||||
bool isMainShadowNoCascades = compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadows);
|
||||
bool isMainShadowCascades = compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsCascades);
|
||||
bool isMainShadowScreen = compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsScreen);
|
||||
bool isMainShadow = isMainShadowNoCascades || isMainShadowCascades || isMainShadowScreen;
|
||||
|
||||
bool isAdditionalShadow = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightShadows);
|
||||
if (isAdditionalShadow && !compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsPixel))
|
||||
return true;
|
||||
|
||||
bool isDeferredAdditionalShadow = compilerData.shaderKeywordSet.IsEnabled(m_DeferredAdditionalLightShadows);
|
||||
if (isDeferredAdditionalShadow && !compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsPixel))
|
||||
return true;
|
||||
|
||||
bool isShadowVariant = isMainShadow || isAdditionalShadow || isDeferredAdditionalShadow;
|
||||
if (!isShadowVariant && compilerData.shaderKeywordSet.IsEnabled(m_SoftShadows))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StripUnused(ShaderFeatures features, Shader shader, ShaderSnippetData snippetData, ShaderCompilerData compilerData)
|
||||
{
|
||||
if (StripUnusedFeatures(features, shader, snippetData, compilerData))
|
||||
return true;
|
||||
|
||||
if (StripInvalidVariants(compilerData))
|
||||
return true;
|
||||
|
||||
if (StripUnsupportedVariants(compilerData))
|
||||
return true;
|
||||
|
||||
if (StripUnusedPass(features, snippetData))
|
||||
return true;
|
||||
|
||||
// Strip terrain holes
|
||||
// TODO: checking for the string name here is expensive
|
||||
// maybe we can rename alpha clip keyword name to be specific to terrain?
|
||||
if (compilerData.shaderKeywordSet.IsEnabled(m_AlphaTestOn) &&
|
||||
!IsFeatureEnabled(features, ShaderFeatures.TerrainHoles) &&
|
||||
shader.name.Contains(kTerrainShaderName))
|
||||
return true;
|
||||
|
||||
// TODO: Test against lightMode tag instead.
|
||||
if (snippetData.passName == kPassNameGBuffer)
|
||||
{
|
||||
if (!IsFeatureEnabled(features, ShaderFeatures.DeferredShading))
|
||||
return true;
|
||||
if (IsFeatureEnabled(features, ShaderFeatures.DeferredWithAccurateGbufferNormals) && !compilerData.shaderKeywordSet.IsEnabled(m_GbufferNormalsOct))
|
||||
return true;
|
||||
if (IsFeatureEnabled(features, ShaderFeatures.DeferredWithoutAccurateGbufferNormals) && compilerData.shaderKeywordSet.IsEnabled(m_GbufferNormalsOct))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LogShaderVariants(Shader shader, ShaderSnippetData snippetData, ShaderVariantLogLevel logLevel, int prevVariantsCount, int currVariantsCount)
|
||||
{
|
||||
if (logLevel == ShaderVariantLogLevel.AllShaders || shader.name.Contains("Universal Render Pipeline"))
|
||||
{
|
||||
float percentageCurrent = (float)currVariantsCount / (float)prevVariantsCount * 100f;
|
||||
float percentageTotal = (float)m_TotalVariantsOutputCount / (float)m_TotalVariantsInputCount * 100f;
|
||||
|
||||
string result = string.Format("STRIPPING: {0} ({1} pass) ({2}) -" +
|
||||
" Remaining shader variants = {3}/{4} = {5}% - Total = {6}/{7} = {8}%",
|
||||
shader.name, snippetData.passName, snippetData.shaderType.ToString(), currVariantsCount,
|
||||
prevVariantsCount, percentageCurrent, m_TotalVariantsOutputCount, m_TotalVariantsInputCount,
|
||||
percentageTotal);
|
||||
Debug.Log(result);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnProcessShader(Shader shader, ShaderSnippetData snippetData, IList<ShaderCompilerData> compilerDataList)
|
||||
{
|
||||
#if PROFILE_BUILD
|
||||
Profiler.BeginSample(k_ProcessShaderTag);
|
||||
#endif
|
||||
UniversalRenderPipelineAsset urpAsset = GraphicsSettings.renderPipelineAsset as UniversalRenderPipelineAsset;
|
||||
if (urpAsset == null || compilerDataList == null || compilerDataList.Count == 0)
|
||||
return;
|
||||
|
||||
// Local Keywords need to be initialized with the shader
|
||||
InitializeLocalShaderKeywords(shader);
|
||||
|
||||
m_stripTimer.Start();
|
||||
|
||||
int prevVariantCount = compilerDataList.Count;
|
||||
var inputShaderVariantCount = compilerDataList.Count;
|
||||
for (int i = 0; i < inputShaderVariantCount;)
|
||||
{
|
||||
bool removeInput = StripUnused(ShaderBuildPreprocessor.supportedFeatures, shader, snippetData, compilerDataList[i]);
|
||||
if (removeInput)
|
||||
compilerDataList[i] = compilerDataList[--inputShaderVariantCount];
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
if (compilerDataList is List<ShaderCompilerData> inputDataList)
|
||||
inputDataList.RemoveRange(inputShaderVariantCount, inputDataList.Count - inputShaderVariantCount);
|
||||
else
|
||||
{
|
||||
for (int i = compilerDataList.Count - 1; i >= inputShaderVariantCount; --i)
|
||||
compilerDataList.RemoveAt(i);
|
||||
}
|
||||
|
||||
if (urpAsset.shaderVariantLogLevel != ShaderVariantLogLevel.Disabled)
|
||||
{
|
||||
m_TotalVariantsInputCount += prevVariantCount;
|
||||
m_TotalVariantsOutputCount += compilerDataList.Count;
|
||||
LogShaderVariants(shader, snippetData, urpAsset.shaderVariantLogLevel, prevVariantCount, compilerDataList.Count);
|
||||
}
|
||||
m_stripTimer.Stop();
|
||||
double stripTimeMs = m_stripTimer.Elapsed.TotalMilliseconds;
|
||||
m_stripTimer.Reset();
|
||||
|
||||
#if PROFILE_BUILD
|
||||
Profiler.EndSample();
|
||||
#endif
|
||||
shaderPreprocessed?.Invoke(shader, snippetData, prevVariantCount, stripTimeMs);
|
||||
}
|
||||
}
|
||||
class ShaderBuildPreprocessor : IPreprocessBuildWithReport
|
||||
#if PROFILE_BUILD
|
||||
, IPostprocessBuildWithReport
|
||||
#endif
|
||||
{
|
||||
public static ShaderFeatures supportedFeatures
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_supportedFeatures <= 0)
|
||||
{
|
||||
FetchAllSupportedFeatures();
|
||||
}
|
||||
return _supportedFeatures;
|
||||
}
|
||||
}
|
||||
|
||||
private static ShaderFeatures _supportedFeatures = 0;
|
||||
public int callbackOrder { get { return 0; } }
|
||||
#if PROFILE_BUILD
|
||||
public void OnPostprocessBuild(BuildReport report)
|
||||
{
|
||||
Profiler.enabled = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
FetchAllSupportedFeatures();
|
||||
#if PROFILE_BUILD
|
||||
Profiler.enableBinaryLog = true;
|
||||
Profiler.logFile = "profilerlog.raw";
|
||||
Profiler.enabled = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void FetchAllSupportedFeatures()
|
||||
{
|
||||
List<UniversalRenderPipelineAsset> urps = new List<UniversalRenderPipelineAsset>();
|
||||
urps.Add(GraphicsSettings.defaultRenderPipeline as UniversalRenderPipelineAsset);
|
||||
for (int i = 0; i < QualitySettings.names.Length; i++)
|
||||
{
|
||||
urps.Add(QualitySettings.GetRenderPipelineAssetAt(i) as UniversalRenderPipelineAsset);
|
||||
}
|
||||
|
||||
// Must reset flags.
|
||||
_supportedFeatures = 0;
|
||||
foreach (UniversalRenderPipelineAsset urp in urps)
|
||||
{
|
||||
if (urp != null)
|
||||
{
|
||||
_supportedFeatures |= GetSupportedShaderFeatures(urp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipelineAsset pipelineAsset)
|
||||
{
|
||||
ShaderFeatures shaderFeatures;
|
||||
shaderFeatures = ShaderFeatures.MainLight;
|
||||
|
||||
if (pipelineAsset.supportsMainLightShadows)
|
||||
shaderFeatures |= ShaderFeatures.MainLightShadows;
|
||||
|
||||
if (pipelineAsset.additionalLightsRenderingMode == LightRenderingMode.PerVertex)
|
||||
{
|
||||
shaderFeatures |= ShaderFeatures.VertexLighting;
|
||||
}
|
||||
else if (pipelineAsset.additionalLightsRenderingMode == LightRenderingMode.PerPixel)
|
||||
{
|
||||
shaderFeatures |= ShaderFeatures.AdditionalLights;
|
||||
|
||||
if (pipelineAsset.supportsAdditionalLightShadows)
|
||||
shaderFeatures |= ShaderFeatures.AdditionalLightShadows;
|
||||
}
|
||||
|
||||
bool anyShadows = pipelineAsset.supportsMainLightShadows ||
|
||||
(shaderFeatures & ShaderFeatures.AdditionalLightShadows) != 0;
|
||||
if (pipelineAsset.supportsSoftShadows && anyShadows)
|
||||
shaderFeatures |= ShaderFeatures.SoftShadows;
|
||||
|
||||
if (pipelineAsset.supportsMixedLighting)
|
||||
shaderFeatures |= ShaderFeatures.MixedLighting;
|
||||
|
||||
if (pipelineAsset.supportsTerrainHoles)
|
||||
shaderFeatures |= ShaderFeatures.TerrainHoles;
|
||||
|
||||
if (pipelineAsset.useFastSRGBLinearConversion)
|
||||
shaderFeatures |= ShaderFeatures.UseFastSRGBLinearConversion;
|
||||
|
||||
bool hasScreenSpaceShadows = false;
|
||||
bool hasScreenSpaceOcclusion = false;
|
||||
bool hasDeferredRenderer = false;
|
||||
bool withAccurateGbufferNormals = false;
|
||||
bool withoutAccurateGbufferNormals = false;
|
||||
|
||||
int rendererCount = pipelineAsset.m_RendererDataList.Length;
|
||||
for (int rendererIndex = 0; rendererIndex < rendererCount; ++rendererIndex)
|
||||
{
|
||||
ScriptableRenderer renderer = pipelineAsset.GetRenderer(rendererIndex);
|
||||
if (renderer is ForwardRenderer)
|
||||
{
|
||||
ForwardRenderer forwardRenderer = (ForwardRenderer)renderer;
|
||||
if (forwardRenderer.renderingMode == RenderingMode.Deferred)
|
||||
{
|
||||
hasDeferredRenderer |= true;
|
||||
withAccurateGbufferNormals |= forwardRenderer.accurateGbufferNormals;
|
||||
withoutAccurateGbufferNormals |= !forwardRenderer.accurateGbufferNormals;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for Screen Space Ambient Occlusion Renderer Feature
|
||||
ScriptableRendererData rendererData = pipelineAsset.m_RendererDataList[rendererIndex];
|
||||
if (rendererData != null)
|
||||
{
|
||||
for (int rendererFeatureIndex = 0; rendererFeatureIndex < rendererData.rendererFeatures.Count; rendererFeatureIndex++)
|
||||
{
|
||||
ScriptableRendererFeature rendererFeature = rendererData.rendererFeatures[rendererFeatureIndex];
|
||||
|
||||
ScreenSpaceShadows ssshadows = rendererFeature as ScreenSpaceShadows;
|
||||
hasScreenSpaceShadows |= ssshadows != null;
|
||||
|
||||
ScreenSpaceAmbientOcclusion ssao = rendererFeature as ScreenSpaceAmbientOcclusion;
|
||||
hasScreenSpaceOcclusion |= ssao != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDeferredRenderer)
|
||||
shaderFeatures |= ShaderFeatures.DeferredShading;
|
||||
|
||||
// We can only strip accurateGbufferNormals related variants if all DeferredRenderers use the same option.
|
||||
if (withAccurateGbufferNormals && !withoutAccurateGbufferNormals)
|
||||
shaderFeatures |= ShaderFeatures.DeferredWithAccurateGbufferNormals;
|
||||
|
||||
if (!withAccurateGbufferNormals && withoutAccurateGbufferNormals)
|
||||
shaderFeatures |= ShaderFeatures.DeferredWithoutAccurateGbufferNormals;
|
||||
|
||||
if (hasScreenSpaceShadows)
|
||||
shaderFeatures |= ShaderFeatures.ScreenSpaceShadows;
|
||||
|
||||
if (hasScreenSpaceOcclusion)
|
||||
shaderFeatures |= ShaderFeatures.ScreenSpaceOcclusion;
|
||||
|
||||
return shaderFeatures;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user