Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Universal/light layers #3677

Merged
merged 41 commits into from Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
2578116
Initial light layer support.
kaychang-unity Feb 26, 2021
4507696
Merge branch 'master' into universal/light-layers
kaychang-unity Feb 27, 2021
aa9d82e
Updated changelog.
kaychang-unity Feb 27, 2021
ade05b1
Auto-formatting.
kaychang-unity Mar 19, 2021
8ab4cec
Merge branch 'master' into universal/light-layers
kaychang-unity Mar 19, 2021
6c7decb
Update com.unity.render-pipelines.universal/CHANGELOG.md
kaychang-unity Mar 23, 2021
40926e3
Merge branch 'universal/light-layers' of https://github.com/Unity-Tec…
kaychang-unity Mar 23, 2021
b360f0c
Minor fixes.
kaychang-unity Mar 23, 2021
bf099f9
Adjusted code to compile out IsMatchingLightLayer() when light layers…
kaychang-unity Mar 24, 2021
e339f85
Refactoring.
kaychang-unity Mar 27, 2021
c66c694
Added test scenes for light layers (148_Lighting_LightLayers and 148_…
kaychang-unity Mar 27, 2021
9c6b7ca
Formating.
kaychang-unity Mar 27, 2021
b785c92
Disable filtering for lightmaps.
kaychang-unity Mar 30, 2021
b5ca656
Added 148_Lighting_LightLayers and 148_Lighting_LightLayers_deferred …
kaychang-unity Mar 30, 2021
39d53c1
Merge branch 'master' into universal/light-layers
kaychang-unity Mar 30, 2021
4e6bef7
AdditionalLightData is now unconditionally created when OnEnable() is…
kaychang-unity Mar 30, 2021
4a0d7dd
Added some reference images.
kaychang-unity Mar 30, 2021
2156ee1
Added fake quality level that references UniversalRPAssetLightLayers.…
kaychang-unity Mar 31, 2021
8387800
Moved UI element for light layer mask in Light inspector.
kaychang-unity Mar 31, 2021
f73446b
Detect invalid platforms (GLES2) and display error message.
kaychang-unity Mar 31, 2021
153108b
More reference images.
kaychang-unity Apr 1, 2021
f63de3c
Reference images.
kaychang-unity Apr 5, 2021
93e6ae5
Wait for 2 frames before taking screenshots. This fixes the test scen…
kaychang-unity Apr 5, 2021
ff54327
Reference images.
kaychang-unity Apr 6, 2021
9dfba80
Tweaked error message.
kaychang-unity Apr 7, 2021
96ff6a3
Merge branch 'master' into universal/light-layers
kaychang-unity Apr 9, 2021
e86e7b1
Removed duplicate assets.
kaychang-unity Apr 10, 2021
f29f19f
Updated UX to match HDRP.
kaychang-unity Apr 12, 2021
c87063f
Fixed null reference in Player mode.
kaychang-unity Apr 13, 2021
7dbe1d3
Update com.unity.render-pipelines.universal/Runtime/DeferredLights.cs
kaychang-unity Apr 14, 2021
72ef39a
Added comment.
kaychang-unity Apr 14, 2021
4e6f55c
Moved rendering layer texture from 32 to 8 bits as currently only lig…
kaychang-unity Apr 14, 2021
e6a344d
A lot of internal renaming from lightLayers to layerMask.
kaychang-unity Apr 14, 2021
ee81c8d
Hide light layers for baked lights.
kaychang-unity Apr 15, 2021
5c72df6
Merge branch 'master' into universal/light-layers
kaychang-unity Apr 16, 2021
41d9a7d
Merge branch 'master' into universal/light-layers-test
phi-lira Apr 19, 2021
f1c308b
Fixed formatting to pass yamato format test.
phi-lira Apr 19, 2021
f5c389c
Terrain vertex lit ignores light layers (because default vertex lit c…
kaychang-unity Apr 21, 2021
4ca80bc
More missing instancing_option renderinglayer.
kaychang-unity Apr 21, 2021
722dd17
Temporarily sable 153_Lighting_EnlightenTerrain.unity because it is b…
kaychang-unity Apr 21, 2021
810b205
Merge branch 'master' into universal/light-layers
kaychang-unity Apr 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.render-pipelines.universal/CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added View Vector node to mimic old behavior of View Direction node in URP.
- Added support for the PlayStation 5 platform.
- Enabled deferred renderer in UI.
- Light layers interface.
kaychang-unity marked this conversation as resolved.
Show resolved Hide resolved

### Changed
- The Forward Renderer asset is renamed to the Universal Renderer asset. The Universal Renderer asset contains the property Rendering Path that lets you select the Forward or the Deferred Rendering Path.
Expand Down
Expand Up @@ -691,6 +691,7 @@ static class LitKeywords
{ CoreKeywordDescriptors.ShadowsSoft },
{ CoreKeywordDescriptors.LightmapShadowMixing },
{ CoreKeywordDescriptors.ShadowsShadowmask },
{ CoreKeywordDescriptors.LightLayers },
};

public static readonly KeywordCollection GBuffer = new KeywordCollection
Expand All @@ -701,6 +702,7 @@ static class LitKeywords
{ CoreKeywordDescriptors.ShadowsSoft },
{ CoreKeywordDescriptors.LightmapShadowMixing },
{ CoreKeywordDescriptors.MixedLightingSubtractive },
{ CoreKeywordDescriptors.LightLayers },
{ GBufferNormalsOct },
};

