#if UNITY_EDITOR using UnityEditor; using UnityEditor.ProjectWindowCallback; using ShaderKeywordFilter = UnityEditor.ShaderKeywordFilter; #endif using System; using UnityEngine.Scripting.APIUpdating; using UnityEngine.Assertions; namespace UnityEngine.Rendering.Universal { /// /// Defines if Unity will copy the depth that can be bound in shaders as _CameraDepthTexture after the opaques pass or after the transparents pass. /// public enum CopyDepthMode { /// Depth will be copied after the opaques pass AfterOpaques = 0, // Reserve space for after transparent mode // AfterTransparents = 1, /// Depth will be written by a depth prepass ForcePrepass = 2 } [Serializable, ReloadGroup, ExcludeFromPreset] public class UniversalRendererData : ScriptableRendererData, ISerializationCallbackReceiver { #if UNITY_EDITOR [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812")] internal class CreateUniversalRendererAsset : EndNameEditAction { public override void Action(int instanceId, string pathName, string resourceFile) { var instance = UniversalRenderPipelineAsset.CreateRendererAsset(pathName, RendererType.UniversalRenderer, false) as UniversalRendererData; Selection.activeObject = instance; } } [MenuItem("Assets/Create/Rendering/URP Universal Renderer", priority = CoreUtils.Sections.section3 + CoreUtils.Priorities.assetsCreateRenderingMenuPriority + 2)] static void CreateUniversalRendererData() { ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance(), "New Custom Universal Renderer Data.asset", null, null); } #endif [Serializable, ReloadGroup] public sealed class ShaderResources { [Reload("Shaders/Utils/Blit.shader")] public Shader blitPS; [Reload("Shaders/Utils/CopyDepth.shader")] public Shader copyDepthPS; [Obsolete("Obsolete, this feature will be supported by new 'ScreenSpaceShadows' renderer feature")] public Shader screenSpaceShadowPS; [Reload("Shaders/Utils/Sampling.shader")] public Shader samplingPS; [Reload("Shaders/Utils/StencilDeferred.shader")] public Shader stencilDeferredPS; [Reload("Shaders/Utils/FallbackError.shader")] public Shader fallbackErrorPS; [Reload("Shaders/Utils/MaterialError.shader")] public Shader materialErrorPS; // Core blitter shaders, adapted from HDRP // TODO: move to core and share with HDRP [Reload("Shaders/Utils/CoreBlit.shader"), SerializeField] internal Shader coreBlitPS; [Reload("Shaders/Utils/CoreBlitColorAndDepth.shader"), SerializeField] internal Shader coreBlitColorAndDepthPS; [Reload("Shaders/CameraMotionVectors.shader")] public Shader cameraMotionVector; [Reload("Shaders/ObjectMotionVectors.shader")] public Shader objectMotionVector; } public PostProcessData postProcessData = null; #if ENABLE_VR && ENABLE_XR_MODULE [Reload("Runtime/Data/XRSystemData.asset")] public XRSystemData xrSystemData = null; #endif public ShaderResources shaders = null; const int k_LatestAssetVersion = 2; [SerializeField] int m_AssetVersion = 0; [SerializeField] LayerMask m_OpaqueLayerMask = -1; [SerializeField] LayerMask m_TransparentLayerMask = -1; [SerializeField] StencilStateData m_DefaultStencilState = new StencilStateData() { passOperation = StencilOp.Replace }; // This default state is compatible with deferred renderer. [SerializeField] bool m_ShadowTransparentReceive = true; [SerializeField] RenderingMode m_RenderingMode = RenderingMode.Forward; [SerializeField] DepthPrimingMode m_DepthPrimingMode = DepthPrimingMode.Disabled; // Default disabled because there are some outstanding issues with Text Mesh rendering. [SerializeField] CopyDepthMode m_CopyDepthMode = CopyDepthMode.AfterOpaques; #if UNITY_EDITOR // Do not strip accurateGbufferNormals on Mobile Vulkan as some GPUs do not support R8G8B8A8_SNorm, which then force us to use accurateGbufferNormals [ShaderKeywordFilter.ApplyRulesIfNotGraphicsAPI(GraphicsDeviceType.Vulkan)] [ShaderKeywordFilter.RemoveIf(true, keywordNames: ShaderKeywordStrings._GBUFFER_NORMALS_OCT)] #endif [SerializeField] bool m_AccurateGbufferNormals = false; //[SerializeField] bool m_TiledDeferredShading = false; #if UNITY_EDITOR // NOTE: Atm clustered enabled only makes sense when rendering mode is forward. This filter attribute // only considers this boolean here. So it is up to the rest of the system to ensure that rendering mode is forward. // Maybe it would make sense to merge clustered state into the RenderingMode enum by adding ForwardPlus etc there? [ShaderKeywordFilter.SelectOrRemove(true, keywordNames: ShaderKeywordStrings.ClusteredRendering)] [ShaderKeywordFilter.RemoveIf(true, overridePriority: true, keywordNames: new string[] {ShaderKeywordStrings.AdditionalLightsVertex, ShaderKeywordStrings.AdditionalLightsPixel})] #endif [SerializeField] bool m_ClusteredRendering = false; const TileSize k_DefaultTileSize = TileSize._32; [SerializeField] TileSize m_TileSize = k_DefaultTileSize; [SerializeField] IntermediateTextureMode m_IntermediateTextureMode = IntermediateTextureMode.Always; protected override ScriptableRenderer Create() { if (!Application.isPlaying) { ReloadAllNullProperties(); } return new UniversalRenderer(this); } /// /// Use this to configure how to filter opaque objects. /// public LayerMask opaqueLayerMask { get => m_OpaqueLayerMask; set { SetDirty(); m_OpaqueLayerMask = value; } } /// /// Use this to configure how to filter transparent objects. /// public LayerMask transparentLayerMask { get => m_TransparentLayerMask; set { SetDirty(); m_TransparentLayerMask = value; } } public StencilStateData defaultStencilState { get => m_DefaultStencilState; set { SetDirty(); m_DefaultStencilState = value; } } /// /// True if transparent objects receive shadows. /// public bool shadowTransparentReceive { get => m_ShadowTransparentReceive; set { SetDirty(); m_ShadowTransparentReceive = value; } } /// /// Rendering mode. /// public RenderingMode renderingMode { get => m_RenderingMode; set { SetDirty(); m_RenderingMode = value; } } /// /// Depth priming mode. /// public DepthPrimingMode depthPrimingMode { get => m_DepthPrimingMode; set { SetDirty(); m_DepthPrimingMode = value; } } /// /// Copy depth mode. /// public CopyDepthMode copyDepthMode { get => m_CopyDepthMode; set { SetDirty(); m_CopyDepthMode = value; } } /// /// Use Octaedron Octahedron normal vector encoding for gbuffer normals. /// The overhead is negligible from desktop GPUs, while it should be avoided for mobile GPUs. /// public bool accurateGbufferNormals { get => m_AccurateGbufferNormals; set { SetDirty(); m_AccurateGbufferNormals = value; } } /* public bool tiledDeferredShading { get => m_TiledDeferredShading; set { SetDirty(); m_TiledDeferredShading = value; } } */ internal bool clusteredRendering { get => m_ClusteredRendering; set { SetDirty(); m_ClusteredRendering = value; } } internal TileSize tileSize { get => m_TileSize; set { Assert.IsTrue(value.IsValid()); SetDirty(); m_TileSize = value; } } /// /// Controls when URP renders via an intermediate texture. /// public IntermediateTextureMode intermediateTextureMode { get => m_IntermediateTextureMode; set { SetDirty(); m_IntermediateTextureMode = value; } } protected override void OnValidate() { base.OnValidate(); if (!m_TileSize.IsValid()) { m_TileSize = k_DefaultTileSize; } } protected override void OnEnable() { base.OnEnable(); // Upon asset creation, OnEnable is called and `shaders` reference is not yet initialized // We need to call the OnEnable for data migration when updating from old versions of UniversalRP that // serialized resources in a different format. Early returning here when OnEnable is called // upon asset creation is fine because we guarantee new assets get created with all resources initialized. if (shaders == null) return; ReloadAllNullProperties(); } private void ReloadAllNullProperties() { #if UNITY_EDITOR ResourceReloader.TryReloadAllNullIn(this, UniversalRenderPipelineAsset.packagePath); #if ENABLE_VR && ENABLE_XR_MODULE ResourceReloader.TryReloadAllNullIn(xrSystemData, UniversalRenderPipelineAsset.packagePath); #endif #endif } void ISerializationCallbackReceiver.OnBeforeSerialize() { m_AssetVersion = k_LatestAssetVersion; } void ISerializationCallbackReceiver.OnAfterDeserialize() { if (m_AssetVersion <= 0) { // Default to old intermediate texture mode for compatibility reason. m_IntermediateTextureMode = IntermediateTextureMode.Always; } if (m_AssetVersion <= 1) { // To avoid breaking existing projects, keep the old AfterOpaques behaviour. The new AfterTransparents default will only apply to new projects. m_CopyDepthMode = CopyDepthMode.AfterOpaques; } m_AssetVersion = k_LatestAssetVersion; } } }