Skip to content

Commit

Permalink
URP Forward+ Improved Tiling
Browse files Browse the repository at this point in the history
This PR revamps the tiling math and algorithm used for URP Forward+, and makes it available for general use. This has far tighter bounds than previously, while keeping CPU usage reasonable. It also streamlines a number of things.

Some algorithmic explanations in TDD, but feel free to throw me any questions :) https://docs.google.com/document/d/1-NA5XUqAboVAB4fsMfV9O3eQOrC0RKOvPT9_SGjgwMc/edit#heading=h.wo67r6cr8k6c

Part of the following initiatives:
https://jira.unity3d.com/browse/RND-406
https://jira.unity3d.com/browse/RND-177
  • Loading branch information
pbbastian committed May 23, 2022
1 parent d8f6fd5 commit b155398
Show file tree
Hide file tree
Showing 49 changed files with 1,192 additions and 649 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ static class Descriptors
{ CoreKeywordDescriptors.ShadowsSoft },
{ CoreKeywordDescriptors.LightmapShadowMixing },
{ CoreKeywordDescriptors.ShadowsShadowmask },
{ CoreKeywordDescriptors.ClusteredRendering },
{ CoreKeywordDescriptors.ForwardPlus },
{ Descriptors.DecalsNormalBlend },
{ CoreKeywordDescriptors.LODFadeCrossFade, new FieldCondition(Fields.LodCrossFade, true) },
};
Expand All @@ -1044,7 +1044,7 @@ static class Descriptors
{ CoreKeywordDescriptors.AdditionalLights },
{ CoreKeywordDescriptors.AdditionalLightShadows },
{ CoreKeywordDescriptors.ShadowsSoft },
{ CoreKeywordDescriptors.ClusteredRendering },
{ CoreKeywordDescriptors.ForwardPlus },
{ Descriptors.DecalsNormalBlend },
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ static class LitKeywords
{ CoreKeywordDescriptors.LightLayers },
{ CoreKeywordDescriptors.DebugDisplay },
{ CoreKeywordDescriptors.LightCookies },
{ CoreKeywordDescriptors.ClusteredRendering },
{ CoreKeywordDescriptors.ForwardPlus },
};

public static readonly KeywordCollection DOTSForward = new KeywordCollection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1973,10 +1973,10 @@ static class CoreKeywordDescriptors
stages = KeywordShaderStage.Fragment,
};

public static readonly KeywordDescriptor ClusteredRendering = new KeywordDescriptor()
public static readonly KeywordDescriptor ForwardPlus = new KeywordDescriptor()
{
displayName = "Clustered Rendering",
referenceName = "_CLUSTERED_RENDERING",
displayName = "Forward+",
referenceName = "_FORWARD_PLUS",
type = KeywordType.Boolean,
definition = KeywordDefinition.MultiCompile,
scope = KeywordScope.Global,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ enum ShaderFeatures : long
DecalNormalBlendLow = (1 << 21),
DecalNormalBlendMedium = (1 << 22),
DecalNormalBlendHigh = (1 << 23),
ClusteredRendering = (1 << 24),
ForwardPlus = (1 << 24),
RenderPassEnabled = (1 << 25),
MainLightShadowsCascade = (1 << 26),
DrawProcedural = (1 << 27),
Expand Down Expand Up @@ -112,7 +112,7 @@ internal class ShaderPreprocessor : IShaderVariantStripper, IShaderVariantStripp
LocalKeyword m_DecalNormalBlendLow;
LocalKeyword m_DecalNormalBlendMedium;
LocalKeyword m_DecalNormalBlendHigh;
LocalKeyword m_ClusteredRendering;
LocalKeyword m_ForwardPlus;
LocalKeyword m_EditorVisualization;
LocalKeyword m_LODFadeCrossFade;

Expand Down Expand Up @@ -179,7 +179,7 @@ public void InitializeLocalShaderKeywords([DisallowNull] Shader shader)
m_DecalNormalBlendLow = TryGetLocalKeyword(shader, ShaderKeywordStrings.DecalNormalBlendLow);
m_DecalNormalBlendMedium = TryGetLocalKeyword(shader, ShaderKeywordStrings.DecalNormalBlendMedium);
m_DecalNormalBlendHigh = TryGetLocalKeyword(shader, ShaderKeywordStrings.DecalNormalBlendHigh);
m_ClusteredRendering = TryGetLocalKeyword(shader, ShaderKeywordStrings.ClusteredRendering);
m_ForwardPlus = TryGetLocalKeyword(shader, ShaderKeywordStrings.ForwardPlus);
m_EditorVisualization = TryGetLocalKeyword(shader, ShaderKeywordStrings.EDITOR_VISUALIZATION);
m_LODFadeCrossFade = TryGetLocalKeyword(shader, ShaderKeywordStrings.LOD_FADE_CROSSFADE);

Expand Down Expand Up @@ -470,7 +470,7 @@ bool StripUnusedFeatures(ShaderFeatures features, Shader shader, ShaderSnippetDa
return true;
}

if (stripTool.StripMultiCompile(m_ClusteredRendering, ShaderFeatures.ClusteredRendering))
if (stripTool.StripMultiCompile(m_ForwardPlus, ShaderFeatures.ForwardPlus))
return true;

// Screen Space Occlusion
Expand Down Expand Up @@ -652,7 +652,7 @@ bool StripInvalidVariants(ShaderCompilerData compilerData)
bool isMainShadow = isMainShadowNoCascades || isMainShadowCascades || isMainShadowScreen;

bool isAdditionalShadow = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightShadows);
if (isAdditionalShadow && !(compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsPixel) || compilerData.shaderKeywordSet.IsEnabled(m_ClusteredRendering) || compilerData.shaderKeywordSet.IsEnabled(m_DeferredStencil)))
if (isAdditionalShadow && !(compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsPixel) || compilerData.shaderKeywordSet.IsEnabled(m_ForwardPlus) || compilerData.shaderKeywordSet.IsEnabled(m_DeferredStencil)))
return true;