Expand Down
Expand Up @@ -551,6 +551,7 @@ static class CorePragmas
{ Pragma.OnlyRenderers(new[] { Platform.GLES, Platform.GLES3, Platform.GLCore }) },
{ Pragma.MultiCompileInstancing },
{ Pragma.MultiCompileFog },
{ Pragma.InstancingOptions(InstancingOptions.RenderingLayer) },
{ Pragma.Vertex("vert") },
{ Pragma.Fragment("frag") },
};
Expand Down Expand Up @@ -587,6 +588,7 @@ static class CorePragmas
{ Pragma.ExcludeRenderers(new[] { Platform.GLES, Platform.GLES3, Platform.GLCore }) },
{ Pragma.MultiCompileInstancing },
{ Pragma.MultiCompileFog },
{ Pragma.InstancingOptions(InstancingOptions.RenderingLayer) },
{ Pragma.DOTSInstancing },
{ Pragma.Vertex("vert") },
{ Pragma.Fragment("frag") },
Expand All @@ -598,6 +600,7 @@ static class CorePragmas
{ Pragma.ExcludeRenderers(new[] { Platform.GLES, Platform.GLES3, Platform.GLCore }) },
{ Pragma.MultiCompileInstancing },
{ Pragma.MultiCompileFog },
{ Pragma.InstancingOptions(InstancingOptions.RenderingLayer) },
{ Pragma.DOTSInstancing },
{ Pragma.Vertex("vert") },
{ Pragma.Fragment("frag") },
Expand Down Expand Up @@ -802,6 +805,15 @@ static class CoreKeywordDescriptors
scope = KeywordScope.Global,
};

public static readonly KeywordDescriptor LightLayers = new KeywordDescriptor()
{
displayName = "Light Layers",
referenceName = "_LIGHT_LAYERS",
type = KeywordType.Boolean,
definition = KeywordDefinition.MultiCompile,
scope = KeywordScope.Global,
};

public static readonly KeywordDescriptor SmoothnessChannel = new KeywordDescriptor()
{
displayName = "Smoothness Channel",
Expand Down
Expand Up @@ -26,7 +26,8 @@ enum ShaderFeatures
DeferredWithoutAccurateGbufferNormals = (1 << 10),
ScreenSpaceOcclusion = (1 << 11),
ScreenSpaceShadows = (1 << 12),
UseFastSRGBLinearConversion = (1 << 13)
UseFastSRGBLinearConversion = (1 << 13),
LightLayers = (1 << 14),
}

