#if UNITY_EDITOR using UnityEditor; using UnityEditor.ProjectWindowCallback; using ShaderKeywordFilter = UnityEditor.ShaderKeywordFilter; #endif using System; using UnityEngine.Scripting.APIUpdating; using UnityEngine.Assertions; using UnityEngine.Experimental.Rendering; 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, /// Depth will be copied after the transparents pass AfterTransparents, /// Depth will be written by a depth prepass ForcePrepass } /// /// Render path exposed as flags to allow compatibility to be expressed with multiple options. /// [Flags] public enum RenderPathCompatibility { /// Forward Rendering Path Forward = 1 << 0, /// Deferred Rendering Path Deferred = 1 << 1, /// Forward+ Rendering Path ForwardPlus = 1 << 2, /// All Rendering Paths All = Forward | Deferred | ForwardPlus } [AttributeUsage(AttributeTargets.Field)] sealed class RenderPathCompatibleAttribute : Attribute { public RenderPathCompatibility renderPath; public RenderPathCompatibleAttribute(RenderPathCompatibility renderPath) { this.renderPath = renderPath; } } /// /// Dept format options for the depth texture and depth attachment. /// Each option is marked with all the render paths its compatible with. /// public enum DepthFormat { /// /// Default format for Android and Switch platforms is and for other platforms /// [RenderPathCompatible(RenderPathCompatibility.All)] Default, /// /// Format containing 16 unsigned normalized bits in depth component. Corresponds to . /// [RenderPathCompatible(RenderPathCompatibility.Forward | RenderPathCompatibility.ForwardPlus)] Depth_16 = GraphicsFormat.D16_UNorm, /// /// Format containing 24 unsigned normalized bits in depth component. Corresponds to . /// [RenderPathCompatible(RenderPathCompatibility.Forward | RenderPathCompatibility.ForwardPlus)] Depth_24 = GraphicsFormat.D24_UNorm, /// /// Format containing 32 signed float bits in depth component. Corresponds to . /// [RenderPathCompatible(RenderPathCompatibility.Forward | RenderPathCompatibility.ForwardPlus)] Depth_32 = GraphicsFormat.D32_SFloat, /// /// Format containing 16 unsigned normalized bits in depth component and 8 unsigned integer bits in stencil. Corresponds to . /// [RenderPathCompatible(RenderPathCompatibility.All)] Depth_16_Stencil_8 = GraphicsFormat.D16_UNorm_S8_UInt, /// /// Format containing 24 unsigned normalized bits in depth component and 8 unsigned integer bits in stencil. Corresponds to . /// [RenderPathCompatible(RenderPathCompatibility.All)] Depth_24_Stencil_8 = GraphicsFormat.D24_UNorm_S8_UInt, /// /// Format containing 32 signed float bits in depth component and 8 unsigned integer bits in stencil. Corresponds to . /// [RenderPathCompatible(RenderPathCompatibility.All)] Depth_32_Stencil_8 = GraphicsFormat.D32_SFloat_S8_UInt, } /// /// Class containing resources needed for the UniversalRenderer. /// [Serializable, ReloadGroup, ExcludeFromPreset] [URPHelpURL("urp-universal-renderer")] public partial 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 /// /// Resources needed for Post Processing. /// public PostProcessData postProcessData = 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.AfterTransparents; [SerializeField] DepthFormat m_DepthAttachmentFormat = DepthFormat.Default; [SerializeField] DepthFormat m_DepthTextureFormat = DepthFormat.Default; #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(false, keywordNames: ShaderKeywordStrings._GBUFFER_NORMALS_OCT)] #endif [SerializeField] bool m_AccurateGbufferNormals = false; [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; } } /// /// The default stencil state settings. /// 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; } } /// /// Depth format used for CameraDepthAttachment /// public DepthFormat depthAttachmentFormat { get { if (m_DepthAttachmentFormat != DepthFormat.Default && !SystemInfo.IsFormatSupported((GraphicsFormat)m_DepthAttachmentFormat, GraphicsFormatUsage.Render)) { Debug.LogWarning("Selected Depth Attachment Format is not supported on this platform, falling back to Default"); return DepthFormat.Default; } return m_DepthAttachmentFormat; } set { SetDirty(); if (renderingMode == RenderingMode.Deferred && !GraphicsFormatUtility.IsStencilFormat((GraphicsFormat)value)) { Debug.LogWarning("Depth format without stencil is not supported on Deferred renderer, falling back to Default"); m_DepthAttachmentFormat = DepthFormat.Default; } else { m_DepthAttachmentFormat = value; } } } /// /// Depth format used for CameraDepthTexture /// public DepthFormat depthTextureFormat { get { if (m_DepthTextureFormat != DepthFormat.Default && !SystemInfo.IsFormatSupported((GraphicsFormat) m_DepthTextureFormat, GraphicsFormatUsage.Render)) { Debug.LogWarning($"Selected Depth Texture Format {m_DepthTextureFormat.ToString()} is not supported on this platform, falling back to Default"); return DepthFormat.Default; } return m_DepthTextureFormat; } set { SetDirty(); m_DepthTextureFormat = value; } } /// /// Use 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; } } /// /// Controls when URP renders via an intermediate texture. /// public IntermediateTextureMode intermediateTextureMode { get => m_IntermediateTextureMode; set { SetDirty(); m_IntermediateTextureMode = value; } } /// protected override void OnEnable() { base.OnEnable(); ReloadAllNullProperties(); } private void ReloadAllNullProperties() { // 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 UNITY_EDITOR ResourceReloader.TryReloadAllNullIn(this, UniversalRenderPipelineAsset.packagePath); if (postProcessData != null) ResourceReloader.TryReloadAllNullIn(postProcessData, UniversalRenderPipelineAsset.packagePath); #endif } /// void ISerializationCallbackReceiver.OnBeforeSerialize() { m_AssetVersion = k_LatestAssetVersion; } /// void ISerializationCallbackReceiver.OnAfterDeserialize() { 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; } } }