Skip to content

Commit

Permalink
URP Forward+ (#4500)
Browse files Browse the repository at this point in the history
* Create local test project

* Update mathematics version, and add burst

* Min max Z job

* Add constructor for min max Z job

* Z-sort job prototype (untested)

* Working radix sort using mean Z

* Added re-ordering job and profiling marker

* 1-level tiling

* TilingJob -> FineTilingJob

* Work on groups of 32 lights at a time

* Minor optimizations

* rename

* Move some data into one struct

* Hierarchical tiling

* Perf improvements for hierarchical tiling

* Aperture Z-distribution

* Represent tile cone as SDF instead

* Separate tiling into X & Y + better debug view

* Extract light data for slice culling

* First pass of integration into URP lighting

* Add clustering lighting UI option

* Overlap culling with setup

* Get rid of last Shader.SetGlobal

* Clean up buffers in ForwardLights

* Fix support for shadows

* Support for directional lights

* Remove unused code

* Use more general shader keyword, move setting to UniversalRenderer, expose tile size to UI, reduce tile size if it doesn't fit in buffers, introduce new 8 px tile size

* Handle ZBin factor better and reduce max Zbins to 4096

* Add clustered keyword to SM4.5 shaders

* Make work on Android, fix shadows being stripped, strip clustered variants properly

* Change back to UBOs

* Combine slices into tile structure

* Add clustered keyword to remaining shaders, and remove CPU part from keyword name

* Re-integrate Lighting.hlsl changes after merge with refactor in master

* Hide UI behind flag, do some minor clean up and fixing

* Update UI text to reflect experimental

* Remove local test project

* Remove screenshots

* Revert a change

* Undo some unintentional changes and make new API points internal

* Remove unused var

* Remove some more public API

* Clarify some magic numbers

* Add keyword to Shader Graph targets

* Fix for crashes

* Fix assertion failure

* fix for merge

* Workaround memory allocation assert bug

* Fix GPU crash

* Remove workaround for preview cameras
  • Loading branch information
pbbastian authored May 12, 2021
1 parent 828d718 commit 023ee4d
Show file tree
Hide file tree
Showing 50 changed files with 1,197 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,7 @@ static class Descriptors
{ CoreKeywordDescriptors.ShadowsSoft },
{ CoreKeywordDescriptors.LightmapShadowMixing },
{ CoreKeywordDescriptors.ShadowsShadowmask },
{ CoreKeywordDescriptors.ClusteredRendering },
{ Descriptors.DecalsNormalBlend },
{ Descriptors.LodCrossFade, new FieldCondition(Fields.LodCrossFade, true) },
};
Expand All @@ -961,6 +962,7 @@ static class Descriptors
{ CoreKeywordDescriptors.AdditionalLights },
{ CoreKeywordDescriptors.AdditionalLightShadows },
{ CoreKeywordDescriptors.ShadowsSoft },
{ CoreKeywordDescriptors.ClusteredRendering },
{ Descriptors.DecalsNormalBlend },
};

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

public static readonly KeywordCollection GBuffer = new KeywordCollection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1438,6 +1438,15 @@ static class CoreKeywordDescriptors
definition = KeywordDefinition.ShaderFeature,
scope = KeywordScope.Global,
};

public static readonly KeywordDescriptor ClusteredRendering = new KeywordDescriptor()
{
displayName = "Clustered Rendering",
referenceName = "_CLUSTERED_RENDERING",
type = KeywordType.Boolean,
definition = KeywordDefinition.MultiCompile,
scope = KeywordScope.Global,
};
}
#endregion

Expand Down
48 changes: 40 additions & 8 deletions com.unity.render-pipelines.universal/Editor/ShaderPreprocessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum ShaderFeatures
DecalNormalBlendLow = (1 << 22),
DecalNormalBlendMedium = (1 << 23),
DecalNormalBlendHigh = (1 << 24),
ClusteredRendering = (1 << 25)
}

internal class ShaderPreprocessor : IPreprocessShaders
Expand Down Expand Up @@ -82,13 +83,13 @@ internal class ShaderPreprocessor : IPreprocessShaders
ShaderKeyword m_UseFastSRGBLinearConversion = new ShaderKeyword(ShaderKeywordStrings.UseFastSRGBLinearConversion);
ShaderKeyword m_LightLayers = new ShaderKeyword(ShaderKeywordStrings.LightLayers);
ShaderKeyword m_DebugDisplay = new ShaderKeyword(ShaderKeywordStrings.DEBUG_DISPLAY);

ShaderKeyword m_DBufferMRT1 = new ShaderKeyword(ShaderKeywordStrings.DBufferMRT1);
ShaderKeyword m_DBufferMRT2 = new ShaderKeyword(ShaderKeywordStrings.DBufferMRT2);
ShaderKeyword m_DBufferMRT3 = new ShaderKeyword(ShaderKeywordStrings.DBufferMRT3);
ShaderKeyword m_DecalNormalBlendLow = new ShaderKeyword(ShaderKeywordStrings.DecalNormalBlendLow);
ShaderKeyword m_DecalNormalBlendMedium = new ShaderKeyword(ShaderKeywordStrings.DecalNormalBlendMedium);
ShaderKeyword m_DecalNormalBlendHigh = new ShaderKeyword(ShaderKeywordStrings.DecalNormalBlendHigh);
ShaderKeyword m_ClusteredRendering = new ShaderKeyword(ShaderKeywordStrings.ClusteredRendering);

