From c3067b74c7352c67f17db5c2ad4af0b66cb6a782 Mon Sep 17 00:00:00 2001 From: Robert Jessop Date: Fri, 19 Jan 2024 21:07:52 +0000 Subject: [PATCH 01/10] 2021.3/documentation staging Final ever regular docs sync to main. --- .../Documentation~/lighting/reflection-probes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/lighting/reflection-probes.md b/Packages/com.unity.render-pipelines.universal/Documentation~/lighting/reflection-probes.md index e342047c43e..d148c5113bc 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/lighting/reflection-probes.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/lighting/reflection-probes.md @@ -46,7 +46,9 @@ When a GameObject is within multiple reflection probe volumes, maximum two of th * If the Importance values and the box volumes are the same, Unity determines which two reflection probe volumes contain larger surface areas of a GameObject, and picks the probes of those volumes. -When two reflection probes affect a GameObject, for each pixel, Unity calculates the weight of each probe depending on the distance of this pixel from the faces of the probe box volumes and the values of the **Blend Distance** properties. If the pixel is relatively close to faces of both box volumes and the sum of weights of both probes is less than 1, Unity assigns the remaining weight to the skybox reflection. +When two reflection probes affect a GameObject, for each pixel, Unity calculates the weight of each probe depending on the distance of this pixel from the faces of the probe box volumes and the values of the **Blend Distance** properties. + +If the pixel is relatively close to faces of both box volumes and the sum of weights of both probes is less than 1, Unity assigns the remaining weight to the `_GlossyEnvironmentCubeMap`. This cube map contains the reflection from the lighting source set in the Lighting window under **Environment Lighting** > **Source**. In most cases this source is the skybox. If the pixel is within both box volumes and farther than the Blend Distance values from faces of both volumes: From 238b078e21bec8dc58827b85db301a2864e39d5b Mon Sep 17 00:00:00 2001 From: Arttu Peltonen Date: Tue, 23 Jan 2024 22:32:02 +0000 Subject: [PATCH 02/10] Fix incorrect volume stack dispose (UUM-54394, UUM-35147) Fix for https://jira.unity3d.com/browse/UUM-54394 Incidentally this seems to be the same issue that was originally reported and fixed with this bug https://jira.unity3d.com/browse/UUM-35147, but it was never backported to 21.3. So this PR is effectively the missing backport of https://github.cds.internal.unity3d.com/unity/unity/pull/28676 into 21.3. --- .../Runtime/UniversalAdditionalCameraData.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalAdditionalCameraData.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalAdditionalCameraData.cs index 7751957dc2f..34700c65af1 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalAdditionalCameraData.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalAdditionalCameraData.cs @@ -530,7 +530,6 @@ public VolumeStack volumeStack if (s_CachedVolumeStacks == null) s_CachedVolumeStacks = new List(4); - m_VolumeStack.Dispose(); s_CachedVolumeStacks.Add(m_VolumeStack); } From 80743d11a82ff1255f9bedeb375d4c7ae96a6434 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Tue, 23 Jan 2024 22:32:06 +0000 Subject: [PATCH 03/10] [Port] [2021.3] [VFX] Limit System name length to avoid UI freeze Jira: UUM-55369 How to reproduce: 1. Open any project with Visual Effect Graph installed 2. Create a VFX Graph and open it 3. In a System Label enter loads of characters Actual result: The following console errror >Layout update is struggling to process current layout (consider simplifying to avoid recursive layout): EditorPanelRootElement unity-panel-container3 (x:0.00, y:0.00, width:1084.00, height:590.00) world rect: (x:0.00, y:0.00, width:1084.00, height:590.00)" is logged in the Console and the Editor might freeze and the user will have to close it without saving Expected result: The System Label should have a character limit or other form of validation Reproduced on: Windows 11 ![screenshot](https://jira.unity3d.com/secure/attachment/1311055/Unity_f3YwlUrMU6.png) --- .../Editor/Utils/VFXSystemBorder.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Packages/com.unity.visualeffectgraph/Editor/Utils/VFXSystemBorder.cs b/Packages/com.unity.visualeffectgraph/Editor/Utils/VFXSystemBorder.cs index 1f43e952135..0878f11f8cc 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Utils/VFXSystemBorder.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Utils/VFXSystemBorder.cs @@ -16,6 +16,8 @@ class VFXSystemBorderFactory : UxmlFactory class VFXSystemBorder : GraphElement, IControlledElement, IDisposable { + private const int kMaximumSystemNameLength = 128; + class Content : ImmediateModeElement { VFXSystemBorder m_Border; @@ -85,6 +87,7 @@ public VFXSystemBorder() m_TitleField.Q("unity-text-input").RegisterCallback(OnTitleBlur); m_TitleField.RegisterCallback>(OnTitleChange); + m_TitleField.maxLength = kMaximumSystemNameLength; m_Title.RegisterCallback(OnTitleRelayout); Content content = new Content(this); From 13a24ee916fb2d0273af975c735115364e429453 Mon Sep 17 00:00:00 2001 From: Volkan Ilbeyli Date: Thu, 1 Feb 2024 11:27:24 +0000 Subject: [PATCH 04/10] [2021.3][SpeedTree] Fix shadergraph error on SpeedTree8ColorAlpha Fixes error message shown when the SpeedTree8ColorAlpha subgraph is opened ( [JIRA](https://jira.unity3d.com/browse/UUM-40439) ) Trunk is fixed with a commit 31f5e59b6438a867fe8ac561689124544d080592 in the [SpeedTree9 integration PR](https://github.cds.internal.unity3d.com/unity/unity/pull/37774) ![image](https://media.github.cds.internal.unity3d.com/user/5527/files/8a2d91cd-7b62-4e42-8a04-f715b1361848) --- .../ShaderGraphLibrary/LODDitheringTransition.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.shadergraph/ShaderGraphLibrary/LODDitheringTransition.hlsl b/Packages/com.unity.shadergraph/ShaderGraphLibrary/LODDitheringTransition.hlsl index 38d60764ce5..c7cb9f652b9 100644 --- a/Packages/com.unity.shadergraph/ShaderGraphLibrary/LODDitheringTransition.hlsl +++ b/Packages/com.unity.shadergraph/ShaderGraphLibrary/LODDitheringTransition.hlsl @@ -46,7 +46,7 @@ void LODDitheringTransitionSG_float(float3 viewDirWS, float4 screenPos, out floa multiplyAlpha = f < 0 ? 0.0f : 1.0f; #endif } -void DoLODCrossFade_half(float3 viewDirWS, float4 screenPos, out half halfAlpha) +void LODDitheringTransitionSG_half(float3 viewDirWS, float4 screenPos, out half halfAlpha) { #if !defined (SHADER_API_GLES) && !defined(SHADER_STAGE_RAY_TRACING) float p = GenerateHashedRandomFloat(ComputeFadeMaskSeed(viewDirWS, screenPos.xy)); From 296b88ca42dc3a9d08f86703531af1e6da5ea278 Mon Sep 17 00:00:00 2001 From: Evergreen Date: Fri, 2 Feb 2024 11:43:14 +0000 Subject: [PATCH 05/10] 2021.3: Fixed bright pixels when using a camera with skybox and MSAA rendering opaque objects with alpha clipping together with a transparent object if additive blending The issue is previous frame not cleared before drawing opaque objects with alpha clipping, causing incorrect pixel blending for alpha to coverage. Particularly noticeable with transparent objects using additive blending, resulting in overly bright pixels. Bug: https://jira.unity3d.com/browse/UUM-52949 Backport: https://jira.unity3d.com/browse/UUM-54426 --- .../Runtime/ScriptableRenderer.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs index 9629d5c1cee..c31aa17c862 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs @@ -853,7 +853,19 @@ protected static ClearFlag GetCameraClearFlag(ref CameraData cameraData) if ((cameraClearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null) || cameraClearFlags == CameraClearFlags.Nothing) - return ClearFlag.DepthStencil; + { + // Clear color if msaa is used. If color is not cleared will alpha to coverage blend with previous frame if alpha clipping is enabled of any opaque objects. + if (cameraData.cameraTargetDescriptor.msaaSamples > 1) + { + // Sets the clear color to black to make the alpha to coverage blending blend with black when using alpha clipping. + cameraData.camera.backgroundColor = Color.black; + return ClearFlag.DepthStencil | ClearFlag.Color; + } + else + { + return ClearFlag.DepthStencil; + } + } return ClearFlag.All; } From 0d7a5bebdcae43926433b91f8080292797399d8b Mon Sep 17 00:00:00 2001 From: Julien Amsellem Date: Mon, 5 Feb 2024 11:36:52 +0000 Subject: [PATCH 06/10] [Backport][2021.3][VFX] Copy paste PointCache when the asset is missing raise exception and lose links Jira: UUM-46548 Steps to reproduce: 1. Create new project and import visual effects graph package 2. Create new empty graph 3. Open attached project in another editor instance 4. Open "New VFX" effect from the attached project 5. In visual effects window, select all nodes and blocks and copy them 6. Return to the newly create project and paste them 7. Notice that node connections are lost, some nodes might not have been copied over and there's an exception in console ArgumentException: Object of type 'UnityEngine.Object' cannot be converted to type 'UnityEditor.Experimental.VFX.Utility.PointCacheAsset'. Expected result: All nodes and their connections are copied over to the new project Note: the exception can also be reproduced by deleting point cache file that is used by a visual effect. Reproduced with: 2021.3.29f1 using 12.1.12 2022.3.7f1 using 14.0.8 2023.1.9f1 using 15.0.6 2023.2.0b4 using 16.0.3 --- .../Editor/GraphView/Views/VFXPaste.cs | 5 +- .../Editor/Tests/VFXCopyPasteTests.cs | 62 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/VFXPaste.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/VFXPaste.cs index 4245e038782..7ac8a24832c 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/VFXPaste.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/VFXPaste.cs @@ -401,8 +401,11 @@ void PasteModelSettings(VFXModel model, Property[] settings, Type type) { string name = settings[i].name; var field = fields.Find(t => t.Name == name); - if (field != null) + try + { field.SetValue(model, settings[i].value.Get()); + } + catch { } // Don't break paste operation if a field value cannot be assigned (see UUM-46548) } } diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/VFXCopyPasteTests.cs b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/VFXCopyPasteTests.cs index 976e2c83d73..5dee7af53d4 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/VFXCopyPasteTests.cs +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/VFXCopyPasteTests.cs @@ -1,5 +1,6 @@ #if !UNITY_EDITOR_OSX || MAC_FORCE_TESTS using System; +using System.Collections; using System.IO; using System.Linq; using System.Collections.Generic; @@ -9,6 +10,9 @@ using UnityEditor.VFX; using UnityEditor.VFX.UI; using UnityEditor.Experimental.GraphView; +using UnityEditor.Experimental.VFX.Utility; +using UnityEditor.VFX.Block; +using UnityEngine.TestTools; using UnityEngine.UIElements; namespace UnityEditor.VFX.Test @@ -432,6 +436,64 @@ public void PasteSystems() // Assert all names are unique, and the expected number of elements was obtained Assert.IsTrue(uniqueNames.Count() == spawnerCount + GPUSystemsCount, "Some systems have the same name or are null or empty."); } + + [UnityTest, Description("UUM-46548")] + public IEnumerator PasteMissingPointCacheAsset() + { + VFXViewWindow window = EditorWindow.GetWindow(); + + VFXView view = window.graphView; + view.controller = m_ViewController; + + // Create one system + var spawner = VFXTestCommon.CreateSpawners(view, m_ViewController, 1).Single(); + var contextInitializeDesc = VFXLibrary.GetContexts().FirstOrDefault(o => o.name.Contains("Init")); + var contextOutputDesc = VFXLibrary.GetContexts().FirstOrDefault(o => o.name.StartsWith("Output Particle Quad")); + var output = m_ViewController.AddVFXContext(Vector2.zero, contextOutputDesc); + var init = m_ViewController.AddVFXContext(Vector2.zero, contextInitializeDesc); + var flowEdge = new VFXFlowEdgeController( + ((VFXContextController)m_ViewController.GetNewNodeController(output)).flowInputAnchors.FirstOrDefault(), + ((VFXContextController)m_ViewController.GetNewNodeController(init)).flowOutputAnchors.FirstOrDefault()); + m_ViewController.AddElement(flowEdge); + m_ViewController.ApplyChanges(); + + // Create a point cache operator + var pCacheAssetPath = "Assets/AllTests/VFXTests/GraphicsTests/UnityLogoPrimeCount.pcache"; + var copypCacheAssetPath = Path.Combine(VFXTestCommon.tempBasePath, "pointCache.pcache"); + File.Copy(pCacheAssetPath, copypCacheAssetPath, true); + AssetDatabase.ImportAsset(copypCacheAssetPath); + var pointCacheAsset = AssetDatabase.LoadAssetAtPath(copypCacheAssetPath, typeof(PointCacheAsset)); + var pointCacheOperator = VFXLibrary.GetOperators().Single(x => x.modelType == typeof(VFXOperatorPointCache)).CreateInstance() as VFXOperatorPointCache; + pointCacheOperator.SetSettingValue("Asset", pointCacheAsset); + m_ViewController.AddVFXModel(Vector2.zero, pointCacheOperator); + yield return null; + + // Create a set position from map + var setPositionBlock = VFXLibrary.GetBlocks().First(x => x.name.StartsWith("Set Position from Map")).CreateInstance() as AttributeFromMap; + var initializeContext = m_ViewController.contexts.Single(x => x.model is VFXBasicInitialize); + initializeContext.model.LinkFrom(spawner, 0, 0); + initializeContext.AddBlock(0, setPositionBlock); + setPositionBlock.GetInputSlot(0).Link(pointCacheOperator.GetOutputSlot(1)); + m_ViewController.ApplyChanges(); + yield return null; + + // Copy paste them + view.ClearSelection(); + foreach (var element in view.Query().OfType().ToList().OfType()) + { + view.AddToSelection(element); + } + view.CopySelectionCallback(); + // We delete the point cache asset to check that it does not break the past operation + AssetDatabase.DeleteAsset(copypCacheAssetPath); + view.PasteCallback(); + m_ViewController.ApplyChanges(); + yield return null; + + Assert.AreEqual(1, spawner.outputFlowSlot.Length); + Assert.AreEqual(1, initializeContext.model.inputFlowSlot.Length); + Assert.AreEqual(1, initializeContext.model.outputFlowSlot.Length); + } } } #endif From 5447fdbd7a92dfb6e85f316ac0c2256f124c4c4c Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 5 Feb 2024 11:36:54 +0000 Subject: [PATCH 07/10] [Port] [2021.3] [UUM-45496] Fix debug input errors when emptying input actions Fix https://jira.unity3d.com/browse/UUM-45496 This PR fixes a bug where errors would be logged in console after domain reload when 1) user goes to Project Settings > Player and selects Active Input Handling: Input System Package (New), 2) user goes to Project Settings > Input Manager and deletes all entries in the list, but 3) does not (yet) install the Input System Package through Package Manager. In this situation (which is inherently incorrect because input is misconfigured), the debug action registration code gave errors after domain reload due to incorrect indexing of the input axes array. Code is fixed to not rely on existing elements in that array. --- .../Runtime/Inputs/InputRegistering.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Inputs/InputRegistering.cs b/Packages/com.unity.render-pipelines.core/Runtime/Inputs/InputRegistering.cs index 2c77fe8da64..6e26a8cbaf9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Inputs/InputRegistering.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Inputs/InputRegistering.cs @@ -59,11 +59,14 @@ static void CopyEntry(SerializedProperty spAxis, InputManagerEntry entry) static void AddEntriesWithoutCheck(SerializedProperty spAxes, List newEntries) { + if (newEntries.Count == 0) + return; + int endOfCurrentInputList = spAxes.arraySize; spAxes.arraySize = endOfCurrentInputList + newEntries.Count; - - SerializedProperty spAxis = spAxes.GetArrayElementAtIndex(endOfCurrentInputList - 1); - spAxis.Next(false); + // Assignment to spAxes.arraySize resizes the spAxes array to at least 1 larger than it used to be, and + // therefore it is OK to use endOfCurrentInputList ("one-past-end of previous size") to get the array iterator. + SerializedProperty spAxis = spAxes.GetArrayElementAtIndex(endOfCurrentInputList); for (int i = 0; i < newEntries.Count; ++i, spAxis.Next(false)) CopyEntry(spAxis, newEntries[i]); } @@ -74,6 +77,9 @@ static void AddEntriesWithoutCheck(SerializedProperty spAxes, List result = new List<(string name, InputManagerEntry.Kind kind)>(size); + if (size == 0) + return result; + SerializedProperty spAxis = spAxes.GetArrayElementAtIndex(0); for (int i = 0; i < size; ++i, spAxis.Next(false)) result.Add((spAxis.FindPropertyRelative("m_Name").stringValue, (InputManagerEntry.Kind)spAxis.FindPropertyRelative("type").intValue)); From 631cc776d8622f73548f6c43ee530beeaf06ffd3 Mon Sep 17 00:00:00 2001 From: Mark Green Date: Tue, 6 Feb 2024 11:46:21 +0000 Subject: [PATCH 08/10] [Port] [2021.3] DOCG-4894 Restructure customizing URP documentation Restructure and rename the Customizing URP documentation section to get it ready for Render Graph documentation. Most of the PR renames or moves pages, but there is some new content where I had to create a new landing page or introduction. Jira ticket: [DOCG-4894](https://jira.unity3d.com/browse/DOCG-4894) --- .../Documentation~/TableOfContents.md | 36 ++- .../inject-render-pass-via-script.md} | 62 +++- .../Documentation~/customizing-urp.md | 13 +- .../Documentation~/faq.md | 4 - .../Documentation~/how-to.md | 9 - .../renderer-feature-decal-landing.md | 8 + .../create-custom-renderer-feature.md | 4 +- .../custom-rendering-pass-workflow-in-urp.md | 32 ++ .../custom-rendering-passes.md | 10 + .../intro-to-scriptable-render-passes.md | 38 +++ ...renderer-feature-render-objects-landing.md | 8 + .../renderer-feature-render-objects.md | 2 +- .../scriptable-render-passes.md | 13 + ...y-scriptable-feature-to-specific-camera.md | 46 +++ ...ass-using-a-scriptable-renderer-feature.md | 161 ++++++++++ .../intro-to-scriptable-renderer-features.md | 29 ++ .../scriptable-renderer-feature-reference.md | 35 +++ .../scriptable-renderer-features-landing.md | 10 + .../write-a-scriptable-render-pass.md | 288 ++++++++++++++++++ .../rendering-in-universalrp.md | 2 +- .../Documentation~/urp-renderer-feature.md | 23 +- 21 files changed, 771 insertions(+), 62 deletions(-) rename Packages/com.unity.render-pipelines.universal/Documentation~/{using-begincamerarendering.md => customize/inject-render-pass-via-script.md} (56%) delete mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/how-to.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-feature-decal-landing.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/custom-rendering-pass-workflow-in-urp.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/custom-rendering-passes.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/intro-to-scriptable-render-passes.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/renderer-feature-render-objects-landing.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-render-passes.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/apply-scriptable-feature-to-specific-camera.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/inject-a-pass-using-a-scriptable-renderer-feature.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/intro-to-scriptable-renderer-features.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/scriptable-renderer-feature-reference.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/scriptable-renderer-features-landing.md create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/write-a-scriptable-render-pass.md diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md b/Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md index a8d12ae16cb..bb0265956cf 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md @@ -10,6 +10,7 @@ * [Package samples](package-samples.md) * [URP Package Samples](package-sample-urp-package-samples.md) * [Scene Templates](scene-templates.md) + * [Change Quality settings with code](quality/quality-settings-through-code.md) * [Understand performance](understand-performance.md) * [Configure for better performance](configure-for-better-performance.md) * [Render Pipeline Concepts](urp-concepts.md) @@ -17,12 +18,16 @@ * [URP Global Settings](urp-global-settings.md) * [Universal Renderer](urp-universal-renderer.md) * [Deferred Rendering Path](rendering/deferred-rendering-path.md) - * [Renderer Feature](urp-renderer-feature.md) + * [Graphics settings window reference in URP](urp-global-settings.md) + * [Pre-built effects (Renderer Features)](urp-renderer-feature.md) * [How to add a Renderer Feature](urp-renderer-feature-how-to-add.md) - * [Render Objects Renderer Feature](renderer-features/how-to-custom-effect-render-objects.md) - * [Ambient Occlusion](post-processing-ssao.md) - * [Decal](renderer-feature-decal.md) - * [Decal Shader Graph](decal-shader.md) + * [Render Objects Renderer Feature](renderer-features/renderer-feature-render-objects-landing.md) + * [Example: How to create a custom rendering effect using the Render Objects Renderer Feature](renderer-features/how-to-custom-effect-render-objects.md) + * [Render Objects Renderer Feature reference](renderer-features/renderer-feature-render-objects.md) + * [Decal Renderer Feature](renderer-feature-decal-landing.md) + * [Decal Renderer Feature](renderer-feature-decal.md) + * [Decal Shader Graph](decal-shader.md) + * [Screen Space Ambient Occlusion (SSAO) Renderer Feature](post-processing-ssao.md) * [Upgrade guides](upgrade-guides.md) * [Render Pipeline Converter](features/rp-converter.md) * [Upgrading to URP 12.0.x](upgrade-guide-2021-2.md) @@ -105,14 +110,19 @@ * [Visualizing normal vectors](writing-shaders-urp-unlit-normals.md) * [Reconstruct the world space positions](writing-shaders-urp-reconstruct-world-position.md) * [URP ShaderLab Pass tags](urp-shaders/urp-shaderlab-pass-tags.md) -* [How to](how-to.md) - * [Blit in XR](renderer-features/how-to-fullscreen-blit-in-xr-spi.md) - * [Use Render Objects Renderer Feature](renderer-features/how-to-custom-effect-render-objects.md) - * [Create custom Renderer Feature](containers/create-custom-renderer-feature-1.md) - * [Change Quality settings with code](quality/quality-settings-through-code.md) -* [Customizing URP](customizing-urp.md) - * [beginCameraRendering event](using-begincamerarendering.md) - * [Create custom Renderer Feature](renderer-features/create-custom-renderer-feature.md) +* [Custom rendering and post-processing](customizing-urp.md) + * [Custom render passes](renderer-features/custom-rendering-passes.md) + * [Custom render pass workflow in URP](renderer-features/custom-rendering-pass-workflow-in-urp.md) + * [Scriptable Render Passes](renderer-features/scriptable-render-passes.md) + * [Scriptable Render Passes](renderer-features/intro-to-scriptable-render-passes.md) + * [Write a Scriptable Render Pass](renderer-features/write-a-scriptable-render-pass.md) + * [Inject a pass via scripting](customize/inject-render-pass-via-script.md) + * [Scriptable Renderer Features](renderer-features/scriptable-renderer-features/scriptable-renderer-features-landing.md) + * [Introduction to Scriptable Renderer Features](renderer-features/scriptable-renderer-features/intro-to-scriptable-renderer-features.md) + * [Inject a custom render pass using a Scriptable Renderer Feature](renderer-features/scriptable-renderer-features/inject-a-pass-using-a-scriptable-renderer-feature.md) + * [Apply a Scriptable Renderer Feature to a specific camera type](renderer-features/scriptable-renderer-features/apply-scriptable-feature-to-specific-camera.md) + * [Example of a complete Scriptable Renderer Feature](renderer-features/create-custom-renderer-feature.md) + * [Scriptable Renderer Feature and Scriptable Render Pass API reference](renderer-features/scriptable-renderer-features/scriptable-renderer-feature-reference.md) * [Optimization](urp-optimization.md) * [Rendering Debugger](features/rendering-debugger.md) * [Optimize for better performance](optimize-for-better-performance.md) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/using-begincamerarendering.md b/Packages/com.unity.render-pipelines.universal/Documentation~/customize/inject-render-pass-via-script.md similarity index 56% rename from Packages/com.unity.render-pipelines.universal/Documentation~/using-begincamerarendering.md rename to Packages/com.unity.render-pipelines.universal/Documentation~/customize/inject-render-pass-via-script.md index b7fe714b56d..721eb80da90 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/using-begincamerarendering.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/customize/inject-render-pass-via-script.md @@ -1,21 +1,57 @@ -# Using the beginCameraRendering event +# Inject a render pass via scripting -The example on this page shows how to use the [beginCameraRendering](https://docs.unity3d.com/ScriptReference/Rendering.RenderPipelineManager-beginCameraRendering.html) event to run a custom method. - -## beginCameraRendering event overview - -Unity raises a `beginCameraRendering` event before it renders each active Camera in every frame. If a Camera is inactive (for example, if the __Camera__ component checkbox is cleared on a Camera GameObject), Unity does not raise a `beginCameraRendering` event for this Camera. +Unity raises a [beginCameraRendering](https://docs.unity3d.com/ScriptReference/Rendering.RenderPipelineManager-beginCameraRendering.html) event before it renders each active Camera in every frame. If a Camera is inactive (for example, if the **Camera** component checkbox is cleared on a Camera GameObject), Unity does not raise a `beginCameraRendering` event for this Camera. When you subscribe a method to this event, you can execute custom logic before Unity renders the Camera. Examples of custom logic include rendering extra Cameras to Render Textures, and using those Textures for effects like planar reflections or surveillance camera views. Other events in the [RenderPipelineManager](https://docs.unity3d.com/ScriptReference/Rendering.RenderPipelineManager.html) class provide more ways to customize URP. You can also use the principles described in this article with those events. -## beginCameraRendering event example +## Use the RenderPipelineManager API + +1. Subscribe a method to one of the events in the [RenderPipelineManager](https://docs.unity3d.com/ScriptReference/Rendering.RenderPipelineManager.html) class. + +2. In the subscribed method, use the `EnqueuePass` method of a `ScriptableRenderer` instance to inject a custom render pass into the URP frame rendering. + +Example code: + +```C# +public class EnqueuePass : MonoBehaviour +{ + [SerializeField] private BlurSettings settings; + private BlurRenderPass blurRenderPass; + + private void OnEnable() + { + ... + blurRenderPass = new BlurRenderPass(settings); + // Subscribe the OnBeginCamera method to the beginCameraRendering event. + RenderPipelineManager.beginCameraRendering += OnBeginCamera; + } + + private void OnDisable() + { + RenderPipelineManager.beginCameraRendering -= OnBeginCamera; + blurRenderPass.Dispose(); + ... + } + + private void OnBeginCamera(ScriptableRenderContext context, Camera cam) + { + ... + // Use the EnqueuePass method to inject a custom render pass + cam.GetUniversalAdditionalCameraData() + .scriptableRenderer.EnqueuePass(blurRenderPass); + } +} +``` + +## Example This example demonstrates how to subscribe a method to the `beginCameraRendering` event. -To follow the steps in this example, create a [new Unity project using the __Universal Project Template__](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@8.0/manual/creating-a-new-project-with-urp.html). -1. In the Scene, create a Cube. Name it Example Cube. +To follow the steps in this example, create a [new Unity project using the **Universal Project Template**](../creating-a-new-project-with-urp.md) + +1. In the scene, create a Cube. Name it Example Cube. 2. In your Project, create a C# script. Call it `URPCallbackExample`. 3. Copy and paste the following code into the script. ```C# @@ -46,14 +82,14 @@ To follow the steps in this example, create a [new Unity project using the __Uni } } ``` - > **NOTE**: When you subscribe to an event, your handler method (in this example, `WriteLogMessage`) must accept the parameters defined in the event delegate. In this example, the event delegate is `RenderPipeline.BeginCameraRendering`, which expects the following parameters: ``. + > **Note**: When you subscribe to an event, your handler method (in this example, `WriteLogMessage`) must accept the parameters defined in the event delegate. In this example, the event delegate is `RenderPipeline.BeginCameraRendering`, which expects the following parameters: ``. 4. Attach the `URPCallbackExample` script to Example Cube. -5. Select __Play__. Unity prints the message from the script in the Console window each time Unity raises the `beginCameraRendering` event. +5. Select **Play**. Unity prints the message from the script in the Console window each time Unity raises the `beginCameraRendering` event. - ![Unity prints log message in console.](Images/customizing-urp/log-message-in-console.png) + ![Unity prints log message in console.](../Images/customizing-urp/log-message-in-console.png) 6. To raise a call to the `OnDisable()` method: In the Play mode, select Example Cube and clear the checkbox next to the script component title. Unity unsubscribes `WriteLogMessage` from the `RenderPipelineManager.beginCameraRendering` event and stops printing the message in the Console window. - ![Deactivate the script component. Clear the checkbox next to the script component title.](Images/customizing-urp/deactivate-script-component.png) + ![Deactivate the script component. Clear the checkbox next to the script component title.](../Images/customizing-urp/deactivate-script-component.png) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/customizing-urp.md b/Packages/com.unity.render-pipelines.universal/Documentation~/customizing-urp.md index 887afd90725..b2905b4fbd8 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/customizing-urp.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/customizing-urp.md @@ -1,7 +1,12 @@ -# Customizing URP +# Custom rendering and post-processing -This section contains information on how to customize and extend the rendering process in URP. +Customize and extend the rendering process in the Universal Render Pipeline (URP). URP uses Renderer Features to implement certain effects. URP includes a selection of pre-built Renderer Features and the ability to create customized Renderer Features known as Scriptable Renderer Features. -This section contains the following articles: +| Page | Description | +|-|-| +|[Custom render passes](renderer-features/custom-rendering-passes.md)|Create a custom render pass in a C# script and inject it into the URP frame rendering loop.| +|[Scriptable Renderer Feature and Scriptable Render Pass API reference](renderer-features/scriptable-renderer-features/scriptable-renderer-feature-reference.md)|Common methods you can use to write Scriptable Renderer Passes and Scriptable Renderer Features.| -* [Using the beginCameraRendering event](using-begincamerarendering.md) +## Additional resources + +- [Pre-built effects (Renderer Features)](urp-renderer-feature.md) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/faq.md b/Packages/com.unity.render-pipelines.universal/Documentation~/faq.md index e626d69566f..258a9ffce59 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/faq.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/faq.md @@ -68,7 +68,3 @@ You can set the Background Type in the Camera Inspector to control how a Camera' ## What rendering space does URP work in? By default, URP uses a linear color space while rendering. You can also use a gamma color space, which is non-linear. To do so, toggle it in the Player Settings. - -## How do I extend URP with scriptable render pass? - -To create a scriptable render pass, you have to create a `ScriptableRendererFeature` script. This is because the scriptable render feature is a container that can have the pass in it. To create the scriptable render feature in the Editor, click on **Asset** > **Create** > **Rendering** > **Universal Render Pipeline** > **Renderer Feature**. diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/how-to.md b/Packages/com.unity.render-pipelines.universal/Documentation~/how-to.md deleted file mode 100644 index a15d6cc3404..00000000000 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/how-to.md +++ /dev/null @@ -1,9 +0,0 @@ -# Practical how-to guides - -This section contains practical how-to guides. - -The section contains the following topics: - -* [How to perform a full screen blit in Single Pass Instanced rendering in XR](renderer-features/how-to-fullscreen-blit-in-xr-spi.md). - -* [How to create a custom rendering effect using the Render Objects Renderer Feature](containers/how-to-custom-effect-render-objects.md) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-feature-decal-landing.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-feature-decal-landing.md new file mode 100644 index 00000000000..e36304c66ea --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-feature-decal-landing.md @@ -0,0 +1,8 @@ +# Decal Renderer Feature + +A Decal Renderer Features projects specific materials (decals) onto other objects in the scene. Decals interact with the scene's lighting and wrap around meshes. + +|Page|Description| +|-|-| +|[Decal Renderer Feature](renderer-feature-decal.md)|Use a Decal Renderer Feature in your scene.| +|[Decal Shader Graph](decal-shader.md)|Project a material as a decal if the material uses a Shader Graph with the Decal Material type.| diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/create-custom-renderer-feature.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/create-custom-renderer-feature.md index 5b9d43d979f..6df64b48f05 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/create-custom-renderer-feature.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/create-custom-renderer-feature.md @@ -1,6 +1,6 @@ -# How to create a custom Renderer Feature +# Example of a complete Scriptable Renderer Feature -This section describes how to create a custom Renderer Feature for a URP Renderer. +The example workflow on this page implements a custom Renderer Feature that uses [custom Render Passes](./intro-to-scriptable-render-passes.md) to add a blur effect to the camera output. This section assumes the following: diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/custom-rendering-pass-workflow-in-urp.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/custom-rendering-pass-workflow-in-urp.md new file mode 100644 index 00000000000..8544648fd69 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/custom-rendering-pass-workflow-in-urp.md @@ -0,0 +1,32 @@ +# Custom render pass workflow in URP + +A custom render pass is a way to change how the Universal Render Pipeline (URP) renders a scene or the objects within a scene. A custom render pass contains your own rendering code, which you add to the rendering pipeline at an injection point. + +To add a custom render pass, complete the following tasks: + +- [Create the code](#create-code) for a custom render pass using the Scriptable Render Pass API. +- [Inject the custom render pass](#inject-pass) using the `RenderPipelineManager` API, or by [creating a Scriptable Renderer Feature](#create-srf) that you add to the URP Renderer. + +## Create the code for a custom render pass + +Use the `ScriptableRenderPass` to create the code for a custom render pass. + +Refer to [Write a Scriptable Render Pass](write-a-scriptable-render-pass.md) for more information. + +## Inject the custom render pass using the RenderPipelineManager API + +Unity raises a [beginCameraRendering](https://docs.unity3d.com/ScriptReference/Rendering.RenderPipelineManager-beginCameraRendering.html) event before it renders each active Camera in every frame. You can subscribe a method to this event, to execute your custom render pass before Unity renders the Camera. + +Refer to [Inject a render pass via scripting](../customize/inject-render-pass-via-script.md) for more information. + +## Create a Scriptable Renderer Feature + +Scriptable Renderer Features control when and how the Scriptable Render Passes apply to a particular renderer or camera, and can also manage multiple Scriptable Render Passes at once. + +To create a Scriptable Renderer Feature, you do the following: + +* Create a Scriptable Renderer Feature using the API. +* Add the Scriptable Renderer Feature to the Universal Renderer asset, so it's included in the rendering pipeline. +* Enqueue your custom render pass in the Scriptable Renderer Feature. + +Refer to [Inject a pass using a Scriptable Renderer Feature](scriptable-renderer-features/inject-a-pass-using-a-scriptable-renderer-feature.md) for more information. diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/custom-rendering-passes.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/custom-rendering-passes.md new file mode 100644 index 00000000000..fba130418a3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/custom-rendering-passes.md @@ -0,0 +1,10 @@ +# Custom render passes + +Create a custom render pass in a C# script and inject it into the Universal Render Pipeline (URP) frame rendering loop. + +|Page|Description| +|-|-| +|[Custom render pass workflow in URP](custom-rendering-pass-workflow-in-urp.md)|Add and inject a custom render pass to change how URP renders a scene or the objects within a scene.| +|[Scriptable Render Passes](scriptable-render-passes.md)|Use the Scriptable Render Pass API to create a custom render pass.| +|[Scriptable Renderer Features](scriptable-renderer-features/scriptable-renderer-features-landing.md)|Use the Scriptable Renderer Feature API to inject a custom render pass into a URP renderer.| + diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/intro-to-scriptable-render-passes.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/intro-to-scriptable-render-passes.md new file mode 100644 index 00000000000..59cc3fbdd66 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/intro-to-scriptable-render-passes.md @@ -0,0 +1,38 @@ +# Introduction to Scriptable Render Passes + +Scriptable Render Passes are a way to alter how Unity renders a scene or the objects within a scene. They allow you to fine tune how Unity renders each scene in your project on a scene-by-scene basis. + +The following sections explain the fundamentals of Scriptable Render Passes: + +* [What is a Scriptable Render Pass?](#scriptable-render-pass) +* [Scriptable Render Passes in Scenes](#scriptable-render-passes-in-scenes) + +You can use Scriptable Renderer Features to inject Scriptable Render Passes into a renderer. For more information, refer to [Scriptable Render Passes in Scenes](#scriptable-render-passes-in-scenes). + +## What is a Scriptable Render Pass? + +You inject a Scriptable Render Pass into the render pipeline to achieve a custom visual effect. To do this, you add the Scriptable Render Pass via a MonoBehavior script with the `EnqueuePass` method and add this script as a component to a renderer, camera, or GameObject. + +A Scriptable Render Pass lets you to do the following: + +* Change the properties of materials in your scene. +* Change the order that Unity renders GameObjects in. +* Lets Unity read camera buffers and use them in shaders. + +For example, you can use a Scriptable Render Pass to blur a camera’s view when showing the in-game menu. + +Unity injects Scriptable Render Passes at certain points during the URP render loop. These points are called injection points. You can change the injection point Unity inserts your pass at to control how the Scriptable Render Pass affects the appearance of your scene. For more information on injection points, refer to [Injection Points](../customize/custom-pass-injection-points.md). + +## Scriptable Render Passes in Scenes + +You can inject a Scriptable Render Pass into a scene via any GameObject present in the scene. This gives you more precise control over when the render pass is active. But this means you must have a GameObject inject the render pass at every point you want to use it. As a result, it's better to inject any common effects in your project via a Scriptable Renderer Feature instead. + +When you inject a Scriptable Render Pass into a scene via any GameObject, it's important to consider how URP uses this script. The first Camera to render the Scriptable Render Pass uses up the render pass, and is the only Camera the render pass applies to. Any Cameras that the Scriptable Render Pass would apply that render after the first Camera don't render the effect. + +For example, if you have two Cameras and you add the Scriptable Render Pass in the `Update` method, only the first Camera to render uses the Scriptable Render Pass effect. This is because the first camera uses up the instance of the effect. As the second Camera renders before the next call of the `Update` method, a second instance of the Scriptable Render Pass isn't available to use. As a result, the second Camera doesn't apply the effect from the Scriptable Render Pass to its output. + +## Additional resources + +* [How to create a Custom Renderer Feature](create-custom-renderer-feature.md) +* [Scriptable Renderer Feature Reference](scriptable-renderer-features/scriptable-renderer-feature-reference.md) +* [How to inject a Custom Render Pass via scripting](../customize/custom-pass-injection-points.md) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/renderer-feature-render-objects-landing.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/renderer-feature-render-objects-landing.md new file mode 100644 index 00000000000..1553f460f21 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/renderer-feature-render-objects-landing.md @@ -0,0 +1,8 @@ +# Render Objects Renderer Feature + +Use a Render Objects Renderer Feature to draw objects on a certain layer, at a certain time, with specific overrides. + +|Page|Description| +|-|-| +|[Example: How to create a custom rendering effect using the Render Objects Renderer Feature](how-to-custom-effect-render-objects.md) |An example that draws a silhouette when a character goes behind other objects.| +|[Render Objects Renderer Feature reference](renderer-feature-render-objects.md)|Properties that configure the behaviour of a Render Objects Renderer Feature.| diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/renderer-feature-render-objects.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/renderer-feature-render-objects.md index 7ae054e2946..55a6e9c556d 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/renderer-feature-render-objects.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/renderer-feature-render-objects.md @@ -1,4 +1,4 @@ -# Render Objects Renderer Feature +# Render Objects Renderer Feature reference URP draws objects in the **DrawOpaqueObjects** and **DrawTransparentObjects** passes. You might need to draw objects at a different point in the frame rendering, or interpret and write rendering data (like depth and stencil) in alternate ways. The Render Objects Renderer Feature lets you do such customizations by letting you draw objects on a certain layer, at a certain time, with specific overrides. diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-render-passes.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-render-passes.md new file mode 100644 index 00000000000..cc38e8984da --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-render-passes.md @@ -0,0 +1,13 @@ +# Scriptable Render Passes + +Use the `ScriptableRenderPass` API to write a custom render pass. You can then inject the pass into the Universal Render Pipeline (URP) frame rendering loop using the `RenderPipelineManager` API or a Scriptable Renderer Feature. + +|Page|Description| +|-|-| +|[Introduction to Scriptable Render Passes](intro-to-scriptable-render-passes.md)|What a Scriptable Render Pass is, and how you can inject it into a scene.| +|[Write a Scriptable Render Pass](write-a-scriptable-render-pass.md)|An example of a `ScriptableRenderPass` instance that uses `Blit` to create a red tint effect.| +|[Inject a pass via scripting](../customize/inject-render-pass-via-script.md)|Use the `RenderPipelineManager` API to inject a render pass, without using a Scriptable Renderer Feature.| + +## Additional resources + +- [Inject a pass using a Scriptable Renderer Feature](scriptable-renderer-features/inject-a-pass-using-a-scriptable-renderer-feature.md) \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/apply-scriptable-feature-to-specific-camera.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/apply-scriptable-feature-to-specific-camera.md new file mode 100644 index 00000000000..1bb9064e88e --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/apply-scriptable-feature-to-specific-camera.md @@ -0,0 +1,46 @@ +# Apply a Scriptable Renderer Feature to a specific camera type + +This guide covers how to apply a Scriptable Renderer Feature to a specific camera type. + +This method allows you to control which cameras the effect of a Scriptable Renderer Feature applies to. This is particularly relevant when a project uses additional cameras to render elements such as reflections where the use of the Scriptable Renderer Feature could lead to unexpected results. + +You can add logic to the Scriptable Renderer Feature script to check for a specific camera type, before the Scriptable Renderer Feature applies the effect. + +This guide is split into the following sections: + +* [Prerequisites](#prerequisites) +* [Apply Scriptable Renderer Feature to a specific Camera](#scriptable-renderer-feature-game-camera) + +## Prerequisites + +This guide assumes that you already have a complete Scriptable Renderer Feature to work with. If you do not, refer to [How to Create a Custom Renderer Feature](../create-custom-renderer-feature.md). + +## Apply Scriptable Renderer Feature to Game Cameras + +This script applies the Scriptable Renderer Feature to a specific camera type. In this example, it applies the feature only to Game cameras. + +1. Open the C# script of the Scriptable Renderer Feature you want to apply to the cameras. +2. In the `AddRenderPasses` method, add the following `if` statement: + + ```c# + if (renderingData.cameraData.cameraType == CameraType.Game) + ``` + +3. Add the necessary render passes from the Scriptable Renderer Feature to the renderer with the `EnqueuePass` method as shown below. + + ```c# + if (renderingData.cameraData.cameraType == CameraType.Game) + { + renderer.EnqueuePass(yourRenderPass); + } + ``` + +This Scriptable Renderer Feature now only applies to Cameras with the Game camera type. + +> **Note**: Be aware that URP calls the `AddRenderPasses` method at least once per camera per frame so it is best to minimise complexity here to avoid performance issues. + +## Additional resources + +* [Introduction to Scriptable Renderer Features](./intro-to-scriptable-renderer-features.md) +* [Introduction to Scriptable Render Passes](../intro-to-scriptable-render-passes.md) +* [How to create a Custom Renderer Feature](../create-custom-renderer-feature.md) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/inject-a-pass-using-a-scriptable-renderer-feature.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/inject-a-pass-using-a-scriptable-renderer-feature.md new file mode 100644 index 00000000000..61aa233ef75 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/inject-a-pass-using-a-scriptable-renderer-feature.md @@ -0,0 +1,161 @@ +# Inject a pass using a Scriptable Renderer Feature + +This section describes how to create a [Scriptable Renderer Feature](intro-to-scriptable-renderer-features.md) for a URP Renderer. A Scriptable Renderer Feature enqueues a `ScriptableRenderPass` instance every frame. + +You need to [write a Scriptable Render Pass](../write-a-scriptable-render-pass.md) first. + +This walkthrough contains the following sections: + +* [Create a scriptable Renderer Feature](#scriptable-renderer-feature) +* [Add the Renderer Feature to the the Universal Renderer asset](#add-renderer-feature-to-asset) +* [Enqueue the render pass in the custom renderer feature](#enqueue-the-render-pass-in-the-custom-renderer-feature) +* [Complete code for the scripts in this example](#code-renderer-feature) + +## Create a scriptable Renderer Feature + +1. Create a new C# script and name it `MyRendererFeature.cs`. + +2. In the script, remove the code that Unity inserted in the `MyRendererFeature` class. + +3. Add the following `using` directive: + + ```C# + using UnityEngine.Rendering; + using UnityEngine.Rendering.Universal; + ``` + +3. Create the `MyRendererFeature` class that inherits from the **ScriptableRendererFeature** class. + + ```C# + public class MyRendererFeature : ScriptableRendererFeature + ``` + +4. In the `MyRendererFeature` class, implement the following methods: + + * `Create`: Unity calls this method on the following events: + + * When the Renderer Feature loads the first time. + + * When you enable or disable the Renderer Feature. + + * When you change a property in the inspector of the Renderer Feature. + + * `AddRenderPasses`: Unity calls this method every frame, once for each camera. This method lets you inject `ScriptableRenderPass` instances into the scriptable Renderer. + +Now you have the custom `MyRendererFeature` Renderer Feature with its main methods. + +Below is the complete code for this step. + +```C# +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering.Universal; + +public class MyRendererFeature : ScriptableRendererFeature +{ + public override void Create() + { + + } + + public override void AddRenderPasses(ScriptableRenderer renderer, + ref RenderingData renderingData) + { + + } +} +``` + +### Add the Renderer Feature to the Universal Renderer asset + +Add the Renderer Feature you created to the the Universal Renderer asset. For information on how to do this, refer to the page [How to add a Renderer Feature to a Renderer](../../urp-renderer-feature-how-to-add.md). + +## Enqueue a render pass in the custom renderer feature + +In this section, you instantiate a render pass in the `Create` method of the `MyRendererFeature` class, and enqueue it in the `AddRenderPasses` method. + +This section uses the example `RedTintRenderPass` Scriptable Render Pass from the [Write a Scriptable Render Pass](../write-a-scriptable-render-pass.md) page. + +1. Declare the following fields: + + ```C# + [SerializeField] private Shader shader; + private Material material; + private RedTintRenderPass redTintRenderPass; + ``` + +1. In the `Create` method, instantiate the `RedTintRenderPass` class. + + In the method, use the `renderPassEvent` field to specify when to execute the render pass. + + ```C# + public override void Create() + { + if (shader == null) + { + return; + } + material = CoreUtils.CreateEngineMaterial(shader); + redTintRenderPass = new RedTintRenderPass(material); + + renderPassEvent = RenderPassEvent.AfterRenderingSkybox; + } + ``` + +2. In the `AddRenderPasses` method, enqueue the render pass with the `EnqueuePass` method. + + ```C# + public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) + { + if (renderingData.cameraData.cameraType == CameraType.Game) + { + renderer.EnqueuePass(redTintRenderPass); + } + } + ``` + +## Custom Renderer Feature code + +Below is the complete code for the custom Renderer Feature script. + +```C# +using System; +using UnityEditor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +public class MyRendererFeature : ScriptableRendererFeature +{ + [SerializeField] private Shader shader; + private Material material; + private RedTintRenderPass redTintRenderPass; + + public override void Create() + { + if (shader == null) + { + return; + } + material = CoreUtils.CreateEngineMaterial(shader); + redTintRenderPass = new RedTintRenderPass(material); + + redTintRenderPass.renderPassEvent = RenderPassEvent.AfterRenderingSkybox; + } + + public override void AddRenderPasses(ScriptableRenderer renderer, + ref RenderingData renderingData) + { + if (renderingData.cameraData.cameraType == CameraType.Game) + { + renderer.EnqueuePass(redTintRenderPass); + } + } + public override void Dispose(bool disposing) + { + CoreUtils.Destroy(material); + } +} + +``` diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/intro-to-scriptable-renderer-features.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/intro-to-scriptable-renderer-features.md new file mode 100644 index 00000000000..0e29e2063c3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/intro-to-scriptable-renderer-features.md @@ -0,0 +1,29 @@ +# Introduction to Scriptable Renderer Features + +Scriptable Renderer Features are components you can add to a renderer to alter how URP renders a project. + +The following sections explain the fundamentals of Scriptable Renderer Features: + +* [What is a Scriptable Renderer Feature?](#scriptable-renderer-feature) +* [Scriptable Renderer Feature or Scriptable Render Pass?](#renderer-feature-or-render-pass) + +Scriptable Render Passes are a fundamental part of Scriptable Renderer Features. For more information, refer to [Scriptable Render Pass Fundamentals](../intro-to-scriptable-render-passes.md). + +## What is a Scriptable Renderer Feature + +A Scriptable Renderer Feature is a customizable type of [Renderer Feature](../../urp-renderer-feature.md), which is a scriptable component you can add to a renderer to alter how Unity renders a scene or the objects within a scene. The Scriptable Renderer Feature manages and applies Scriptable Render Passes to create custom effects. + +Scriptable Renderer Features control when and how the Scriptable Render Passes apply to a particular renderer or camera, and can also manage multiple Scriptable Render Passes at once. This makes it easier to create complex effects which require multiple render passes with a Scriptable Renderer Feature than by injecting individual Scriptable Render Passes. + +## Scriptable Renderer Feature or Scriptable Render Pass? + +Scriptable Renderer Features and Scriptable Render Passes can both achieve similar outcomes but some scenarios suit the use of one over the other. The key difference is in the workflow for the two methods, a Scriptable Renderer Feature must be added to a renderer in order to run, while Scriptable Render Passes offer more flexibility but require additional work to apply across multiple scenes. + +Scriptable Renderer Features are useful for effects you want to apply to multiple cameras, scenes, or across your entire project. When you add the Scriptable Renderer Feature to a renderer, everything that uses that renderer uses the Scriptable Renderer Feature. This means you can make a change to the Scriptable Renderer Feature once and apply it everywhere that effect is in use. + +Alternately, the injection of individual Scriptable Render Passes offers the ability to add an effect at a single point within a scene or project. This avoids the need for complex scripts such as a renderer feature that works with volumes, and also helps to minimize the possible performance impact of adding such effects. For more information on this, refer to [Scriptable Render Passes in Scenes](../intro-to-scriptable-render-passes.md#scriptable-render-passes-in-scenes). + +## Additional resources + +* [Introduction to Scriptable Render Passes](../intro-to-scriptable-render-passes.md) +* [How to create a Custom Renderer Feature](../create-custom-renderer-feature.md) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/scriptable-renderer-feature-reference.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/scriptable-renderer-feature-reference.md new file mode 100644 index 00000000000..6adb4aeb6d4 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/scriptable-renderer-feature-reference.md @@ -0,0 +1,35 @@ +# Scriptable Renderer Feature Reference + +When working with Scriptable Renderer Features and Scriptable Render Passes there are predefined methods that you need to implement for URP to call at specific points in the pipeline. + +The following sections summarize the common methods used to write Scriptable Renderer Features and Scriptable Render Passes: + +* [Scriptable Renderer Feature Methods](#scriptable-renderer-feature-methods) +* [Scriptable Render Pass Methods](#scriptable-render-pass-methods) + +## Scriptable Renderer Feature Methods + +You can use the following methods within a Scriptable Renderer Feature to handle its core functions. For more information on Scriptable Renderer Feature scripting and further details on the methods listed below, refer to [ScriptableRendererFeature](xref:UnityEngine.Rendering.Universal.ScriptableRendererFeature). + +| **Method** | **Description** | +| ---------- | --------------- | +| `AddRenderPasses` | Use this method to add one or more Render Passes into the rendering sequence of the renderer with the `EnqueuePass` method.