internal class ShaderPreprocessor : IPreprocessShaders
Expand Down Expand Up @@ -60,6 +61,7 @@ internal class ShaderPreprocessor : IPreprocessShaders
ShaderKeyword m_UseDrawProcedural = new ShaderKeyword(ShaderKeywordStrings.UseDrawProcedural);
ShaderKeyword m_ScreenSpaceOcclusion = new ShaderKeyword(ShaderKeywordStrings.ScreenSpaceOcclusion);
ShaderKeyword m_UseFastSRGBLinearConversion = new ShaderKeyword(ShaderKeywordStrings.UseFastSRGBLinearConversion);
ShaderKeyword m_LightLayers = new ShaderKeyword(ShaderKeywordStrings.LightLayers);

ShaderKeyword m_LocalDetailMulx2;
ShaderKeyword m_LocalDetailScaled;
Expand Down Expand Up @@ -136,6 +138,10 @@ bool StripUnusedFeatures(ShaderFeatures features, Shader shader, ShaderSnippetDa
!IsFeatureEnabled(features, ShaderFeatures.MixedLighting))
return true;

if (compilerData.shaderKeywordSet.IsEnabled(m_LightLayers) &&
!IsFeatureEnabled(features, ShaderFeatures.LightLayers))
return true;

// No additional light shadows
bool isAdditionalLightShadow = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightShadows);
if (!IsFeatureEnabled(features, ShaderFeatures.AdditionalLightShadows) && isAdditionalLightShadow)
Expand Down Expand Up @@ -427,6 +433,9 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline
if (pipelineAsset.useFastSRGBLinearConversion)
shaderFeatures |= ShaderFeatures.UseFastSRGBLinearConversion;

if (pipelineAsset.supportsLightLayers)
shaderFeatures |= ShaderFeatures.LightLayers;

bool hasScreenSpaceShadows = false;
bool hasScreenSpaceOcclusion = false;
bool hasDeferredRenderer = false;
Expand Down
Expand Up @@ -74,6 +74,7 @@ internal class Styles
public static GUIContent srpBatcher = EditorGUIUtility.TrTextContent("SRP Batcher", "If enabled, the render pipeline uses the SRP batcher.");
public static GUIContent dynamicBatching = EditorGUIUtility.TrTextContent("Dynamic Batching", "If enabled, the render pipeline will batch drawcalls with few triangles together by copying their vertex buffers into a shared buffer on a per-frame basis.");
public static GUIContent mixedLightingSupportLabel = EditorGUIUtility.TrTextContent("Mixed Lighting", "Makes the render pipeline include mixed-lighting Shader Variants in the build.");
public static GUIContent supportsLightLayers = EditorGUIUtility.TrTextContent("Light Layers", "When enabled, UniversalRP uses rendering layers instead of culling mask for the purpose of selecting how lights affect groups of geometry. For deferred rendering, an extra render target is allocated.");
public static GUIContent debugLevel = EditorGUIUtility.TrTextContent("Debug Level", "Controls the level of debug information generated by the render pipeline. When Profiling is selected, the pipeline provides detailed profiling tags.");
public static GUIContent shaderVariantLogLevel = EditorGUIUtility.TrTextContent("Shader Variant Log Level", "Controls the level logging in of shader variants information is outputted when a build is performed. Information will appear in the Unity console when the build finishes.");

Expand Down Expand Up @@ -145,6 +146,7 @@ internal class Styles
SerializedProperty m_SRPBatcher;
SerializedProperty m_SupportsDynamicBatching;
SerializedProperty m_MixedLightingSupportedProp;
SerializedProperty m_SupportsLightLayers;
SerializedProperty m_DebugLevelProp;

