diff --git a/Packages/com.unity.render-pipelines.core/Editor/AssetDatabaseHelper.cs b/Packages/com.unity.render-pipelines.core/Editor/AssetDatabaseHelper.cs new file mode 100644 index 00000000000..dd6742f1efc --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/AssetDatabaseHelper.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.Rendering +{ + /// Set of helpers for AssetDatabase operations. + public static class AssetDatabaseHelper + { + /// + /// Finds all assets of type T in the project. + /// + /// Asset type extension i.e ".mat" for materials + /// The type of material you are looking for + /// A IEnumerable object + public static IEnumerable FindAssets(string extension = null) + { + string typeName = typeof(T).ToString(); + int i = typeName.LastIndexOf('.'); + if (i != -1) + { + typeName = typeName.Substring(i+1, typeName.Length - i-1); + } + + string query = !string.IsNullOrEmpty(extension) ? $"t:{typeName} glob:\"**/*{extension}\"" : $"t:{typeName}"; + + foreach (var guid in AssetDatabase.FindAssets(query)) + { + var asset = AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); + if (asset is T castAsset) + yield return castAsset; + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Editor/AssetDatabaseHelper.cs.meta b/Packages/com.unity.render-pipelines.core/Editor/AssetDatabaseHelper.cs.meta new file mode 100644 index 00000000000..af6fffbb136 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/AssetDatabaseHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ecc2633973414f6d8bbab97cf0c937b4 +timeCreated: 1693402114 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Editor/MaterialUpgrader.cs b/Packages/com.unity.render-pipelines.core/Editor/MaterialUpgrader.cs index 64255d66b6e..8dec029b006 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/MaterialUpgrader.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/MaterialUpgrader.cs @@ -38,6 +38,13 @@ public class MaterialUpgrader string m_OldShader; string m_NewShader; + private static string[] s_PathsWhiteList = new[] + { + "Hidden/", + "HDRP/", + "Shader Graphs/" + }; + /// /// Retrieves path to new shader. /// @@ -309,20 +316,6 @@ public void RenameKeywordToFloat(string oldName, string newName, float setVal, f m_KeywordFloatRename.Add(new KeywordFloatRename { keyword = oldName, property = newName, setVal = setVal, unsetVal = unsetVal }); } - /// - /// Checking if the passed in value is a path to a Material. - /// - /// Path to test. - /// Returns true if the passed in value is a path to a material. - static bool IsMaterialPath(string path) - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentNullException(nameof(path)); - } - return path.EndsWith(".mat", StringComparison.OrdinalIgnoreCase); - } - static MaterialUpgrader GetUpgrader(List upgraders, Material material) { if (material == null || material.shader == null) @@ -364,6 +357,29 @@ static bool ShouldUpgradeShader(Material material, HashSet shaderNamesTo return !shaderNamesToIgnore.Contains(material.shader.name); } + + private static bool IsNotAutomaticallyUpgradable(List upgraders, Material material) + { + return GetUpgrader(upgraders, material) == null && !material.shader.name.ContainsAny(s_PathsWhiteList); + } + + + /// + /// Checking if project folder contains any materials that are not using built-in shaders. + /// + /// List if MaterialUpgraders + /// Returns true if at least one material uses a non-built-in shader (ignores Hidden, HDRP and Shader Graph Shaders) + public static bool ProjectFolderContainsNonBuiltinMaterials(List upgraders) + { + foreach (var material in AssetDatabaseHelper.FindAssets(".mat")) + { + if(IsNotAutomaticallyUpgradable(upgraders, material)) + return true; + } + + return false; + } + /// /// Upgrade the project folder. /// @@ -388,31 +404,21 @@ public static void UpgradeProjectFolder(List upgraders, HashSe if ((!Application.isBatchMode) && (!EditorUtility.DisplayDialog(DialogText.title, "The upgrade will overwrite materials in your project. " + DialogText.projectBackMessage, DialogText.proceed, DialogText.cancel))) return; - int totalMaterialCount = 0; - foreach (string s in UnityEditor.AssetDatabase.GetAllAssetPaths()) - { - if (IsMaterialPath(s)) - totalMaterialCount++; - } - + var materialAssets = AssetDatabase.FindAssets($"t:{nameof(Material)} glob:\"**/*.mat\""); int materialIndex = 0; - foreach (string path in UnityEditor.AssetDatabase.GetAllAssetPaths()) - { - if (IsMaterialPath(path)) - { - materialIndex++; - if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(progressBarName, string.Format("({0} of {1}) {2}", materialIndex, totalMaterialCount, path), (float)materialIndex / (float)totalMaterialCount)) - break; - Material m = UnityEditor.AssetDatabase.LoadMainAssetAtPath(path) as Material; + foreach (var guid in materialAssets) + { + Material material = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); + materialIndex++; + if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(progressBarName, string.Format("({0} of {1}) {2}", materialIndex, materialAssets.Length, material), (float)materialIndex / (float)materialAssets.Length)) + break; - if (!ShouldUpgradeShader(m, shaderNamesToIgnore)) - continue; + if (!ShouldUpgradeShader(material, shaderNamesToIgnore)) + continue; - Upgrade(m, upgraders, flags); + Upgrade(material, upgraders, flags); - //SaveAssetsAndFreeMemory(); - } } // Upgrade terrain specifically since it is a builtin material diff --git a/Packages/com.unity.render-pipelines.core/Editor/StringExtensions.cs b/Packages/com.unity.render-pipelines.core/Editor/StringExtensions.cs index 9733346f0e9..9d9571ef04c 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/StringExtensions.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/StringExtensions.cs @@ -16,5 +16,29 @@ public static class StringExtensions /// The replacement /// The string with the invalid characters replaced public static string ReplaceInvalidFileNameCharacters(this string input, string replacement = "_") => k_InvalidRegEx.Replace(input, replacement); + + + /// + /// Checks if a string contains any of the strings given in strings to check and early out if it does + /// + /// The input string + /// List of strings to check + /// True if a string contains any of the strings given in strings + public static bool ContainsAny(this string input, params string[] stringsToCheck) + { + if(string.IsNullOrEmpty(input)) + return false; + + foreach (var value in stringsToCheck) + { + if(string.IsNullOrEmpty(value)) + continue; + + if (input.Contains(value)) + return true; + } + + return false; + } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeParameter.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeParameter.cs index 2b33338d4c3..a92c1291281 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeParameter.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeParameter.cs @@ -1875,6 +1875,20 @@ public override object Clone() { return new AnimationCurveParameter(new AnimationCurve(GetValue().keys), overrideState); } + + /// + /// Returns a hash code for the animationCurve. + /// + /// A hash code for the animationCurve. + public override int GetHashCode() + { + unchecked + { + var hash = overrideState.GetHashCode(); + + return hash * 23 + value.GetHashCode(); + } + } } /// diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl index eedecaf0a20..1f561dfab68 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl @@ -66,6 +66,48 @@ // The function of the shader library are stateless, no uniform declare in it. // Any function that require an explicit precision, use float or half qualifier, when the function can support both, it use real (see below) // If a function require to have both a half and a float version, then both need to be explicitly define + +/// +/// Hardware Support for Wave Operations +/// + +// Support for wave operations is intentionally limited to the compute shader stage in order to make this functionality available to a wider range of hardware. +#if defined(SHADER_STAGE_COMPUTE) + // + // Platform Support + // + #if (defined(UNITY_PLATFORM_SUPPORTS_WAVE_32) || defined(UNITY_PLATFORM_SUPPORTS_WAVE_64)) + #if defined(UNITY_PLATFORM_SUPPORTS_WAVE_32) + #define UNITY_HW_WAVE_SIZE 32 + #elif defined(UNITY_PLATFORM_SUPPORTS_WAVE_64) + #define UNITY_HW_WAVE_SIZE 64 + #endif + + #define UNITY_PLATFORM_SUPPORTS_WAVE 1 + // + // Device Support + // + #elif (defined(UNITY_DEVICE_SUPPORTS_WAVE_ANY) || defined(UNITY_DEVICE_SUPPORTS_WAVE_8) || defined(UNITY_DEVICE_SUPPORTS_WAVE_16) || defined(UNITY_DEVICE_SUPPORTS_WAVE_32) || defined(UNITY_DEVICE_SUPPORTS_WAVE_64) || defined(UNITY_DEVICE_SUPPORTS_WAVE_128)) + #if defined(UNITY_DEVICE_SUPPORTS_WAVE_8) + #define UNITY_HW_WAVE_SIZE 8 + #elif defined(UNITY_DEVICE_SUPPORTS_WAVE_16) + #define UNITY_HW_WAVE_SIZE 16 + #elif defined(UNITY_DEVICE_SUPPORTS_WAVE_32) + #define UNITY_HW_WAVE_SIZE 32 + #elif defined(UNITY_DEVICE_SUPPORTS_WAVE_64) + #define UNITY_HW_WAVE_SIZE 64 + #elif defined(UNITY_DEVICE_SUPPORTS_WAVE_128) + #define UNITY_HW_WAVE_SIZE 128 + #endif + + #define UNITY_DEVICE_SUPPORTS_WAVE 1 + #endif + + #if (defined(UNITY_PLATFORM_SUPPORTS_WAVE) || defined(UNITY_DEVICE_SUPPORTS_WAVE)) + #define UNITY_HW_SUPPORTS_WAVE 1 + #endif +#endif + #ifndef real // The including shader should define whether half @@ -368,8 +410,8 @@ #define LODDitheringTransition ERROR_ON_UNSUPPORTED_FUNCTION(LODDitheringTransition) #endif -// On everything but GCN consoles or DXC compiled shaders we error on cross-lane operations -#if !defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(UNITY_COMPILER_DXC) +#if !defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(UNITY_COMPILER_DXC) && !defined(UNITY_HW_SUPPORTS_WAVE) +// Intercept wave functions when they aren't supported to provide better error messages #define WaveActiveAllTrue ERROR_ON_UNSUPPORTED_FUNCTION(WaveActiveAllTrue) #define WaveActiveAnyTrue ERROR_ON_UNSUPPORTED_FUNCTION(WaveActiveAnyTrue) #define WaveGetLaneIndex ERROR_ON_UNSUPPORTED_FUNCTION(WaveGetLaneIndex) diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Hashes.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Hashes.hlsl index 4d6ce25e8f8..16a61a30acc 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Hashes.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Hashes.hlsl @@ -14,7 +14,7 @@ void Hash_Tchou_2_1_float(float2 i, out float o) uint r; uint2 v = (uint2) (int2) round(i); Hash_Tchou_2_1_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_2_1_half(half2 i, out half o) @@ -22,7 +22,7 @@ void Hash_Tchou_2_1_half(half2 i, out half o) uint r; uint2 v = (uint2) (int2) round(i); Hash_Tchou_2_1_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_2_3_uint(uint2 q, out uint3 o) @@ -45,7 +45,7 @@ void Hash_Tchou_2_3_float(float2 i, out float3 o) uint3 r; uint2 v = (uint2) (int2) round(i); Hash_Tchou_2_3_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_2_3_half(half2 i, out half3 o) @@ -53,7 +53,7 @@ void Hash_Tchou_2_3_half(half2 i, out half3 o) uint3 r; uint2 v = (uint2) (int2) round(i); Hash_Tchou_2_3_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_2_2_uint(uint2 v, out uint2 o) @@ -73,7 +73,7 @@ void Hash_Tchou_2_2_float(float2 i, out float2 o) uint2 r; uint2 v = (uint2) (int2) round(i); Hash_Tchou_2_2_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_2_2_half(half2 i, out half2 o) @@ -81,7 +81,7 @@ void Hash_Tchou_2_2_half(half2 i, out half2 o) uint2 r; uint2 v = (uint2) (int2) round(i); Hash_Tchou_2_2_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_3_1_uint(uint3 v, out uint o) @@ -102,7 +102,7 @@ void Hash_Tchou_3_1_float(float3 i, out float o) uint r; uint3 v = (uint3) (int3) round(i); Hash_Tchou_3_1_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_3_1_half(half3 i, out half o) @@ -110,7 +110,7 @@ void Hash_Tchou_3_1_half(half3 i, out half o) uint r; uint3 v = (uint3) (int3) round(i); Hash_Tchou_3_1_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_3_3_uint(uint3 v, out uint3 o) @@ -132,14 +132,14 @@ void Hash_Tchou_3_3_float(float3 i, out float3 o) { uint3 r, v = (uint3) (int3) round(i); Hash_Tchou_3_3_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_Tchou_3_3_half(half3 i, out half3 o) { uint3 r, v = (uint3) (int3) round(i); Hash_Tchou_3_3_uint(v, r); - o = r * (1.0 / float(0xffffffff)); + o = (r >> 8) * (1.0 / float(0x00ffffff)); } void Hash_LegacySine_2_1_float(float2 i, out float o) diff --git a/Packages/com.unity.render-pipelines.high-definition-config/Runtime/ShaderConfig.cs b/Packages/com.unity.render-pipelines.high-definition-config/Runtime/ShaderConfig.cs index b1b9410fc24..1a2753c6342 100644 --- a/Packages/com.unity.render-pipelines.high-definition-config/Runtime/ShaderConfig.cs +++ b/Packages/com.unity.render-pipelines.high-definition-config/Runtime/ShaderConfig.cs @@ -15,6 +15,15 @@ internal enum FPTLMaxLightSizes Ultra = 255 } + internal enum PathTracingLightListSizes + { + Low = 8, + Medium = 16, + High = 32, + Ultra = 64 + } + + /// /// Project-wide shader configuration options. /// @@ -53,7 +62,18 @@ public enum ShaderOptions /// Lower count will mean some memory savings. /// Note: For any rendering bigger than 4k (in native) it is recommended to use Low count per tile, to avoid possible artifacts. /// - FPTLMaxLightCount = FPTLMaxLightSizes.High + FPTLMaxLightCount = FPTLMaxLightSizes.High, + + /// + /// The upper limit for the maximum amount of elements per cell in the light cluster. The maximum can be set in the project settings. This value caps the maximum. + /// + LightClusterMaxCellElementCount = 24, + + /// + /// Maximum number of lights used in the path tracer light list. This number can be one of the prespecified possibilities in PathTracingLightListSizes, or can be chosen manually. + /// Lower count will mean some memory savings. + /// + PathTracingMaxLightCount = PathTracingLightListSizes.Medium }; // Note: #define can't be use in include file in C# so we chose this way to configure both C# and hlsl @@ -94,6 +114,12 @@ public class ShaderConfig /// Indicates the maximum number of lights available for Fine Prunning Tile Lighting. /// public static int FPTLMaxLightCount = (int)ShaderOptions.FPTLMaxLightCount; + /// Indicates the cap on the maximum number of elements per cell in the light cluster. + /// + public const int LightClusterMaxCellElementCount = (int)ShaderOptions.LightClusterMaxCellElementCount; + /// Indicates the maximum number of lights in the path tracing light list. + /// + public static int PathTracingMaxLightCount = (int)ShaderOptions.PathTracingMaxLightCount; } /// diff --git a/Packages/com.unity.render-pipelines.high-definition-config/Runtime/ShaderConfig.cs.hlsl b/Packages/com.unity.render-pipelines.high-definition-config/Runtime/ShaderConfig.cs.hlsl index adae23cd603..1dea1fe82a3 100644 --- a/Packages/com.unity.render-pipelines.high-definition-config/Runtime/ShaderConfig.cs.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition-config/Runtime/ShaderConfig.cs.hlsl @@ -16,6 +16,7 @@ #define SHADEROPTIONS_BARN_DOOR (0) #define SHADEROPTIONS_GLOBAL_MIP_BIAS (1) #define SHADEROPTIONS_FPTLMAX_LIGHT_COUNT (63) +#define SHADEROPTIONS_PATH_TRACING_MAX_LIGHT_COUNT (16) // // UnityEngine.Rendering.HighDefinition.InternalLightCullingDefs: static fields diff --git a/Packages/com.unity.render-pipelines.high-definition/Documentation~/HDRP-Config-Package.md b/Packages/com.unity.render-pipelines.high-definition/Documentation~/HDRP-Config-Package.md index d3eca1c1745..f19b7083099 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Documentation~/HDRP-Config-Package.md +++ b/Packages/com.unity.render-pipelines.high-definition/Documentation~/HDRP-Config-Package.md @@ -7,6 +7,8 @@ For example, you can use it to: * Disable Area Light. * Disable Pre-exposition. * Enable [camera-relative rendering](Camera-Relative-Rendering.md). +* Increase the size of the tile and cluster light list for rasterization. +* Increase the size of [the Path Tracing light list](Ray-Tracing-Path-Tracing.md). ## Using the HDRP Config package diff --git a/Packages/com.unity.render-pipelines.high-definition/Documentation~/Ray-Tracing-Path-Tracing.md b/Packages/com.unity.render-pipelines.high-definition/Documentation~/Ray-Tracing-Path-Tracing.md index 397cf4f4f67..af205bd5945 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Documentation~/Ray-Tracing-Path-Tracing.md +++ b/Packages/com.unity.render-pipelines.high-definition/Documentation~/Ray-Tracing-Path-Tracing.md @@ -168,6 +168,14 @@ If there is any noise that affects the exposure in the final converged frame, ad * **Limit Max** +## Path tracing and Light sources + +Due to the fundamentally different nature of Path Tracing, light sources are queried differently. To support this, the path tracer needs to build some additional data structures that contain light source information. These data structures limit the maximum number of lights that can be evaluated in local neighborhoods. In the current implementation, there are two such data structures. + +The first one is the [Ray Tracing Light Cluster](Ray-Tracing-Light-Cluster.md). It is used to resolve the lights around a specific point. The maximum number of lights per cell in this cluster can be increased if necessary. + +The second one is the Path Tracing light list, an internal data structure used to capture all light sources relevant to a specific path segment. If too many light sources are close to each other, they might not all fit in the light list. This might result in artifacts. To remove these artifacts, you can change the `PathTracingMaxLightCount` setting through the [HDRP Config mechanism](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/index.html?subfolder=/manual/HDRP-Config-Package.html). + ## Limitations This section contains information on the limitations of HDRP's path tracing implementation. Mainly, this is a list of features that HDRP supports in its rasterized render pipeline, but not in its path-traced render pipeline. diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/TransparencyUIBlock.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/TransparencyUIBlock.cs index 3fe7473bef1..1272fd44241 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/TransparencyUIBlock.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/TransparencyUIBlock.cs @@ -74,7 +74,12 @@ protected override bool showSection if (materials[0].IsShaderGraph()) { var shader = materials[0].shader; - var defaultRefractionModel = shader.GetPropertyDefaultFloatValue(shader.FindPropertyIndex(kRefractionModel)); + + var propertyIndex = shader.FindPropertyIndex(kRefractionModel); + if (propertyIndex == -1) + return false; + + var defaultRefractionModel = shader.GetPropertyDefaultFloatValue(propertyIndex); if (defaultRefractionModel == 0) return false; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs index 5e87227e4d7..c000fae0c8d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs @@ -179,6 +179,7 @@ public class Styles public const string cacheErrorFormat = "This configuration will lead to more than 2 GB reserved for this cache at runtime! ({0} requested) Only {1} element will be reserved instead."; public const string cacheInfoFormat = "Reserving {0} in memory at runtime."; public const string multipleDifferenteValueMessage = "Multiple different values"; + public const string rayTracingUnsupportedMessage = "The current HDRP Asset does not support Ray Tracing."; public static readonly GUIContent cookieSizeContent = EditorGUIUtility.TrTextContent("Cookie Size", "Specifies the maximum size for the individual 2D cookies that HDRP uses for Directional and Spot Lights."); public static readonly GUIContent cookieTextureArraySizeContent = EditorGUIUtility.TrTextContent("Texture Array Size", "Sets the maximum Texture Array size for the 2D cookies HDRP uses for Directional and Spot Lights. Higher values allow HDRP to use more cookies concurrently on screen."); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Raytracing/LightClusterEditor.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Raytracing/LightClusterEditor.cs new file mode 100644 index 00000000000..b74f2c4b315 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Raytracing/LightClusterEditor.cs @@ -0,0 +1,27 @@ +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.HighDefinition; + +namespace UnityEditor.Rendering.HighDefinition +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(LightCluster))] + class LightClusterEditor : VolumeComponentEditor + { + public override void OnInspectorGUI() + { + HDRenderPipelineAsset currentAsset = HDRenderPipeline.currentAsset; + bool notSupported = currentAsset != null && !currentAsset.currentPlatformRenderPipelineSettings.supportRayTracing; + if (notSupported) + { + EditorGUILayout.Space(); + HDEditorUtils.QualitySettingsHelpBox(HDRenderPipelineUI.Styles.rayTracingUnsupportedMessage, + MessageType.Warning, HDRenderPipelineUI.Expandable.Rendering, + "m_RenderPipelineSettings.supportRayTracing"); + } + using var disableScope = new EditorGUI.DisabledScope(notSupported); + + base.OnInspectorGUI(); + } + } +} diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Raytracing/LightClusterEditor.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Raytracing/LightClusterEditor.cs.meta new file mode 100644 index 00000000000..224c1780c69 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Raytracing/LightClusterEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d4669e8c9d524c4e972b97a5c8b9e3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Upgraders/UpgradeStandardShaderMaterials.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Upgraders/UpgradeStandardShaderMaterials.cs index c41b49d5a5f..491776f0cc5 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Upgraders/UpgradeStandardShaderMaterials.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Upgraders/UpgradeStandardShaderMaterials.cs @@ -7,7 +7,7 @@ namespace UnityEditor.Rendering.HighDefinition { class UpgradeStandardShaderMaterials { - static List GetHDUpgraders() + public static List GetHDUpgraders() { var upgraders = new List(); upgraders.Add(new StandardsToHDLitMaterialUpgrader("Standard", "HDRP/Lit")); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/UIBlocks/VFXShaderGraphGUI.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/UIBlocks/VFXShaderGraphGUI.cs index afbe5b1a500..86d7dcc9e17 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/UIBlocks/VFXShaderGraphGUI.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/UIBlocks/VFXShaderGraphGUI.cs @@ -15,6 +15,9 @@ public VFXShaderGraphGUILit() { uiBlocks.Clear(); uiBlocks.Add(new SurfaceOptionUIBlock(MaterialUIBlock.ExpandableBit.Base, features: vfxSurfaceOptionFeatures)); + //VFX inspector UI is taking a shortcut here: + //We aren't doing distinction between LightingShaderGraphGUI & LitShaderGUI + //Only refraction has to be added to cover all settings cases uiBlocks.Add(new TransparencyUIBlock(MaterialUIBlock.ExpandableBit.Transparency, TransparencyUIBlock.Features.Refraction)); } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.Window.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.Window.cs index 56606ee55aa..4711297b4ea 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.Window.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.Window.cs @@ -53,6 +53,7 @@ static class Style public static readonly string resolveAllQuality = L10n.Tr("Fix All Qualities"); public static readonly string resolveAllBuildTarget = L10n.Tr("Fix All Platforms"); public static readonly string fixAllOnNonHDRP = L10n.Tr("The active Quality Level is not using a High Definition Render Pipeline asset. If you attempt a Fix All, the Quality Level will be changed to use it."); + public static readonly string nonBuiltinMaterialWarning = L10n.Tr("The project contains materials that are not using built-in shaders. These will be skipped in the automated migration process."); public struct ConfigStyle { @@ -439,6 +440,13 @@ private void CreateGUI() currentQualityScope.Add(dxrScopeCurrentQuality); container.Add(CreateTitle(Style.migrationTitle)); + + if (MaterialUpgrader.ProjectFolderContainsNonBuiltinMaterials( + UpgradeStandardShaderMaterials.GetHDUpgraders())) + { + container.Add(new HelpBox(HelpBox.Kind.Warning, Style.nonBuiltinMaterialWarning)); + } + container.Add(CreateLargeButton(Style.migrateAllButton, UpgradeStandardShaderMaterials.UpgradeMaterialsProject)); container.Add(CreateLargeButton(Style.migrateSelectedButton, UpgradeStandardShaderMaterials.UpgradeMaterialsSelection)); container.Add(CreateLargeButton(Style.migrateMaterials, HDRenderPipelineMenuItems.UpgradeMaterials)); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs index 19f5d21347d..9a644594fb4 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs @@ -776,7 +776,8 @@ public bool useScreenSpaceShadows /// public bool interactsWithSky { - get => m_InteractsWithSky; + // m_InteractWithSky can be true if user changed from directional to point light, so we need to check current type + get => m_InteractsWithSky && legacyLight.type == LightType.Directional; set { if (m_InteractsWithSky == value) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.Jobs.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.Jobs.cs index ad88040c204..c5e369b3d70 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.Jobs.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.Jobs.cs @@ -79,8 +79,6 @@ internal struct CreateGpuLightDataJob : IJobParallelFor public float aerosolExtinctionCoefficient; [ReadOnly] public float maxShadowDistance; - [ReadOnly] - public float shadowOutBorderDistance; #endregion @@ -639,21 +637,6 @@ private void ConvertDirectionalLightToGPUFormat( var bakingOutput = visibleLightBakingOutput[lightIndex]; lightData.shadowMaskSelector[bakingOutput.occlusionMaskChannel] = 1.0f; lightData.nonLightMappedOnly = visibleLightShadowCasterMode[lightIndex] == LightShadowCasterMode.NonLightmappedOnly ? 1 : 0; - // Get shadow info from the volume stack. - float maxDistanceSq = maxShadowDistance * maxShadowDistance; - float outBorderDistance = shadowOutBorderDistance; - if (outBorderDistance < 1e-4f) - { - lightData.cascadesBorderFadeScaleBias = new Vector2(1e6f, -maxDistanceSq * 1e6f); - } - else - { - outBorderDistance = 1.0f - outBorderDistance; - outBorderDistance *= outBorderDistance; - float distanceFadeNear = outBorderDistance * maxDistanceSq; - lightData.cascadesBorderFadeScaleBias.x = 1.0f / (maxDistanceSq - distanceFadeNear); - lightData.cascadesBorderFadeScaleBias.y = -distanceFadeNear / (maxDistanceSq - distanceFadeNear); - } } else { @@ -764,7 +747,6 @@ public void StartCreateGpuLightDataJob( aerosolExtinctionCoefficient = skySettings.GetAerosolExtinctionCoefficient(), maxShadowDistance = shadowSettings.maxShadowDistance.value, - shadowOutBorderDistance = shadowSettings.cascadeShadowBorders[shadowSettings.cascadeShadowSplitCount.value - 1], // light entity data lightRenderDataArray = lightEntities.lightData, diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs index 3bf4f5806fa..562fed9c0fb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs @@ -95,8 +95,6 @@ struct DirectionalLightData [SurfaceDataAttributes(precision = FieldPrecision.Real)] public Vector4 shadowMaskSelector; // Used with ShadowMask feature - public Vector2 cascadesBorderFadeScaleBias; - public float diffuseDimmer; public float specularDimmer; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs.hlsl index 2a893426276..1146c0ab2fb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs.hlsl @@ -5,29 +5,16 @@ #ifndef LIGHTDEFINITION_CS_HLSL #define LIGHTDEFINITION_CS_HLSL // -// UnityEngine.Rendering.HighDefinition.GPULightType: static fields -// -#define GPULIGHTTYPE_DIRECTIONAL (0) -#define GPULIGHTTYPE_POINT (1) -#define GPULIGHTTYPE_SPOT (2) -#define GPULIGHTTYPE_PROJECTOR_PYRAMID (3) -#define GPULIGHTTYPE_PROJECTOR_BOX (4) -#define GPULIGHTTYPE_TUBE (5) -#define GPULIGHTTYPE_RECTANGLE (6) -#define GPULIGHTTYPE_DISC (7) - -// -// UnityEngine.Rendering.HighDefinition.GPUImageBasedLightingType: static fields +// UnityEngine.Rendering.HighDefinition.EnvCacheType: static fields // -#define GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION (0) -#define GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION (1) +#define ENVCACHETYPE_TEXTURE2D (0) +#define ENVCACHETYPE_CUBEMAP (1) // -// UnityEngine.Rendering.HighDefinition.CookieMode: static fields +// UnityEngine.Rendering.HighDefinition.EnvLightReflectionDataRT: static fields // -#define COOKIEMODE_NONE (0) -#define COOKIEMODE_CLAMP (1) -#define COOKIEMODE_REPEAT (2) +#define MAX_PLANAR_REFLECTIONS (16) +#define MAX_CUBE_REFLECTIONS (64) // // UnityEngine.Rendering.HighDefinition.EnvShapeType: static fields @@ -43,64 +30,81 @@ #define ENVCONSTANTS_CONVOLUTION_MIP_COUNT (7) // -// UnityEngine.Rendering.HighDefinition.EnvLightReflectionData: static fields +// UnityEngine.Rendering.HighDefinition.GPUImageBasedLightingType: static fields // -#define MAX_PLANAR_REFLECTIONS (16) -#define MAX_CUBE_REFLECTIONS (64) +#define GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION (0) +#define GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION (1) // -// UnityEngine.Rendering.HighDefinition.EnvLightReflectionDataRT: static fields +// UnityEngine.Rendering.HighDefinition.CookieMode: static fields +// +#define COOKIEMODE_NONE (0) +#define COOKIEMODE_CLAMP (1) +#define COOKIEMODE_REPEAT (2) + +// +// UnityEngine.Rendering.HighDefinition.EnvLightReflectionData: static fields // #define MAX_PLANAR_REFLECTIONS (16) #define MAX_CUBE_REFLECTIONS (64) // -// UnityEngine.Rendering.HighDefinition.EnvCacheType: static fields +// UnityEngine.Rendering.HighDefinition.GPULightType: static fields // -#define ENVCACHETYPE_TEXTURE2D (0) -#define ENVCACHETYPE_CUBEMAP (1) +#define GPULIGHTTYPE_DIRECTIONAL (0) +#define GPULIGHTTYPE_POINT (1) +#define GPULIGHTTYPE_SPOT (2) +#define GPULIGHTTYPE_PROJECTOR_PYRAMID (3) +#define GPULIGHTTYPE_PROJECTOR_BOX (4) +#define GPULIGHTTYPE_TUBE (5) +#define GPULIGHTTYPE_RECTANGLE (6) +#define GPULIGHTTYPE_DISC (7) -// Generated from UnityEngine.Rendering.HighDefinition.DirectionalLightData +// Generated from UnityEngine.Rendering.HighDefinition.EnvLightData // PackingRules = Exact -struct DirectionalLightData +struct EnvLightData { - float3 positionRWS; uint lightLayers; - float lightDimmer; - float volumetricLightDimmer; - float3 forward; - int cookieMode; - float4 cookieScaleOffset; - float3 right; - int shadowIndex; - float3 up; - int contactShadowIndex; - float3 color; - int contactShadowMask; - float3 shadowTint; - float shadowDimmer; - float volumetricShadowDimmer; - int nonLightMappedOnly; - real minRoughness; - int screenSpaceShadowIndex; - real4 shadowMaskSelector; - float2 cascadesBorderFadeScaleBias; - float diffuseDimmer; - float specularDimmer; - float penumbraTint; - float isRayTracedContactShadow; - float distanceFromCamera; - float angularDiameter; - float flareFalloff; - float flareCosInner; - float flareCosOuter; - float __unused__; - float3 flareTint; - float flareSize; - float3 surfaceTint; - float4 surfaceTextureScaleOffset; + float3 capturePositionRWS; + int influenceShapeType; + float3 proxyExtents; + real minProjectionDistance; + float3 proxyPositionRWS; + float3 proxyForward; + float3 proxyUp; + float3 proxyRight; + float3 influencePositionRWS; + float3 influenceForward; + float3 influenceUp; + float3 influenceRight; + float3 influenceExtents; + float3 blendDistancePositive; + float3 blendDistanceNegative; + float3 blendNormalDistancePositive; + float3 blendNormalDistanceNegative; + real3 boxSideFadePositive; + real3 boxSideFadeNegative; + float weight; + float multiplier; + float rangeCompressionFactorCompensation; + float roughReflections; + float distanceBasedRoughness; + int envIndex; + float4 L0L1; + float4 L2_1; + float L2_2; + int normalizeWithAPV; + float2 padding; }; +// Generated from UnityEngine.Rendering.HighDefinition.EnvLightReflectionDataRT +// PackingRules = Exact +CBUFFER_START(EnvLightReflectionDataRT) + float4x4 _PlanarCaptureVPRT[16]; + float4 _PlanarScaleOffsetRT[16]; + float4 _CubeScaleOffsetRT[64]; +CBUFFER_END + // Generated from UnityEngine.Rendering.HighDefinition.LightData // PackingRules = Exact struct LightData @@ -141,43 +145,6 @@ struct LightData float boxLightSafeExtent; }; -// Generated from UnityEngine.Rendering.HighDefinition.EnvLightData -// PackingRules = Exact -struct EnvLightData -{ - uint lightLayers; - float3 capturePositionRWS; - int influenceShapeType; - float3 proxyExtents; - real minProjectionDistance; - float3 proxyPositionRWS; - float3 proxyForward; - float3 proxyUp; - float3 proxyRight; - float3 influencePositionRWS; - float3 influenceForward; - float3 influenceUp; - float3 influenceRight; - float3 influenceExtents; - float3 blendDistancePositive; - float3 blendDistanceNegative; - float3 blendNormalDistancePositive; - float3 blendNormalDistanceNegative; - real3 boxSideFadePositive; - real3 boxSideFadeNegative; - float weight; - float multiplier; - float rangeCompressionFactorCompensation; - float roughReflections; - float distanceBasedRoughness; - int envIndex; - float4 L0L1; - float4 L2_1; - float L2_2; - int normalizeWithAPV; - float2 padding; -}; - // Generated from UnityEngine.Rendering.HighDefinition.EnvLightReflectionData // PackingRules = Exact CBUFFER_START(EnvLightReflectionData) @@ -186,13 +153,45 @@ CBUFFER_START(EnvLightReflectionData) float4 _CubeScaleOffset[64]; CBUFFER_END -// Generated from UnityEngine.Rendering.HighDefinition.EnvLightReflectionDataRT +// Generated from UnityEngine.Rendering.HighDefinition.DirectionalLightData // PackingRules = Exact -CBUFFER_START(EnvLightReflectionDataRT) - float4x4 _PlanarCaptureVPRT[16]; - float4 _PlanarScaleOffsetRT[16]; - float4 _CubeScaleOffsetRT[64]; -CBUFFER_END +struct DirectionalLightData +{ + float3 positionRWS; + uint lightLayers; + float lightDimmer; + float volumetricLightDimmer; + float3 forward; + int cookieMode; + float4 cookieScaleOffset; + float3 right; + int shadowIndex; + float3 up; + int contactShadowIndex; + float3 color; + int contactShadowMask; + float3 shadowTint; + float shadowDimmer; + float volumetricShadowDimmer; + int nonLightMappedOnly; + real minRoughness; + int screenSpaceShadowIndex; + real4 shadowMaskSelector; + float diffuseDimmer; + float specularDimmer; + float penumbraTint; + float isRayTracedContactShadow; + float distanceFromCamera; + float angularDiameter; + float flareFalloff; + float flareCosInner; + float flareCosOuter; + float __unused__; + float3 flareTint; + float flareSize; + float3 surfaceTint; + float4 surfaceTextureScaleOffset; +}; #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightEvaluation.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightEvaluation.hlsl index 077b8c0a039..b7dbd8ed50b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightEvaluation.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightEvaluation.hlsl @@ -271,12 +271,20 @@ SHADOW_TYPE EvaluateShadow_Directional( LightLoopContext lightLoopContext, Posit #ifdef SHADOWS_SHADOWMASK float3 camToPixel = posInput.positionWS - GetPrimaryCameraPosition(); float distanceCamToPixel2 = dot(camToPixel, camToPixel); - float fade = saturate(distanceCamToPixel2 * light.cascadesBorderFadeScaleBias.x + light.cascadesBorderFadeScaleBias.y); - // In the transition code (both dithering and blend) we use shadow = lerp( shadow, 1.0, fade ) for last transition - // mean if we expend the code we have (shadow * (1 - fade) + fade). Here to make transition with shadow mask - // we will remove fade and add fade * shadowMask which mean we do a lerp with shadow mask - shadow = shadow - fade + fade * shadowMask; + int shadowSplitIndex = lightLoopContext.shadowContext.shadowSplitIndex; + if (shadowSplitIndex < 0) + { + shadow = shadowMask; + } + else if (shadowSplitIndex == int(_CascadeShadowCount) - 1) + { + float fade = lightLoopContext.shadowContext.fade; + // In the transition code (both dithering and blend) we use shadow = lerp( shadow, 1.0, fade ) for last transition + // mean if we expend the code we have (shadow * (1 - fade) + fade). Here to make transition with shadow mask + // we will remove fade and add fade * shadowMask which mean we do a lerp with shadow mask + shadow = shadow - fade + fade * shadowMask; + } // See comment in EvaluateBSDF_Punctual shadow = light.nonLightMappedOnly ? min(shadowMask, shadow) : shadow; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl index 259170fe9c9..7f8ba241fd6 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl @@ -22,7 +22,7 @@ // normalWS is the vertex normal if available or shading normal use to bias the shadow position -float GetDirectionalShadowAttenuation(HDShadowContext shadowContext, float2 positionSS, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L) +float GetDirectionalShadowAttenuation(inout HDShadowContext shadowContext, float2 positionSS, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L) { #if SHADOW_AUTO_FLIP_NORMAL normalWS *= FastSign(dot(normalWS, L)); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs index 7536ac44e0f..8cc9422ec88 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs @@ -268,7 +268,7 @@ public partial class HDRenderPipeline internal const int k_MaxDecalsOnScreen = 2048; internal const int k_MaxPlanarReflectionsOnScreen = 16; internal const int k_MaxCubeReflectionsOnScreen = 64; - internal const int k_MaxLightsPerClusterCell = 24; + internal const int k_MaxLightsPerClusterCell = ShaderConfig.LightClusterMaxCellElementCount; internal static readonly Vector3 k_BoxCullingExtentThreshold = Vector3.one * 0.01f; #if UNITY_SWITCH @@ -1976,16 +1976,19 @@ void PushLightDataGlobalParams(CommandBuffer cmd) for (int viewId = 0; viewId < m_GpuLightsBuilder.lightsPerViewCount; ++viewId) { HDGpuLightsBuilder.LightsPerView lightsPerView = m_GpuLightsBuilder.lightsPerView[viewId]; - Debug.Assert(lightsPerView.boundsCount <= m_TotalLightCount, "Encountered bounds counts that are greater than the total light count."); + + bool validLightCount = lightsPerView.boundsCount <= m_TileAndClusterData.maxLightCount; + Debug.Assert(validLightCount, "Encountered bounds counts that are greater than the total light count."); /// In the CPU we have stored the left and right eye in one single array, offset by the LightsPerView.boundsOffset. This is before trivial rejection. /// In the GPU we compact them, and access each eye by the actual m_TotalLightCount, which contains the post trivial rejection offset. int inputStartIndex = lightsPerView.boundsOffset; int outputStartIndex = viewId * m_TotalLightCount; + int maxLightCount = (validLightCount) ? lightsPerView.boundsCount : m_TileAndClusterData.maxLightCount; // These two buffers have been set in Rebuild(). At this point, view 0 contains combined data from all views - m_TileAndClusterData.convexBoundsBuffer.SetData(m_GpuLightsBuilder.lightBounds, inputStartIndex, outputStartIndex, lightsPerView.boundsCount); - m_TileAndClusterData.lightVolumeDataBuffer.SetData(m_GpuLightsBuilder.lightVolumes, inputStartIndex, outputStartIndex, lightsPerView.boundsCount); + m_TileAndClusterData.convexBoundsBuffer.SetData(m_GpuLightsBuilder.lightBounds, inputStartIndex, outputStartIndex, maxLightCount); + m_TileAndClusterData.lightVolumeDataBuffer.SetData(m_GpuLightsBuilder.lightVolumes, inputStartIndex, outputStartIndex, maxLightCount); } ConstantBuffer.PushGlobal(cmd, m_EnvLightReflectionData, HDShaderIDs._EnvLightReflectionData); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAlgorithms.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAlgorithms.hlsl index 69baa6b4d70..beefb0fda7a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAlgorithms.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAlgorithms.hlsl @@ -254,12 +254,16 @@ void LoadDirectionalShadowDatas(inout HDShadowData sd, HDShadowContext shadowCon sd.cacheTranslationDelta = shadowContext.shadowDatas[index].cacheTranslationDelta; } -float EvalShadow_CascadedDepth_Blend_SplitIndex(HDShadowContext shadowContext, Texture2D tex, SamplerComparisonState samp, float2 positionSS, float3 positionWS, float3 normalWS, int index, float3 L, out int shadowSplitIndex) +float EvalShadow_CascadedDepth_Blend_SplitIndex(inout HDShadowContext shadowContext, Texture2D tex, SamplerComparisonState samp, float2 positionSS, float3 positionWS, float3 normalWS, int index, float3 L, out int shadowSplitIndex) { float alpha; int cascadeCount; float shadow = 1.0; shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, alpha, cascadeCount); +#ifdef SHADOWS_SHADOWMASK + shadowContext.shadowSplitIndex = shadowSplitIndex; + shadowContext.fade = alpha; +#endif float3 basePositionWS = positionWS; @@ -309,18 +313,22 @@ float EvalShadow_CascadedDepth_Blend_SplitIndex(HDShadowContext shadowContext, T return shadow; } -float EvalShadow_CascadedDepth_Blend(HDShadowContext shadowContext, Texture2D tex, SamplerComparisonState samp, float2 positionSS, float3 positionWS, float3 normalWS, int index, float3 L) +float EvalShadow_CascadedDepth_Blend(inout HDShadowContext shadowContext, Texture2D tex, SamplerComparisonState samp, float2 positionSS, float3 positionWS, float3 normalWS, int index, float3 L) { int unusedSplitIndex; return EvalShadow_CascadedDepth_Blend_SplitIndex(shadowContext, tex, samp, positionSS, positionWS, normalWS, index, L, unusedSplitIndex); } -float EvalShadow_CascadedDepth_Dither_SplitIndex(HDShadowContext shadowContext, Texture2D tex, SamplerComparisonState samp, float2 positionSS, float3 positionWS, float3 normalWS, int index, float3 L, out int shadowSplitIndex) +float EvalShadow_CascadedDepth_Dither_SplitIndex(inout HDShadowContext shadowContext, Texture2D tex, SamplerComparisonState samp, float2 positionSS, float3 positionWS, float3 normalWS, int index, float3 L, out int shadowSplitIndex) { float alpha; int cascadeCount; float shadow = 1.0; shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, alpha, cascadeCount); +#ifdef SHADOWS_SHADOWMASK + shadowContext.shadowSplitIndex = shadowSplitIndex; + shadowContext.fade = alpha; +#endif // Forcing the alpha to zero allows us to avoid the dithering as it requires the screen space position and an additional // shadow read wich can be avoided in this case. @@ -362,7 +370,7 @@ float EvalShadow_CascadedDepth_Dither_SplitIndex(HDShadowContext shadowContext, return shadow; } -float EvalShadow_CascadedDepth_Dither(HDShadowContext shadowContext, Texture2D tex, SamplerComparisonState samp, float2 positionSS, float3 positionWS, float3 normalWS, int index, float3 L) +float EvalShadow_CascadedDepth_Dither(inout HDShadowContext shadowContext, Texture2D tex, SamplerComparisonState samp, float2 positionSS, float3 positionWS, float3 normalWS, int index, float3 L) { int unusedSplitIndex; return EvalShadow_CascadedDepth_Dither_SplitIndex(shadowContext, tex, samp, positionSS, positionWS, normalWS, index, L, unusedSplitIndex); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowContext.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowContext.hlsl index fa5b99b316e..75e0b9973af 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowContext.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowContext.hlsl @@ -11,6 +11,10 @@ struct HDShadowContext { StructuredBuffer shadowDatas; HDDirectionalShadowData directionalShadowData; +#ifdef SHADOWS_SHADOWMASK + int shadowSplitIndex; + float fade; +#endif }; // HD shadow sampling bindings @@ -33,6 +37,10 @@ HDShadowContext InitShadowContext() sc.shadowDatas = _HDShadowDatas; sc.directionalShadowData = _HDDirectionalShadowData[0]; +#ifdef SHADOWS_SHADOWMASK + sc.shadowSplitIndex = -1; + sc.fade = 0.0; +#endif return sc; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowSettings.cs index 6c21c338774..0c4baa3dd69 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowSettings.cs @@ -7,7 +7,7 @@ namespace UnityEngine.Rendering.HighDefinition /// [Serializable, VolumeComponentMenuForRenderPipeline("Shadowing/Shadows", typeof(HDRenderPipeline))] [HDRPHelpURLAttribute("Override-Shadows")] - public class HDShadowSettings : VolumeComponent + public class HDShadowSettings : VolumeComponent, ISerializationCallbackReceiver { float[] m_CascadeShadowSplits = new float[3]; float[] m_CascadeShadowBorders = new float[4]; @@ -26,6 +26,25 @@ public float[] cascadeShadowSplits } } + internal float InterCascadeToSqRangeBorder(float interCascadeBorder, float prevCascadeRelRange, float cascadeRelRange) + { + // Compute the border relative to the cascade range from the inter-cascade range + float rangeBorder = cascadeRelRange >= 0.0f + ? (cascadeRelRange - prevCascadeRelRange) * interCascadeBorder / cascadeRelRange + : 0.0f; + + // Range will be applied to squared distance, which makes the effective range at b = 1-sqrt(1-b'), so we need to output b'=1-(1-b)^2 + return 1.0f - (1.0f - rangeBorder) * (1.0f - rangeBorder); + } + internal float SqRangeBorderToInterCascade(float sqRangeBorder, float prevCascadeRelRange, float cascadeRelRange) + { + // Inverse of InterCascadeToSqRangeBorder + float interCascadeRange = cascadeRelRange - prevCascadeRelRange; + return interCascadeRange > 0.0f + ? Mathf.Clamp01((1.0f - Mathf.Sqrt(1.0f - sqRangeBorder)) * cascadeRelRange / interCascadeRange) + : 0.0f; + } + /// /// Size of the border between each shadow cascades for directional lights. /// @@ -33,10 +52,11 @@ public float[] cascadeShadowBorders { get { - m_CascadeShadowBorders[0] = cascadeShadowBorder0.value; - m_CascadeShadowBorders[1] = cascadeShadowBorder1.value; - m_CascadeShadowBorders[2] = cascadeShadowBorder2.value; - m_CascadeShadowBorders[3] = cascadeShadowBorder3.value; + var splitCount = cascadeShadowSplitCount.value; + m_CascadeShadowBorders[0] = InterCascadeToSqRangeBorder(cascadeShadowBorder0.value, 0.0f, splitCount > 1 ? cascadeShadowSplit0.value : 1.0f); + m_CascadeShadowBorders[1] = InterCascadeToSqRangeBorder(cascadeShadowBorder1.value, cascadeShadowSplit0.value, splitCount > 2 ? cascadeShadowSplit1.value : 1.0f); + m_CascadeShadowBorders[2] = InterCascadeToSqRangeBorder(cascadeShadowBorder2.value, cascadeShadowSplit1.value, splitCount > 3 ? cascadeShadowSplit2.value : 1.0f); + m_CascadeShadowBorders[3] = InterCascadeToSqRangeBorder(cascadeShadowBorder3.value, cascadeShadowSplit2.value, 1.0f); // For now we don't use shadow cascade borders but we still want to have the last split fading out. if (!HDRenderPipeline.s_UseCascadeBorders) @@ -47,6 +67,31 @@ public float[] cascadeShadowBorders } } + [SerializeField] bool interCascadeBorders = false; + /// OnBeforeSerialize. + public void OnBeforeSerialize() + { + // Borders newly serialized are defined against inter-cascade range (as the UI displays) + // Previously serialized borders were sent directly as shader input where they are considered against the full squared range + interCascadeBorders = true; + } + + /// OnAfterDeserialize. + public void OnAfterDeserialize() + { + if (!interCascadeBorders) + { + // Previously serialized borders were sent directly as shader input where they are considered against the full squared range + // This converts those ranges back to inter-cascade ranges (as the UI displays) so now both UI and shader output match + // Note that if a previously defined border would go out of the inter-cascade range, it will now be clamped to it + var splitCount = cascadeShadowSplitCount.value; + cascadeShadowBorder0.value = SqRangeBorderToInterCascade(cascadeShadowBorder0.value, 0.0f, splitCount > 1 ? cascadeShadowSplit0.value : 1.0f); + cascadeShadowBorder1.value = SqRangeBorderToInterCascade(cascadeShadowBorder1.value, cascadeShadowSplit0.value, splitCount > 2 ? cascadeShadowSplit1.value : 1.0f); + cascadeShadowBorder2.value = SqRangeBorderToInterCascade(cascadeShadowBorder2.value, cascadeShadowSplit1.value, splitCount > 3 ? cascadeShadowSplit2.value : 1.0f); + cascadeShadowBorder3.value = SqRangeBorderToInterCascade(cascadeShadowBorder3.value, cascadeShadowSplit2.value, 1.0f); + } + } + /// Sets the maximum distance HDRP renders shadows for all Light types. [Tooltip("Sets the maximum distance HDRP renders shadows for all Light types.")] public NoInterpMinFloatParameter maxShadowDistance = new NoInterpMinFloatParameter(500.0f, 0.0f); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/BaseLitAPI.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/BaseLitAPI.cs index 271463e14d5..b1d21bf41ec 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/BaseLitAPI.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/BaseLitAPI.cs @@ -54,23 +54,6 @@ static public void SetupBaseLitKeywords(Material material) bool enableDisplacement = material.HasProperty(kDisplacementMode) && (GetFilteredDisplacementMode(material) != DisplacementMode.None); - // Displacement mapping requires a height map. - if (enableDisplacement) - { - int layerCount = material.HasProperty(kLayerCount) ? material.GetInt(kLayerCount) : 1; - - // If the layerCount is 1, then it means that the property we're fetching is not from a layered material - // thus it doesn't have a postfix - string[] postfixes = (layerCount > 1) ? new[] { "0", "1", "2", "3" } : new[] { "" }; - - for (int i = 0; i < layerCount; i++) - { - string kHeightMapN = string.Format("{0}{1}", kHeightMap, postfixes[i]); - - enableDisplacement = enableDisplacement && material.HasProperty(kHeightMapN) && (material.GetTexture(kHeightMapN) != null); - } - } - if (enableDisplacement) { var displacementMode = GetFilteredDisplacementMode(material); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingLight.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingLight.hlsl index fe92f9b5746..7f1510b9e56 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingLight.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/Shaders/PathTracingLight.hlsl @@ -24,7 +24,7 @@ // How many lights (at most) do we support at one given shading point // FIXME: hardcoded limits are evil, this LightList should instead be put together in C# -#define MAX_LOCAL_LIGHT_COUNT 16 +#define MAX_LOCAL_LIGHT_COUNT SHADEROPTIONS_PATH_TRACING_MAX_LIGHT_COUNT #define MAX_DISTANT_LIGHT_COUNT 4 #define DELTA_PDF 1000000.0 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassInjectionPoint.cs.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassInjectionPoint.cs.hlsl index 928b798271e..36efe130803 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassInjectionPoint.cs.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassInjectionPoint.cs.hlsl @@ -9,6 +9,7 @@ // #define CUSTOMPASSINJECTIONPOINT_BEFORE_RENDERING (0) #define CUSTOMPASSINJECTIONPOINT_AFTER_OPAQUE_DEPTH_AND_NORMAL (5) +#define CUSTOMPASSINJECTIONPOINT_AFTER_OPAQUE_AND_SKY (6) #define CUSTOMPASSINJECTIONPOINT_BEFORE_PRE_REFRACTION (4) #define CUSTOMPASSINJECTIONPOINT_BEFORE_TRANSPARENT (1) #define CUSTOMPASSINJECTIONPOINT_BEFORE_POST_PROCESS (2) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/EditorShaderVariables.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/EditorShaderVariables.hlsl index 85ada21b011..d09cc1c2259 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/EditorShaderVariables.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/EditorShaderVariables.hlsl @@ -1,10 +1,20 @@ -#ifndef EDITOR_SHADER_VARAIBLES -#define E DITOR_SHADER_VARAIBLES +#ifndef EDITOR_SHADER_VARIABLES +#define EDITOR_SHADER_VARIABLES // ================================ // PER FRAME CONSTANTS // ================================ #if defined(USING_STEREO_MATRICES) + float4x4 unity_StereoMatrixP[2]; + float4x4 unity_StereoMatrixV[2]; + float4x4 unity_StereoMatrixInvV[2]; + float4x4 unity_StereoMatrixVP[2]; + + float4x4 unity_StereoCameraProjection[2]; + float4x4 unity_StereoCameraInvProjection[2]; + float4x4 unity_StereoWorldToCamera[2]; + float4x4 unity_StereoCameraToWorld[2]; + #define glstate_matrix_projection unity_StereoMatrixP[unity_StereoEyeIndex] #define unity_MatrixV unity_StereoMatrixV[unity_StereoEyeIndex] #define unity_MatrixInvV unity_StereoMatrixInvV[unity_StereoEyeIndex] @@ -15,13 +25,11 @@ #define unity_WorldToCamera unity_StereoWorldToCamera[unity_StereoEyeIndex] #define unity_CameraToWorld unity_StereoCameraToWorld[unity_StereoEyeIndex] #else - #if !defined(USING_STEREO_MATRICES) - float4x4 glstate_matrix_projection; - float4x4 unity_MatrixV; - float4x4 unity_MatrixInvV; - float4x4 unity_MatrixVP; - float4 unity_StereoScaleOffset; - #endif + float4x4 glstate_matrix_projection; + float4x4 unity_MatrixV; + float4x4 unity_MatrixInvV; + float4x4 unity_MatrixVP; + float4 unity_StereoScaleOffset; #endif -#endif // EDITOR_SHADER_VARAIBLES +#endif // EDITOR_SHADER_VARIABLES diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs index ed94059dadb..f540d6d38e6 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs @@ -915,7 +915,7 @@ bool AcquireSkyRenderingContext(SkyUpdateContext updateContext, int newHash, str { SphericalHarmonicsL2 cachedAmbientProbe = new SphericalHarmonicsL2(); // Release the old context if needed. - if (IsCachedContextValid(updateContext)) + if (CachedContextNeedsCleanup(updateContext)) { ref var cachedContext = ref m_CachedSkyContexts[updateContext.cachedSkyRenderingContextId]; if (newHash != cachedContext.hash || updateContext.skySettings.GetSkyRendererType() != cachedContext.type) @@ -999,6 +999,16 @@ bool IsCachedContextValid(SkyUpdateContext skyContext) return id != -1 && (skyContext.skySettings.GetSkyRendererType() == m_CachedSkyContexts[id].type) && (m_CachedSkyContexts[id].hash != 0); } + bool CachedContextNeedsCleanup(SkyUpdateContext skyContext) + { + if (skyContext.skySettings == null) // Sky set to None + return false; + + int id = skyContext.cachedSkyRenderingContextId; + // When the renderer changes, the cached context is no longer valid but needs to be cleaned up to allow for proper refCounting. + return id != -1 && (m_CachedSkyContexts[id].hash != 0); + } + int ComputeSkyHash(HDCamera camera, SkyUpdateContext skyContext, Light sunLight, SkyAmbientMode ambientMode, bool staticSky = false) { int sunHash = 0; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/ProbeCameraCache.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/ProbeCameraCache.cs index 101eb0f8686..36825f1bcbb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/ProbeCameraCache.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/ProbeCameraCache.cs @@ -89,7 +89,10 @@ public void Clear() } m_Cache.Clear(); foreach(var camera in m_CameraPool) - CoreUtils.Destroy(camera.gameObject); + { + if (camera != null) + CoreUtils.Destroy(camera.gameObject); + } m_CameraPool.Clear(); } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Actions/GraphViewActions.cs b/Packages/com.unity.shadergraph/Editor/Data/Actions/GraphViewActions.cs index f107e887c6e..56e4187977d 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Actions/GraphViewActions.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Actions/GraphViewActions.cs @@ -108,10 +108,8 @@ void DragGraphInput(GraphData graphData) var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; - graphData.AddNode(node); - - // Setting the guid requires the graph to be set first. node.property = property; + graphData.AddNode(node); break; } case ShaderKeyword keyword: @@ -129,10 +127,8 @@ void DragGraphInput(GraphData graphData) var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; - graphData.AddNode(node); - - // Setting the guid requires the graph to be set first. node.keyword = keyword; + graphData.AddNode(node); break; } case ShaderDropdown dropdown: @@ -152,10 +148,8 @@ void DragGraphInput(GraphData graphData) var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; - graphData.AddNode(node); - - // Setting the guid requires the graph to be set first. node.dropdown = dropdown; + graphData.AddNode(node); } break; } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphConcretization.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphConcretization.cs index 8cc862c10bc..b083a67727c 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphConcretization.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphConcretization.cs @@ -14,7 +14,7 @@ public static void ConcretizeNode(AbstractMaterialNode node) public static void ConcretizeProperties(GraphData graph) { - var propertyNodes = graph.GetNodes().Where(n => !graph.m_Properties.Any(p => p == n.property)).ToArray(); + var propertyNodes = graph.GetNodes().Where(n => !graph.m_Properties.Any(p => p.value.objectId == n.property.objectId)).ToArray(); foreach (var pNode in propertyNodes) graph.ReplacePropertyNodeWithConcreteNodeNoValidate(pNode); } diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs index 68ae6bc6ed5..d3847716da5 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs @@ -251,11 +251,14 @@ GeneratedShader BuildShader(string additionalShaderID, List outTempor } } + var variantLimit = this.m_Mode == GenerationMode.Preview + ? Mathf.Min(ShaderGraphPreferences.previewVariantLimit, ShaderGraphProjectSettings.instance.shaderVariantLimit) + : ShaderGraphProjectSettings.instance.shaderVariantLimit; // Send an action about our current variant usage. This will either add or clear a warning if it exists - var action = new ShaderVariantLimitAction(shaderKeywords.permutations.Count, ShaderGraphPreferences.variantLimit); + var action = new ShaderVariantLimitAction(shaderKeywords.permutations.Count, variantLimit); m_GraphData.owner?.graphDataStore?.Dispatch(action); - if (shaderKeywords.permutations.Count > ShaderGraphPreferences.variantLimit) + if (shaderKeywords.permutations.Count > variantLimit) { // ideally we would not rely on the graph having an asset guid / asset path here (to support compiling asset-less graph datas) string path = AssetDatabase.GUIDToAssetPath(m_GraphData.assetGuid); diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/CustomRenderTexture/CustomTexture.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/CustomRenderTexture/CustomTexture.hlsl index adf3685a591..67c5358eced 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/CustomRenderTexture/CustomTexture.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/CustomRenderTexture/CustomTexture.hlsl @@ -45,6 +45,16 @@ float4 _Time, _SinTime, _CosTime, unity_DeltaTime; // PER FRAME CONSTANTS // ================================ #if defined(USING_STEREO_MATRICES) + float4x4 unity_StereoMatrixP[2]; + float4x4 unity_StereoMatrixV[2]; + float4x4 unity_StereoMatrixInvV[2]; + float4x4 unity_StereoMatrixVP[2]; + + float4x4 unity_StereoCameraProjection[2]; + float4x4 unity_StereoCameraInvProjection[2]; + float4x4 unity_StereoWorldToCamera[2]; + float4x4 unity_StereoCameraToWorld[2]; + #define glstate_matrix_projection unity_StereoMatrixP[unity_StereoEyeIndex] #define unity_MatrixV unity_StereoMatrixV[unity_StereoEyeIndex] #define unity_MatrixInvV unity_StereoMatrixInvV[unity_StereoEyeIndex] @@ -55,14 +65,12 @@ float4 _Time, _SinTime, _CosTime, unity_DeltaTime; #define unity_WorldToCamera unity_StereoWorldToCamera[unity_StereoEyeIndex] #define unity_CameraToWorld unity_StereoCameraToWorld[unity_StereoEyeIndex] #else - #if !defined(USING_STEREO_MATRICES) - float4x4 glstate_matrix_projection; - float4x4 unity_MatrixV; - float4x4 unity_MatrixInvV; - float4x4 unity_MatrixVP; - float4x4 unity_ObjectToWorld; - float4 unity_StereoScaleOffset; - #endif + float4x4 glstate_matrix_projection; + float4x4 unity_MatrixV; + float4x4 unity_MatrixInvV; + float4x4 unity_MatrixVP; + float4x4 unity_ObjectToWorld; + float4 unity_StereoScaleOffset; #endif // Internal diff --git a/Packages/com.unity.shadergraph/Editor/ShaderGraphPreferences.cs b/Packages/com.unity.shadergraph/Editor/ShaderGraphPreferences.cs index 6460748dd6b..f7f217b0e2f 100644 --- a/Packages/com.unity.shadergraph/Editor/ShaderGraphPreferences.cs +++ b/Packages/com.unity.shadergraph/Editor/ShaderGraphPreferences.cs @@ -15,17 +15,17 @@ static class Keys internal delegate void PreferenceChangedDelegate(); internal static PreferenceChangedDelegate onVariantLimitChanged; - static int m_VariantLimit = 128; + static int m_previewVariantLimit = 128; internal static PreferenceChangedDelegate onAllowDeprecatedChanged; - internal static int variantLimit + internal static int previewVariantLimit { - get { return m_VariantLimit; } + get { return m_previewVariantLimit; } set { if (onVariantLimitChanged != null) onVariantLimitChanged(); - TrySave(ref m_VariantLimit, value, Keys.variantLimit); + TrySave(ref m_previewVariantLimit, value, Keys.variantLimit); } } @@ -75,10 +75,18 @@ static void OpenGUI() EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); - var variantLimitValue = EditorGUILayout.DelayedIntField("Shader Variant Limit", variantLimit); + + var actualLimit = ShaderGraphProjectSettings.instance.shaderVariantLimit; + var willPreviewVariantBeIgnored = ShaderGraphPreferences.previewVariantLimit > actualLimit; + + var variantLimitLabel = willPreviewVariantBeIgnored + ? new GUIContent("Preview Variant Limit", EditorGUIUtility.IconContent("console.infoicon").image, $"The Preview Variant Limit is higher than the Shader Variant Limit in Project Settings: {actualLimit}. The Preview Variant Limit will be ignored.") + : new GUIContent("Preview Variant Limit"); + + var variantLimitValue = EditorGUILayout.DelayedIntField(variantLimitLabel, previewVariantLimit); if (EditorGUI.EndChangeCheck()) { - variantLimit = variantLimitValue; + previewVariantLimit = variantLimitValue; } EditorGUI.BeginChangeCheck(); @@ -100,7 +108,7 @@ static void OpenGUI() static void Load() { - m_VariantLimit = EditorPrefs.GetInt(Keys.variantLimit, 128); + m_previewVariantLimit = EditorPrefs.GetInt(Keys.variantLimit, 128); m_AutoAddRemoveBlocks = EditorPrefs.GetBool(Keys.autoAddRemoveBlocks, true); m_AllowDeprecatedBehaviors = EditorPrefs.GetBool(Keys.allowDeprecatedBehaviors, false); diff --git a/Packages/com.unity.shadergraph/Editor/ShaderGraphProjectSettings.cs b/Packages/com.unity.shadergraph/Editor/ShaderGraphProjectSettings.cs index c7330e28019..e41376d7810 100644 --- a/Packages/com.unity.shadergraph/Editor/ShaderGraphProjectSettings.cs +++ b/Packages/com.unity.shadergraph/Editor/ShaderGraphProjectSettings.cs @@ -7,10 +7,13 @@ namespace UnityEditor.ShaderGraph [FilePath("ProjectSettings/ShaderGraphSettings.asset", FilePathAttribute.Location.ProjectFolder)] internal class ShaderGraphProjectSettings : ScriptableSingleton { + [SerializeField] + internal int shaderVariantLimit = 128; [SerializeField] internal int customInterpolatorErrorThreshold = 32; [SerializeField] internal int customInterpolatorWarningThreshold = 16; + internal SerializedObject GetSerializedObject() { return new SerializedObject(this); } internal void Save() { Save(true); } private void OnDisable() { Save(); } @@ -25,6 +28,7 @@ class ShaderGraphProjectSettingsProvider : SettingsProvider private class Styles { + public static readonly GUIContent shaderVariantLimitLabel = L10n.TextContent("Shader Variant Limit", ""); public static readonly GUIContent CustomInterpLabel = L10n.TextContent("Custom Interpolator Channel Settings", ""); public static readonly GUIContent CustomInterpWarnThresholdLabel = L10n.TextContent("Warning Threshold", $"ShaderGraph displays a warning when the user creates more custom interpolators than permitted by this setting. The number of interpolators that trigger this warning must be between {kMinChannelThreshold} and the Error Threshold."); public static readonly GUIContent CustomInterpErrorThresholdLabel = L10n.TextContent("Error Threshold", $"ShaderGraph displays an error message when the user tries to create more custom interpolators than permitted by this setting. The number of interpolators that trigger this error must be between {kMinChannelThreshold} and {kMaxChannelThreshold}."); @@ -32,6 +36,7 @@ private class Styles } SerializedObject m_SerializedObject; + SerializedProperty m_shaderVariantLimit; SerializedProperty m_customInterpWarn; SerializedProperty m_customInterpError; @@ -44,6 +49,7 @@ public override void OnActivate(string searchContext, VisualElement rootElement) { ShaderGraphProjectSettings.instance.Save(); m_SerializedObject = ShaderGraphProjectSettings.instance.GetSerializedObject(); + m_shaderVariantLimit = m_SerializedObject.FindProperty("shaderVariantLimit"); m_customInterpWarn = m_SerializedObject.FindProperty("customInterpolatorWarningThreshold"); m_customInterpError = m_SerializedObject.FindProperty("customInterpolatorErrorThreshold"); } @@ -52,7 +58,15 @@ public override void OnActivate(string searchContext, VisualElement rootElement) void OnGUIHandler(string searchContext) { m_SerializedObject.Update(); + EditorGUI.BeginChangeCheck(); + + var newValue = EditorGUILayout.DelayedIntField(Styles.shaderVariantLimitLabel, m_shaderVariantLimit.intValue); + if (newValue != m_shaderVariantLimit.intValue) + { + m_shaderVariantLimit.intValue = newValue; + ShaderGraphPreferences.onVariantLimitChanged(); + } EditorGUILayout.LabelField(Styles.CustomInterpLabel, EditorStyles.boldLabel); EditorGUI.indentLevel++; diff --git a/Tests/SRPTests/Packages/local.code.coverage.references/package.json b/Tests/SRPTests/Packages/local.code.coverage.references/package.json new file mode 100644 index 00000000000..ebe7a6119fe --- /dev/null +++ b/Tests/SRPTests/Packages/local.code.coverage.references/package.json @@ -0,0 +1,14 @@ +{ + "displayName": "Local Code Coverage references", + "name": "local.code.coverage.references", + "version": "1.0.0", + "unity": "2019.1", + "description": "This is a dummy package that contains references to other packages needed for tests in the repository.", + "keywords": [ + "test" + ], + "category": "Libraries", + "dependencies": { + "com.unity.testtools.codecoverage": "1.2.3" + } + } \ No newline at end of file diff --git a/Tests/SRPTests/Packages/local.gtf.references/package.json b/Tests/SRPTests/Packages/local.gtf.references/package.json new file mode 100644 index 00000000000..3404dcdd4f4 --- /dev/null +++ b/Tests/SRPTests/Packages/local.gtf.references/package.json @@ -0,0 +1,14 @@ +{ + "displayName": "Local Graphics Test Framework references", + "name": "local.gtf.references", + "version": "1.0.0", + "unity": "2019.1", + "description": "This is a dummy package that contains references to other packages needed for tests in the repository.", + "keywords": [ + "test" + ], + "category": "Libraries", + "dependencies": { + "com.unity.testframework.graphics": "7.15.0-exp.1" + } +} diff --git a/Tests/SRPTests/Packages/local.gtf.references/package.json.meta b/Tests/SRPTests/Packages/local.gtf.references/package.json.meta new file mode 100644 index 00000000000..8ef3c40e394 --- /dev/null +++ b/Tests/SRPTests/Packages/local.gtf.references/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 80e8e1f94fd8aec49a0fef20ece34a61 +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Packages/local.utf.references/package.json b/Tests/SRPTests/Packages/local.utf.references/package.json new file mode 100644 index 00000000000..eee0672758e --- /dev/null +++ b/Tests/SRPTests/Packages/local.utf.references/package.json @@ -0,0 +1,16 @@ +{ + "displayName": "Local Unity Test Framework references", + "name": "local.utf.references", + "version": "1.0.0", + "unity": "2019.1", + "description": "This is a dummy package that contains references to other packages needed for tests in the repository.", + "keywords": [ + "test" + ], + "category": "Libraries", + "dependencies": { + "com.unity.test-framework": "1.3.4", + "com.unity.test-framework.build": "0.0.1-preview.14", + "com.unity.test-framework.utp-reporter": "1.1.0-preview" + } +} \ No newline at end of file diff --git a/Tests/SRPTests/Packages/local.utf.references/package.json.meta b/Tests/SRPTests/Packages/local.utf.references/package.json.meta new file mode 100644 index 00000000000..5be5a8fcadc --- /dev/null +++ b/Tests/SRPTests/Packages/local.utf.references/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cc7e9977f49e629489429c898c34c019 +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/HelperTests.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/HelperTests.cs new file mode 100644 index 00000000000..16f5c42ccca --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/HelperTests.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using NUnit.Framework; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace UnityEditor.Rendering.Tests +{ + public class HelperTests + { + private Dictionary assetTypeCount; + private string k_targetFolder = "Assets/HelperResources"; + private List testStrings; + private string[] substrings; + + [SetUp] + public void SetUp() + { + testStrings = new List + { + "", + " ", + "\t", + "\n", + "normalString", + "With Special Characters !@#$%^&*()", + new string('a', 10000), + "UPPER", + "lower", + "MiXeD", + null + }; + + substrings = new[] + { + "normal", + " ", + "Special", + "UPPER", + "lower", + "mixed", + null + }; + + assetTypeCount = new Dictionary(); + string[] assetPaths = AssetDatabase.GetAllAssetPaths(); + foreach (string path in assetPaths) + { + if (path.StartsWith(k_targetFolder)) + { + Object asset = AssetDatabase.LoadAssetAtPath(path, typeof(Object)); + if (asset != null) + { + Type assetType = asset.GetType(); + + if (assetTypeCount.ContainsKey(assetType)) + { + assetTypeCount[assetType]++; + } + else + { + assetTypeCount.Add(assetType, 1); + } + } + } + } + } + + [TearDown] + public void TearDown() + { + assetTypeCount.Clear(); + } + + [Test] + public void ValidateContainsAnyString() + { + Assert.False(testStrings[0].ContainsAny(substrings)); + Assert.True(testStrings[1].ContainsAny(substrings)); + Assert.False(testStrings[2].ContainsAny(substrings)); + Assert.False(testStrings[3].ContainsAny(substrings)); + Assert.True(testStrings[4].ContainsAny(substrings)); + Assert.True(testStrings[5].ContainsAny(substrings)); + Assert.False(testStrings[6].ContainsAny(substrings)); + Assert.True(testStrings[7].ContainsAny(substrings)); + Assert.True(testStrings[8].ContainsAny(substrings)); + Assert.False(testStrings[9].ContainsAny(substrings)); + Assert.False(testStrings[10].ContainsAny(substrings)); + } + + [Test] + public void ValidateFindDataOfType() + { + bool success = true; + foreach (var entry in assetTypeCount) + { + Type type = entry.Key; + int count = 0; + + MethodInfo genericMethod = typeof(AssetDatabaseHelper).GetMethod("FindAssets"); + MethodInfo method = genericMethod.MakeGenericMethod(type); + + object[] parameters = new object[] { null }; + var assets = method.Invoke(null, parameters) as IEnumerable; + + foreach (var asset in assets) + { + if (AssetDatabase.GetAssetPath(asset as Object).StartsWith(k_targetFolder)) + { + count++; + } + } + if (count != entry.Value) + { + success = false; + break; + } + } + Assert.True(success); + } + } +} diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/HelperTests.cs.meta b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/HelperTests.cs.meta new file mode 100644 index 00000000000..5d6e7b2a09d --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/HelperTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 66b8a4eb9b48049dc9754ba9ddac3685 \ No newline at end of file