By default this method applies the render passes to all cameras. To change this, add logic to return early in the method when a specific camera or camera type is detected.

**Note**: URP calls this method once per camera when the renderer is set up, for this reason you should not create or instantiate any resources within this function. | +| `Create` | Use this method to initialize any resources the Scriptable Renderer Feature needs such as Materials and Render Pass instances. | +| `Dispose` | Use this method to clean up the resources allocated to the Scriptable Renderer Feature such as Materials. | +| `SetupRenderPasses` | Use this method to run any setup the Scriptable Render Passes require. For example, you can set the initial values of properties, or run custom setup methods from your Scriptable Render Passes.

If your Scriptable Renderer Feature accesses camera targets to set up its Scriptable Render Passes, do it in this method instead of in the `AddRenderPasses` method. | + +## Scriptable Render Pass Methods + +You can use the following methods within a Scriptable Renderer Pass to handle its core functions. For further information on Scriptable Render Pass scripting and further details on the methods listed below, refer to [ScriptableRenderPass](xref:UnityEngine.Rendering.Universal.ScriptableRenderPass). + +| **Method** | **Description** | +| ---------- | --------------- | +| `Execute` | Use this method to implement the rendering logic for the Scriptable Renderer Feature.

**Note**: You do not need to call `ScriptableRenderContext.submit`, URP handles this and calls it at specific points in the pipeline. | +| `OnCameraCleanup` | Use this method to clean up any resources that were allocated during the render pass. | +| `OnCameraSetup` | Use this method to configure render targets and their clear state. You can also use it to create temporary render target textures.