ShaderKeyword m_LocalDetailMulx2;
ShaderKeyword m_LocalDetailScaled;
Expand Down Expand Up @@ -232,20 +233,23 @@ bool StripUnusedFeatures(ShaderFeatures features, Shader shader, ShaderSnippetDa
// Additional light are shaded per-vertex or per-pixel.
bool isFeaturePerPixelLightingEnabled = IsFeatureEnabled(features, ShaderFeatures.AdditionalLights);
bool isFeaturePerVertexLightingEnabled = IsFeatureEnabled(features, ShaderFeatures.VertexLighting);
bool clusteredRendering = IsFeatureEnabled(features, ShaderFeatures.ClusteredRendering);
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))
// Per-Pixel (_ADDITIONAL_LIGHTS) variant is enabled in the shader.
if (!isFeaturePerPixelLightingEnabled && isAdditionalLightPerPixel)
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;

if (!clusteredRendering && compilerData.shaderKeywordSet.IsEnabled(m_ClusteredRendering))
return true;

// Screen Space Shadows
if (!IsFeatureEnabled(features, ShaderFeatures.ScreenSpaceShadows) &&
compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsScreen))
Expand Down Expand Up @@ -324,7 +328,7 @@ bool StripInvalidVariants(ShaderCompilerData compilerData)
bool isMainShadow = isMainShadowNoCascades || isMainShadowCascades || isMainShadowScreen;

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

bool isDeferredShadow = compilerData.shaderKeywordSet.IsEnabled(m_DeferredLightShadows);
Expand Down Expand Up @@ -394,6 +398,7 @@ public void OnProcessShader(Shader shader, ShaderSnippetData snippetData, IList<
#if PROFILE_BUILD
Profiler.BeginSample(k_ProcessShaderTag);
#endif

UniversalRenderPipelineAsset urpAsset = GraphicsSettings.renderPipelineAsset as UniversalRenderPipelineAsset;
if (urpAsset == null || compilerDataList == null || compilerDataList.Count == 0)
return;
Expand Down Expand Up @@ -510,9 +515,6 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
else if (pipelineAsset.additionalLightsRenderingMode == LightRenderingMode.PerPixel)
{
shaderFeatures |= ShaderFeatures.AdditionalLights;

if (pipelineAsset.supportsAdditionalLightShadows)
shaderFeatures |= ShaderFeatures.AdditionalLightShadows;
}

bool anyShadows = pipelineAsset.supportsMainLightShadows ||
Expand All @@ -537,6 +539,8 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
bool hasDeferredRenderer = false;
bool withAccurateGbufferNormals = false;
bool withoutAccurateGbufferNormals = false;
bool clusteredRendering = false;
bool onlyClusteredRendering = false;

int rendererCount = pipelineAsset.m_RendererDataList.Length;
for (int rendererIndex = 0; rendererIndex < rendererCount; ++rendererIndex)
Expand All @@ -553,6 +557,7 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
}
}

var rendererClustered = false;

ScriptableRendererData rendererData = pipelineAsset.m_RendererDataList[rendererIndex];
if (rendererData != null)
Expand Down Expand Up @@ -589,7 +594,16 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
}
}
}

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

clusteredRendering |= rendererClustered;
onlyClusteredRendering &= rendererClustered;
}

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

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

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

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

return shaderFeatures;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ 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.");
}

SerializedProperty m_OpaqueLayerMask;
Expand All @@ -33,6 +34,8 @@ private static class Styles
SerializedProperty m_DepthPrimingMode;
SerializedProperty m_AccurateGbufferNormals;
//SerializedProperty m_TiledDeferredShading;
SerializedProperty m_ClusteredRendering;
SerializedProperty m_TileSize;
#if ENABLE_RENDER_PASS_UI
SerializedProperty m_UseNativeRenderPass;
#endif
Expand All @@ -41,6 +44,12 @@ private static class Styles
SerializedProperty m_Shaders;
SerializedProperty m_ShadowTransparentReceiveProp;

#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 @@ -50,6 +59,8 @@ private void OnEnable()
m_AccurateGbufferNormals = serializedObject.FindProperty("m_AccurateGbufferNormals");
// Not exposed yet.
//m_TiledDeferredShading = serializedObject.FindProperty("m_TiledDeferredShading");
m_ClusteredRendering = serializedObject.FindProperty("m_ClusteredRendering");
m_TileSize = serializedObject.FindProperty("m_TileSize");
#if ENABLE_RENDER_PASS_UI
m_UseNativeRenderPass = serializedObject.FindProperty("m_UseNativeRenderPass");
#endif
Expand Down Expand Up @@ -86,11 +97,21 @@ public override void OnInspectorGUI()
if (m_RenderingMode.intValue == (int)RenderingMode.Forward)
{
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)
{
EditorGUILayout.HelpBox(Styles.DepthPrimingModeInfo.text, MessageType.Info);
}

EditorGUI.indentLevel--;
}

Expand Down
Loading

0 comments on commit 023ee4d

Please sign in to comment.