bool isShadowVariant = isMainShadow || isAdditionalShadow;
Expand Down Expand Up @@ -915,11 +915,6 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
shaderFeatures |= ShaderFeatures.AdditionalLights;
}

bool anyShadows = pipelineAsset.supportsMainLightShadows ||
(shaderFeatures & ShaderFeatures.AdditionalLightShadows) != 0;
if (pipelineAsset.supportsSoftShadows && anyShadows)
shaderFeatures |= ShaderFeatures.SoftShadows;

if (pipelineAsset.supportsMixedLighting)
shaderFeatures |= ShaderFeatures.MixedLighting;

Expand All @@ -939,8 +934,7 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
bool hasScreenSpaceOcclusion = false;
bool hasDeferredRenderer = false;
bool accurateGbufferNormals = false;
bool clusteredRendering = false;
bool onlyClusteredRendering = false;
bool forwardPlus = false;
bool usesRenderPass = false;

{
Expand All @@ -967,8 +961,6 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
if (!renderer.stripAdditionalLightOffVariants)
shaderFeatures |= ShaderFeatures.AdditionalLightsKeepOffVariants;

var rendererClustered = false;

ScriptableRendererData rendererData = pipelineAsset.m_RendererDataList[rendererIndex];
if (rendererData != null)
{
Expand Down Expand Up @@ -1013,8 +1005,7 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline

if (rendererData is UniversalRendererData universalRendererData)
{
rendererClustered = universalRendererData.renderingMode == RenderingMode.Forward &&
universalRendererData.clusteredRendering;
forwardPlus = universalRendererData.renderingMode == RenderingMode.ForwardPlus;

if (RenderingLayerUtils.RequireRenderingLayers(universalRendererData,
pipelineAsset.msaaSampleCount,
Expand Down Expand Up @@ -1043,9 +1034,6 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
#endif
}
}

clusteredRendering |= rendererClustered;
onlyClusteredRendering &= rendererClustered;
}

if (hasDeferredRenderer)
Expand All @@ -1069,24 +1057,27 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
if (pipelineAsset.reflectionProbeBoxProjection)
shaderFeatures |= ShaderFeatures.ReflectionProbeBoxProjection;

if (clusteredRendering)
if (forwardPlus)
{
shaderFeatures |= ShaderFeatures.ClusteredRendering;
}

if (onlyClusteredRendering)
{
shaderFeatures &= ~(ShaderFeatures.AdditionalLights | ShaderFeatures.VertexLighting);
shaderFeatures |= ShaderFeatures.ForwardPlus;
{
shaderFeatures &= ~(ShaderFeatures.AdditionalLights | ShaderFeatures.VertexLighting);
}
}

if (pipelineAsset.additionalLightsRenderingMode == LightRenderingMode.PerPixel || clusteredRendering)
if (pipelineAsset.additionalLightsRenderingMode == LightRenderingMode.PerPixel || forwardPlus)
{
if (pipelineAsset.supportsAdditionalLightShadows)
{
shaderFeatures |= ShaderFeatures.AdditionalLightShadows;
}
}

bool anyShadows = pipelineAsset.supportsMainLightShadows ||
(shaderFeatures & ShaderFeatures.AdditionalLightShadows) != 0;
if (pipelineAsset.supportsSoftShadows && anyShadows)
shaderFeatures |= ShaderFeatures.SoftShadows;

return shaderFeatures;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ private static class Styles
public static readonly GUIContent defaultStencilStateLabel = EditorGUIUtility.TrTextContent("Default Stencil State", "Configure the stencil state for the opaque and transparent render passes.");
public static readonly GUIContent shadowTransparentReceiveLabel = EditorGUIUtility.TrTextContent("Transparent Receive Shadows", "When disabled, none of the transparent objects will receive shadows.");
public static readonly GUIContent invalidStencilOverride = EditorGUIUtility.TrTextContent("Error: When using the deferred rendering path, the Renderer requires the control over the 4 highest bits of the stencil buffer to store Material types. The current combination of the stencil override options prevents the Renderer from controlling the required bits. Try changing one of the options to Replace.");
public static readonly GUIContent clusteredRenderingLabel = EditorGUIUtility.TrTextContent("Clustered (experimental)", "(Experimental) Enables clustered rendering, allowing for more lights per object and more accurate light cullling.");
public static readonly GUIContent intermediateTextureMode = EditorGUIUtility.TrTextContent("Intermediate Texture", "Controls when URP renders via an intermediate texture.");
}

Expand All @@ -46,21 +45,13 @@ private static class Styles
SerializedProperty m_DepthPrimingMode;
SerializedProperty m_CopyDepthMode;
SerializedProperty m_AccurateGbufferNormals;
SerializedProperty m_ClusteredRendering;
SerializedProperty m_TileSize;
SerializedProperty m_UseNativeRenderPass;
SerializedProperty m_DefaultStencilState;
SerializedProperty m_PostProcessData;
SerializedProperty m_Shaders;
SerializedProperty m_ShadowTransparentReceiveProp;
SerializedProperty m_IntermediateTextureMode;

#if URP_ENABLE_CLUSTERED_UI
static bool s_EnableClusteredUI => true;
#else
static bool s_EnableClusteredUI => false;
#endif

private void OnEnable()
{
m_OpaqueLayerMask = serializedObject.FindProperty("m_OpaqueLayerMask");
Expand All @@ -69,8 +60,6 @@ private void OnEnable()
m_DepthPrimingMode = serializedObject.FindProperty("m_DepthPrimingMode");
m_CopyDepthMode = serializedObject.FindProperty("m_CopyDepthMode");
m_AccurateGbufferNormals = serializedObject.FindProperty("m_AccurateGbufferNormals");
m_ClusteredRendering = serializedObject.FindProperty("m_ClusteredRendering");
m_TileSize = serializedObject.FindProperty("m_TileSize");
m_UseNativeRenderPass = serializedObject.FindProperty("m_UseNativeRenderPass");
m_DefaultStencilState = serializedObject.FindProperty("m_DefaultStencilState");
m_PostProcessData = serializedObject.FindProperty("postProcessData");
Expand Down Expand Up @@ -102,18 +91,10 @@ public override void OnInspectorGUI()
EditorGUI.indentLevel--;
}

if (m_RenderingMode.intValue == (int)RenderingMode.Forward)
if (m_RenderingMode.intValue == (int)RenderingMode.Forward || m_RenderingMode.intValue == (int)RenderingMode.ForwardPlus)
{
EditorGUI.indentLevel++;

if (s_EnableClusteredUI)
{
EditorGUILayout.PropertyField(m_ClusteredRendering, Styles.clusteredRenderingLabel);
EditorGUI.BeginDisabledGroup(!m_ClusteredRendering.boolValue);
EditorGUILayout.PropertyField(m_TileSize);
EditorGUI.EndDisabledGroup();
}

EditorGUILayout.PropertyField(m_DepthPrimingMode, Styles.DepthPrimingModeLabel);
if (m_DepthPrimingMode.intValue != (int)DepthPrimingMode.Disabled)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ${VFXBegin:VFXPassForwardLitAdditionalPragma}
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma multi_compile_fragment _ _LIGHT_LAYERS
#pragma multi_compile_fragment _ _LIGHT_COOKIES
#pragma multi_compile _ _CLUSTERED_RENDERING
#pragma multi_compile _ _FORWARD_PLUS
#pragma multi_compile_fog
#pragma multi_compile _ DEBUG_DISPLAY
${VFXEnd}
Expand Down Expand Up @@ -100,7 +100,7 @@ void frag(ps_input i
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
VFXTransformPSInputs(i);
${VFXComputeNormalWS}

#ifdef VFX_SHADERGRAPH
${VFXAdditionalInterpolantsPreparation}

Expand All @@ -112,15 +112,15 @@ void frag(ps_input i

float alpha = OUTSG.${SHADERGRAPH_PARAM_ALPHA};
#else

float alpha = VFXGetFragmentColor(i).a;
#if URP_USE_BASE_COLOR_MAP_ALPHA
alpha *= VFXGetTextureColor(VFX_SAMPLER(baseColorMap),i).a;
#endif
#endif

VFXClipFragmentColor(alpha,i);

#if defined(WRITE_NORMAL_BUFFER)
#ifdef VFX_SHADERGRAPH
#if HAS_SHADERGRAPH_PARAM_NORMALTS
Expand Down
Loading

0 comments on commit b155398

Please sign in to comment.