123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- using System;
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEditor.Build;
- using UnityEngine;
- using UnityEngine.Rendering.Universal;
- using UnityEngine.Rendering;
- namespace UnityEditor.Rendering.Universal
- {
- internal class ShaderPreprocessor : IPreprocessShaders
- {
- [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)
- }
- ShaderKeyword m_MainLightShadows = new ShaderKeyword(ShaderKeywordStrings.MainLightShadows);
- ShaderKeyword m_AdditionalLightsVertex = new ShaderKeyword(ShaderKeywordStrings.AdditionalLightsVertex);
- ShaderKeyword m_AdditionalLightsPixel = new ShaderKeyword(ShaderKeywordStrings.AdditionalLightsPixel);
- ShaderKeyword m_AdditionalLightShadows = new ShaderKeyword(ShaderKeywordStrings.AdditionalLightShadows);
- ShaderKeyword m_CascadeShadows = new ShaderKeyword(ShaderKeywordStrings.MainLightShadowCascades);
- ShaderKeyword m_SoftShadows = new ShaderKeyword(ShaderKeywordStrings.SoftShadows);
- ShaderKeyword m_MixedLightingSubtractive = new ShaderKeyword(ShaderKeywordStrings.MixedLightingSubtractive);
- ShaderKeyword m_Lightmap = new ShaderKeyword("LIGHTMAP_ON");
- ShaderKeyword m_DirectionalLightmap = new ShaderKeyword("DIRLIGHTMAP_COMBINED");
- ShaderKeyword m_AlphaTestOn = new ShaderKeyword("_ALPHATEST_ON");
- ShaderKeyword m_DeprecatedVertexLights = new ShaderKeyword("_VERTEX_LIGHTS");
- ShaderKeyword m_DeprecatedShadowsEnabled = new ShaderKeyword("_SHADOWS_ENABLED");
- ShaderKeyword m_DeprecatedShadowsCascade = new ShaderKeyword("_SHADOWS_CASCADE");
- ShaderKeyword m_DeprecatedLocalShadowsEnabled = new ShaderKeyword("_LOCAL_SHADOWS_ENABLED");
- 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; } }
- bool StripUnusedShader(ShaderFeatures features, Shader shader, ShaderCompilerData compilerData)
- {
- if (!CoreUtils.HasFlag(features, ShaderFeatures.MainLightShadows) &&
- shader.name.Contains("ScreenSpaceShadows"))
- return true;
- return false;
- }
- bool StripUnusedPass(ShaderFeatures features, ShaderSnippetData snippetData)
- {
- if (snippetData.passType == PassType.Meta)
- return true;
- if (snippetData.passType == PassType.ShadowCaster)
- if (!CoreUtils.HasFlag(features, ShaderFeatures.MainLightShadows) && !CoreUtils.HasFlag(features, ShaderFeatures.AdditionalLightShadows))
- return true;
- return false;
- }
- bool StripUnusedFeatures(ShaderFeatures features, Shader shader, ShaderCompilerData compilerData)
- {
- // strip main light shadows and cascade variants
- if (!CoreUtils.HasFlag(features, ShaderFeatures.MainLightShadows))
- {
- if (compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadows))
- return true;
- if (compilerData.shaderKeywordSet.IsEnabled(m_CascadeShadows))
- return true;
- }
- bool isAdditionalLightPerVertex = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsVertex);
- bool isAdditionalLightPerPixel = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsPixel);
- bool isAdditionalLightShadow = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightShadows);
- // Additional light are shaded per-vertex. Strip additional lights per-pixel and shadow variants
- if (CoreUtils.HasFlag(features, ShaderFeatures.VertexLighting) &&
- (isAdditionalLightPerPixel || isAdditionalLightShadow))
- return true;
- // No additional lights
- if (!CoreUtils.HasFlag(features, ShaderFeatures.AdditionalLights) &&
- (isAdditionalLightPerPixel || isAdditionalLightPerVertex || isAdditionalLightShadow))
- return true;
- // No additional light shadows
- if (!CoreUtils.HasFlag(features, ShaderFeatures.AdditionalLightShadows) && isAdditionalLightShadow)
- return true;
- if (!CoreUtils.HasFlag(features, ShaderFeatures.SoftShadows) &&
- compilerData.shaderKeywordSet.IsEnabled(m_SoftShadows))
- return true;
- if (compilerData.shaderKeywordSet.IsEnabled(m_MixedLightingSubtractive) &&
- !CoreUtils.HasFlag(features, ShaderFeatures.MixedLighting))
- return true;
- bool isBuiltInTerrainLit = shader.name.Contains("Universal Render Pipeline/Terrain/Lit");
- if (isBuiltInTerrainLit && compilerData.shaderKeywordSet.IsEnabled(m_AlphaTestOn) &&
- !CoreUtils.HasFlag(features, ShaderFeatures.TerrainHoles))
- 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;
- if (compilerData.shaderCompilerPlatform == ShaderCompilerPlatform.GLES20)
- {
- if (compilerData.shaderKeywordSet.IsEnabled(m_CascadeShadows))
- return true;
- }
- return false;
- }
- bool StripInvalidVariants(ShaderCompilerData compilerData)
- {
- bool isMainShadow = compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadows);
- bool isAdditionalShadow = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightShadows);
- bool isShadowVariant = isMainShadow || isAdditionalShadow;
- if (!isMainShadow && compilerData.shaderKeywordSet.IsEnabled(m_CascadeShadows))
- return true;
- if (!isShadowVariant && compilerData.shaderKeywordSet.IsEnabled(m_SoftShadows))
- return true;
- if (isAdditionalShadow && !compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsPixel))
- return true;
- return false;
- }
- bool StripDeprecated(ShaderCompilerData compilerData)
- {
- if (compilerData.shaderKeywordSet.IsEnabled(m_DeprecatedVertexLights))
- return true;
- if (compilerData.shaderKeywordSet.IsEnabled(m_DeprecatedShadowsCascade))
- return true;
- if (compilerData.shaderKeywordSet.IsEnabled(m_DeprecatedShadowsEnabled))
- return true;
- if (compilerData.shaderKeywordSet.IsEnabled(m_DeprecatedLocalShadowsEnabled))
- return true;
- return false;
- }
- bool StripUnused(ShaderFeatures features, Shader shader, ShaderSnippetData snippetData, ShaderCompilerData compilerData)
- {
- if (StripUnusedShader(features, shader, compilerData))
- return true;
- if (StripUnusedPass(features, snippetData))
- return true;
- if (StripUnusedFeatures(features, shader, compilerData))
- return true;
- if (StripUnsupportedVariants(compilerData))
- return true;
- if (StripInvalidVariants(compilerData))
- return true;
- if (StripDeprecated(compilerData))
- 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)
- {
- UniversalRenderPipelineAsset urpAsset = GraphicsSettings.renderPipelineAsset as UniversalRenderPipelineAsset;
- if (urpAsset == null || compilerDataList == null || compilerDataList.Count == 0)
- return;
- ShaderFeatures features = GetSupportedShaderFeatures(urpAsset);
- int prevVariantCount = compilerDataList.Count;
- for (int i = 0; i < compilerDataList.Count; ++i)
- {
- if (StripUnused(features, shader, snippetData, compilerDataList[i]))
- {
- compilerDataList.RemoveAt(i);
- --i;
- }
- }
- if (urpAsset.shaderVariantLogLevel != ShaderVariantLogLevel.Disabled)
- {
- m_TotalVariantsInputCount += prevVariantCount;
- m_TotalVariantsOutputCount += compilerDataList.Count;
- LogShaderVariants(shader, snippetData, urpAsset.shaderVariantLogLevel, prevVariantCount, compilerDataList.Count);
- }
- }
- ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipelineAsset pipelineAsset)
- {
- ShaderFeatures shaderFeatures;
- shaderFeatures = ShaderFeatures.MainLight;
- if (pipelineAsset.supportsMainLightShadows)
- shaderFeatures |= ShaderFeatures.MainLightShadows;
- if (pipelineAsset.additionalLightsRenderingMode == LightRenderingMode.PerVertex)
- {
- shaderFeatures |= ShaderFeatures.AdditionalLights;
- shaderFeatures |= ShaderFeatures.VertexLighting;
- }
- else if (pipelineAsset.additionalLightsRenderingMode == LightRenderingMode.PerPixel)
- {
- shaderFeatures |= ShaderFeatures.AdditionalLights;
- if (pipelineAsset.supportsAdditionalLightShadows)
- shaderFeatures |= ShaderFeatures.AdditionalLightShadows;
- }
- bool anyShadows = pipelineAsset.supportsMainLightShadows ||
- CoreUtils.HasFlag(shaderFeatures, ShaderFeatures.AdditionalLightShadows);
- if (pipelineAsset.supportsSoftShadows && anyShadows)
- shaderFeatures |= ShaderFeatures.SoftShadows;
- if (pipelineAsset.supportsMixedLighting)
- shaderFeatures |= ShaderFeatures.MixedLighting;
- if (pipelineAsset.supportsTerrainHoles)
- shaderFeatures |= ShaderFeatures.TerrainHoles;
- return shaderFeatures;
- }
- }
- }
|