SerializedProperty m_ShaderVariantLogLevel;
Expand Down Expand Up @@ -225,6 +227,7 @@ void OnEnable()
m_SRPBatcher = serializedObject.FindProperty("m_UseSRPBatcher");
m_SupportsDynamicBatching = serializedObject.FindProperty("m_SupportsDynamicBatching");
m_MixedLightingSupportedProp = serializedObject.FindProperty("m_MixedLightingSupported");
m_SupportsLightLayers = serializedObject.FindProperty("m_SupportsLightLayers");
m_DebugLevelProp = serializedObject.FindProperty("m_DebugLevel");

m_ShaderVariantLogLevel = serializedObject.FindProperty("m_ShaderVariantLogLevel");
Expand Down Expand Up @@ -608,6 +611,7 @@ void DrawAdvancedSettings()
EditorGUILayout.PropertyField(m_SRPBatcher, Styles.srpBatcher);
EditorGUILayout.PropertyField(m_SupportsDynamicBatching, Styles.dynamicBatching);
EditorGUILayout.PropertyField(m_MixedLightingSupportedProp, Styles.mixedLightingSupportLabel);
EditorGUILayout.PropertyField(m_SupportsLightLayers, Styles.supportsLightLayers);
EditorGUILayout.PropertyField(m_DebugLevelProp, Styles.debugLevel);
EditorGUILayout.PropertyField(m_ShaderVariantLogLevel, Styles.shaderVariantLogLevel);
EditorGUI.indentLevel--;
Expand Down
Expand Up @@ -58,6 +58,10 @@ class Styles
new GUIContent("Custom"),
new GUIContent("Use Pipeline Settings")
};

public readonly GUIContent LightLayer = EditorGUIUtility.TrTextContent("Light Layer", "Specifies the current Light Layers that the Light affects. This Light illuminates corresponding Renderers with the same Light Layer flags.");
public readonly GUIContent linkLightAndShadowLayers = EditorGUIUtility.TrTextContent("Link Light Layer", "When enabled, the Light Layer property in the General section specifies the light layers for both lighting and for shadows. When disabled, you can use the Light Layer property below to specify the light layers for shadows seperately to lighting.");
public readonly GUIContent ShadowLayer = EditorGUIUtility.TrTextContent("Shadow Layer", "Specifies the light layer to use for shadows.");
}

static Styles s_Styles;
Expand Down Expand Up @@ -91,6 +95,10 @@ class Styles
SerializedProperty m_UseAdditionalDataProp; // Does light use shadow bias settings defined in UniversalRP asset file?
SerializedProperty m_AdditionalLightsShadowResolutionTierProp; // Index of the AdditionalLights ShadowResolution Tier

SerializedProperty m_LightLayersMask;
SerializedProperty m_LinkLightLayers;
SerializedProperty m_ShadowLayersMask;

protected override void OnEnable()
{
m_AdditionalLightData = lightProperty.gameObject.GetComponent<UniversalAdditionalLightData>();
Expand All @@ -107,11 +115,20 @@ void init(UniversalAdditionalLightData additionalLightData)
m_UseAdditionalDataProp = m_AdditionalLightDataSO.FindProperty("m_UsePipelineSettings");
m_AdditionalLightsShadowResolutionTierProp = m_AdditionalLightDataSO.FindProperty("m_AdditionalLightsShadowResolutionTier");

m_LightLayersMask = m_AdditionalLightDataSO.FindProperty("m_LightLayersMask");
m_LinkLightLayers = m_AdditionalLightDataSO.FindProperty("m_LinkLightLayers");
m_ShadowLayersMask = m_AdditionalLightDataSO.FindProperty("m_ShadowLayersMask");

settings.ApplyModifiedProperties();
}

