initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,519 @@
using System.Diagnostics;
using UnityEngine.Assertions;
using UnityEngine.Rendering.Universal.Internal;
namespace UnityEngine.Rendering.Universal
{
internal enum DecalSurfaceData
{
[Tooltip("Decals will affect only base color and emission.")]
Albedo,
[Tooltip("Decals will affect only base color, normal and emission.")]
AlbedoNormal,
[Tooltip("Decals will affect base color, normal, metallic, ambient occlusion, smoothness and emission.")]
AlbedoNormalMAOS,
}
internal enum DecalTechnique
{
Invalid,
DBuffer,
ScreenSpace,
GBuffer,
}
internal enum DecalTechniqueOption
{
[Tooltip("Automatically selects technique based on build platform.")]
Automatic,
[Tooltip("Renders decals into DBuffer and then applied during opaque rendering. Requires DepthNormal prepass which makes not viable solution for the tile based renderers common on mobile.")]
[InspectorName("DBuffer")]
DBuffer,
[Tooltip("Renders decals after opaque objects with normal reconstructed from depth. The decals are simply rendered as mesh on top of opaque ones, as result does not support blending per single surface data (etc. normal blending only).")]
ScreenSpace,
}
[System.Serializable]
internal class DBufferSettings
{
public DecalSurfaceData surfaceData = DecalSurfaceData.AlbedoNormalMAOS;
}
internal enum DecalNormalBlend
{
[Tooltip("Low quality of normal reconstruction (Uses 1 sample).")]
Low,
[Tooltip("Medium quality of normal reconstruction (Uses 5 samples).")]
Medium,
[Tooltip("High quality of normal reconstruction (Uses 9 samples).")]
High,
}
[System.Serializable]
internal class DecalScreenSpaceSettings
{
public DecalNormalBlend normalBlend = DecalNormalBlend.Low;
public bool useGBuffer = true;
}
[System.Serializable]
internal class DecalSettings
{
public DecalTechniqueOption technique = DecalTechniqueOption.Automatic;
public float maxDrawDistance = 1000f;
public DBufferSettings dBufferSettings;
public DecalScreenSpaceSettings screenSpaceSettings;
}
internal class SharedDecalEntityManager : System.IDisposable
{
private DecalEntityManager m_DecalEntityManager;
private int m_ReferenceCounter;
public DecalEntityManager Get()
{
if (m_DecalEntityManager == null)
{
Assert.AreEqual(m_ReferenceCounter, 0);
m_DecalEntityManager = new DecalEntityManager();
var decalProjectors = GameObject.FindObjectsOfType<DecalProjector>();
foreach (var decalProjector in decalProjectors)
{
if (!decalProjector.isActiveAndEnabled || m_DecalEntityManager.IsValid(decalProjector.decalEntity))
continue;
decalProjector.decalEntity = m_DecalEntityManager.CreateDecalEntity(decalProjector);
}
DecalProjector.onDecalAdd += OnDecalAdd;
DecalProjector.onDecalRemove += OnDecalRemove;
DecalProjector.onDecalPropertyChange += OnDecalPropertyChange;
DecalProjector.onDecalMaterialChange += OnDecalMaterialChange;
}
m_ReferenceCounter++;
return m_DecalEntityManager;
}
public void Release(DecalEntityManager decalEntityManager)
{
if (m_ReferenceCounter == 0)
return;
m_ReferenceCounter--;
if (m_ReferenceCounter == 0)
{
Dispose();
}
}
public void Dispose()
{
m_DecalEntityManager.Dispose();
m_DecalEntityManager = null;
m_ReferenceCounter = 0;
DecalProjector.onDecalAdd -= OnDecalAdd;
DecalProjector.onDecalRemove -= OnDecalRemove;
DecalProjector.onDecalPropertyChange -= OnDecalPropertyChange;
DecalProjector.onDecalMaterialChange -= OnDecalMaterialChange;
}
private void OnDecalAdd(DecalProjector decalProjector)
{
if (!m_DecalEntityManager.IsValid(decalProjector.decalEntity))
decalProjector.decalEntity = m_DecalEntityManager.CreateDecalEntity(decalProjector);
}
private void OnDecalRemove(DecalProjector decalProjector)
{
m_DecalEntityManager.DestroyDecalEntity(decalProjector.decalEntity);
}
private void OnDecalPropertyChange(DecalProjector decalProjector)
{
if (m_DecalEntityManager.IsValid(decalProjector.decalEntity))
m_DecalEntityManager.UpdateDecalEntityData(decalProjector.decalEntity, decalProjector);
}
private void OnDecalMaterialChange(DecalProjector decalProjector)
{
// Decal will end up in new chunk after material change
OnDecalRemove(decalProjector);
OnDecalAdd(decalProjector);
}
}
[DisallowMultipleRendererFeature("Decal")]
[Tooltip("With this Renderer Feature, Unity can project specific Materials (decals) onto other objects in the Scene.")]
internal class DecalRendererFeature : ScriptableRendererFeature
{
private static SharedDecalEntityManager sharedDecalEntityManager { get; } = new SharedDecalEntityManager();
[SerializeField]
private DecalSettings m_Settings = new DecalSettings();
[SerializeField]
[HideInInspector]
[Reload("Shaders/Utils/CopyDepth.shader")]
private Shader m_CopyDepthPS;
[SerializeField]
[HideInInspector]
[Reload("Runtime/Decal/DBuffer/DBufferClear.shader")]
private Shader m_DBufferClear;
private DecalTechnique m_Technique = DecalTechnique.Invalid;
private DBufferSettings m_DBufferSettings;
private DecalScreenSpaceSettings m_ScreenSpaceSettings;
private bool m_RecreateSystems;
private CopyDepthPass m_CopyDepthPass;
private DecalPreviewPass m_DecalPreviewPass;
private Material m_CopyDepthMaterial;
// Entities
private DecalEntityManager m_DecalEntityManager;
private DecalUpdateCachedSystem m_DecalUpdateCachedSystem;
private DecalUpdateCullingGroupSystem m_DecalUpdateCullingGroupSystem;
private DecalUpdateCulledSystem m_DecalUpdateCulledSystem;
private DecalCreateDrawCallSystem m_DecalCreateDrawCallSystem;
private DecalDrawErrorSystem m_DrawErrorSystem;
// DBuffer
private DBufferRenderPass m_DBufferRenderPass;
private DecalForwardEmissivePass m_ForwardEmissivePass;
private DecalDrawDBufferSystem m_DecalDrawDBufferSystem;
private DecalDrawFowardEmissiveSystem m_DecalDrawForwardEmissiveSystem;
private Material m_DBufferClearMaterial;
// Screen Space
private DecalScreenSpaceRenderPass m_ScreenSpaceDecalRenderPass;
private DecalDrawScreenSpaceSystem m_DecalDrawScreenSpaceSystem;
private DecalSkipCulledSystem m_DecalSkipCulledSystem;
// GBuffer
private DecalGBufferRenderPass m_GBufferRenderPass;
private DecalDrawGBufferSystem m_DrawGBufferSystem;
private DeferredLights m_DeferredLights;
internal bool intermediateRendering => m_Technique == DecalTechnique.DBuffer;
public override void Create()
{
#if UNITY_EDITOR
ResourceReloader.TryReloadAllNullIn(this, UniversalRenderPipelineAsset.packagePath);
#endif
m_DecalPreviewPass = new DecalPreviewPass();
m_RecreateSystems = true;
}
internal DBufferSettings GetDBufferSettings()
{
if (m_Settings.technique == DecalTechniqueOption.Automatic)
{
return new DBufferSettings() { surfaceData = DecalSurfaceData.AlbedoNormalMAOS };
}
else
{
return m_Settings.dBufferSettings;
}
}
internal DecalScreenSpaceSettings GetScreenSpaceSettings()
{
if (m_Settings.technique == DecalTechniqueOption.Automatic)
{
return new DecalScreenSpaceSettings()
{
normalBlend = DecalNormalBlend.Low,
useGBuffer = false,
};
}
else
{
return m_Settings.screenSpaceSettings;
}
}
internal DecalTechnique GetTechnique(ScriptableRendererData renderer)
{
var universalRenderer = renderer as UniversalRendererData;
if (universalRenderer == null)
{
Debug.LogError("Only universal renderer supports Decal renderer feature.");
return DecalTechnique.Invalid;
}
bool isDeferred = universalRenderer.renderingMode == RenderingMode.Deferred;
return GetTechnique(isDeferred);
}
internal DecalTechnique GetTechnique(ScriptableRenderer renderer)
{
var universalRenderer = renderer as UniversalRenderer;
if (universalRenderer == null)
{
Debug.LogError("Only universal renderer supports Decal renderer feature.");
return DecalTechnique.Invalid;
}
bool isDeferred = universalRenderer.renderingMode == RenderingMode.Deferred;
return GetTechnique(isDeferred);
}
private DecalTechnique GetTechnique(bool isDeferred)
{
if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES2)
{
Debug.LogError("Decals are not supported with OpenGLES2.");
return DecalTechnique.Invalid;
}
DecalTechnique technique = DecalTechnique.Invalid;
switch (m_Settings.technique)
{
case DecalTechniqueOption.Automatic:
if (IsAutomaticDBuffer())
technique = DecalTechnique.DBuffer;
else
technique = DecalTechnique.ScreenSpace;
break;
case DecalTechniqueOption.ScreenSpace:
if (m_Settings.screenSpaceSettings.useGBuffer && isDeferred)
technique = DecalTechnique.GBuffer;
else
technique = DecalTechnique.ScreenSpace;
break;
case DecalTechniqueOption.DBuffer:
technique = DecalTechnique.DBuffer;
break;
}
bool mrt4 = SystemInfo.supportedRenderTargetCount >= 4;
if (technique == DecalTechnique.DBuffer && !mrt4)
{
Debug.LogError("Decal DBuffer technique requires MRT4 support.");
return DecalTechnique.Invalid;
}
if (technique == DecalTechnique.GBuffer && !mrt4)
{
Debug.LogError("Decal useGBuffer option requires MRT4 support.");
return DecalTechnique.Invalid;
}
return technique;
}
private bool IsAutomaticDBuffer()
{
// As WebGL uses gles here we should not use DBuffer
#if UNITY_EDITOR
if (UnityEditor.EditorUserBuildSettings.selectedBuildTargetGroup == UnityEditor.BuildTargetGroup.WebGL)
return false;
#else
if (Application.platform == RuntimePlatform.WebGLPlayer)
return false;
#endif
return !GraphicsSettings.HasShaderDefine(BuiltinShaderDefine.SHADER_API_MOBILE);
}
private void RecreateSystemsIfNeeded(ScriptableRenderer renderer, in CameraData cameraData)
{
if (!m_RecreateSystems)
return;
m_Technique = GetTechnique(renderer);
m_DBufferSettings = GetDBufferSettings();
m_ScreenSpaceSettings = GetScreenSpaceSettings();
m_CopyDepthMaterial = CoreUtils.CreateEngineMaterial(m_CopyDepthPS);
m_CopyDepthPass = new CopyDepthPass(RenderPassEvent.AfterRenderingPrePasses, m_CopyDepthMaterial);
m_DBufferClearMaterial = CoreUtils.CreateEngineMaterial(m_DBufferClear);
if (m_DecalEntityManager == null)
{
m_DecalEntityManager = sharedDecalEntityManager.Get();
}
m_DecalUpdateCachedSystem = new DecalUpdateCachedSystem(m_DecalEntityManager);
m_DecalUpdateCulledSystem = new DecalUpdateCulledSystem(m_DecalEntityManager);
m_DecalCreateDrawCallSystem = new DecalCreateDrawCallSystem(m_DecalEntityManager, m_Settings.maxDrawDistance);
if (intermediateRendering)
{
m_DecalUpdateCullingGroupSystem = new DecalUpdateCullingGroupSystem(m_DecalEntityManager, m_Settings.maxDrawDistance);
}
else
{
m_DecalSkipCulledSystem = new DecalSkipCulledSystem(m_DecalEntityManager);
}
m_DrawErrorSystem = new DecalDrawErrorSystem(m_DecalEntityManager, m_Technique);
var universalRenderer = renderer as UniversalRenderer;
Assert.IsNotNull(universalRenderer);
switch (m_Technique)
{
case DecalTechnique.ScreenSpace:
m_CopyDepthPass = new CopyDepthPass(RenderPassEvent.AfterRenderingOpaques, m_DBufferClearMaterial);
m_DecalDrawScreenSpaceSystem = new DecalDrawScreenSpaceSystem(m_DecalEntityManager);
m_ScreenSpaceDecalRenderPass = new DecalScreenSpaceRenderPass(m_ScreenSpaceSettings, intermediateRendering ? m_DecalDrawScreenSpaceSystem : null);
break;
case DecalTechnique.GBuffer:
m_DeferredLights = universalRenderer.deferredLights;
m_CopyDepthPass = new CopyDepthPass(RenderPassEvent.AfterRenderingOpaques, m_DBufferClearMaterial);
m_DrawGBufferSystem = new DecalDrawGBufferSystem(m_DecalEntityManager);
m_GBufferRenderPass = new DecalGBufferRenderPass(m_ScreenSpaceSettings, intermediateRendering ? m_DrawGBufferSystem : null);
break;
case DecalTechnique.DBuffer:
m_DecalDrawDBufferSystem = new DecalDrawDBufferSystem(m_DecalEntityManager);
m_DBufferRenderPass = new DBufferRenderPass(m_DBufferClearMaterial, m_DBufferSettings, m_DecalDrawDBufferSystem);
m_DecalDrawForwardEmissiveSystem = new DecalDrawFowardEmissiveSystem(m_DecalEntityManager);
m_ForwardEmissivePass = new DecalForwardEmissivePass(m_DecalDrawForwardEmissiveSystem);
if (universalRenderer.actualRenderingMode == RenderingMode.Deferred)
{
m_DBufferRenderPass.deferredLights = universalRenderer.deferredLights;
m_DBufferRenderPass.deferredLights.DisableFramebufferFetchInput();
}
break;
}
m_RecreateSystems = false;
}
public override void OnCameraPreCull(ScriptableRenderer renderer, in CameraData cameraData)
{
if (cameraData.cameraType == CameraType.Preview)
return;
RecreateSystemsIfNeeded(renderer, cameraData);
ChangeAdaptivePerformanceDrawDistances();
m_DecalEntityManager.Update();
m_DecalUpdateCachedSystem.Execute();
if (intermediateRendering)
{
m_DecalUpdateCullingGroupSystem.Execute(cameraData.camera);
}
else
{
m_DecalSkipCulledSystem.Execute(cameraData.camera);
m_DecalCreateDrawCallSystem.Execute();
if (m_Technique == DecalTechnique.ScreenSpace)
{
m_DecalDrawScreenSpaceSystem.Execute(cameraData);
}
else if (m_Technique == DecalTechnique.GBuffer)
{
m_DrawGBufferSystem.Execute(cameraData);
}
}
m_DrawErrorSystem.Execute(cameraData);
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if (renderingData.cameraData.cameraType == CameraType.Preview)
{
renderer.EnqueuePass(m_DecalPreviewPass);
return;
}
RecreateSystemsIfNeeded(renderer, renderingData.cameraData);
ChangeAdaptivePerformanceDrawDistances();
if (intermediateRendering)
{
m_DecalUpdateCulledSystem.Execute();
m_DecalCreateDrawCallSystem.Execute();
}
switch (m_Technique)
{
case DecalTechnique.ScreenSpace:
renderer.EnqueuePass(m_ScreenSpaceDecalRenderPass);
break;
case DecalTechnique.GBuffer:
m_GBufferRenderPass.Setup(m_DeferredLights);
renderer.EnqueuePass(m_GBufferRenderPass);
break;
case DecalTechnique.DBuffer:
var universalRenderer = renderer as UniversalRenderer;
if (universalRenderer.actualRenderingMode == RenderingMode.Deferred)
{
m_CopyDepthPass.Setup(
new RenderTargetHandle(m_DBufferRenderPass.cameraDepthAttachmentIndentifier),
new RenderTargetHandle(m_DBufferRenderPass.cameraDepthTextureIndentifier)
);
}
else
{
m_CopyDepthPass.Setup(
new RenderTargetHandle(m_DBufferRenderPass.cameraDepthTextureIndentifier),
new RenderTargetHandle(m_DBufferRenderPass.dBufferDepthIndentifier)
);
}
m_CopyDepthPass.MssaSamples = 1;
renderer.EnqueuePass(m_CopyDepthPass);
renderer.EnqueuePass(m_DBufferRenderPass);
renderer.EnqueuePass(m_ForwardEmissivePass);
break;
}
}
internal override bool SupportsNativeRenderPass()
{
return m_Technique == DecalTechnique.GBuffer || m_Technique == DecalTechnique.ScreenSpace;
}
protected override void Dispose(bool disposing)
{
CoreUtils.Destroy(m_CopyDepthMaterial);
CoreUtils.Destroy(m_DBufferClearMaterial);
if (m_DecalEntityManager != null)
{
m_DecalEntityManager = null;
sharedDecalEntityManager.Release(m_DecalEntityManager);
}
}
[Conditional("ADAPTIVE_PERFORMANCE_4_0_0_OR_NEWER")]
private void ChangeAdaptivePerformanceDrawDistances()
{
#if ADAPTIVE_PERFORMANCE_4_0_0_OR_NEWER
if (UniversalRenderPipeline.asset.useAdaptivePerformance)
{
if (m_DecalCreateDrawCallSystem != null)
{
m_DecalCreateDrawCallSystem.maxDrawDistance = AdaptivePerformance.AdaptivePerformanceRenderSettings.DecalsDrawDistance;
}
if (m_DecalUpdateCullingGroupSystem != null)
{
m_DecalUpdateCullingGroupSystem.boundingDistance = AdaptivePerformance.AdaptivePerformanceRenderSettings.DecalsDrawDistance;
}
}
#endif
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a1614fc811f8f184697d9bee70ab9fe5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 9ba98ca4f0fc0754caca09e38af0cc0a, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,21 @@
using System;
namespace UnityEngine.Rendering.Universal
{
/// <summary>
/// <para>Prevents ScriptableRendererFeatures of same type to be added more than once to a Scriptable Renderer.</para>
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class DisallowMultipleRendererFeature : Attribute
{
/// <summary>
/// Set the custom title for renderer feature.
/// </summary>
public string customTitle { private set; get; }
public DisallowMultipleRendererFeature(string customTitle = null)
{
this.customTitle = customTitle;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 43a7ba8bc4aba4c199e05fe79d3f9bee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,102 @@
using System.Collections.Generic;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.Universal
{
public enum RenderQueueType
{
Opaque,
Transparent,
}
[ExcludeFromPreset]
[Tooltip("Render Objects simplifies the injection of additional render passes by exposing a selection of commonly used settings.")]
public class RenderObjects : ScriptableRendererFeature
{
[System.Serializable]
public class RenderObjectsSettings
{
public string passTag = "RenderObjectsFeature";
public RenderPassEvent Event = RenderPassEvent.AfterRenderingOpaques;
public FilterSettings filterSettings = new FilterSettings();
public Material overrideMaterial = null;
public int overrideMaterialPassIndex = 0;
public bool overrideDepthState = false;
public CompareFunction depthCompareFunction = CompareFunction.LessEqual;
public bool enableWrite = true;
public StencilStateData stencilSettings = new StencilStateData();
public CustomCameraSettings cameraSettings = new CustomCameraSettings();
}
[System.Serializable]
public class FilterSettings
{
// TODO: expose opaque, transparent, all ranges as drop down
public RenderQueueType RenderQueueType;
public LayerMask LayerMask;
public string[] PassNames;
public FilterSettings()
{
RenderQueueType = RenderQueueType.Opaque;
LayerMask = 0;
}
}
[System.Serializable]
public class CustomCameraSettings
{
public bool overrideCamera = false;
public bool restoreCamera = true;
public Vector4 offset;
public float cameraFieldOfView = 60.0f;
}
public RenderObjectsSettings settings = new RenderObjectsSettings();
RenderObjectsPass renderObjectsPass;
public override void Create()
{
FilterSettings filter = settings.filterSettings;
// Render Objects pass doesn't support events before rendering prepasses.
// The camera is not setup before this point and all rendering is monoscopic.
// Events before BeforeRenderingPrepasses should be used for input texture passes (shadow map, LUT, etc) that doesn't depend on the camera.
// These events are filtering in the UI, but we still should prevent users from changing it from code or
// by changing the serialized data.
if (settings.Event < RenderPassEvent.BeforeRenderingPrePasses)
settings.Event = RenderPassEvent.BeforeRenderingPrePasses;
renderObjectsPass = new RenderObjectsPass(settings.passTag, settings.Event, filter.PassNames,
filter.RenderQueueType, filter.LayerMask, settings.cameraSettings);
renderObjectsPass.overrideMaterial = settings.overrideMaterial;
renderObjectsPass.overrideMaterialPassIndex = settings.overrideMaterialPassIndex;
if (settings.overrideDepthState)
renderObjectsPass.SetDetphState(settings.enableWrite, settings.depthCompareFunction);
if (settings.stencilSettings.overrideStencilState)
renderObjectsPass.SetStencilState(settings.stencilSettings.stencilReference,
settings.stencilSettings.stencilCompareFunction, settings.stencilSettings.passOperation,
settings.stencilSettings.failOperation, settings.stencilSettings.zFailOperation);
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(renderObjectsPass);
}
internal override bool SupportsNativeRenderPass()
{
return true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6b3d386ba5cd94485973aee1479b272e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,416 @@
using System;
namespace UnityEngine.Rendering.Universal
{
[Serializable]
internal class ScreenSpaceAmbientOcclusionSettings
{
// Parameters
[SerializeField] internal bool Downsample = false;
[SerializeField] internal bool AfterOpaque = false;
[SerializeField] internal DepthSource Source = DepthSource.DepthNormals;
[SerializeField] internal NormalQuality NormalSamples = NormalQuality.Medium;
[SerializeField] internal float Intensity = 3.0f;
[SerializeField] internal float DirectLightingStrength = 0.25f;
[SerializeField] internal float Radius = 0.035f;
[SerializeField] internal int SampleCount = 4;
// Enums
internal enum DepthSource
{
Depth = 0,
DepthNormals = 1
}
internal enum NormalQuality
{
Low,
Medium,
High
}
}
[DisallowMultipleRendererFeature]
[Tooltip("The Ambient Occlusion effect darkens creases, holes, intersections and surfaces that are close to each other.")]
internal class ScreenSpaceAmbientOcclusion : ScriptableRendererFeature
{
// Serialized Fields
[SerializeField, HideInInspector] private Shader m_Shader = null;
[SerializeField] private ScreenSpaceAmbientOcclusionSettings m_Settings = new ScreenSpaceAmbientOcclusionSettings();
// Private Fields
private Material m_Material;
private ScreenSpaceAmbientOcclusionPass m_SSAOPass = null;
// Constants
private const string k_ShaderName = "Hidden/Universal Render Pipeline/ScreenSpaceAmbientOcclusion";
private const string k_OrthographicCameraKeyword = "_ORTHOGRAPHIC";
private const string k_NormalReconstructionLowKeyword = "_RECONSTRUCT_NORMAL_LOW";
private const string k_NormalReconstructionMediumKeyword = "_RECONSTRUCT_NORMAL_MEDIUM";
private const string k_NormalReconstructionHighKeyword = "_RECONSTRUCT_NORMAL_HIGH";
private const string k_SourceDepthKeyword = "_SOURCE_DEPTH";
private const string k_SourceDepthNormalsKeyword = "_SOURCE_DEPTH_NORMALS";
internal bool afterOpaque => m_Settings.AfterOpaque;
/// <inheritdoc/>
public override void Create()
{
// Create the pass...
if (m_SSAOPass == null)
{
m_SSAOPass = new ScreenSpaceAmbientOcclusionPass();
}
GetMaterial();
}
/// <inheritdoc/>
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if (!GetMaterial())
{
Debug.LogErrorFormat(
"{0}.AddRenderPasses(): Missing material. {1} render pass will not be added. Check for missing reference in the renderer resources.",
GetType().Name, name);
return;
}
bool shouldAdd = m_SSAOPass.Setup(m_Settings, renderer, m_Material);
if (shouldAdd)
{
renderer.EnqueuePass(m_SSAOPass);
}
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
CoreUtils.Destroy(m_Material);
}
private bool GetMaterial()
{
if (m_Material != null)
{
return true;
}
if (m_Shader == null)
{
m_Shader = Shader.Find(k_ShaderName);
if (m_Shader == null)
{
return false;
}
}
m_Material = CoreUtils.CreateEngineMaterial(m_Shader);
return m_Material != null;
}
// The SSAO Pass
private class ScreenSpaceAmbientOcclusionPass : ScriptableRenderPass
{
// Properties
private bool isRendererDeferred => m_Renderer != null && m_Renderer is UniversalRenderer && ((UniversalRenderer)m_Renderer).renderingMode == RenderingMode.Deferred;
// Private Variables
private bool m_SupportsR8RenderTextureFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.R8);
private Material m_Material;
private Vector4[] m_CameraTopLeftCorner = new Vector4[2];
private Vector4[] m_CameraXExtent = new Vector4[2];
private Vector4[] m_CameraYExtent = new Vector4[2];
private Vector4[] m_CameraZExtent = new Vector4[2];
private Matrix4x4[] m_CameraViewProjections = new Matrix4x4[2];
private ProfilingSampler m_ProfilingSampler = ProfilingSampler.Get(URPProfileId.SSAO);
private ScriptableRenderer m_Renderer = null;
private RenderTargetIdentifier m_SSAOTexture1Target = new RenderTargetIdentifier(s_SSAOTexture1ID, 0, CubemapFace.Unknown, -1);
private RenderTargetIdentifier m_SSAOTexture2Target = new RenderTargetIdentifier(s_SSAOTexture2ID, 0, CubemapFace.Unknown, -1);
private RenderTargetIdentifier m_SSAOTexture3Target = new RenderTargetIdentifier(s_SSAOTexture3ID, 0, CubemapFace.Unknown, -1);
private RenderTargetIdentifier m_SSAOTextureFinalTarget = new RenderTargetIdentifier(s_SSAOTextureFinalID, 0, CubemapFace.Unknown, -1);
private RenderTextureDescriptor m_AOPassDescriptor;
private RenderTextureDescriptor m_BlurPassesDescriptor;
private RenderTextureDescriptor m_FinalDescriptor;
private ScreenSpaceAmbientOcclusionSettings m_CurrentSettings;
// Constants
private const string k_SSAOTextureName = "_ScreenSpaceOcclusionTexture";
private const string k_SSAOAmbientOcclusionParamName = "_AmbientOcclusionParam";
// Statics
private static readonly int s_BaseMapID = Shader.PropertyToID("_BaseMap");
private static readonly int s_SSAOParamsID = Shader.PropertyToID("_SSAOParams");
private static readonly int s_SSAOTexture1ID = Shader.PropertyToID("_SSAO_OcclusionTexture1");
private static readonly int s_SSAOTexture2ID = Shader.PropertyToID("_SSAO_OcclusionTexture2");
private static readonly int s_SSAOTexture3ID = Shader.PropertyToID("_SSAO_OcclusionTexture3");
private static readonly int s_SSAOTextureFinalID = Shader.PropertyToID("_SSAO_OcclusionTexture");
private static readonly int s_CameraViewXExtentID = Shader.PropertyToID("_CameraViewXExtent");
private static readonly int s_CameraViewYExtentID = Shader.PropertyToID("_CameraViewYExtent");
private static readonly int s_CameraViewZExtentID = Shader.PropertyToID("_CameraViewZExtent");
private static readonly int s_ProjectionParams2ID = Shader.PropertyToID("_ProjectionParams2");
private static readonly int s_CameraViewProjectionsID = Shader.PropertyToID("_CameraViewProjections");
private static readonly int s_CameraViewTopLeftCornerID = Shader.PropertyToID("_CameraViewTopLeftCorner");
private enum ShaderPasses
{
AO = 0,
BlurHorizontal = 1,
BlurVertical = 2,
BlurFinal = 3,
AfterOpaque = 4
}
internal ScreenSpaceAmbientOcclusionPass()
{
m_CurrentSettings = new ScreenSpaceAmbientOcclusionSettings();
}
internal bool Setup(ScreenSpaceAmbientOcclusionSettings featureSettings, ScriptableRenderer renderer, Material material)
{
m_Material = material;
m_Renderer = renderer;
m_CurrentSettings = featureSettings;
ScreenSpaceAmbientOcclusionSettings.DepthSource source;
if (isRendererDeferred)
{
renderPassEvent = featureSettings.AfterOpaque ? RenderPassEvent.AfterRenderingOpaques : RenderPassEvent.AfterRenderingGbuffer;
source = ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals;
}
else
{
// Rendering after PrePasses is usually correct except when depth priming is in play:
// then we rely on a depth resolve taking place after the PrePasses in order to have it ready for SSAO.
// Hence we set the event to RenderPassEvent.AfterRenderingPrePasses + 1 at the earliest.
renderPassEvent = featureSettings.AfterOpaque ? RenderPassEvent.AfterRenderingOpaques : RenderPassEvent.AfterRenderingPrePasses + 1;
source = m_CurrentSettings.Source;
}
switch (source)
{
case ScreenSpaceAmbientOcclusionSettings.DepthSource.Depth:
ConfigureInput(ScriptableRenderPassInput.Depth);
break;
case ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals:
ConfigureInput(ScriptableRenderPassInput.Normal);// need depthNormal prepass for forward-only geometry
break;
default:
throw new ArgumentOutOfRangeException();
}
return m_Material != null
&& m_CurrentSettings.Intensity > 0.0f
&& m_CurrentSettings.Radius > 0.0f
&& m_CurrentSettings.SampleCount > 0;
}
/// <inheritdoc/>
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
RenderTextureDescriptor cameraTargetDescriptor = renderingData.cameraData.cameraTargetDescriptor;
int downsampleDivider = m_CurrentSettings.Downsample ? 2 : 1;
// Update SSAO parameters in the material
Vector4 ssaoParams = new Vector4(
m_CurrentSettings.Intensity, // Intensity
m_CurrentSettings.Radius, // Radius
1.0f / downsampleDivider, // Downsampling
m_CurrentSettings.SampleCount // Sample count
);
m_Material.SetVector(s_SSAOParamsID, ssaoParams);
#if ENABLE_VR && ENABLE_XR_MODULE
int eyeCount = renderingData.cameraData.xr.enabled && renderingData.cameraData.xr.singlePassEnabled ? 2 : 1;
#else
int eyeCount = 1;
#endif
for (int eyeIndex = 0; eyeIndex < eyeCount; eyeIndex++)
{
Matrix4x4 view = renderingData.cameraData.GetViewMatrix(eyeIndex);
Matrix4x4 proj = renderingData.cameraData.GetProjectionMatrix(eyeIndex);
m_CameraViewProjections[eyeIndex] = proj * view;
// camera view space without translation, used by SSAO.hlsl ReconstructViewPos() to calculate view vector.
Matrix4x4 cview = view;
cview.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
Matrix4x4 cviewProj = proj * cview;
Matrix4x4 cviewProjInv = cviewProj.inverse;
Vector4 topLeftCorner = cviewProjInv.MultiplyPoint(new Vector4(-1, 1, -1, 1));
Vector4 topRightCorner = cviewProjInv.MultiplyPoint(new Vector4(1, 1, -1, 1));
Vector4 bottomLeftCorner = cviewProjInv.MultiplyPoint(new Vector4(-1, -1, -1, 1));
Vector4 farCentre = cviewProjInv.MultiplyPoint(new Vector4(0, 0, 1, 1));
m_CameraTopLeftCorner[eyeIndex] = topLeftCorner;
m_CameraXExtent[eyeIndex] = topRightCorner - topLeftCorner;
m_CameraYExtent[eyeIndex] = bottomLeftCorner - topLeftCorner;
m_CameraZExtent[eyeIndex] = farCentre;
}
m_Material.SetVector(s_ProjectionParams2ID, new Vector4(1.0f / renderingData.cameraData.camera.nearClipPlane, 0.0f, 0.0f, 0.0f));
m_Material.SetMatrixArray(s_CameraViewProjectionsID, m_CameraViewProjections);
m_Material.SetVectorArray(s_CameraViewTopLeftCornerID, m_CameraTopLeftCorner);
m_Material.SetVectorArray(s_CameraViewXExtentID, m_CameraXExtent);
m_Material.SetVectorArray(s_CameraViewYExtentID, m_CameraYExtent);
m_Material.SetVectorArray(s_CameraViewZExtentID, m_CameraZExtent);
// Update keywords
CoreUtils.SetKeyword(m_Material, k_OrthographicCameraKeyword, renderingData.cameraData.camera.orthographic);
ScreenSpaceAmbientOcclusionSettings.DepthSource source = this.isRendererDeferred
? ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals
: m_CurrentSettings.Source;
if (source == ScreenSpaceAmbientOcclusionSettings.DepthSource.Depth)
{
switch (m_CurrentSettings.NormalSamples)
{
case ScreenSpaceAmbientOcclusionSettings.NormalQuality.Low:
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionLowKeyword, true);
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionMediumKeyword, false);
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionHighKeyword, false);
break;
case ScreenSpaceAmbientOcclusionSettings.NormalQuality.Medium:
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionLowKeyword, false);
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionMediumKeyword, true);
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionHighKeyword, false);
break;
case ScreenSpaceAmbientOcclusionSettings.NormalQuality.High:
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionLowKeyword, false);
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionMediumKeyword, false);
CoreUtils.SetKeyword(m_Material, k_NormalReconstructionHighKeyword, true);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
switch (source)
{
case ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals:
CoreUtils.SetKeyword(m_Material, k_SourceDepthKeyword, false);
CoreUtils.SetKeyword(m_Material, k_SourceDepthNormalsKeyword, true);
break;
default:
CoreUtils.SetKeyword(m_Material, k_SourceDepthKeyword, true);
CoreUtils.SetKeyword(m_Material, k_SourceDepthNormalsKeyword, false);
break;
}
// Set up the descriptors
RenderTextureDescriptor descriptor = cameraTargetDescriptor;
descriptor.msaaSamples = 1;
descriptor.depthBufferBits = 0;
m_AOPassDescriptor = descriptor;
m_AOPassDescriptor.width /= downsampleDivider;
m_AOPassDescriptor.height /= downsampleDivider;
m_AOPassDescriptor.colorFormat = RenderTextureFormat.ARGB32;
m_BlurPassesDescriptor = descriptor;
m_BlurPassesDescriptor.colorFormat = RenderTextureFormat.ARGB32;
m_FinalDescriptor = descriptor;
m_FinalDescriptor.colorFormat = m_SupportsR8RenderTextureFormat ? RenderTextureFormat.R8 : RenderTextureFormat.ARGB32;
// Get temporary render textures
cmd.GetTemporaryRT(s_SSAOTexture1ID, m_AOPassDescriptor, FilterMode.Bilinear);
cmd.GetTemporaryRT(s_SSAOTexture2ID, m_BlurPassesDescriptor, FilterMode.Bilinear);
cmd.GetTemporaryRT(s_SSAOTexture3ID, m_BlurPassesDescriptor, FilterMode.Bilinear);
cmd.GetTemporaryRT(s_SSAOTextureFinalID, m_FinalDescriptor, FilterMode.Bilinear);
// Configure targets and clear color
ConfigureTarget(m_CurrentSettings.AfterOpaque ? m_Renderer.cameraColorTarget : s_SSAOTexture2ID);
ConfigureClear(ClearFlag.None, Color.white);
}
/// <inheritdoc/>
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (m_Material == null)
{
Debug.LogErrorFormat("{0}.Execute(): Missing material. ScreenSpaceAmbientOcclusion pass will not execute. Check for missing reference in the renderer resources.", GetType().Name);
return;
}
CommandBuffer cmd = CommandBufferPool.Get();
using (new ProfilingScope(cmd, m_ProfilingSampler))
{
if (!m_CurrentSettings.AfterOpaque)
{
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.ScreenSpaceOcclusion, true);
}
PostProcessUtils.SetSourceSize(cmd, m_AOPassDescriptor);
// Execute the SSAO
Render(cmd, m_SSAOTexture1Target, ShaderPasses.AO);
// Execute the Blur Passes
RenderAndSetBaseMap(cmd, m_SSAOTexture1Target, m_SSAOTexture2Target, ShaderPasses.BlurHorizontal);
PostProcessUtils.SetSourceSize(cmd, m_BlurPassesDescriptor);
RenderAndSetBaseMap(cmd, m_SSAOTexture2Target, m_SSAOTexture3Target, ShaderPasses.BlurVertical);
RenderAndSetBaseMap(cmd, m_SSAOTexture3Target, m_SSAOTextureFinalTarget, ShaderPasses.BlurFinal);
// Set the global SSAO texture and AO Params
cmd.SetGlobalTexture(k_SSAOTextureName, m_SSAOTextureFinalTarget);
cmd.SetGlobalVector(k_SSAOAmbientOcclusionParamName, new Vector4(0f, 0f, 0f, m_CurrentSettings.DirectLightingStrength));
// If true, SSAO pass is inserted after opaque pass and is expected to modulate lighting result now.
if (m_CurrentSettings.AfterOpaque)
{
// This implicitly also bind depth attachment. Explicitly binding m_Renderer.cameraDepthTarget does not work.
cmd.SetRenderTarget(
m_Renderer.cameraColorTarget,
RenderBufferLoadAction.Load,
RenderBufferStoreAction.Store
);
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_Material, 0, (int)ShaderPasses.AfterOpaque);
}
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
private void Render(CommandBuffer cmd, RenderTargetIdentifier target, ShaderPasses pass)
{
cmd.SetRenderTarget(
target,
RenderBufferLoadAction.DontCare,
RenderBufferStoreAction.Store,
target,
RenderBufferLoadAction.DontCare,
RenderBufferStoreAction.DontCare
);
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_Material, 0, (int)pass);
}
private void RenderAndSetBaseMap(CommandBuffer cmd, RenderTargetIdentifier baseMap, RenderTargetIdentifier target, ShaderPasses pass)
{
cmd.SetGlobalTexture(s_BaseMapID, baseMap);
Render(cmd, target, pass);
}
/// <inheritdoc/>
public override void OnCameraCleanup(CommandBuffer cmd)
{
if (cmd == null)
{
throw new ArgumentNullException("cmd");
}
if (!m_CurrentSettings.AfterOpaque)
{
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.ScreenSpaceOcclusion, false);
}
cmd.ReleaseTemporaryRT(s_SSAOTexture1ID);
cmd.ReleaseTemporaryRT(s_SSAOTexture2ID);
cmd.ReleaseTemporaryRT(s_SSAOTexture3ID);
cmd.ReleaseTemporaryRT(s_SSAOTextureFinalID);
}
}
}
}

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: f62c9c65cf3354c93be831c8bc075510
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- m_Shader: {instanceID: 0}
- m_BlueNoise: {fileID: 2800000, guid: cbdfedcb32329429aae80014a0d36ad9, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,224 @@
using System;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Rendering.Universal
{
[Serializable]
internal class ScreenSpaceShadowsSettings
{
}
[DisallowMultipleRendererFeature]
[Tooltip("Screen Space Shadows")]
internal class ScreenSpaceShadows : ScriptableRendererFeature
{
// Serialized Fields
[SerializeField, HideInInspector] private Shader m_Shader = null;
[SerializeField] private ScreenSpaceShadowsSettings m_Settings = new ScreenSpaceShadowsSettings();
// Private Fields
private Material m_Material;
private ScreenSpaceShadowsPass m_SSShadowsPass = null;
private ScreenSpaceShadowsPostPass m_SSShadowsPostPass = null;
// Constants
private const string k_ShaderName = "Hidden/Universal Render Pipeline/ScreenSpaceShadows";
/// <inheritdoc/>
public override void Create()
{
if (m_SSShadowsPass == null)
m_SSShadowsPass = new ScreenSpaceShadowsPass();
if (m_SSShadowsPostPass == null)
m_SSShadowsPostPass = new ScreenSpaceShadowsPostPass();
LoadMaterial();
m_SSShadowsPass.renderPassEvent = RenderPassEvent.AfterRenderingGbuffer;
m_SSShadowsPostPass.renderPassEvent = RenderPassEvent.BeforeRenderingTransparents;
}
/// <inheritdoc/>
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if (!LoadMaterial())
{
Debug.LogErrorFormat(
"{0}.AddRenderPasses(): Missing material. {1} render pass will not be added. Check for missing reference in the renderer resources.",
GetType().Name, name);
return;
}
bool allowMainLightShadows = renderingData.shadowData.supportsMainLightShadows && renderingData.lightData.mainLightIndex != -1;
bool shouldEnqueue = allowMainLightShadows && m_SSShadowsPass.Setup(m_Settings, m_Material);
if (shouldEnqueue)
{
bool isDeferredRenderingMode = renderer is UniversalRenderer && ((UniversalRenderer)renderer).renderingMode == RenderingMode.Deferred;
m_SSShadowsPass.renderPassEvent = isDeferredRenderingMode
? RenderPassEvent.AfterRenderingGbuffer
: RenderPassEvent.AfterRenderingPrePasses;
renderer.EnqueuePass(m_SSShadowsPass);
renderer.EnqueuePass(m_SSShadowsPostPass);
}
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
CoreUtils.Destroy(m_Material);
}
private bool LoadMaterial()
{
if (m_Material != null)
{
return true;
}
if (m_Shader == null)
{
m_Shader = Shader.Find(k_ShaderName);
if (m_Shader == null)
{
return false;
}
}
m_Material = CoreUtils.CreateEngineMaterial(m_Shader);
return m_Material != null;
}
private class ScreenSpaceShadowsPass : ScriptableRenderPass
{
// Profiling tag
private static string m_ProfilerTag = "ScreenSpaceShadows";
private static ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
// Private Variables
private Material m_Material;
private ScreenSpaceShadowsSettings m_CurrentSettings;
private RenderTextureDescriptor m_RenderTextureDescriptor;
private RenderTargetHandle m_RenderTarget;
// Constants
private const string k_SSShadowsTextureName = "_ScreenSpaceShadowmapTexture";
internal ScreenSpaceShadowsPass()
{
m_CurrentSettings = new ScreenSpaceShadowsSettings();
m_RenderTarget.Init(k_SSShadowsTextureName);
}
internal bool Setup(ScreenSpaceShadowsSettings featureSettings, Material material)
{
m_CurrentSettings = featureSettings;
m_Material = material;
ConfigureInput(ScriptableRenderPassInput.Depth);
return m_Material != null;
}
/// <inheritdoc/>
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
m_RenderTextureDescriptor = renderingData.cameraData.cameraTargetDescriptor;
m_RenderTextureDescriptor.depthBufferBits = 0;
m_RenderTextureDescriptor.msaaSamples = 1;
m_RenderTextureDescriptor.graphicsFormat = RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R8_UNorm, FormatUsage.Linear | FormatUsage.Render)
? GraphicsFormat.R8_UNorm
: GraphicsFormat.B8G8R8A8_UNorm;
cmd.GetTemporaryRT(m_RenderTarget.id, m_RenderTextureDescriptor, FilterMode.Point);
RenderTargetIdentifier renderTargetTexture = m_RenderTarget.Identifier();
ConfigureTarget(renderTargetTexture);
ConfigureClear(ClearFlag.None, Color.white);
}
/// <inheritdoc/>
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (m_Material == null)
{
Debug.LogErrorFormat("{0}.Execute(): Missing material. ScreenSpaceShadows pass will not execute. Check for missing reference in the renderer resources.", GetType().Name);
return;
}
Camera camera = renderingData.cameraData.camera;
CommandBuffer cmd = CommandBufferPool.Get();
using (new ProfilingScope(cmd, m_ProfilingSampler))
{
if (!renderingData.cameraData.xr.enabled)
{
cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_Material);
cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
}
else
{
// Avoid setting and restoring camera view and projection matrices when in stereo.
RenderTargetIdentifier screenSpaceShadowTexture = m_RenderTarget.Identifier();
cmd.Blit(null, screenSpaceShadowTexture, m_Material);
}
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, false);
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, false);
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowScreen, true);
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
/// <inheritdoc/>
public override void OnCameraCleanup(CommandBuffer cmd)
{
if (cmd == null)
{
throw new ArgumentNullException("cmd");
}
cmd.ReleaseTemporaryRT(m_RenderTarget.id);
}
}
private class ScreenSpaceShadowsPostPass : ScriptableRenderPass
{
// Profiling tag
private static string m_ProfilerTag = "ScreenSpaceShadows Post";
private static ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
ConfigureTarget(BuiltinRenderTextureType.CurrentActive);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get();
using (new ProfilingScope(cmd, m_ProfilingSampler))
{
ShadowData shadowData = renderingData.shadowData;
int cascadesCount = shadowData.mainLightShadowCascadesCount;
bool mainLightShadows = renderingData.shadowData.supportsMainLightShadows;
bool receiveShadowsNoCascade = mainLightShadows && cascadesCount == 1;
bool receiveShadowsCascades = mainLightShadows && cascadesCount > 1;
// Before transparent object pass, force to disable screen space shadow of main light
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowScreen, false);
// then enable main light shadows with or without cascades
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, receiveShadowsNoCascade);
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, receiveShadowsCascades);
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e32e72b6a3f58a24c9033e2b9275eea0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: