浏览代码

Added first version of shader variant stripper for Lit* shaders in HDRP.

/main
Julien Ignace 6 年前
当前提交
c135df26
共有 6 个文件被更改,包括 164 次插入0 次删除
  1. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/HDRenderPipelineUI.cs
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedHDRenderPipelineAsset.cs
  3. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  4. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.cs
  5. 146
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRPVariantStripper.cs
  6. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRPVariantStripper.cs.meta

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/HDRenderPipelineUI.cs


{
EditorGUILayout.PropertyField(d.renderPipelineResources, _.GetContent("Render Pipeline Resources|Set of resources that need to be loaded when creating stand alone"));
EditorGUILayout.PropertyField(d.diffusionProfileSettings, _.GetContent("Diffusion Profile Settings"));
EditorGUILayout.PropertyField(d.allowShaderVariantStripping, _.GetContent("Enable Shader Variant Stripping (experimental)"));
}
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedHDRenderPipelineAsset.cs


public SerializedProperty renderPipelineResources;
public SerializedProperty diffusionProfileSettings;
public SerializedProperty allowShaderVariantStripping;
public SerializedRenderPipelineSettings renderPipelineSettings;
public SerializedFrameSettings defaultFrameSettings;

renderPipelineResources = serializedObject.FindProperty("m_RenderPipelineResources");
diffusionProfileSettings = serializedObject.Find((HDRenderPipelineAsset s) => s.diffusionProfileSettings);
allowShaderVariantStripping = serializedObject.Find((HDRenderPipelineAsset s) => s.allowShaderVariantStripping);
renderPipelineSettings = new SerializedRenderPipelineSettings(serializedObject.Find((HDRenderPipelineAsset a) => a.renderPipelineSettings));
defaultFrameSettings = new SerializedFrameSettings(serializedObject.FindProperty("m_FrameSettings"));

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


};
readonly HDRenderPipelineAsset m_Asset;
public HDRenderPipelineAsset asset { get { return m_Asset; } }
DiffusionProfileSettings m_InternalSSSAsset;
public DiffusionProfileSettings diffusionProfileSettings

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.cs


return renderPipelineSettings;
}
public bool allowShaderVariantStripping = false;
[SerializeField]
public DiffusionProfileSettings diffusionProfileSettings;

146
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRPVariantStripper.cs


using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build;
using UnityEditor.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
class HDRPVariantStripper : IPreprocessShaders
{
// returns true if the variant should be stripped.
delegate bool VariantStrippingFunc(Shader shader, ShaderSnippetData snippet, ShaderCompilerData inputData);
Dictionary<string, VariantStrippingFunc> m_StripperFuncs;
HDRenderPipelineAsset m_CurrentHDRPAsset;
ShaderKeyword m_ShadowMask;
ShaderKeyword m_Transparent;
ShaderKeyword m_DebugDisplay;
ShaderKeyword m_TileLighting;
ShaderKeyword m_ClusterLighting;
ShaderKeyword m_FeatureSSS;
public HDRPVariantStripper()
{
// TODO: Grab correct configuration/quality asset.
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
if (hdPipeline != null)
m_CurrentHDRPAsset = hdPipeline.asset;
m_StripperFuncs = new Dictionary<string, VariantStrippingFunc>();
m_StripperFuncs.Add("HDRenderPipeline/Lit", LitShaderStripper);
m_StripperFuncs.Add("HDRenderPipeline/LitTessellation", LitShaderStripper);
m_StripperFuncs.Add("HDRenderPipeline/LayeredLit", LitShaderStripper);
m_StripperFuncs.Add("HDRenderPipeline/LayeredLitTessellation", LitShaderStripper);
m_Transparent = new ShaderKeyword("_SURFACE_TYPE_TRANSPARENT");
m_DebugDisplay = new ShaderKeyword("DEBUG_DISPLAY");
m_TileLighting = new ShaderKeyword("USE_FPTL_LIGHTLIST");
m_ClusterLighting = new ShaderKeyword("USE_CLUSTERED_LIGHTLIST");
m_FeatureSSS = new ShaderKeyword("_MATERIAL_FEATURE_SUBSURFACE_SCATTERING");
}
bool LitShaderStripper(Shader shader, ShaderSnippetData snippet, ShaderCompilerData inputData)
{
bool isGBufferPass = snippet.passName == "GBuffer";
bool isForwardPass = snippet.passName == "Forward";
bool isTransparentForwardPass = snippet.passName == "TransparentDepthPostpass" || snippet.passName == "TransparentBackface" || snippet.passName == "TransparentDepthPrepass";
bool isMotionPass = snippet.passName == "Motion Vectors";
// NOTE: All these keyword should be automatically stripped so there's no need to handle them ourselves.
// LIGHTMAP_ON, DIRLIGHTMAP_COMBINED, DYNAMICLIGHTMAP_ON, LIGHTMAP_SHADOW_MIXING, SHADOWS_SHADOWMASK
// FOG_LINEAR, FOG_EXP, FOG_EXP2
// STEREO_INSTANCING_ON, STEREO_MULTIVIEW_ON, STEREO_CUBEMAP_RENDER_ON, UNITY_SINGLE_PASS_STEREO
// INSTANCING_ON
if (!m_CurrentHDRPAsset.renderPipelineSettings.supportMotionVectors && isMotionPass)
return true;
// When using forward only, we never need GBuffer pass (only Forward)
if (m_CurrentHDRPAsset.renderPipelineSettings.supportForwardOnly && isGBufferPass)
return true;
if (inputData.shaderKeywordSet.IsEnabled(m_Transparent))
{
// If transparent, we never need GBuffer pass.
if (isGBufferPass)
return true;
// We will also use cluster instead of tile
if (inputData.shaderKeywordSet.IsEnabled(m_TileLighting))
return true;
}
else // Opaque
{
// If opaque, we never need transparent specific passes (even in forward only mode)
if (isTransparentForwardPass)
return true;
if (!m_CurrentHDRPAsset.renderPipelineSettings.supportForwardOnly && inputData.shaderKeywordSet.IsEnabled(m_ClusterLighting))
return true;
if (!m_CurrentHDRPAsset.renderPipelineSettings.supportForwardOnly)
{
// If opaque and not forward only, then we only need the forward debug pass.
if (isForwardPass && !inputData.shaderKeywordSet.IsEnabled(m_DebugDisplay))
return true;
}
}
// TODO: Expose development build flag.
//if (developmentBuild && inputData.shaderKeywordSet.IsEnabled(m_DebugDisplay))
// return true;
// TODO: Tests for later
// We need to find a way to strip useless shader features for passes/shader stages that don't need them (example, vertex shaders won't ever need SSS Feature flag)
// This causes several problems:
// - Runtime code that "finds" shader variants based on feature flags might not find them anymore... thus fall backing to the "let's give a score to variant" code path that may find the wrong variant.
// - Another issue is that if a feature is declared without a "_" fall-back, if we strip the other variants, none may be left to use! This needs to be changed on our side.
//if (snippet.shaderType == ShaderType.Vertex && inputData.shaderKeywordSet.IsEnabled(m_FeatureSSS))
// return true;
return false;
}
public int callbackOrder { get { return 0; } }
public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> inputData)
{
if (m_CurrentHDRPAsset == null || !m_CurrentHDRPAsset.allowShaderVariantStripping)
return;
// Do we have a shader variant stripper function for this shader?
VariantStrippingFunc stripperFunc = null;
m_StripperFuncs.TryGetValue(shader.name, out stripperFunc);
if (stripperFunc == null)
return;
int inputShaderVariantCount = inputData.Count;
ShaderCompilerData workaround = inputData[0];
for (int i = 0; i < inputData.Count; ++i)
{
ShaderCompilerData input = inputData[i];
if (stripperFunc(shader, snippet, input))
{
inputData.RemoveAt(i);
i--;
}
}
// Currently if a certain snippet is completely stripped (for example if you remove a whole pass) other passes might get broken
// To work around that, we make sure that we always have at least one variant.
if (inputData.Count == 0)
inputData.Add(workaround);
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRPVariantStripper.cs.meta


fileFormatVersion: 2
guid: 168f8e50628e857489eb62f41d9c911f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存