public override void OnInspectorGUI()
{
// Light layers are stored in additional light data. We must create one if it doesn't exist.
UniversalRenderPipelineAsset urpAsset = UniversalRenderPipeline.asset;
if (urpAsset.supportsLightLayers && m_AdditionalLightDataSO == null)
CreateAdditionalLightData();

if (s_Styles == null)
s_Styles = new Styles();

Expand Down Expand Up @@ -173,7 +190,26 @@ public override void OnInspectorGUI()
ShadowsGUI();

settings.DrawRenderMode();
settings.DrawCullingMask();

if (UniversalRenderPipeline.asset.supportsLightLayers)
{
EditorGUI.BeginChangeCheck();
DrawLightLayerMask(m_LightLayersMask, s_Styles.LightLayer);
if (EditorGUI.EndChangeCheck())
{
if (m_LinkLightLayers.boolValue)
{
m_ShadowLayersMask.intValue = m_LightLayersMask.intValue;
lightProperty.renderingLayerMask = m_LightLayersMask.intValue;
}

m_AdditionalLightDataSO.ApplyModifiedProperties();
}
}
else
settings.DrawCullingMask();

settings.ApplyModifiedProperties();

EditorGUILayout.Space();

Expand Down Expand Up @@ -235,7 +271,6 @@ void DrawSpotAngle()

void DrawAdditionalShadowData()
{
bool hasChanged = false;
int selectedUseAdditionalData; // 0: Custom bias - 1: Bias values defined in Pipeline settings

if (m_AdditionalLightDataSO == null)
Expand All @@ -252,13 +287,11 @@ void DrawAdditionalShadowData()
Rect controlRectAdditionalData = EditorGUILayout.GetControlRect(true);
if (m_AdditionalLightDataSO != null)
EditorGUI.BeginProperty(controlRectAdditionalData, Styles.shadowBias, m_UseAdditionalDataProp);
EditorGUI.BeginChangeCheck();

EditorGUI.BeginChangeCheck();
selectedUseAdditionalData = EditorGUI.IntPopup(controlRectAdditionalData, Styles.shadowBias, selectedUseAdditionalData, Styles.displayedDefaultOptions, Styles.optionDefaultValues);
if (EditorGUI.EndChangeCheck())
{
hasChanged = true;
}
bool useAdditionalLightDataChanged = EditorGUI.EndChangeCheck();

if (m_AdditionalLightDataSO != null)
EditorGUI.EndProperty();

Expand All @@ -272,19 +305,16 @@ void DrawAdditionalShadowData()
m_AdditionalLightDataSO.ApplyModifiedProperties();
}

if (hasChanged)
if (useAdditionalLightDataChanged)
{
if (m_AdditionalLightDataSO == null)
{
lightProperty.gameObject.AddComponent<UniversalAdditionalLightData>();
m_AdditionalLightData = lightProperty.gameObject.GetComponent<UniversalAdditionalLightData>();
CreateAdditionalLightData();

var asset = UniversalRenderPipeline.asset;
settings.shadowsBias.floatValue = asset.shadowDepthBias;
settings.shadowsNormalBias.floatValue = asset.shadowNormalBias;
settings.shadowsResolution.intValue = UniversalAdditionalLightData.AdditionalLightsShadowDefaultCustomResolution;

init(m_AdditionalLightData);
}

m_UseAdditionalDataProp.intValue = selectedUseAdditionalData;
Expand Down Expand Up @@ -422,6 +452,31 @@ void ShadowsGUI()
}
}

if (UniversalRenderPipeline.asset.supportsLightLayers)
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_LinkLightLayers, s_Styles.linkLightAndShadowLayers);
// Undo the changes in the light component because the SyncLightAndShadowLayers will change the value automatically when link is ticked
if (EditorGUI.EndChangeCheck())
{
if (m_LinkLightLayers.boolValue)
m_ShadowLayersMask.intValue = m_LightLayersMask.intValue;
lightProperty.renderingLayerMask = m_ShadowLayersMask.intValue;
m_AdditionalLightDataSO.ApplyModifiedProperties();
}

using (new EditorGUI.DisabledGroupScope(m_LinkLightLayers.boolValue))
{
EditorGUI.BeginChangeCheck();
DrawLightLayerMask(m_ShadowLayersMask, s_Styles.ShadowLayer);
if (EditorGUI.EndChangeCheck())
{
lightProperty.renderingLayerMask = m_ShadowLayersMask.intValue;
m_AdditionalLightDataSO.ApplyModifiedProperties();
}
}
}