**Note**: When this method is empty, the render pass will render to the active camera render target. | + +## Additional resources + +* [Introduction to Scriptable Renderer Features](./intro-to-scriptable-renderer-features.md) +* [Introduction to Scriptable Render Passes](intro-to-scriptable-renderer-features.md) +* [How to create a Custom Renderer Feature](../create-custom-renderer-feature.md) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/scriptable-renderer-features-landing.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/scriptable-renderer-features-landing.md new file mode 100644 index 00000000000..d4dfc6ac915 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/scriptable-renderer-features/scriptable-renderer-features-landing.md @@ -0,0 +1,10 @@ +# Scriptable Renderer Features + +Scriptable Renderer Features are components you can add to a renderer to alter how URP renders a project. + +|Page|Description| +|-|-| +|[Introduction to Scriptable Renderer Features](intro-to-scriptable-renderer-features.md)|What a Scriptable Renderer Feature is, and how a Scriptable Renderer Feature relates to a Scriptable Render Pass.| +|[Inject a custom pass using a Scriptable Renderer Feature](inject-a-pass-using-a-scriptable-renderer-feature.md)|Create a Scriptable Renderer Feature, add it to the Universal Renderer, and enqueue a render pass.| +|[Apply a Scriptable Renderer Feature to a specific camera type](apply-scriptable-feature-to-specific-camera.md)|Control which cameras the effect of a Scriptable Renderer Feature applies to.| +|[Example of a complete Scriptable Renderer Feature](../create-custom-renderer-feature.md)|An example of a complete Scriptable Renderer Feature with a Scriptable Render Pass that creates a blur effect.| diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/write-a-scriptable-render-pass.md b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/write-a-scriptable-render-pass.md new file mode 100644 index 00000000000..a4c96defdbf --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/renderer-features/write-a-scriptable-render-pass.md @@ -0,0 +1,288 @@ +# Write a Scriptable Render Pass + +The following example is a `ScriptableRenderPass` instance that performs the following steps: + +1. Creates a temporary render texture using the `RenderTextureDescriptor` API. +2. Applies two passes of the [custom shader](#example-shader) to the camera output using the `RTHandle` and the `Blit` API. + +After you write a Scriptable Render Pass, you can inject the pass using one of the following methods: + +- [Use the `RenderPipelineManager` API](../customize/inject-render-pass-via-script.md) +- [Use a Scriptable Renderer Feature](scriptable-renderer-features/inject-a-pass-using-a-scriptable-renderer-feature.md) + +## Create the scriptable Render Pass + +This section demonstrates how to create a scriptable Render Pass. + +1. Create a new C# script and name it `RedTintRenderPass.cs`. + +2. In the script, remove the code that Unity inserted in the `RedTintRenderPass` class. Add the following `using` directive: + + ```C# + using UnityEngine.Rendering; + using UnityEngine.Rendering.Universal; + ``` + +3. Create the `RedTintRenderPass` class that inherits from the **ScriptableRenderPass** class. + + ```C# + public class RedTintRenderPass : ScriptableRenderPass + ``` + +4. Add the `Execute` method to the class. Unity calls this method every frame, once for each camera. This method lets you implement the rendering logic of the scriptable Render Pass. + + ```C# + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { } + ``` + +Below is the complete code for the RedTintRenderPass.cs file from this section. + +```C# +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +public class RedTintRenderPass : ScriptableRenderPass +{ + public override void Execute(ScriptableRenderContext context, + ref RenderingData renderingData) + { + + } +} +``` + +## Implement the settings for the custom render pass + +1. Add a field for the Material, and the constructor that uses the field. + + ```C# + private Material material; + + public RedTintRenderPass(Material material) + { + this.material = material; + } + ``` + +2. Add the `RenderTextureDescriptor` field and initialize it in the constructor: + + ```C# + using UnityEngine; + + private RenderTextureDescriptor textureDescriptor; + + public RedTintRenderPass(Material material) + { + this.material = material; + + textureDescriptor = new RenderTextureDescriptor(Screen.width, + Screen.height, RenderTextureFormat.Default, 0); + } + ``` + +3. Declare the `RTHandle` field to store the reference to the temporary red tint texture. + + ```C# + private RTHandle textureHandle; + ``` + +4. Implement the `Configure` method. Unity calls this method before executing the render pass. + + ```C# + public override void Configure(CommandBuffer cmd, + RenderTextureDescriptor cameraTextureDescriptor) + { + //Set the red tint texture size to be the same as the camera target size. + textureDescriptor.width = cameraTextureDescriptor.width; + textureDescriptor.height = cameraTextureDescriptor.height; + + //Check if the descriptor has changed, and reallocate the RTHandle if necessary. + RenderingUtils.ReAllocateIfNeeded(ref textureHandle, textureDescriptor); + } + ``` + +5. Use the Blit method to apply the two passes from the custom shader to the camera output. + + ```C# + public override void Execute(ScriptableRenderContext context, + ref RenderingData renderingData) + { + //Get a CommandBuffer from pool. + CommandBuffer cmd = CommandBufferPool.Get(); + + RTHandle cameraTargetHandle = + renderingData.cameraData.renderer.cameraColorTargetHandle; + + // Blit from the camera target to the temporary render texture, + // using the first shader pass. + Blit(cmd, cameraTargetHandle, textureHandle, material, 0); + // Blit from the temporary render texture to the camera target, + // using the second shader pass. + Blit(cmd, textureHandle, cameraTargetHandle, material, 1); + + //Execute the command buffer and release it back to the pool. + context.ExecuteCommandBuffer(cmd); + CommandBufferPool.Release(cmd); + } + ``` + +6. Implement the `Dispose` method that destroys the Material and the temporary render texture after the render pass execution. + + ```C# + public void Dispose() + { + #if UNITY_EDITOR + if (EditorApplication.isPlaying) + { + Object.Destroy(material); + } + else + { + Object.DestroyImmediate(material); + } + #else + Object.Destroy(material); + #endif + + if (textureHandle != null) textureHandle.Release(); + } + ``` + +### Custom render pass code + +Below is the complete code for the custom Render Pass script. + +```C# +using UnityEditor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +public class RedTintRenderPass : ScriptableRenderPass +{ + private Material material; + + private RenderTextureDescriptor textureDescriptor; + private RTHandle textureHandle; + + public RedTintRenderPass(Material material) + { + this.material = material; + + textureDescriptor = new RenderTextureDescriptor(Screen.width, + Screen.height, RenderTextureFormat.Default, 0); + } + + public override void Configure(CommandBuffer cmd, + RenderTextureDescriptor cameraTextureDescriptor) + { + // Set the texture size to be the same as the camera target size. + textureDescriptor.width = cameraTextureDescriptor.width; + textureDescriptor.height = cameraTextureDescriptor.height; + + // Check if the descriptor has changed, and reallocate the RTHandle if necessary + RenderingUtils.ReAllocateIfNeeded(ref textureHandle, textureDescriptor); + } + + public override void Execute(ScriptableRenderContext context, + ref RenderingData renderingData) + { + //Get a CommandBuffer from pool. + CommandBuffer cmd = CommandBufferPool.Get(); + + RTHandle cameraTargetHandle = + renderingData.cameraData.renderer.cameraColorTargetHandle; + + // Blit from the camera target to the temporary render texture, + // using the first shader pass. + Blit(cmd, cameraTargetHandle, textureHandle, material, 0); + // Blit from the temporary render texture to the camera target, + // using the second shader pass. + Blit(cmd, textureHandle, cameraTargetHandle, material, 1); + + //Execute the command buffer and release it back to the pool. + context.ExecuteCommandBuffer(cmd); + CommandBufferPool.Release(cmd); + } + + public void Dispose() + { + #if UNITY_EDITOR + if (EditorApplication.isPlaying) + { + Object.Destroy(material); + } + else + { + Object.DestroyImmediate(material); + } + #else + Object.Destroy(material); + #endif + + if (textureHandle != null) textureHandle.Release(); + } +} +``` + +## The custom shader for the red tint effect + +This section contains the code for the custom shader that implements the red tint effect. + +```c++ +Shader "CustomEffects/RedTint" +{ + HLSLINCLUDE + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + // The Blit.hlsl file provides the vertex shader (Vert), + // the input structure (Attributes), and the output structure (Varyings) + #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" + + + float4 RedTint (Varyings input) : SV_Target + { + float3 color = SAMPLE_TEXTURE2D(_BlitTexture, sampler_LinearClamp, input.texcoord).rgb; + return float4(1, color.gb, 1); + } + + float4 SimpleBlit (Varyings input) : SV_Target + { + float3 color = SAMPLE_TEXTURE2D(_BlitTexture, sampler_LinearClamp, input.texcoord).rgb; + return float4(color.rgb, 1); + } + + ENDHLSL + + SubShader + { + Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"} + LOD 100 + ZTest Always ZWrite Off Cull Off + Pass + { + Name "RedTint" + + HLSLPROGRAM + + #pragma vertex Vert + #pragma fragment RedTint + + ENDHLSL + } + + Pass + { + Name "SimpleBlit" + + HLSLPROGRAM + + #pragma vertex Vert + #pragma fragment SimpleBlit + + ENDHLSL + } + } +} +``` \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/rendering-in-universalrp.md b/Packages/com.unity.render-pipelines.universal/Documentation~/rendering-in-universalrp.md index 4fe93a89b32..6451c65b398 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/rendering-in-universalrp.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/rendering-in-universalrp.md @@ -30,7 +30,7 @@ In the [RenderPipelineManager](https://docs.unity3d.com/ScriptReference/Renderin * [endCameraRendering](https://docs.unity3d.com/ScriptReference/Rendering.RenderPipelineManager-endCameraRendering.html) * [endFrameRendering](https://docs.unity3d.com/ScriptReference/Rendering.RenderPipelineManager-endFrameRendering.html) -For the example of how to use the beginCameraRendering event, see the page [Using the beginCameraRendering event](using-begincamerarendering.md). +For the example of how to use the beginCameraRendering event, refer to [Inject a render pass via scripting](./customize/inject-render-pass-via-script.md). ## Camera loop diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/urp-renderer-feature.md b/Packages/com.unity.render-pipelines.universal/Documentation~/urp-renderer-feature.md index 01bc2ea3a86..7cf0a457b99 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/urp-renderer-feature.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/urp-renderer-feature.md @@ -1,17 +1,10 @@ -# URP Renderer Feature +# Pre-built effects (Renderer Features) -A Renderer Feature is an asset that lets you add extra Render passes to a URP Renderer and configure their behavior. +A Renderer Feature is an asset that lets you add a built-in effect to a Universal Render Pipeline (URP) Renderer, and configure its behavior. -URP contains the pre-built Renderer Feature called [Render Objects](#renderer-feature-render-objects.md). - -## How to add a Renderer Feature - -For information on how to add a Renderer Feature to a Renderer, see the page [How to add a Renderer Feature to a Renderer](urp-renderer-feature-how-to-add.md). - -## Available Renderer Features - -The following Renderer Features are available in URP: - -- [Render Objects](./renderer-features/renderer-feature-render-objects.md) -- [Screen Space Ambient Occlusion](post-processing-ssao.md) -- [Decal](renderer-feature-decal.md) +|Page|Description| +|-|-| +|[How to add a Renderer Feature](urp-renderer-feature-how-to-add.md)|Add a Renderer Feature to a Renderer.| +|[Render Objects Renderer Feature](renderer-features/renderer-feature-render-objects-landing.md)|Draw objects on a certain layer, at a certain time, with specific overrides.| +|[Decal Renderer Feature](renderer-feature-decal-landing.md)|Project specific materials (decals) onto other objects in the scene. Decals interact with the scene's lighting and wrap around meshes.| +|[Screen Space Ambient Occlusion (SSAO) Renderer Feature](post-processing-ssao.md)|Darken creases, holes, intersections, and surfaces that are close to each other, in realtime.| From 3d718c8bd475d2070da78178fd91454901549822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elvar=20=C3=96rn=20Unn=C3=BE=C3=B3rsson?= Date: Thu, 8 Feb 2024 03:03:04 +0000 Subject: [PATCH 09/10] [2021.3][URP] Make ValidateRendererFeatures() use IsSubclassOf instead of BaseType (UUM-56639) Backport of #41408. Fixes UUM-56639. --- .../Runtime/ScriptableRendererData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRendererData.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRendererData.cs index cf98b238019..f07c271e329 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRendererData.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRendererData.cs @@ -138,7 +138,7 @@ internal bool ValidateRendererFeatures() // Collect valid, compiled sub-assets foreach (var asset in subassets) { - if (asset == null || asset.GetType().BaseType != typeof(ScriptableRendererFeature)) continue; + if (asset == null || !asset.GetType().IsSubclassOf(typeof(ScriptableRendererFeature))) continue; AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out var guid, out long localId); loadedAssets.Add(localId, asset); debugOutput += $"-{asset.name}\n--localId={localId}\n"; From 364ad730c56fd5fddc97fdc13d8dc9b6ae2abdf3 Mon Sep 17 00:00:00 2001 From: Richard Horton Date: Fri, 9 Feb 2024 01:10:30 +0000 Subject: [PATCH 10/10] [2021.3] Backport Guide for Upgrading Custom Shaders from BiRP to URP Backport PR: #42967 Adds a guide for users upgrading custom shaders that were originally created to work with the Built-in Render Pipeline so that they work with the Universal Render Pipeline. --- .../Documentation~/TableOfContents.md | 1 + .../Documentation~/upgrading-your-shaders.md | 2 +- .../birp-urp-custom-shader-upgrade-guide.md | 293 ++++++++++++++++++ 3 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 Packages/com.unity.render-pipelines.universal/Documentation~/urp-shaders/birp-urp-custom-shader-upgrade-guide.md diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md b/Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md index bb0265956cf..1511f99f571 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md @@ -101,6 +101,7 @@ * [Particles Unlit](particles-unlit-shader.md) * [Decal](decal-shader.md) * [Upgrading shaders from Built-in](upgrading-your-shaders.md) + * [Upgrade custom shaders for URP compatibility](urp-shaders/birp-urp-custom-shader-upgrade-guide.md) * [Shader stripping](shader-stripping.md) * [Writing custom shaders](writing-custom-shaders-urp.md) * [Creating a sample scene](writing-shaders-urp-basic-prerequisites.md) diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/upgrading-your-shaders.md b/Packages/com.unity.render-pipelines.universal/Documentation~/upgrading-your-shaders.md index 7c1142cdeef..dc704c12020 100644 --- a/Packages/com.unity.render-pipelines.universal/Documentation~/upgrading-your-shaders.md +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/upgrading-your-shaders.md @@ -16,7 +16,7 @@ For [SpeedTree](https://docs.unity3d.com/Manual/SpeedTree.html) Shaders, Unity d ## Custom shaders -You cannot upgrade Custom Unity shaders written for the Built-in Render Pipeline. Instead, custom shaders must be rewritten to work with URP or recreated in [ShaderGraph](https://docs.unity3d.com/Packages/com.unity.shadergraph@12.1/manual/index.html). +You cannot upgrade Custom Unity shaders written for the Built-in Render Pipeline. Instead, custom shaders must be rewritten to work with URP or recreated in [ShaderGraph](https://docs.unity3d.com/Packages/com.unity.shadergraph@12.1/manual/index.html). For an example of how to rewrite and upgrade a Built-In Render Pipeline custom shader to be compatible with URP, refer to [Upgrade custom shaders for URP compatibility](urp-shaders/birp-urp-custom-shader-upgrade-guide.md). Any Materials in a Scene that use a custom shader when you upgrade a project to use URP turn pink to indicate the Material no longer works. To fix this, upgrade or change the Material's shader to one that is compatible with URP. diff --git a/Packages/com.unity.render-pipelines.universal/Documentation~/urp-shaders/birp-urp-custom-shader-upgrade-guide.md b/Packages/com.unity.render-pipelines.universal/Documentation~/urp-shaders/birp-urp-custom-shader-upgrade-guide.md new file mode 100644 index 00000000000..40cc91a2174 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Documentation~/urp-shaders/birp-urp-custom-shader-upgrade-guide.md @@ -0,0 +1,293 @@ +# Upgrade custom shaders for URP compatibility + +Custom Shaders written for the Built-In Render Pipeline are not compatible with the Universal Render Pipeline (URP), and you can't upgrade them automatically with the Render Pipeline Converter. Instead, you must rewrite the incompatible sections of shader code to work with URP. + +You can also recreate custom shaders in Shader Graph. For more information, refer to documentation on [ShaderGraph](https://docs.unity3d.com/Packages/com.unity.shadergraph@latest). + +> **Note**: You can identify any materials in a scene that use custom shaders when you upgrade to URP as they turn magenta (bright pink) to indicate an error. + +This guide demonstrates how to upgrade a custom unlit shader from Built-In Render Pipeline to be fully compatible with URP through the following sections: + +* [Example Built-In Render Pipeline custom shader](#example-built-in-render-pipeline-custom-shader) +* [Make the custom shader URP compatible](#make-the-custom-shader-urp-compatible) +* [Enable tiling and offset for the shader](#enable-tiling-and-offset-for-the-shader) +* [Complete shader code](#complete-shader-code) + +## Example Built-In Render Pipeline custom shader + +The following shader is a simple unlit shader that works with the Built-In Render Pipeline. This guide demonstrates how to upgrade this shader to be compatible with URP. + +```hlsl +Shader "Custom/UnlitShader" +{ + Properties + { + [NoScaleOffset] _MainTex("Main Texture", 2D) = "white" {} + _Color("Color", Color) = (1,1,1,1) + } + + SubShader + { + Tags { "RenderType" = "Opaque" } + + Pass + { + CGPROGRAM + + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct v2f + { + float4 position : SV_POSITION; + float2 uv: TEXCOORD0; + }; + + float4 _Color; + sampler2D _MainTex; + + v2f vert(appdata_base v) + { + v2f o; + + o.position = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + + return o; + } + + fixed4 frag(v2f i) : SV_Target + { + fixed4 texel = tex2D(_MainTex, i.uv); + return texel * _Color; + } + ENDCG + } + } +} +``` + +## Make the custom shader URP compatible + +Built-In Render Pipeline shaders have two issues, which you can see in the Inspector window: + +* A warning that **Material property is found in another cbuffer**. +* The **SRP Batcher** property displays **not compatible**. + +The following steps show how to solve these issues and make a shader compatible with URP and the SRP Batcher. + +1. Change `CGPROGRAM` and `ENDCG` to `HLSLPROGRAM` and `ENDHLSL`. +2. Update the include statement to reference the `Core.hlsl` file. + + ```hlsl + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + ``` + + > **Note**: `Core.hlsl` includes the core SRP library, URP shader variables, and matrix defines and transformations, but it does not include lighting functions or default structs. + +3. Add `"RenderPipeline" = "UniversalPipeline"` to the shader tags. + + ```hlsl + Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } + ``` + + > **Note**: URP does not support all ShaderLab tags. For more information on which tags URP supports, refer to [URP ShaderLab Pass tags](./urp-shaderlab-pass-tags.md). + +4. Replace the `struct v2f` code block with the following `struct Varyings` code block. This changes the struct to use the URP naming convention of `Varyings` instead of `v2f`, and updates the shader to use the correct variables for URP. + + ```hlsl + struct Varyings + { + // The positions in this struct must have the SV_POSITION semantic. + float4 positionHCS : SV_POSITION; + float2 uv : TEXCOORD0; + }; + ``` + +5. Beneath the include statement and above the `Varyings` struct, define a new struct with the name `Attributes`. This is equivalent to the Built-In Render Pipeline's appdata structs but with the new URP naming conventions. +6. Add the variables shown below to the `Attributes` struct. + + ```hlsl + struct Attributes + { + float4 positionOS : POSITION; + float2 uv : TEXCOORD0; + }; + ``` + +7. Update the `v2f vert` function definition to use the new `Varyings` struct and take an instance of the `Attributes` struct as an input, as shown below. + + ```hlsl + Varyings vert(Attributes IN) + ``` + +8. Update the vert function to output an instance of the `Varyings` struct and use the `TransformObjectToHClip` function to convert from object space to clip space. The function also needs to take the input `Attributes` UV and pass it to the output `Varyings` UV. + + ```hlsl + Varyings vert(Attributes IN) + { + Varyings OUT; + + OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); + OUT.uv = IN.uv; + + return OUT; + } + ``` + + > **Note**: URP shaders use suffixes to indicate the space. `OS` means object space, and `HCS` means homogeneous clip space. + +9. Place a `CBUFFER` code block around the properties the shader uses, along with the `UnityPerMaterial` parameter. + + ```hlsl + CBUFFER_START(UnityPerMaterial) + float4 _Color; + sampler2D _MainTex; + CBUFFER_END + ``` + + > **Note**: For a shader to be SRP Batcher compatible, you must declare all material properties within a `CBUFFER` code block. Even if a shader has multiple passes, all passes must use the same `CBUFFER` block. + +10. Update the `frag` function to use the `Varyings` input and the type `half4`, as shown below. The `frag` function must now use this type, as URP shaders do not support fixed types. + + ```hlsl + half4 frag(Varyings IN) : SV_Target + { + half4 texel = tex2D(_MainTex, IN.uv); + return texel * _Color; + } + ``` + +This custom unlit shader is now compatible with the SRP Batcher and ready for use within URP. You can check this in the Inspector window: + +* The warning that **Material property is found in another cbuffer** no longer appears. +* The **SRP Batcher** property displays **compatible**. + +## Enable tiling and offset for the shader + +Although the shader is now compatible with URP and the SRP Batcher, you can't use use the **Tiling** and **Offset** properties without further changes. To add this functionality to the custom unlit shader, use the following steps. + +1. Rename the property `_MainTex` to `_BaseMap` along with any references to this property. This brings the shader code closer to standard URP shader conventions. +2. Remove the `[NoScaleOffset]` ShaderLab attribute from the `_BaseMap` property. You can now see **Tiling** and **Offset** properties in the shader's Inspector window. +3. Add the `[MainTexture]` ShaderLab attribute to the `_BaseMap` property and the `[MainColor]` attribute to the `_Color` property. This tells the Editor which property to return when you request the main texture or main color from another part of your project or in the Editor. The `Properties` section of your shader should now look as follows: + + ```hlsl + Properties + { + [MainTexture] _BaseMap("Main Texture", 2D) = "white" {} + [MainColor] _Color("Color", Color) = (1,1,1,1) + } + ``` + +4. Add the `TEXTURE2D(_BaseMap)` and `SAMPLER(sampler_BaseMap)` macros above the `CBUFFER` block. These macros define the texture and sampler state variables for use later. For more information on sampler states, refer to [Using sampler states](xref:SL-SamplerStates). + + ```hlsl + TEXTURE2D(_BaseMap); + SAMPLER(sampler_BaseMap); + ``` + +5. Change the `sampler2D _BaseMap` variable inside the `CBUFFER` block to `float4 _BaseMap_ST`. This variable now stores the tiling and offset values set in the Inspector. + + ```hlsl + CBUFFER_START(UnityPerMaterial) + float4 _Color; + float4 _BaseMap_ST; + CBUFFER_END + ``` + +6. Change the `frag` function to access the texture with a macro instead of `tex2D` directly. To do this, replace `tex2D` with the `SAMPLE_TEXTURE2D` macro and add `sampler_BaseMap` as an additional parameter, as shown below: + + ```hlsl + half4 frag(Varyings IN) : SV_Target + { + half4 texel = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv); + return texel * _Color; + } + ``` + +7. In the `vert` function, change `OUT.uv` to use a macro instead of passing the texture coordinates as `IN.uv` directly. To do this, replace `IN.uv` with `TRANSFORM_TEX(IN.uv, _BaseMap)`. Your `vert` function should now look like the following example: + + ```hlsl + Varyings vert(Attributes IN) + { + Varyings OUT; + + OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); + OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap); + + return OUT; + } + ``` + + > **Note**: It's important that you define the `vert` function after the `CBUFFER` block, as the `TRANSFORM_TEX` macro uses the parameter with the `_ST` suffix. + +This shader now has a texture, modified by a color, and is fully SRP Batcher compatible. It also fully supports the **Tiling** and **Offset** properties. + +To see an example of the complete shader code, refer to the [Complete shader code](#complete-shader-code) section of this page. + +## Complete shader code + +```hlsl +Shader "Custom/UnlitShader" +{ + Properties + { + _BaseMap("Base Map", 2D) = "white" {} + _Color("Color", Color) = (1,1,1,1) + } + + SubShader + { + Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } + + Pass + { + HLSLPROGRAM + + #pragma vertex vert + #pragma fragment frag + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + + struct Attributes + { + float4 positionOS : POSITION; + float2 uv: TEXCOORD0; + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float2 uv: TEXCOORD0; + }; + + TEXTURE2D(_BaseMap); + SAMPLER(sampler_BaseMap); + + CBUFFER_START(UnityPerMaterial) + float4 _Color; + float4 _BaseMap_ST; + CBUFFER_END + + Varyings vert(Attributes IN) + { + Varyings OUT; + + OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz); + OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap); + + return OUT; + } + + half4 frag(Varyings IN) : SV_Target + { + float4 texel = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv); + return texel * _Color; + } + ENDHLSL + } + } +} +```