EditorGUI.indentLevel -= 1;

if (bakingWarningValue)
Expand All @@ -430,6 +485,28 @@ void ShadowsGUI()
EditorGUILayout.Space();
}

void CreateAdditionalLightData()
{
lightProperty.gameObject.AddComponent<UniversalAdditionalLightData>();
m_AdditionalLightData = lightProperty.gameObject.GetComponent<UniversalAdditionalLightData>();
init(m_AdditionalLightData);
}

internal static void DrawLightLayerMask(SerializedProperty property, GUIContent label)
{
Rect lineRect = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight);
int lightLayer = property.intValue;

EditorGUI.BeginProperty(lineRect, label, property);

EditorGUI.BeginChangeCheck();
lightLayer = EditorGUI.MaskField(lineRect, label ?? GUIContent.none, lightLayer, UniversalRenderPipeline.asset.lightLayerMaskNames);
if (EditorGUI.EndChangeCheck())
property.intValue = lightLayer;

EditorGUI.EndProperty();
}

protected override void OnSceneGUI()
{
if (!(GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset))
Expand Down
Expand Up @@ -100,6 +100,22 @@ public enum ColorGradingMode
[ExcludeFromPreset]
public partial class UniversalRenderPipelineAsset : RenderPipelineAsset, ISerializationCallbackReceiver
{
// Rendering layer settings.
// HDRP use GetRenderingLayerMaskNames to create its light linking system
// Mean here we define our name for light linking.
static readonly string[] k_RenderingLayerNames = new string[]
{
"Light Layer default", "Light Layer 1", "Light Layer 2", "Light Layer 3", "Light Layer 4", "Light Layer 5", "Light Layer 6", "Light Layer 7",
"Unused 0", "Unused 1", "Unused 2", "Unused 3", "Unused 4", "Unused 5", "Unused 6", "Unused 7",
"Unused 8", "Unused 9", "Unused 10", "Unused 11", "Unused 12", "Unused 13", "Unused 14", "Unused 15",
"Unused 16", "Unused 17", "Unused 18", "Unused 19", "Unused 20", "Unused 21", "Unused 22", "Unused 23"
};

static readonly string[] k_LightLayerNames = new string[]
{
"Light Layer default", "Light Layer 1", "Light Layer 2", "Light Layer 3", "Light Layer 4", "Light Layer 5", "Light Layer 6", "Light Layer 7"
};

Shader m_DefaultShader;
ScriptableRenderer[] m_Renderers = new ScriptableRenderer[1];

Expand Down Expand Up @@ -158,6 +174,7 @@ public partial class UniversalRenderPipelineAsset : RenderPipelineAsset, ISerial
[SerializeField] bool m_UseSRPBatcher = true;
[SerializeField] bool m_SupportsDynamicBatching = false;
[SerializeField] bool m_MixedLightingSupported = true;
[SerializeField] bool m_SupportsLightLayers = false;
[SerializeField][Obsolete] PipelineDebugLevel m_DebugLevel;

// Adaptive performance settings
Expand Down Expand Up @@ -709,6 +726,11 @@ public bool supportsMixedLighting
get { return m_MixedLightingSupported; }
}

public bool supportsLightLayers
phi-lira marked this conversation as resolved.
Show resolved Hide resolved
{
get { return m_SupportsLightLayers; }
}

public ShaderVariantLogLevel shaderVariantLogLevel
{
get { return m_ShaderVariantLogLevel; }
Expand Down Expand Up @@ -870,6 +892,14 @@ public override Shader defaultSpeedTree8Shader
}
#endif

/// <summary>Names used for display of rendering layer masks.</summary>
public override string[] renderingLayerMaskNames => k_RenderingLayerNames;

/// <summary>
/// Names used for display of light layers.
/// </summary>
public string[] lightLayerMaskNames { get { return k_LightLayerNames; } }

public void OnBeforeSerialize()
{
}
Expand Down