initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f46c1a0c3e3a98848a0efbf4e1fd5675
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
namespace UnityEngine.Rendering.Universal
|
||||
{
|
||||
/// <summary>
|
||||
/// Let customizable actions inject commands to capture the camera output.
|
||||
///
|
||||
/// You can use this pass to inject capture commands into a command buffer
|
||||
/// with the goal of having camera capture happening in external code.
|
||||
/// </summary>
|
||||
internal class CapturePass : ScriptableRenderPass
|
||||
{
|
||||
RenderTargetHandle m_CameraColorHandle;
|
||||
const string m_ProfilerTag = "Capture Pass";
|
||||
private static readonly ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
|
||||
public CapturePass(RenderPassEvent evt)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(CapturePass));
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the pass
|
||||
/// </summary>
|
||||
/// <param name="actions"></param>
|
||||
public void Setup(RenderTargetHandle colorHandle)
|
||||
{
|
||||
m_CameraColorHandle = colorHandle;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
CommandBuffer cmdBuf = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmdBuf, m_ProfilingSampler))
|
||||
{
|
||||
var colorAttachmentIdentifier = m_CameraColorHandle.Identifier();
|
||||
var captureActions = renderingData.cameraData.captureActions;
|
||||
for (captureActions.Reset(); captureActions.MoveNext();)
|
||||
captureActions.Current(colorAttachmentIdentifier, cmdBuf);
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(cmdBuf);
|
||||
CommandBufferPool.Release(cmdBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0f5a9bd148c9a4a3198fdd2365b6e514
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
// Note: this pass can't be done at the same time as post-processing as it needs to be done in
|
||||
// advance in case we're doing on-tile color grading.
|
||||
/// <summary>
|
||||
/// Renders a color grading LUT texture.
|
||||
/// </summary>
|
||||
public class ColorGradingLutPass : ScriptableRenderPass
|
||||
{
|
||||
readonly Material m_LutBuilderLdr;
|
||||
readonly Material m_LutBuilderHdr;
|
||||
readonly GraphicsFormat m_HdrLutFormat;
|
||||
readonly GraphicsFormat m_LdrLutFormat;
|
||||
|
||||
RenderTargetHandle m_InternalLut;
|
||||
|
||||
bool m_AllowColorGradingACESHDR = true;
|
||||
|
||||
public ColorGradingLutPass(RenderPassEvent evt, PostProcessData data)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(ColorGradingLutPass));
|
||||
renderPassEvent = evt;
|
||||
overrideCameraTarget = true;
|
||||
|
||||
Material Load(Shader shader)
|
||||
{
|
||||
if (shader == null)
|
||||
{
|
||||
Debug.LogError($"Missing shader. {GetType().DeclaringType.Name} render pass will not execute. Check for missing reference in the renderer resources.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return CoreUtils.CreateEngineMaterial(shader);
|
||||
}
|
||||
|
||||
m_LutBuilderLdr = Load(data.shaders.lutBuilderLdrPS);
|
||||
m_LutBuilderHdr = Load(data.shaders.lutBuilderHdrPS);
|
||||
|
||||
// Warm up lut format as IsFormatSupported adds GC pressure...
|
||||
const FormatUsage kFlags = FormatUsage.Linear | FormatUsage.Render;
|
||||
if (SystemInfo.IsFormatSupported(GraphicsFormat.R16G16B16A16_SFloat, kFlags))
|
||||
m_HdrLutFormat = GraphicsFormat.R16G16B16A16_SFloat;
|
||||
else if (SystemInfo.IsFormatSupported(GraphicsFormat.B10G11R11_UFloatPack32, kFlags))
|
||||
m_HdrLutFormat = GraphicsFormat.B10G11R11_UFloatPack32;
|
||||
else
|
||||
// Obviously using this for log lut encoding is a very bad idea for precision but we
|
||||
// need it for compatibility reasons and avoid black screens on platforms that don't
|
||||
// support floating point formats. Expect banding and posterization artifact if this
|
||||
// ends up being used.
|
||||
m_HdrLutFormat = GraphicsFormat.R8G8B8A8_UNorm;
|
||||
|
||||
m_LdrLutFormat = GraphicsFormat.R8G8B8A8_UNorm;
|
||||
base.useNativeRenderPass = false;
|
||||
|
||||
if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3 && Graphics.minOpenGLESVersion <= OpenGLESVersion.OpenGLES30 && SystemInfo.graphicsDeviceName.StartsWith("Adreno (TM) 3"))
|
||||
m_AllowColorGradingACESHDR = false;
|
||||
}
|
||||
|
||||
public void Setup(in RenderTargetHandle internalLut)
|
||||
{
|
||||
m_InternalLut = internalLut;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
var cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.ColorGradingLUT)))
|
||||
{
|
||||
// Fetch all color grading settings
|
||||
var stack = VolumeManager.instance.stack;
|
||||
var channelMixer = stack.GetComponent<ChannelMixer>();
|
||||
var colorAdjustments = stack.GetComponent<ColorAdjustments>();
|
||||
var curves = stack.GetComponent<ColorCurves>();
|
||||
var liftGammaGain = stack.GetComponent<LiftGammaGain>();
|
||||
var shadowsMidtonesHighlights = stack.GetComponent<ShadowsMidtonesHighlights>();
|
||||
var splitToning = stack.GetComponent<SplitToning>();
|
||||
var tonemapping = stack.GetComponent<Tonemapping>();
|
||||
var whiteBalance = stack.GetComponent<WhiteBalance>();
|
||||
|
||||
ref var postProcessingData = ref renderingData.postProcessingData;
|
||||
bool hdr = postProcessingData.gradingMode == ColorGradingMode.HighDynamicRange;
|
||||
|
||||
// Prepare texture & material
|
||||
int lutHeight = postProcessingData.lutSize;
|
||||
int lutWidth = lutHeight * lutHeight;
|
||||
var format = hdr ? m_HdrLutFormat : m_LdrLutFormat;
|
||||
var material = hdr ? m_LutBuilderHdr : m_LutBuilderLdr;
|
||||
var desc = new RenderTextureDescriptor(lutWidth, lutHeight, format, 0);
|
||||
desc.vrUsage = VRTextureUsage.None; // We only need one for both eyes in VR
|
||||
cmd.GetTemporaryRT(m_InternalLut.id, desc, FilterMode.Bilinear);
|
||||
|
||||
// Prepare data
|
||||
var lmsColorBalance = ColorUtils.ColorBalanceToLMSCoeffs(whiteBalance.temperature.value, whiteBalance.tint.value);
|
||||
var hueSatCon = new Vector4(colorAdjustments.hueShift.value / 360f, colorAdjustments.saturation.value / 100f + 1f, colorAdjustments.contrast.value / 100f + 1f, 0f);
|
||||
var channelMixerR = new Vector4(channelMixer.redOutRedIn.value / 100f, channelMixer.redOutGreenIn.value / 100f, channelMixer.redOutBlueIn.value / 100f, 0f);
|
||||
var channelMixerG = new Vector4(channelMixer.greenOutRedIn.value / 100f, channelMixer.greenOutGreenIn.value / 100f, channelMixer.greenOutBlueIn.value / 100f, 0f);
|
||||
var channelMixerB = new Vector4(channelMixer.blueOutRedIn.value / 100f, channelMixer.blueOutGreenIn.value / 100f, channelMixer.blueOutBlueIn.value / 100f, 0f);
|
||||
|
||||
var shadowsHighlightsLimits = new Vector4(
|
||||
shadowsMidtonesHighlights.shadowsStart.value,
|
||||
shadowsMidtonesHighlights.shadowsEnd.value,
|
||||
shadowsMidtonesHighlights.highlightsStart.value,
|
||||
shadowsMidtonesHighlights.highlightsEnd.value
|
||||
);
|
||||
|
||||
var (shadows, midtones, highlights) = ColorUtils.PrepareShadowsMidtonesHighlights(
|
||||
shadowsMidtonesHighlights.shadows.value,
|
||||
shadowsMidtonesHighlights.midtones.value,
|
||||
shadowsMidtonesHighlights.highlights.value
|
||||
);
|
||||
|
||||
var (lift, gamma, gain) = ColorUtils.PrepareLiftGammaGain(
|
||||
liftGammaGain.lift.value,
|
||||
liftGammaGain.gamma.value,
|
||||
liftGammaGain.gain.value
|
||||
);
|
||||
|
||||
var (splitShadows, splitHighlights) = ColorUtils.PrepareSplitToning(
|
||||
splitToning.shadows.value,
|
||||
splitToning.highlights.value,
|
||||
splitToning.balance.value
|
||||
);
|
||||
|
||||
var lutParameters = new Vector4(lutHeight, 0.5f / lutWidth, 0.5f / lutHeight,
|
||||
lutHeight / (lutHeight - 1f));
|
||||
|
||||
// Fill in constants
|
||||
material.SetVector(ShaderConstants._Lut_Params, lutParameters);
|
||||
material.SetVector(ShaderConstants._ColorBalance, lmsColorBalance);
|
||||
material.SetVector(ShaderConstants._ColorFilter, colorAdjustments.colorFilter.value.linear);
|
||||
material.SetVector(ShaderConstants._ChannelMixerRed, channelMixerR);
|
||||
material.SetVector(ShaderConstants._ChannelMixerGreen, channelMixerG);
|
||||
material.SetVector(ShaderConstants._ChannelMixerBlue, channelMixerB);
|
||||
material.SetVector(ShaderConstants._HueSatCon, hueSatCon);
|
||||
material.SetVector(ShaderConstants._Lift, lift);
|
||||
material.SetVector(ShaderConstants._Gamma, gamma);
|
||||
material.SetVector(ShaderConstants._Gain, gain);
|
||||
material.SetVector(ShaderConstants._Shadows, shadows);
|
||||
material.SetVector(ShaderConstants._Midtones, midtones);
|
||||
material.SetVector(ShaderConstants._Highlights, highlights);
|
||||
material.SetVector(ShaderConstants._ShaHiLimits, shadowsHighlightsLimits);
|
||||
material.SetVector(ShaderConstants._SplitShadows, splitShadows);
|
||||
material.SetVector(ShaderConstants._SplitHighlights, splitHighlights);
|
||||
|
||||
// YRGB curves
|
||||
material.SetTexture(ShaderConstants._CurveMaster, curves.master.value.GetTexture());
|
||||
material.SetTexture(ShaderConstants._CurveRed, curves.red.value.GetTexture());
|
||||
material.SetTexture(ShaderConstants._CurveGreen, curves.green.value.GetTexture());
|
||||
material.SetTexture(ShaderConstants._CurveBlue, curves.blue.value.GetTexture());
|
||||
|
||||
// Secondary curves
|
||||
material.SetTexture(ShaderConstants._CurveHueVsHue, curves.hueVsHue.value.GetTexture());
|
||||
material.SetTexture(ShaderConstants._CurveHueVsSat, curves.hueVsSat.value.GetTexture());
|
||||
material.SetTexture(ShaderConstants._CurveLumVsSat, curves.lumVsSat.value.GetTexture());
|
||||
material.SetTexture(ShaderConstants._CurveSatVsSat, curves.satVsSat.value.GetTexture());
|
||||
|
||||
// Tonemapping (baked into the lut for HDR)
|
||||
if (hdr)
|
||||
{
|
||||
material.shaderKeywords = null;
|
||||
|
||||
switch (tonemapping.mode.value)
|
||||
{
|
||||
case TonemappingMode.Neutral: material.EnableKeyword(ShaderKeywordStrings.TonemapNeutral); break;
|
||||
case TonemappingMode.ACES: material.EnableKeyword(m_AllowColorGradingACESHDR ? ShaderKeywordStrings.TonemapACES : ShaderKeywordStrings.TonemapNeutral); break;
|
||||
default: break; // None
|
||||
}
|
||||
}
|
||||
|
||||
renderingData.cameraData.xr.StopSinglePass(cmd);
|
||||
|
||||
// Render the lut
|
||||
cmd.Blit(null, m_InternalLut.id, material);
|
||||
|
||||
renderingData.cameraData.xr.StartSinglePass(cmd);
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnFinishCameraStackRendering(CommandBuffer cmd)
|
||||
{
|
||||
cmd.ReleaseTemporaryRT(m_InternalLut.id);
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
CoreUtils.Destroy(m_LutBuilderLdr);
|
||||
CoreUtils.Destroy(m_LutBuilderHdr);
|
||||
}
|
||||
|
||||
// Precomputed shader ids to same some CPU cycles (mostly affects mobile)
|
||||
static class ShaderConstants
|
||||
{
|
||||
public static readonly int _Lut_Params = Shader.PropertyToID("_Lut_Params");
|
||||
public static readonly int _ColorBalance = Shader.PropertyToID("_ColorBalance");
|
||||
public static readonly int _ColorFilter = Shader.PropertyToID("_ColorFilter");
|
||||
public static readonly int _ChannelMixerRed = Shader.PropertyToID("_ChannelMixerRed");
|
||||
public static readonly int _ChannelMixerGreen = Shader.PropertyToID("_ChannelMixerGreen");
|
||||
public static readonly int _ChannelMixerBlue = Shader.PropertyToID("_ChannelMixerBlue");
|
||||
public static readonly int _HueSatCon = Shader.PropertyToID("_HueSatCon");
|
||||
public static readonly int _Lift = Shader.PropertyToID("_Lift");
|
||||
public static readonly int _Gamma = Shader.PropertyToID("_Gamma");
|
||||
public static readonly int _Gain = Shader.PropertyToID("_Gain");
|
||||
public static readonly int _Shadows = Shader.PropertyToID("_Shadows");
|
||||
public static readonly int _Midtones = Shader.PropertyToID("_Midtones");
|
||||
public static readonly int _Highlights = Shader.PropertyToID("_Highlights");
|
||||
public static readonly int _ShaHiLimits = Shader.PropertyToID("_ShaHiLimits");
|
||||
public static readonly int _SplitShadows = Shader.PropertyToID("_SplitShadows");
|
||||
public static readonly int _SplitHighlights = Shader.PropertyToID("_SplitHighlights");
|
||||
public static readonly int _CurveMaster = Shader.PropertyToID("_CurveMaster");
|
||||
public static readonly int _CurveRed = Shader.PropertyToID("_CurveRed");
|
||||
public static readonly int _CurveGreen = Shader.PropertyToID("_CurveGreen");
|
||||
public static readonly int _CurveBlue = Shader.PropertyToID("_CurveBlue");
|
||||
public static readonly int _CurveHueVsHue = Shader.PropertyToID("_CurveHueVsHue");
|
||||
public static readonly int _CurveHueVsSat = Shader.PropertyToID("_CurveHueVsSat");
|
||||
public static readonly int _CurveLumVsSat = Shader.PropertyToID("_CurveLumVsSat");
|
||||
public static readonly int _CurveSatVsSat = Shader.PropertyToID("_CurveSatVsSat");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ab9de92acc9d124bbc8f9b8e240d9c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Copy the given color buffer to the given destination color buffer.
|
||||
///
|
||||
/// You can use this pass to copy a color buffer to the destination,
|
||||
/// so you can use it later in rendering. For example, you can copy
|
||||
/// the opaque texture to use it for distortion effects.
|
||||
/// </summary>
|
||||
public class CopyColorPass : ScriptableRenderPass
|
||||
{
|
||||
const int mipTruncation = 3;
|
||||
static int sizeID = Shader.PropertyToID("_Size");
|
||||
static int sourceID = Shader.PropertyToID("_Source");
|
||||
static int destinationID = Shader.PropertyToID("_Destination");
|
||||
static int opaqueTextureDimID = Shader.PropertyToID("_CameraOpaqueTexture_Dim");
|
||||
|
||||
int m_SampleOffsetShaderHandle;
|
||||
Material m_SamplingMaterial;
|
||||
Downsampling m_DownsamplingMethod;
|
||||
Material m_CopyColorMaterial;
|
||||
ComputeShader m_ColorPyramidCompute;
|
||||
public bool m_RequiresMips;
|
||||
|
||||
private int m_MipLevels;
|
||||
private int[] m_Size;
|
||||
private int downsampleKernelID;
|
||||
private int gaussianKernelID;
|
||||
|
||||
private bool m_ReconstructTiles = false;
|
||||
private static GlobalKeyword _RECONSTRUCT_VRS_TILES;
|
||||
|
||||
|
||||
private RenderTargetIdentifier source { get; set; }
|
||||
private RenderTargetHandle destination { get; set; }
|
||||
private RTPermanentHandle permanentDest { get; set; }
|
||||
private bool useRT;
|
||||
private RenderTargetHandle tempBuffer { get; set; }
|
||||
private RenderTextureDescriptor tempDescriptor;
|
||||
|
||||
/// <summary>
|
||||
/// Create the CopyColorPass
|
||||
/// </summary>
|
||||
public CopyColorPass(RenderPassEvent evt, Material samplingMaterial, ComputeShader colorPyramid, Material copyColorMaterial = null, bool reconstructTiles = false)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(CopyColorPass));
|
||||
|
||||
m_SamplingMaterial = samplingMaterial;
|
||||
m_CopyColorMaterial = copyColorMaterial;
|
||||
m_SampleOffsetShaderHandle = Shader.PropertyToID("_SampleOffset");
|
||||
renderPassEvent = evt;
|
||||
m_ColorPyramidCompute = colorPyramid;
|
||||
downsampleKernelID = m_ColorPyramidCompute.FindKernel("KColorDownsample");
|
||||
gaussianKernelID = m_ColorPyramidCompute.FindKernel("KColorGaussian");
|
||||
m_DownsamplingMethod = Downsampling.None;
|
||||
m_MipLevels = 1;
|
||||
if (reconstructTiles)
|
||||
{
|
||||
m_ReconstructTiles = true;
|
||||
//Debug.Log(m_CopyColorMaterial.shader.name + " 0");
|
||||
_RECONSTRUCT_VRS_TILES = GlobalKeyword.Create("_RECONSTRUCT_VRS_TILES");
|
||||
}
|
||||
base.useNativeRenderPass = false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Configure the pass with the source and destination to execute on.
|
||||
/// </summary>
|
||||
/// <param name="source">Source Render Target</param>
|
||||
/// <param name="destination">Destination Render Target</param>
|
||||
public void Setup(RenderTargetIdentifier source, RenderTargetHandle destination, Downsampling downsampling, bool RequiresMips)
|
||||
{
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
m_DownsamplingMethod = downsampling;
|
||||
m_RequiresMips = RequiresMips;
|
||||
useRT = false;
|
||||
}
|
||||
|
||||
public void Setup(RenderTargetIdentifier source, RTPermanentHandle destination, Downsampling downsampling, bool RequiresMips)
|
||||
{
|
||||
this.source = source;
|
||||
this.permanentDest = destination;
|
||||
m_DownsamplingMethod = downsampling;
|
||||
m_RequiresMips = RequiresMips;
|
||||
useRT = true;
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
|
||||
RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
descriptor.msaaSamples = 1;
|
||||
descriptor.depthBufferBits = 0;
|
||||
|
||||
if (m_DownsamplingMethod == Downsampling._2xBilinear)
|
||||
{
|
||||
descriptor.width /= 2;
|
||||
descriptor.height /= 2;
|
||||
}
|
||||
else if (m_DownsamplingMethod == Downsampling._4xBox || m_DownsamplingMethod == Downsampling._4xBilinear)
|
||||
{
|
||||
descriptor.width /= 4;
|
||||
descriptor.height /= 4;
|
||||
}
|
||||
descriptor.autoGenerateMips = false;
|
||||
descriptor.useMipMap = m_RequiresMips;
|
||||
if (m_RequiresMips)
|
||||
{
|
||||
descriptor.enableRandomWrite = true;
|
||||
// mips with smallest dimension of 1, 2, and 4 useless, and compute shader works on 8x8 blocks, so subtract 3 (mipTruncation) from the mip count
|
||||
m_MipLevels = Mathf.FloorToInt(
|
||||
Mathf.Max( Mathf.Log(descriptor.width, 2), Mathf.Log(descriptor.height, 2))
|
||||
) + 1 - mipTruncation;
|
||||
descriptor.mipCount = m_MipLevels;
|
||||
}
|
||||
m_Size = new int[4] { descriptor.width, descriptor.height, 0, 0 };
|
||||
|
||||
if (useRT)
|
||||
{
|
||||
permanentDest.GetRenderTexture(descriptor, renderingData.cameraData.camera.name, "Opaque");
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.GetTemporaryRT(destination.id, descriptor, m_RequiresMips == true ? FilterMode.Trilinear : FilterMode.Bilinear);
|
||||
//cmd.SetGlobalTexture(SLZGlobals.instance.opaqueTexID, destination.Identifier());
|
||||
}
|
||||
|
||||
//cmd.GetTemporaryRT(destination.id, descriptor, FilterMode.Bilinear,);
|
||||
if (m_RequiresMips)
|
||||
{
|
||||
tempDescriptor = descriptor;
|
||||
tempDescriptor.width /= 2;
|
||||
tempDescriptor.height /= 2;
|
||||
tempDescriptor.useMipMap = false;
|
||||
tempDescriptor.enableRandomWrite = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_SamplingMaterial == null)
|
||||
{
|
||||
Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_SamplingMaterial, GetType().Name);
|
||||
return;
|
||||
}
|
||||
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
|
||||
//It is possible that the given color target is now the frontbuffer
|
||||
if (source == renderingData.cameraData.renderer.GetCameraColorFrontBuffer(cmd))
|
||||
{
|
||||
source = renderingData.cameraData.renderer.cameraColorTarget;
|
||||
}
|
||||
RenderTargetIdentifier opaqueColorRT;
|
||||
if (useRT)
|
||||
{
|
||||
opaqueColorRT = new RenderTargetIdentifier(permanentDest.renderTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
opaqueColorRT = destination.Identifier();
|
||||
}
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.CopyColor)))
|
||||
{
|
||||
|
||||
ScriptableRenderer.SetRenderTarget(cmd, opaqueColorRT, BuiltinRenderTextureType.CameraTarget, clearFlag,
|
||||
clearColor);
|
||||
bool useDrawProceduleBlit = renderingData.cameraData.xr.enabled;
|
||||
if (m_ReconstructTiles)
|
||||
{
|
||||
cmd.EnableKeyword(_RECONSTRUCT_VRS_TILES);
|
||||
}
|
||||
switch (m_DownsamplingMethod)
|
||||
{
|
||||
case Downsampling.None:
|
||||
RenderingUtils.Blit(cmd, source, opaqueColorRT, m_CopyColorMaterial, 0, useDrawProceduleBlit);
|
||||
break;
|
||||
case Downsampling._2xBilinear:
|
||||
RenderingUtils.Blit(cmd, source, opaqueColorRT, m_CopyColorMaterial, 0, useDrawProceduleBlit);
|
||||
break;
|
||||
case Downsampling._4xBox:
|
||||
m_SamplingMaterial.SetFloat(m_SampleOffsetShaderHandle, 2);
|
||||
RenderingUtils.Blit(cmd, source, opaqueColorRT, m_SamplingMaterial, 0, useDrawProceduleBlit);
|
||||
break;
|
||||
case Downsampling._4xBilinear:
|
||||
RenderingUtils.Blit(cmd, source, opaqueColorRT, m_CopyColorMaterial, 0, useDrawProceduleBlit);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// In shader, we need to know how many mip levels to 1x1 and not actually how many mips there are, so re-add mipTruncation to the true number of mips
|
||||
Shader.SetGlobalVector(opaqueTextureDimID,
|
||||
new Vector4( tempDescriptor.width * 2, tempDescriptor.height * 2, m_MipLevels - 1, m_MipLevels + mipTruncation));
|
||||
|
||||
if (m_MipLevels > 1 && m_RequiresMips)
|
||||
{
|
||||
int slices = 1;
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
if (renderingData.cameraData.xr.enabled)
|
||||
{
|
||||
slices = 2;
|
||||
}
|
||||
#endif
|
||||
int[] mipSize = new int[4];
|
||||
Array.Copy(m_Size, mipSize, 4);
|
||||
tempBuffer = new RenderTargetHandle();
|
||||
cmd.GetTemporaryRT(tempBuffer.id, tempDescriptor, FilterMode.Bilinear);
|
||||
cmd.SetComputeIntParams(m_ColorPyramidCompute, sizeID, mipSize);
|
||||
|
||||
cmd.SetComputeTextureParam(m_ColorPyramidCompute, downsampleKernelID, destinationID, tempBuffer.Identifier(), 0);
|
||||
cmd.SetComputeTextureParam(m_ColorPyramidCompute, gaussianKernelID, sourceID, tempBuffer.Identifier(), 0);
|
||||
for (int i = 1; i < m_MipLevels; i++)
|
||||
{
|
||||
|
||||
cmd.SetComputeTextureParam(m_ColorPyramidCompute, downsampleKernelID, sourceID, opaqueColorRT, i - 1);
|
||||
|
||||
mipSize[0] = Mathf.Max(mipSize[0] >> 1, 1);
|
||||
mipSize[1] = Mathf.Max(mipSize[1] >> 1, 1);
|
||||
cmd.DispatchCompute(m_ColorPyramidCompute, downsampleKernelID, Mathf.CeilToInt((float)mipSize[0] / 8.0f + 0.00001f),
|
||||
Mathf.CeilToInt((float)mipSize[1] / 8.0f + 0.00001f), slices); ;
|
||||
|
||||
cmd.SetComputeIntParams(m_ColorPyramidCompute, sizeID, mipSize);
|
||||
|
||||
cmd.SetComputeTextureParam(m_ColorPyramidCompute, gaussianKernelID, destinationID, opaqueColorRT, i);
|
||||
cmd.DispatchCompute(m_ColorPyramidCompute, gaussianKernelID, Mathf.CeilToInt((float)mipSize[0] / 8.0f + 0.0001f),
|
||||
Mathf.CeilToInt((float)mipSize[1] / 8.0f + 0.0001f), slices);
|
||||
|
||||
}
|
||||
cmd.ReleaseTemporaryRT(tempBuffer.id);
|
||||
}
|
||||
|
||||
if (m_ReconstructTiles)
|
||||
{
|
||||
cmd.DisableKeyword(_RECONSTRUCT_VRS_TILES);
|
||||
}
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
if (destination != RenderTargetHandle.CameraTarget)
|
||||
{
|
||||
cmd.ReleaseTemporaryRT(destination.id);
|
||||
destination = RenderTargetHandle.CameraTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7e18083ec47e7446fac286a4ecd439fc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
using System;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Copy the given depth buffer into the given destination depth buffer.
|
||||
///
|
||||
/// You can use this pass to copy a depth buffer to a destination,
|
||||
/// so you can use it later in rendering. If the source texture has MSAA
|
||||
/// enabled, the pass uses a custom MSAA resolve. If the source texture
|
||||
/// does not have MSAA enabled, the pass uses a Blit or a Copy Texture
|
||||
/// operation, depending on what the current platform supports.
|
||||
/// </summary>
|
||||
public class CopyDepthPass : ScriptableRenderPass
|
||||
{
|
||||
private RenderTargetHandle source { get; set; }
|
||||
private RenderTargetHandle destination { get; set; }
|
||||
internal bool AllocateRT { get; set; }
|
||||
internal int MssaSamples { get; set; }
|
||||
Material m_CopyDepthMaterial;
|
||||
public CopyDepthPass(RenderPassEvent evt, Material copyDepthMaterial)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(CopyDepthPass));
|
||||
AllocateRT = true;
|
||||
m_CopyDepthMaterial = copyDepthMaterial;
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the pass with the source and destination to execute on.
|
||||
/// </summary>
|
||||
/// <param name="source">Source Render Target</param>
|
||||
/// <param name="destination">Destination Render Targt</param>
|
||||
public void Setup(RenderTargetHandle source, RenderTargetHandle destination)
|
||||
{
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
this.AllocateRT = !destination.HasInternalRenderTargetId();
|
||||
this.MssaSamples = -1;
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
var descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
descriptor.colorFormat = RenderTextureFormat.Depth;
|
||||
descriptor.depthBufferBits = 32; //TODO: do we really need this. double check;
|
||||
descriptor.msaaSamples = 1;
|
||||
if (this.AllocateRT)
|
||||
cmd.GetTemporaryRT(destination.id, descriptor, FilterMode.Point);
|
||||
|
||||
// On Metal iOS, prevent camera attachments to be bound and cleared during this pass.
|
||||
ConfigureTarget(new RenderTargetIdentifier(destination.Identifier(), 0, CubemapFace.Unknown, -1), descriptor.depthStencilFormat, descriptor.width, descriptor.height, descriptor.msaaSamples, true);
|
||||
ConfigureClear(ClearFlag.None, Color.black);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_CopyDepthMaterial == null)
|
||||
{
|
||||
Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_CopyDepthMaterial, GetType().Name);
|
||||
return;
|
||||
}
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.CopyDepth)))
|
||||
{
|
||||
int cameraSamples = 0;
|
||||
if (MssaSamples == -1)
|
||||
{
|
||||
RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
cameraSamples = descriptor.msaaSamples;
|
||||
}
|
||||
else
|
||||
cameraSamples = MssaSamples;
|
||||
|
||||
// When auto resolve is supported or multisampled texture is not supported, set camera samples to 1
|
||||
if (SystemInfo.supportsMultisampleAutoResolve || SystemInfo.supportsMultisampledTextures == 0)
|
||||
cameraSamples = 1;
|
||||
|
||||
CameraData cameraData = renderingData.cameraData;
|
||||
|
||||
switch (cameraSamples)
|
||||
{
|
||||
case 8:
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
|
||||
cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
|
||||
cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
|
||||
break;
|
||||
|
||||
// MSAA disabled, auto resolve supported or ms textures not supported
|
||||
default:
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
|
||||
break;
|
||||
}
|
||||
|
||||
cmd.SetGlobalTexture("_CameraDepthAttachment", source.Identifier());
|
||||
|
||||
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
// XR uses procedural draw instead of cmd.blit or cmd.DrawFullScreenMesh
|
||||
if (renderingData.cameraData.xr.enabled)
|
||||
{
|
||||
// XR flip logic is not the same as non-XR case because XR uses draw procedure
|
||||
// and draw procedure does not need to take projection matrix yflip into account
|
||||
// We y-flip if
|
||||
// 1) we are bliting from render texture to back buffer and
|
||||
// 2) renderTexture starts UV at top
|
||||
// XRTODO: handle scalebias and scalebiasRt for src and dst separately
|
||||
bool isRenderToBackBufferTarget = destination.Identifier() == cameraData.xr.renderTarget && !cameraData.xr.renderTargetIsRenderTexture;
|
||||
bool yflip = isRenderToBackBufferTarget && SystemInfo.graphicsUVStartsAtTop;
|
||||
float flipSign = (yflip) ? -1.0f : 1.0f;
|
||||
Vector4 scaleBiasRt = (flipSign < 0.0f)
|
||||
? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
|
||||
: new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
|
||||
cmd.SetGlobalVector(ShaderPropertyId.scaleBiasRt, scaleBiasRt);
|
||||
|
||||
cmd.DrawProcedural(Matrix4x4.identity, m_CopyDepthMaterial, 0, MeshTopology.Quads, 4);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Blit has logic to flip projection matrix when rendering to render texture.
|
||||
// Currently the y-flip is handled in CopyDepthPass.hlsl by checking _ProjectionParams.x
|
||||
// If you replace this Blit with a Draw* that sets projection matrix double check
|
||||
// to also update shader.
|
||||
// scaleBias.x = flipSign
|
||||
// scaleBias.y = scale
|
||||
// scaleBias.z = bias
|
||||
// scaleBias.w = unused
|
||||
// In game view final target acts as back buffer were target is not flipped
|
||||
bool isGameViewFinalTarget = (cameraData.cameraType == CameraType.Game && destination == RenderTargetHandle.CameraTarget);
|
||||
bool yflip = (cameraData.IsCameraProjectionMatrixFlipped()) && !isGameViewFinalTarget;
|
||||
float flipSign = yflip ? -1.0f : 1.0f;
|
||||
Vector4 scaleBiasRt = (flipSign < 0.0f)
|
||||
? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
|
||||
: new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
|
||||
cmd.SetGlobalVector(ShaderPropertyId.scaleBiasRt, scaleBiasRt);
|
||||
|
||||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_CopyDepthMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
if (this.AllocateRT)
|
||||
cmd.ReleaseTemporaryRT(destination.id);
|
||||
destination = RenderTargetHandle.CameraTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d6268b3babfc1004c82ace3c407f46ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,384 @@
|
|||
using System;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Copy the given depth buffer into the given destination depth buffer.
|
||||
///
|
||||
/// You can use this pass to copy a depth buffer to a destination,
|
||||
/// so you can use it later in rendering. If the source texture has MSAA
|
||||
/// enabled, the pass uses a custom MSAA resolve. If the source texture
|
||||
/// does not have MSAA enabled, the pass uses a Blit or a Copy Texture
|
||||
/// operation, depending on what the current platform supports.
|
||||
/// </summary>
|
||||
public class CopyDepthToHiZPass : ScriptableRenderPass
|
||||
{
|
||||
private static int computeParamID = Shader.PropertyToID("data1");
|
||||
private static int computeParam2ID = Shader.PropertyToID("data2");
|
||||
private static int computeMipSourceID = Shader.PropertyToID("_MipSource");
|
||||
private static int computeMipDestID = Shader.PropertyToID("_MipDest");
|
||||
private static int computeMipDest2ID = Shader.PropertyToID("_MipDest2");
|
||||
|
||||
private RenderTargetHandle source { get; set; }
|
||||
private RenderTargetHandle destination { get; set; }
|
||||
internal bool AllocateRT { get; set; }
|
||||
internal int MssaSamples { get; set; }
|
||||
private int mipLevels;
|
||||
private bool isArray;
|
||||
private bool requiresMinMax;
|
||||
Material m_CopyDepthToColorMaterial;
|
||||
public static ComputeShader m_HiZMipCompute;
|
||||
private GlobalKeyword m_StereoArrayKW;
|
||||
private LocalKeyword m_SRVSourceKW;
|
||||
private LocalKeyword m_MinMaxKW;
|
||||
public CopyDepthToHiZPass(RenderPassEvent evt, Material copyDepthToColorMaterial)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(CopyDepthPass));
|
||||
AllocateRT = true;
|
||||
m_CopyDepthToColorMaterial = copyDepthToColorMaterial;
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the pass with the source and destination to execute on.
|
||||
/// </summary>
|
||||
/// <param name="source">Source Render Target</param>
|
||||
/// <param name="destination">Destination Render Targt</param>
|
||||
public void Setup(RenderTargetHandle source, RenderTargetHandle destination, bool requiresMinMax)
|
||||
{
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
this.AllocateRT = true;// !destination.HasInternalRenderTargetId();
|
||||
this.MssaSamples = -1;
|
||||
this.requiresMinMax = requiresMinMax;
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
var descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
descriptor.colorFormat = requiresMinMax ? RenderTextureFormat.RGHalf : RenderTextureFormat.RHalf;
|
||||
descriptor.width /= 2;
|
||||
descriptor.height /= 2;
|
||||
descriptor.depthBufferBits = 0;
|
||||
descriptor.msaaSamples = 1;
|
||||
descriptor.useMipMap = true;
|
||||
descriptor.autoGenerateMips = false;
|
||||
descriptor.sRGB = false;
|
||||
descriptor.enableRandomWrite = true;
|
||||
mipLevels = Mathf.FloorToInt(
|
||||
Mathf.Max(
|
||||
Mathf.Log(descriptor.width, 2),
|
||||
Mathf.Log(descriptor.height, 2)
|
||||
)
|
||||
) + 1;
|
||||
isArray = descriptor.dimension == TextureDimension.Tex2DArray;
|
||||
if (this.AllocateRT)
|
||||
cmd.GetTemporaryRT(destination.id, descriptor, FilterMode.Point);
|
||||
|
||||
|
||||
|
||||
// On Metal iOS, prevent camera attachments to be bound and cleared during this pass.
|
||||
ConfigureTarget(new RenderTargetIdentifier(destination.Identifier(), 0, CubemapFace.Unknown, -1), descriptor.depthStencilFormat, descriptor.width, descriptor.height, descriptor.msaaSamples, false);
|
||||
ConfigureClear(ClearFlag.None, Color.black);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_CopyDepthToColorMaterial == null)
|
||||
{
|
||||
Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_CopyDepthToColorMaterial, GetType().Name);
|
||||
return;
|
||||
}
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.HiZPrepass)))
|
||||
{
|
||||
/*
|
||||
int cameraSamples = 0;
|
||||
if (MssaSamples == -1)
|
||||
{
|
||||
RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
cameraSamples = descriptor.msaaSamples;
|
||||
}
|
||||
else
|
||||
cameraSamples = MssaSamples;
|
||||
|
||||
// When auto resolve is supported or multisampled texture is not supported, set camera samples to 1
|
||||
if (SystemInfo.supportsMultisampleAutoResolve || SystemInfo.supportsMultisampledTextures == 0)
|
||||
cameraSamples = 1;
|
||||
cameraSamples = 1;
|
||||
CameraData cameraData = renderingData.cameraData;
|
||||
|
||||
switch (cameraSamples)
|
||||
{
|
||||
case 8:
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
|
||||
cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
|
||||
cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
|
||||
break;
|
||||
|
||||
// MSAA disabled, auto resolve supported or ms textures not supported
|
||||
default:
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
|
||||
cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
|
||||
break;
|
||||
}
|
||||
|
||||
cmd.SetGlobalTexture("_CameraDepthAttachment", source.Identifier());
|
||||
|
||||
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
// XR uses procedural draw instead of cmd.blit or cmd.DrawFullScreenMesh
|
||||
if (renderingData.cameraData.xr.enabled)
|
||||
{
|
||||
// XR flip logic is not the same as non-XR case because XR uses draw procedure
|
||||
// and draw procedure does not need to take projection matrix yflip into account
|
||||
// We y-flip if
|
||||
// 1) we are bliting from render texture to back buffer and
|
||||
// 2) renderTexture starts UV at top
|
||||
// XRTODO: handle scalebias and scalebiasRt for src and dst separately
|
||||
bool isRenderToBackBufferTarget = destination.Identifier() == cameraData.xr.renderTarget && !cameraData.xr.renderTargetIsRenderTexture;
|
||||
bool yflip = isRenderToBackBufferTarget && SystemInfo.graphicsUVStartsAtTop;
|
||||
float flipSign = (yflip) ? -1.0f : 1.0f;
|
||||
Vector4 scaleBiasRt = (flipSign < 0.0f)
|
||||
? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
|
||||
: new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
|
||||
cmd.SetGlobalVector(ShaderPropertyId.scaleBiasRt, scaleBiasRt);
|
||||
|
||||
cmd.DrawProcedural(Matrix4x4.identity, m_CopyDepthToColorMaterial, 0, MeshTopology.Quads, 4);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Blit has logic to flip projection matrix when rendering to render texture.
|
||||
// Currently the y-flip is handled in CopyDepthPass.hlsl by checking _ProjectionParams.x
|
||||
// If you replace this Blit with a Draw* that sets projection matrix double check
|
||||
// to also update shader.
|
||||
// scaleBias.x = flipSign
|
||||
// scaleBias.y = scale
|
||||
// scaleBias.z = bias
|
||||
// scaleBias.w = unused
|
||||
// In game view final target acts as back buffer were target is not flipped
|
||||
bool isGameViewFinalTarget = (cameraData.cameraType == CameraType.Game && destination == RenderTargetHandle.CameraTarget);
|
||||
bool yflip = (cameraData.IsCameraProjectionMatrixFlipped()) && !isGameViewFinalTarget;
|
||||
float flipSign = yflip ? -1.0f : 1.0f;
|
||||
Vector4 scaleBiasRt = (flipSign < 0.0f)
|
||||
? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
|
||||
: new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
|
||||
cmd.SetGlobalVector(ShaderPropertyId.scaleBiasRt, scaleBiasRt);
|
||||
|
||||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_CopyDepthToColorMaterial);
|
||||
}
|
||||
*/
|
||||
int width = renderingData.cameraData.cameraTargetDescriptor.width;
|
||||
int height = renderingData.cameraData.cameraTargetDescriptor.height;
|
||||
int[] widthHeight = new int[4];
|
||||
int[] data2 = new int[4];
|
||||
widthHeight[0] = width;
|
||||
widthHeight[1] = height;
|
||||
int highestMip = mipLevels - 1;
|
||||
int i = 0;
|
||||
int slices = 1;
|
||||
|
||||
if (m_SRVSourceKW == null)
|
||||
{
|
||||
m_SRVSourceKW = new LocalKeyword(m_HiZMipCompute, "SRV_SOURCE");
|
||||
}
|
||||
|
||||
|
||||
m_MinMaxKW = new LocalKeyword(m_HiZMipCompute, "MIN_AND_MAX");
|
||||
if (requiresMinMax)
|
||||
{
|
||||
cmd.EnableKeyword(m_HiZMipCompute, m_MinMaxKW);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.DisableKeyword(m_HiZMipCompute, m_MinMaxKW);
|
||||
}
|
||||
//if (m_StereoArrayKW == null)
|
||||
//{
|
||||
//m_StereoArrayKW = new GlobalKeyword("STEREO_INSTANCING_ON");
|
||||
//}
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
if (renderingData.cameraData.xr.enabled)
|
||||
{
|
||||
slices = 2;
|
||||
}
|
||||
#else
|
||||
cmd.DisableKeyword(m_HiZMipCompute, m_StereoArrayKW);
|
||||
#endif
|
||||
do
|
||||
{
|
||||
|
||||
widthHeight[2] = width >> (i);
|
||||
widthHeight[3] = height >> (i);
|
||||
|
||||
widthHeight[0] = width >> (i + 1);
|
||||
widthHeight[0] = widthHeight[0] == 0 ? 1 : widthHeight[0];
|
||||
|
||||
widthHeight[1] = height >> (i + 1);
|
||||
widthHeight[1] = widthHeight[1] == 0 ? 1 : widthHeight[1];
|
||||
|
||||
|
||||
|
||||
int UOdd = (widthHeight[2] & 1) != 0 ? 1 : 0;
|
||||
int VOdd = (widthHeight[3] & 1) != 0 ? 1 : 0;
|
||||
|
||||
int UOdd2 = (widthHeight[0] & 1) != 0 ? 1 : 0;
|
||||
int VOdd2 = (widthHeight[1] & 1) != 0 ? 1 : 0;
|
||||
|
||||
RenderTargetIdentifier src;
|
||||
RenderTargetIdentifier dst;
|
||||
bool inputSRV = false;
|
||||
if (i == 0)
|
||||
{
|
||||
cmd.EnableKeyword(m_HiZMipCompute, m_SRVSourceKW);
|
||||
src = source.Identifier();
|
||||
dst = destination.Identifier();
|
||||
inputSRV = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (inputSRV == false)
|
||||
//{
|
||||
cmd.DisableKeyword(m_HiZMipCompute, m_SRVSourceKW);
|
||||
//}
|
||||
src = destination.Identifier();
|
||||
dst = destination.Identifier();
|
||||
inputSRV = false;
|
||||
}
|
||||
|
||||
|
||||
if (UOdd == 1 || VOdd == 1)
|
||||
{
|
||||
data2[1] = UOdd;
|
||||
data2[2] = VOdd;
|
||||
data2[3] = UOdd & VOdd;
|
||||
DispatchOdd(ref cmd, src, dst, widthHeight, data2, i - 1, slices, inputSRV);
|
||||
i++;
|
||||
}
|
||||
else if (UOdd2 == 1 || VOdd2 == 1)
|
||||
{
|
||||
//Debug.Log(string.Format("{0} x {1} is odd?", widthHeight[0], widthHeight[1]));
|
||||
DispatchEvenSingle(ref cmd, src, dst, widthHeight, data2, i - 1, slices, inputSRV);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int processLevels = Mathf.Min(mipLevels - i - 1, 2);
|
||||
data2[0] = processLevels;
|
||||
DispatchEvenMultiLevel(ref cmd, src, dst, widthHeight, data2, i - 1, slices, inputSRV);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
} while (i <= highestMip);
|
||||
|
||||
/* Old method for passing mip dimension info to shaders,
|
||||
* Precalculates the ratios of each mip to mip 0. This isn't
|
||||
* ideal as it takes up way too many registers. Better to just
|
||||
* calculate mip 0 dimension / exp2(mipLevel)
|
||||
Vector4[] mipDims = new Vector4[15];
|
||||
float mip0Width = (float)(width >> 1);
|
||||
float mip0Height = (float)(height >> 1);
|
||||
for (int j = 0; j < mipLevels; j++)
|
||||
{
|
||||
mipDims[j] = new Vector4();
|
||||
mipDims[j].x = (float)Mathf.Max(width >> j+1, 1);
|
||||
mipDims[j].y = (float)Mathf.Max(height >> j+1, 1);
|
||||
mipDims[j].z = mip0Width / mipDims[j].x;
|
||||
mipDims[j].w = mip0Height / mipDims[j].y;
|
||||
}
|
||||
*/
|
||||
//float mipNum = BitConverter.Int32BitsToSingle(highestMip);
|
||||
Vector4 dim = new Vector4();
|
||||
|
||||
dim.x = (float)(width >> 1);
|
||||
dim.y = (float)(height >> 1);
|
||||
dim.z = 1.0f / dim.x;
|
||||
dim.w = 1.0f / dim.y;
|
||||
SLZGlobals.instance.SetHiZGlobal(highestMip, dim);
|
||||
//Debug.Log(string.Format("Mip dim: {0} {1} {2} {3} {4}", mipDims[0], mipDims[2], mipDims[4], mipDims[6], mipDims[8]));
|
||||
}
|
||||
//Debug.Log("Last Mip: " + i);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
void DispatchEvenSingle(ref CommandBuffer cmd, RenderTargetIdentifier source1, RenderTargetIdentifier dest1,
|
||||
int[] widthHeight, int[] data2, int currMipLevel, int slices, bool inputSRV)
|
||||
{
|
||||
int kernel = 0;
|
||||
cmd.SetComputeIntParams(m_HiZMipCompute, computeParamID, widthHeight);
|
||||
//cmd.SetComputeIntParams(m_HiZMipCompute, computeParam2ID, data2);
|
||||
if (inputSRV)
|
||||
{
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, kernel, computeMipSourceID, source1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, kernel, computeMipSourceID, source1, currMipLevel);
|
||||
}
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, kernel, computeMipDestID, dest1, currMipLevel + 1);
|
||||
cmd.DispatchCompute(m_HiZMipCompute, kernel, Mathf.CeilToInt(((float)widthHeight[0]) / 8.0f), Mathf.CeilToInt(((float)widthHeight[1]) / 8.0f), slices);
|
||||
}
|
||||
void DispatchEvenMultiLevel(ref CommandBuffer cmd, RenderTargetIdentifier source1, RenderTargetIdentifier dest1,
|
||||
int[] widthHeight, int[] data2, int currMipLevel, int slices, bool inputSRV)
|
||||
{
|
||||
cmd.SetComputeIntParams(m_HiZMipCompute, computeParamID, widthHeight);
|
||||
cmd.SetComputeIntParams(m_HiZMipCompute, computeParam2ID, data2);
|
||||
if (inputSRV)
|
||||
{
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, 1, computeMipSourceID, source1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, 1, computeMipSourceID, source1, currMipLevel);
|
||||
}
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, 1, computeMipDestID, dest1, currMipLevel + 1);
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, 1, computeMipDest2ID, dest1, data2[0] > 1 ? currMipLevel + 2 : currMipLevel + 1);
|
||||
cmd.DispatchCompute(m_HiZMipCompute, 1, Mathf.CeilToInt(((float)widthHeight[0]) / 8.0f), Mathf.CeilToInt(((float)widthHeight[1]) / 8.0f), slices);
|
||||
}
|
||||
|
||||
void DispatchOdd(ref CommandBuffer cmd, RenderTargetIdentifier source1, RenderTargetIdentifier dest1,
|
||||
int[] widthHeight, int[] data2, int currMipLevel, int slices, bool inputSRV)
|
||||
{
|
||||
cmd.SetComputeIntParams(m_HiZMipCompute, computeParamID, widthHeight);
|
||||
cmd.SetComputeIntParams(m_HiZMipCompute, computeParam2ID, data2);
|
||||
if (inputSRV)
|
||||
{
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, 2, computeMipSourceID, source1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, 2, computeMipSourceID, source1, currMipLevel);
|
||||
}
|
||||
cmd.SetComputeTextureParam(m_HiZMipCompute, 2, computeMipDestID, dest1, currMipLevel + 1);
|
||||
cmd.DispatchCompute(m_HiZMipCompute, 2, Mathf.CeilToInt(((float)widthHeight[0]) / 8.0f), Mathf.CeilToInt(((float)widthHeight[1]) / 8.0f), slices);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
if (this.AllocateRT)
|
||||
cmd.ReleaseTemporaryRT(destination.id);
|
||||
destination = RenderTargetHandle.CameraTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 42929c61842e7a54fbac0c52da20fbf1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
public class SetHiZ0GlobalPass : ScriptableRenderPass
|
||||
{
|
||||
private RenderTargetIdentifier source { get; set; }
|
||||
private int prevHiZ0TextureID;
|
||||
|
||||
public SetHiZ0GlobalPass(RenderPassEvent evt)
|
||||
{
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
public void Setup(RenderTargetIdentifier source, int prevHiZ0ID)
|
||||
{
|
||||
this.source = source;
|
||||
prevHiZ0TextureID = prevHiZ0ID;
|
||||
}
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
|
||||
cmd.SetGlobalTexture(prevHiZ0TextureID, source);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Release();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Copy the given color buffer to the given destination color buffer.
|
||||
///
|
||||
/// You can use this pass to copy a color buffer to the destination,
|
||||
/// so you can use it later in rendering. For example, you can copy
|
||||
/// the opaque texture to use it for distortion effects.
|
||||
/// </summary>
|
||||
public class CopyHiZ0Pass : ScriptableRenderPass
|
||||
{
|
||||
//const int mipTruncation = 3;
|
||||
//static int sizeID = Shader.PropertyToID("_Size");
|
||||
static int sourceID = Shader.PropertyToID("_Source");
|
||||
static int destinationID = Shader.PropertyToID("_Destination");
|
||||
static int opaqueTextureDimID = Shader.PropertyToID("_CameraOpaqueTexture_Dim");
|
||||
|
||||
int m_SampleOffsetShaderHandle;
|
||||
Material m_SamplingMaterial;
|
||||
Downsampling m_DownsamplingMethod;
|
||||
Material m_CopyColorMaterial;
|
||||
ComputeShader m_ColorPyramidCompute;
|
||||
public bool m_RequiresMips;
|
||||
|
||||
private int m_MipLevels;
|
||||
private int[] m_Size;
|
||||
private int downsampleKernelID;
|
||||
private int gaussianKernelID;
|
||||
|
||||
private RenderTargetIdentifier source { get; set; }
|
||||
private RTPermanentHandle destination { get; set; }
|
||||
private RenderTargetHandle tempBuffer { get; set; }
|
||||
private RenderTextureDescriptor tempDescriptor;
|
||||
|
||||
/// <summary>
|
||||
/// Create the CopyColorPass
|
||||
/// </summary>
|
||||
public CopyHiZ0Pass(RenderPassEvent evt, Material samplingMaterial, Material copyColorMaterial = null)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(CopyColorPass));
|
||||
|
||||
m_SamplingMaterial = samplingMaterial;
|
||||
m_CopyColorMaterial = copyColorMaterial;
|
||||
renderPassEvent = evt;
|
||||
m_DownsamplingMethod = Downsampling.None;
|
||||
m_MipLevels = 1;
|
||||
base.useNativeRenderPass = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the pass with the source and destination to execute on.
|
||||
/// </summary>
|
||||
/// <param name="source">Source Render Target</param>
|
||||
/// <param name="destination">Destination Render Target</param>
|
||||
public void Setup(RenderTargetIdentifier source, RTPermanentHandle destination)
|
||||
{
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
//m_DownsamplingMethod = downsampling;
|
||||
//m_RequiresMips = RequiresMips;
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
|
||||
bool requiresMinMax = renderingData.cameraData.requiresMinMaxDepthPyr;
|
||||
var descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
descriptor.colorFormat = requiresMinMax ? RenderTextureFormat.RGHalf : RenderTextureFormat.RHalf;
|
||||
descriptor.width /= 2;
|
||||
descriptor.height /= 2;
|
||||
descriptor.depthBufferBits = 0;
|
||||
descriptor.msaaSamples = 1;
|
||||
descriptor.useMipMap = false;
|
||||
descriptor.autoGenerateMips = false;
|
||||
descriptor.sRGB = false;
|
||||
descriptor.enableRandomWrite = false;
|
||||
destination.GetRenderTexture(descriptor, renderingData.cameraData.camera.name, "PrevHiZ");
|
||||
//cmd.GetTemporaryRT(destination.id, descriptor, FilterMode.Point);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_SamplingMaterial == null)
|
||||
{
|
||||
Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_SamplingMaterial, GetType().Name);
|
||||
return;
|
||||
}
|
||||
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.StoreHiZ0)))
|
||||
{
|
||||
//RenderTargetIdentifier oldHiZRT = destination.Identifier();
|
||||
|
||||
ScriptableRenderer.SetRenderTarget(cmd, destination.renderTexture, BuiltinRenderTextureType.CameraTarget, clearFlag,
|
||||
clearColor);
|
||||
|
||||
bool useDrawProceduleBlit = renderingData.cameraData.xr.enabled;
|
||||
RenderingUtils.Blit(cmd, source, destination.renderTexture, m_CopyColorMaterial, 0, useDrawProceduleBlit);
|
||||
}
|
||||
// In shader, we need to know how many mip levels to 1x1 and not actually how many mips there are, so re-add mipTruncation to the true number of mips
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
//if (destination != RenderTargetHandle.CameraTarget)
|
||||
//{
|
||||
// cmd.ReleaseTemporaryRT(destination.id);
|
||||
// destination = RenderTargetHandle.CameraTarget;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 869dc0af1ec250040b7d629b43f8415b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
using UnityEngine.Experimental.GlobalIllumination;
|
||||
using UnityEngine.Profiling;
|
||||
using Unity.Collections;
|
||||
|
||||
// cleanup code
|
||||
// listMinDepth and maxDepth should be stored in a different uniform block?
|
||||
// Point lights stored as vec4
|
||||
// RelLightIndices should be stored in ushort instead of uint.
|
||||
// TODO use Unity.Mathematics
|
||||
// TODO Check if there is a bitarray structure (with dynamic size) available in Unity
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
// Render all tiled-based deferred lights.
|
||||
internal class DeferredPass : ScriptableRenderPass
|
||||
{
|
||||
DeferredLights m_DeferredLights;
|
||||
|
||||
public DeferredPass(RenderPassEvent evt, DeferredLights deferredLights)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(DeferredPass));
|
||||
base.renderPassEvent = evt;
|
||||
m_DeferredLights = deferredLights;
|
||||
}
|
||||
|
||||
// ScriptableRenderPass
|
||||
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescripor)
|
||||
{
|
||||
RenderTargetIdentifier lightingAttachmentId = m_DeferredLights.GbufferAttachmentIdentifiers[m_DeferredLights.GBufferLightingIndex];
|
||||
RenderTargetIdentifier depthAttachmentId = m_DeferredLights.DepthAttachmentIdentifier;
|
||||
if (m_DeferredLights.UseRenderPass)
|
||||
ConfigureInputAttachments(m_DeferredLights.DeferredInputAttachments, m_DeferredLights.DeferredInputIsTransient);
|
||||
|
||||
// TODO: change to m_DeferredLights.GetGBufferFormat(m_DeferredLights.GBufferLightingIndex) when it's not GraphicsFormat.None
|
||||
// TODO: Cannot currently bind depth texture as read-only!
|
||||
ConfigureTarget(lightingAttachmentId, depthAttachmentId, cameraTextureDescripor.graphicsFormat);
|
||||
}
|
||||
|
||||
// ScriptableRenderPass
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
m_DeferredLights.ExecuteDeferredPass(context, ref renderingData);
|
||||
}
|
||||
|
||||
// ScriptableRenderPass
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
m_DeferredLights.OnCameraCleanup(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1d258bcfb9f91794090920274896e493
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
public class DepthNormalOnlyPass : ScriptableRenderPass
|
||||
{
|
||||
internal RenderTextureDescriptor normalDescriptor { get; set; }
|
||||
internal RenderTextureDescriptor depthDescriptor { get; set; }
|
||||
internal bool allocateDepth { get; set; } = true;
|
||||
internal bool allocateNormal { get; set; } = true;
|
||||
internal List<ShaderTagId> shaderTagIds { get; set; }
|
||||
|
||||
private bool clearDepth = true;
|
||||
private RenderTargetHandle depthHandle { get; set; }
|
||||
private RenderTargetHandle normalHandle { get; set; }
|
||||
private FilteringSettings m_FilteringSettings;
|
||||
private int m_RendererMSAASamples = 1;
|
||||
|
||||
// Constants
|
||||
private const int k_DepthBufferBits = 32;
|
||||
private static readonly List<ShaderTagId> k_DepthNormals = new List<ShaderTagId> { new ShaderTagId("DepthNormals"), new ShaderTagId("DepthNormalsOnly") };
|
||||
|
||||
/// <summary>
|
||||
/// Create the DepthNormalOnlyPass
|
||||
/// </summary>
|
||||
public DepthNormalOnlyPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask, bool clearDepth = true)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(DepthNormalOnlyPass));
|
||||
m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);
|
||||
renderPassEvent = evt;
|
||||
useNativeRenderPass = false;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the pass
|
||||
/// </summary>
|
||||
public void Setup(RenderTextureDescriptor baseDescriptor, RenderTargetHandle depthHandle, RenderTargetHandle normalHandle, bool clearDepth = true)
|
||||
{
|
||||
// Find compatible render-target format for storing normals.
|
||||
// Shader code outputs normals in signed format to be compatible with deferred gbuffer layout.
|
||||
// Deferred gbuffer format is signed so that normals can be blended for terrain geometry.
|
||||
GraphicsFormat normalsFormat;
|
||||
if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R8G8_SNorm, FormatUsage.Render))
|
||||
normalsFormat = GraphicsFormat.R8G8_SNorm; // Preferred format
|
||||
else if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R16G16_SFloat, FormatUsage.Render))
|
||||
normalsFormat = GraphicsFormat.R16G16_SFloat; // fallback
|
||||
else if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R8G8B8A8_SNorm, FormatUsage.Render))
|
||||
normalsFormat = GraphicsFormat.R8G8B8A8_SNorm; // Preferred format
|
||||
else if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R32G32_SFloat, FormatUsage.Render))
|
||||
normalsFormat = GraphicsFormat.R32G32_SFloat; // fallback
|
||||
else
|
||||
normalsFormat = GraphicsFormat.R32G32B32A32_SFloat; // fallback
|
||||
|
||||
this.depthHandle = depthHandle;
|
||||
|
||||
m_RendererMSAASamples = baseDescriptor.msaaSamples;
|
||||
//baseDescriptor.useMipMap = true;
|
||||
//baseDescriptor.mipCount = 3;
|
||||
baseDescriptor.colorFormat = RenderTextureFormat.Depth;
|
||||
baseDescriptor.depthBufferBits = k_DepthBufferBits;
|
||||
|
||||
// Never have MSAA on this depth texture. When doing MSAA depth priming this is the texture that is resolved to and used for post-processing.
|
||||
baseDescriptor.msaaSamples = 1;// Depth-Only pass don't use MSAA
|
||||
|
||||
depthDescriptor = baseDescriptor;
|
||||
|
||||
this.normalHandle = normalHandle;
|
||||
baseDescriptor.graphicsFormat = normalsFormat;
|
||||
baseDescriptor.depthBufferBits = 0;
|
||||
|
||||
normalDescriptor = baseDescriptor;
|
||||
|
||||
this.allocateDepth = true;
|
||||
this.allocateNormal = true;
|
||||
this.shaderTagIds = k_DepthNormals;
|
||||
this.clearDepth = clearDepth;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
if (this.allocateNormal)
|
||||
{
|
||||
RenderTextureDescriptor desc = normalDescriptor;
|
||||
desc.msaaSamples = renderingData.cameraData.renderer.useDepthPriming ? m_RendererMSAASamples : 1;
|
||||
cmd.GetTemporaryRT(normalHandle.id, desc, FilterMode.Point);
|
||||
}
|
||||
if (this.allocateDepth)
|
||||
cmd.GetTemporaryRT(depthHandle.id, depthDescriptor, FilterMode.Point);
|
||||
|
||||
if (renderingData.cameraData.renderer.useDepthPriming && (renderingData.cameraData.renderType == CameraRenderType.Base || renderingData.cameraData.clearDepth))
|
||||
{
|
||||
ConfigureTarget(
|
||||
new RenderTargetIdentifier(normalHandle.Identifier(), 0, CubemapFace.Unknown, -1),
|
||||
new RenderTargetIdentifier(renderingData.cameraData.renderer.cameraDepthTarget, 0, CubemapFace.Unknown, -1)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigureTarget(
|
||||
new RenderTargetIdentifier(normalHandle.Identifier(), 0, CubemapFace.Unknown, -1),
|
||||
new RenderTargetIdentifier(depthHandle.Identifier(), 0, CubemapFace.Unknown, -1)
|
||||
);
|
||||
}
|
||||
if (clearDepth)
|
||||
{
|
||||
ConfigureClear(ClearFlag.All, Color.black);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigureClear(ClearFlag.ColorStencil, Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
// NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
|
||||
// Currently there's an issue which results in mismatched markers.
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.DepthNormalPrepass)))
|
||||
{
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
|
||||
var sortFlags = renderingData.cameraData.defaultOpaqueSortFlags;
|
||||
var drawSettings = CreateDrawingSettings(this.shaderTagIds, ref renderingData, sortFlags);
|
||||
drawSettings.perObjectData = PerObjectData.None;
|
||||
|
||||
ref CameraData cameraData = ref renderingData.cameraData;
|
||||
Camera camera = cameraData.camera;
|
||||
|
||||
context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref m_FilteringSettings);
|
||||
}
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
{
|
||||
throw new ArgumentNullException("cmd");
|
||||
}
|
||||
|
||||
if (depthHandle != RenderTargetHandle.CameraTarget)
|
||||
{
|
||||
if (this.allocateNormal)
|
||||
cmd.ReleaseTemporaryRT(normalHandle.id);
|
||||
if (this.allocateDepth)
|
||||
cmd.ReleaseTemporaryRT(depthHandle.id);
|
||||
normalHandle = RenderTargetHandle.CameraTarget;
|
||||
depthHandle = RenderTargetHandle.CameraTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6dfa2b31659ab4047b6bc33be7d8f07e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Render all objects that have a 'DepthOnly' pass into the given depth buffer.
|
||||
///
|
||||
/// You can use this pass to prime a depth buffer for subsequent rendering.
|
||||
/// Use it as a z-prepass, or use it to generate a depth buffer.
|
||||
/// </summary>
|
||||
public class DepthOnlyPass : ScriptableRenderPass
|
||||
{
|
||||
private static readonly ShaderTagId k_ShaderTagId = new ShaderTagId("DepthOnly");
|
||||
|
||||
private RenderTargetHandle depthAttachmentHandle { get; set; }
|
||||
internal RenderTextureDescriptor descriptor { get; set; }
|
||||
internal bool allocateDepth { get; set; } = true;
|
||||
internal bool clearDepth = true;
|
||||
internal ShaderTagId shaderTagId { get; set; } = k_ShaderTagId;
|
||||
|
||||
FilteringSettings m_FilteringSettings;
|
||||
|
||||
// Constants
|
||||
private const int k_DepthBufferBits = 32;
|
||||
|
||||
/// <summary>
|
||||
/// Create the DepthOnlyPass
|
||||
/// </summary>
|
||||
public DepthOnlyPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(DepthOnlyPass));
|
||||
m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);
|
||||
renderPassEvent = evt;
|
||||
useNativeRenderPass = false;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the pass
|
||||
/// </summary>
|
||||
public void Setup(
|
||||
RenderTextureDescriptor baseDescriptor,
|
||||
RenderTargetHandle depthAttachmentHandle, bool clearDepth = true)
|
||||
{
|
||||
|
||||
this.depthAttachmentHandle = depthAttachmentHandle;
|
||||
baseDescriptor.colorFormat = RenderTextureFormat.Depth;
|
||||
baseDescriptor.depthBufferBits = k_DepthBufferBits;
|
||||
|
||||
// Depth-Only pass don't use MSAA
|
||||
baseDescriptor.msaaSamples = 1;
|
||||
descriptor = baseDescriptor;
|
||||
|
||||
this.allocateDepth = true;
|
||||
this.shaderTagId = k_ShaderTagId;
|
||||
this.clearDepth = clearDepth;
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
if (this.allocateDepth)
|
||||
cmd.GetTemporaryRT(depthAttachmentHandle.id, descriptor, FilterMode.Point);
|
||||
var desc = renderingData.cameraData.cameraTargetDescriptor;
|
||||
|
||||
// When depth priming is in use the camera target should not be overridden so the Camera's MSAA depth attachment is used.
|
||||
if (renderingData.cameraData.renderer.useDepthPriming && (renderingData.cameraData.renderType == CameraRenderType.Base || renderingData.cameraData.clearDepth))
|
||||
{
|
||||
ConfigureTarget(renderingData.cameraData.renderer.cameraDepthTarget, descriptor.depthStencilFormat, desc.width, desc.height, 1, true);
|
||||
}
|
||||
// When not using depth priming the camera target should be set to our non MSAA depth target.
|
||||
else
|
||||
{
|
||||
ConfigureTarget(new RenderTargetIdentifier(depthAttachmentHandle.Identifier(), 0, CubemapFace.Unknown, -1), descriptor.depthStencilFormat, desc.width, desc.height, 1, true);
|
||||
}
|
||||
|
||||
// Only clear depth here so we don't clear any bound color target. It might be unused by this pass but that doesn't mean we can just clear it. (e.g. in case of overlay cameras + depth priming)
|
||||
// if
|
||||
if (clearDepth)
|
||||
{
|
||||
ConfigureClear(ClearFlag.Depth, Color.black);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigureClear(ClearFlag.Stencil, Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
// NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
|
||||
// Currently there's an issue which results in mismatched markers.
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.DepthPrepass)))
|
||||
{
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
|
||||
var sortFlags = renderingData.cameraData.defaultOpaqueSortFlags;
|
||||
var drawSettings = CreateDrawingSettings(this.shaderTagId, ref renderingData, sortFlags);
|
||||
drawSettings.perObjectData = PerObjectData.None;
|
||||
|
||||
context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref m_FilteringSettings);
|
||||
}
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
if (depthAttachmentHandle != RenderTargetHandle.CameraTarget)
|
||||
{
|
||||
if (this.allocateDepth)
|
||||
cmd.ReleaseTemporaryRT(depthAttachmentHandle.id);
|
||||
depthAttachmentHandle = RenderTargetHandle.CameraTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2b327960b30da614ca5f44f2fef0137a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Profiling;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Draw objects into the given color and depth target
|
||||
///
|
||||
/// You can use this pass to render objects that have a material and/or shader
|
||||
/// with the pass names UniversalForward or SRPDefaultUnlit.
|
||||
/// </summary>
|
||||
public class DrawObjectsPass : ScriptableRenderPass
|
||||
{
|
||||
#if DEBUG_NO_SHADERS
|
||||
static Material s_defaultMat;
|
||||
static Material defaultMat
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_defaultMat == null)
|
||||
{
|
||||
Shader s = Shader.Find("Hidden/DUMMY_SHADER");
|
||||
s_defaultMat = new Material(s);
|
||||
}
|
||||
return s_defaultMat;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
FilteringSettings m_FilteringSettings;
|
||||
RenderStateBlock m_RenderStateBlock;
|
||||
List<ShaderTagId> m_ShaderTagIdList = new List<ShaderTagId>();
|
||||
string m_ProfilerTag;
|
||||
ProfilingSampler m_ProfilingSampler;
|
||||
bool m_IsOpaque;
|
||||
public bool useMotionVectorData;
|
||||
bool m_UseDepthPriming;
|
||||
|
||||
// Skybox Drawing Params ---------------------------------------------------
|
||||
static GlobalKeyword s_DrawProcedural = GlobalKeyword.Create("DRAW_SKY_PROCEDURAL");
|
||||
public bool drawSkybox;
|
||||
static readonly int s_WorldSpaceLightPos0 = Shader.PropertyToID("_WorldSpaceLightPosSun");
|
||||
static readonly int s_LightColor0 = Shader.PropertyToID("_LightColorSun");
|
||||
//
|
||||
|
||||
static readonly int s_DrawObjectPassDataPropID = Shader.PropertyToID("_DrawObjectPassData");
|
||||
|
||||
public DrawObjectsPass(string profilerTag, ShaderTagId[] shaderTagIds, bool opaque, RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask, StencilState stencilState, int stencilReference)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(DrawObjectsPass));
|
||||
|
||||
m_ProfilerTag = profilerTag;
|
||||
m_ProfilingSampler = new ProfilingSampler(profilerTag);
|
||||
foreach (ShaderTagId sid in shaderTagIds)
|
||||
m_ShaderTagIdList.Add(sid);
|
||||
renderPassEvent = evt;
|
||||
m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);
|
||||
m_RenderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
|
||||
m_IsOpaque = opaque;
|
||||
|
||||
if (stencilState.enabled)
|
||||
{
|
||||
m_RenderStateBlock.stencilReference = stencilReference;
|
||||
m_RenderStateBlock.mask = RenderStateMask.Stencil;
|
||||
m_RenderStateBlock.stencilState = stencilState;
|
||||
}
|
||||
}
|
||||
|
||||
public DrawObjectsPass(string profilerTag, bool opaque, RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask, StencilState stencilState, int stencilReference)
|
||||
: this(profilerTag,
|
||||
new ShaderTagId[] { new ShaderTagId("SRPDefaultUnlit"), new ShaderTagId("UniversalForward"), new ShaderTagId("UniversalForwardOnly") },
|
||||
opaque, evt, renderQueueRange, layerMask, stencilState, stencilReference)
|
||||
{ }
|
||||
|
||||
internal DrawObjectsPass(URPProfileId profileId, bool opaque, RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask, StencilState stencilState, int stencilReference)
|
||||
: this(profileId.GetType().Name, opaque, evt, renderQueueRange, layerMask, stencilState, stencilReference)
|
||||
{
|
||||
m_ProfilingSampler = ProfilingSampler.Get(profileId);
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
if (renderingData.cameraData.renderer.useDepthPriming && m_IsOpaque && (renderingData.cameraData.renderType == CameraRenderType.Base || renderingData.cameraData.clearDepth))
|
||||
{
|
||||
m_RenderStateBlock.depthState = new DepthState(false, CompareFunction.Equal);
|
||||
m_RenderStateBlock.mask |= RenderStateMask.Depth;
|
||||
}
|
||||
else if (m_RenderStateBlock.depthState.compareFunction == CompareFunction.Equal)
|
||||
{
|
||||
m_RenderStateBlock.depthState = new DepthState(true, CompareFunction.LessEqual);
|
||||
m_RenderStateBlock.mask |= RenderStateMask.Depth;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
// NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
|
||||
// Currently there's an issue which results in mismatched markers.
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, m_ProfilingSampler))
|
||||
{
|
||||
// Global render pass data containing various settings.
|
||||
// x,y,z are currently unused
|
||||
// w is used for knowing whether the object is opaque(1) or alpha blended(0)
|
||||
Vector4 drawObjectPassData = new Vector4(0.0f, 0.0f, 0.0f, (m_IsOpaque) ? 1.0f : 0.0f);
|
||||
cmd.SetGlobalVector(s_DrawObjectPassDataPropID, drawObjectPassData);
|
||||
|
||||
// scaleBias.x = flipSign
|
||||
// scaleBias.y = scale
|
||||
// scaleBias.z = bias
|
||||
// scaleBias.w = unused
|
||||
float flipSign = (renderingData.cameraData.IsCameraProjectionMatrixFlipped()) ? -1.0f : 1.0f;
|
||||
Vector4 scaleBias = (flipSign < 0.0f)
|
||||
? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
|
||||
: new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
|
||||
cmd.SetGlobalVector(ShaderPropertyId.scaleBiasRt, scaleBias);
|
||||
|
||||
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
|
||||
Camera camera = renderingData.cameraData.camera;
|
||||
var sortFlags = (m_IsOpaque) ? renderingData.cameraData.defaultOpaqueSortFlags : SortingCriteria.CommonTransparent;
|
||||
if (renderingData.cameraData.renderer.useDepthPriming && m_IsOpaque && (renderingData.cameraData.renderType == CameraRenderType.Base || renderingData.cameraData.clearDepth))
|
||||
sortFlags = SortingCriteria.SortingLayer | SortingCriteria.RenderQueue | SortingCriteria.OptimizeStateChanges | SortingCriteria.CanvasOrder;
|
||||
|
||||
var filterSettings = m_FilteringSettings;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// When rendering the preview camera, we want the layer mask to be forced to Everything
|
||||
if (renderingData.cameraData.isPreviewCamera)
|
||||
{
|
||||
filterSettings.layerMask = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
DrawingSettings drawSettings = CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, sortFlags);
|
||||
if (useMotionVectorData)
|
||||
{
|
||||
drawSettings.perObjectData = drawSettings.perObjectData | PerObjectData.MotionVectors;
|
||||
}
|
||||
|
||||
if (drawSkybox)
|
||||
{
|
||||
Material skybox = RenderSettings.skybox;
|
||||
if (skybox)
|
||||
{
|
||||
Light sun = RenderSettings.sun;
|
||||
Vector4 sunDir;
|
||||
Vector4 lightColor;
|
||||
if (sun && sun.isActiveAndEnabled)
|
||||
{
|
||||
sunDir = -sun.transform.forward;
|
||||
lightColor = (Vector4)sun.color * sun.intensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
sunDir = new Vector4(0,0,-1,0);
|
||||
lightColor = Color.black;
|
||||
}
|
||||
skybox.SetVector(s_WorldSpaceLightPos0, sunDir);
|
||||
skybox.SetVector(s_LightColor0, lightColor);
|
||||
cmd.EnableKeyword(s_DrawProcedural);
|
||||
cmd.DrawProcedural(Matrix4x4.identity, skybox, 0, MeshTopology.Triangles, 3, 1);
|
||||
cmd.DisableKeyword(s_DrawProcedural);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
}
|
||||
}
|
||||
#if !DEBUG_NO_SHADERS
|
||||
var activeDebugHandler = GetActiveDebugHandler(renderingData);
|
||||
if (activeDebugHandler != null)
|
||||
{
|
||||
activeDebugHandler.DrawWithDebugRenderState(context, cmd, ref renderingData, ref drawSettings, ref filterSettings, ref m_RenderStateBlock,
|
||||
(ScriptableRenderContext ctx, ref RenderingData data, ref DrawingSettings ds, ref FilteringSettings fs, ref RenderStateBlock rsb) =>
|
||||
{
|
||||
ctx.DrawRenderers(data.cullResults, ref ds, ref fs, ref rsb);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref filterSettings, ref m_RenderStateBlock);
|
||||
|
||||
// Render objects that did not match any shader pass with error shader
|
||||
RenderingUtils.RenderObjectsWithError(context, ref renderingData.cullResults, camera, filterSettings, SortingCriteria.None);
|
||||
}
|
||||
#else
|
||||
drawSettings.overrideMaterial = defaultMat;
|
||||
context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref filterSettings);
|
||||
#endif
|
||||
}
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d2138a73081d8c34d901cf7a321f1099
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
namespace UnityEngine.Rendering.Universal
|
||||
{
|
||||
/// <summary>
|
||||
/// Draw the skybox into the given color buffer using the given depth buffer for depth testing.
|
||||
///
|
||||
/// This pass renders the standard Unity skybox.
|
||||
/// </summary>
|
||||
public class DrawSkyboxPass : ScriptableRenderPass
|
||||
{
|
||||
public DrawSkyboxPass(RenderPassEvent evt)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(DrawSkyboxPass));
|
||||
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
CameraData cameraData = renderingData.cameraData;
|
||||
Camera camera = cameraData.camera;
|
||||
|
||||
var activeDebugHandler = GetActiveDebugHandler(renderingData);
|
||||
if (activeDebugHandler != null)
|
||||
{
|
||||
// TODO: The skybox needs to work the same as the other shaders, but until it does we'll not render it
|
||||
// when certain debug modes are active (e.g. wireframe/overdraw modes)
|
||||
if (activeDebugHandler.IsScreenClearNeeded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
// XRTODO: Remove this code once Skybox pass is moved to SRP land.
|
||||
if (cameraData.xr.enabled)
|
||||
{
|
||||
// Setup Legacy XR buffer states
|
||||
if (cameraData.xr.singlePassEnabled)
|
||||
{
|
||||
// Setup legacy skybox stereo buffer
|
||||
camera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Left, cameraData.GetProjectionMatrix(0));
|
||||
camera.SetStereoViewMatrix(Camera.StereoscopicEye.Left, cameraData.GetViewMatrix(0));
|
||||
camera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Right, cameraData.GetProjectionMatrix(1));
|
||||
camera.SetStereoViewMatrix(Camera.StereoscopicEye.Right, cameraData.GetViewMatrix(1));
|
||||
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
|
||||
// Use legacy stereo instancing mode to have legacy XR code path configured
|
||||
cmd.SetSinglePassStereo(SystemInfo.supportsMultiview ? SinglePassStereoMode.Multiview : SinglePassStereoMode.Instancing);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
|
||||
// Calling into built-in skybox pass
|
||||
context.DrawSkybox(camera);
|
||||
|
||||
// Disable Legacy XR path
|
||||
cmd.SetSinglePassStereo(SinglePassStereoMode.None);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
// We do not need to submit here due to special handling of stereo matrices in core.
|
||||
// context.Submit();
|
||||
CommandBufferPool.Release(cmd);
|
||||
|
||||
camera.ResetStereoProjectionMatrices();
|
||||
camera.ResetStereoViewMatrices();
|
||||
}
|
||||
else
|
||||
{
|
||||
camera.projectionMatrix = cameraData.GetProjectionMatrix(0);
|
||||
camera.worldToCameraMatrix = cameraData.GetViewMatrix(0);
|
||||
|
||||
context.DrawSkybox(camera);
|
||||
|
||||
// XRTODO: remove this call because it creates issues with nested profiling scopes
|
||||
// See examples in UniversalRenderPipeline.RenderSingleCamera() and in ScriptableRenderer.Execute()
|
||||
context.Submit(); // Submit and execute the skybox pass before resetting the matrices
|
||||
|
||||
camera.ResetProjectionMatrix();
|
||||
camera.ResetWorldToCameraMatrix();
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
context.DrawSkybox(camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ae3e4e9915f7b6347b65203987c4f8b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Copy the given color target to the current camera target
|
||||
///
|
||||
/// You can use this pass to copy the result of rendering to
|
||||
/// the camera target. The pass takes the screen viewport into
|
||||
/// consideration.
|
||||
/// </summary>
|
||||
public class FinalBlitPass : ScriptableRenderPass
|
||||
{
|
||||
RenderTargetIdentifier m_Source;
|
||||
Material m_BlitMaterial;
|
||||
|
||||
public FinalBlitPass(RenderPassEvent evt, Material blitMaterial)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(FinalBlitPass));
|
||||
base.useNativeRenderPass = false;
|
||||
|
||||
m_BlitMaterial = blitMaterial;
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure the pass
|
||||
/// </summary>
|
||||
/// <param name="baseDescriptor"></param>
|
||||
/// <param name="colorHandle"></param>
|
||||
public void Setup(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorHandle)
|
||||
{
|
||||
m_Source = colorHandle.id;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_BlitMaterial == null)
|
||||
{
|
||||
Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_BlitMaterial, GetType().Name);
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: We need to get the cameraData.targetTexture as this will get the targetTexture of the camera stack.
|
||||
// Overlay cameras need to output to the target described in the base camera while doing camera stack.
|
||||
ref CameraData cameraData = ref renderingData.cameraData;
|
||||
RenderTargetIdentifier cameraTarget = (cameraData.targetTexture != null) ? new RenderTargetIdentifier(cameraData.targetTexture) : BuiltinRenderTextureType.CameraTarget;
|
||||
|
||||
bool isSceneViewCamera = cameraData.isSceneViewCamera;
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
|
||||
if (m_Source == cameraData.renderer.GetCameraColorFrontBuffer(cmd))
|
||||
{
|
||||
m_Source = renderingData.cameraData.renderer.cameraColorTarget;
|
||||
}
|
||||
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.FinalBlit)))
|
||||
{
|
||||
GetActiveDebugHandler(renderingData)?.UpdateShaderGlobalPropertiesForFinalValidationPass(cmd, ref cameraData, true);
|
||||
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.LinearToSRGBConversion,
|
||||
cameraData.requireSrgbConversion);
|
||||
|
||||
cmd.SetGlobalTexture(ShaderPropertyId.sourceTex, m_Source);
|
||||
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
if (cameraData.xr.enabled)
|
||||
{
|
||||
int depthSlice = cameraData.xr.singlePassEnabled ? -1 : cameraData.xr.GetTextureArraySlice();
|
||||
cameraTarget =
|
||||
new RenderTargetIdentifier(cameraData.xr.renderTarget, 0, CubemapFace.Unknown, depthSlice);
|
||||
|
||||
CoreUtils.SetRenderTarget(
|
||||
cmd,
|
||||
cameraTarget,
|
||||
RenderBufferLoadAction.Load,
|
||||
RenderBufferStoreAction.Store,
|
||||
ClearFlag.None,
|
||||
Color.black);
|
||||
|
||||
cmd.SetViewport(cameraData.pixelRect);
|
||||
|
||||
// We y-flip if
|
||||
// 1) we are bliting from render texture to back buffer(UV starts at bottom) and
|
||||
// 2) renderTexture starts UV at top
|
||||
bool yflip = !cameraData.xr.renderTargetIsRenderTexture && SystemInfo.graphicsUVStartsAtTop;
|
||||
Vector4 scaleBias = yflip ? new Vector4(1, -1, 0, 1) : new Vector4(1, 1, 0, 0);
|
||||
cmd.SetGlobalVector(ShaderPropertyId.scaleBias, scaleBias);
|
||||
|
||||
cmd.DrawProcedural(Matrix4x4.identity, m_BlitMaterial, 0, MeshTopology.Quads, 4);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (isSceneViewCamera || cameraData.isDefaultViewport)
|
||||
{
|
||||
// This set render target is necessary so we change the LOAD state to DontCare.
|
||||
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget,
|
||||
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, // color
|
||||
RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare); // depth
|
||||
cmd.Blit(m_Source, cameraTarget, m_BlitMaterial);
|
||||
cameraData.renderer.ConfigureCameraTarget(cameraTarget, cameraTarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Final blit pass should always blit to backbuffer. The first time we do we don't need to Load contents to tile.
|
||||
// We need to keep in the pipeline of first render pass to each render target to properly set load/store actions.
|
||||
// meanwhile we set to load so split screen case works.
|
||||
CoreUtils.SetRenderTarget(
|
||||
cmd,
|
||||
cameraTarget,
|
||||
RenderBufferLoadAction.Load,
|
||||
RenderBufferStoreAction.Store,
|
||||
ClearFlag.None,
|
||||
Color.black);
|
||||
|
||||
Camera camera = cameraData.camera;
|
||||
cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
|
||||
cmd.SetViewport(cameraData.pixelRect);
|
||||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_BlitMaterial);
|
||||
cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
|
||||
cameraData.renderer.ConfigureCameraTarget(cameraTarget, cameraTarget);
|
||||
}
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b66efce03c1804a4fbef78cccf176e4d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
using UnityEngine.Experimental.GlobalIllumination;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
using UnityEngine.Profiling;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
// Render all tiled-based deferred lights.
|
||||
internal class GBufferPass : ScriptableRenderPass
|
||||
{
|
||||
static readonly int s_CameraNormalsTextureID = Shader.PropertyToID("_CameraNormalsTexture");
|
||||
static ShaderTagId s_ShaderTagLit = new ShaderTagId("Lit");
|
||||
static ShaderTagId s_ShaderTagSimpleLit = new ShaderTagId("SimpleLit");
|
||||
static ShaderTagId s_ShaderTagUnlit = new ShaderTagId("Unlit");
|
||||
static ShaderTagId s_ShaderTagUniversalGBuffer = new ShaderTagId("UniversalGBuffer");
|
||||
static ShaderTagId s_ShaderTagUniversalMaterialType = new ShaderTagId("UniversalMaterialType");
|
||||
|
||||
ProfilingSampler m_ProfilingSampler = new ProfilingSampler("Render GBuffer");
|
||||
|
||||
DeferredLights m_DeferredLights;
|
||||
|
||||
ShaderTagId[] m_ShaderTagValues;
|
||||
RenderStateBlock[] m_RenderStateBlocks;
|
||||
|
||||
FilteringSettings m_FilteringSettings;
|
||||
RenderStateBlock m_RenderStateBlock;
|
||||
|
||||
public GBufferPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask, StencilState stencilState, int stencilReference, DeferredLights deferredLights)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(GBufferPass));
|
||||
base.renderPassEvent = evt;
|
||||
|
||||
m_DeferredLights = deferredLights;
|
||||
m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);
|
||||
m_RenderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
|
||||
|
||||
m_RenderStateBlock.stencilState = stencilState;
|
||||
m_RenderStateBlock.stencilReference = stencilReference;
|
||||
m_RenderStateBlock.mask = RenderStateMask.Stencil;
|
||||
|
||||
m_ShaderTagValues = new ShaderTagId[4];
|
||||
m_ShaderTagValues[0] = s_ShaderTagLit;
|
||||
m_ShaderTagValues[1] = s_ShaderTagSimpleLit;
|
||||
m_ShaderTagValues[2] = s_ShaderTagUnlit;
|
||||
m_ShaderTagValues[3] = new ShaderTagId(); // Special catch all case for materials where UniversalMaterialType is not defined or the tag value doesn't match anything we know.
|
||||
|
||||
m_RenderStateBlocks = new RenderStateBlock[4];
|
||||
m_RenderStateBlocks[0] = DeferredLights.OverwriteStencil(m_RenderStateBlock, (int)StencilUsage.MaterialMask, (int)StencilUsage.MaterialLit);
|
||||
m_RenderStateBlocks[1] = DeferredLights.OverwriteStencil(m_RenderStateBlock, (int)StencilUsage.MaterialMask, (int)StencilUsage.MaterialSimpleLit);
|
||||
m_RenderStateBlocks[2] = DeferredLights.OverwriteStencil(m_RenderStateBlock, (int)StencilUsage.MaterialMask, (int)StencilUsage.MaterialUnlit);
|
||||
m_RenderStateBlocks[3] = m_RenderStateBlocks[0];
|
||||
}
|
||||
|
||||
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
|
||||
{
|
||||
RenderTargetHandle[] gbufferAttachments = m_DeferredLights.GbufferAttachments;
|
||||
|
||||
if (cmd != null)
|
||||
{
|
||||
// Create and declare the render targets used in the pass
|
||||
for (int i = 0; i < gbufferAttachments.Length; ++i)
|
||||
{
|
||||
// Lighting buffer has already been declared with line ConfigureCameraTarget(m_ActiveCameraColorAttachment.Identifier(), ...) in DeferredRenderer.Setup
|
||||
if (i == m_DeferredLights.GBufferLightingIndex)
|
||||
continue;
|
||||
|
||||
// Normal buffer may have already been created if there was a depthNormal prepass before.
|
||||
// DepthNormal prepass is needed for forward-only materials when SSAO is generated between gbuffer and deferred lighting pass.
|
||||
if (i == m_DeferredLights.GBufferNormalSmoothnessIndex && m_DeferredLights.HasNormalPrepass)
|
||||
{
|
||||
if (m_DeferredLights.UseRenderPass)
|
||||
m_DeferredLights.DeferredInputIsTransient[i] = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// No need to setup temporaryRTs if we are using input attachments as they will be Memoryless
|
||||
if (m_DeferredLights.UseRenderPass && i != m_DeferredLights.GBufferShadowMask && i != m_DeferredLights.GBufferRenderingLayers && (i != m_DeferredLights.GbufferDepthIndex && !m_DeferredLights.HasDepthPrepass))
|
||||
continue;
|
||||
|
||||
RenderTextureDescriptor gbufferSlice = cameraTextureDescriptor;
|
||||
gbufferSlice.depthBufferBits = 0; // make sure no depth surface is actually created
|
||||
gbufferSlice.stencilFormat = GraphicsFormat.None;
|
||||
gbufferSlice.graphicsFormat = m_DeferredLights.GetGBufferFormat(i);
|
||||
cmd.GetTemporaryRT(m_DeferredLights.GbufferAttachments[i].id, gbufferSlice);
|
||||
}
|
||||
}
|
||||
|
||||
ConfigureTarget(m_DeferredLights.GbufferAttachmentIdentifiers, m_DeferredLights.DepthAttachmentIdentifier, m_DeferredLights.GbufferFormats);
|
||||
|
||||
// We must explicitely specify we don't want any clear to avoid unwanted side-effects.
|
||||
// ScriptableRenderer will implicitely force a clear the first time the camera color/depth targets are bound.
|
||||
ConfigureClear(ClearFlag.None, Color.black);
|
||||
}
|
||||
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
CommandBuffer gbufferCommands = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(gbufferCommands, m_ProfilingSampler))
|
||||
{
|
||||
context.ExecuteCommandBuffer(gbufferCommands);
|
||||
gbufferCommands.Clear();
|
||||
|
||||
// User can stack several scriptable renderers during rendering but deferred renderer should only lit pixels added by this gbuffer pass.
|
||||
// If we detect we are in such case (camera is in overlay mode), we clear the highest bits of stencil we have control of and use them to
|
||||
// mark what pixel to shade during deferred pass. Gbuffer will always mark pixels using their material types.
|
||||
if (m_DeferredLights.IsOverlay)
|
||||
{
|
||||
m_DeferredLights.ClearStencilPartial(gbufferCommands);
|
||||
context.ExecuteCommandBuffer(gbufferCommands);
|
||||
gbufferCommands.Clear();
|
||||
}
|
||||
|
||||
ref CameraData cameraData = ref renderingData.cameraData;
|
||||
Camera camera = cameraData.camera;
|
||||
ShaderTagId lightModeTag = s_ShaderTagUniversalGBuffer;
|
||||
DrawingSettings drawingSettings = CreateDrawingSettings(lightModeTag, ref renderingData, renderingData.cameraData.defaultOpaqueSortFlags);
|
||||
ShaderTagId universalMaterialTypeTag = s_ShaderTagUniversalMaterialType;
|
||||
|
||||
NativeArray<ShaderTagId> tagValues = new NativeArray<ShaderTagId>(m_ShaderTagValues, Allocator.Temp);
|
||||
NativeArray<RenderStateBlock> stateBlocks = new NativeArray<RenderStateBlock>(m_RenderStateBlocks, Allocator.Temp);
|
||||
|
||||
context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref m_FilteringSettings, universalMaterialTypeTag, false, tagValues, stateBlocks);
|
||||
|
||||
tagValues.Dispose();
|
||||
stateBlocks.Dispose();
|
||||
|
||||
// Render objects that did not match any shader pass with error shader
|
||||
RenderingUtils.RenderObjectsWithError(context, ref renderingData.cullResults, camera, m_FilteringSettings, SortingCriteria.None);
|
||||
|
||||
// If any sub-system needs camera normal texture, make it available.
|
||||
gbufferCommands.SetGlobalTexture(s_CameraNormalsTextureID, m_DeferredLights.GbufferAttachmentIdentifiers[m_DeferredLights.GBufferNormalSmoothnessIndex]);
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(gbufferCommands);
|
||||
CommandBufferPool.Release(gbufferCommands);
|
||||
}
|
||||
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
RenderTargetHandle[] gbufferAttachments = m_DeferredLights.GbufferAttachments;
|
||||
|
||||
for (int i = 0; i < gbufferAttachments.Length; ++i)
|
||||
{
|
||||
if (i == m_DeferredLights.GBufferLightingIndex)
|
||||
continue;
|
||||
|
||||
if (i == m_DeferredLights.GBufferNormalSmoothnessIndex && m_DeferredLights.HasNormalPrepass)
|
||||
continue;
|
||||
|
||||
cmd.ReleaseTemporaryRT(gbufferAttachments[i].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 10e31bb2e2b26314bb6132009378847c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
namespace UnityEngine.Rendering.Universal
|
||||
{
|
||||
/// <summary>
|
||||
/// Invokes OnRenderObject callback
|
||||
/// </summary>
|
||||
|
||||
internal class InvokeOnRenderObjectCallbackPass : ScriptableRenderPass
|
||||
{
|
||||
public InvokeOnRenderObjectCallbackPass(RenderPassEvent evt)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(InvokeOnRenderObjectCallbackPass));
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
context.InvokeOnRenderObjectCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 65317dda628fae54d953accd02570d92
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
using System;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Renders a shadow map for the main Light.
|
||||
/// </summary>
|
||||
public class MainLightShadowCasterPass : ScriptableRenderPass
|
||||
{
|
||||
private static class MainLightShadowConstantBuffer
|
||||
{
|
||||
public static int _WorldToShadow;
|
||||
public static int _ShadowParams;
|
||||
public static int _CascadeShadowSplitSpheres0;
|
||||
public static int _CascadeShadowSplitSpheres1;
|
||||
public static int _CascadeShadowSplitSpheres2;
|
||||
public static int _CascadeShadowSplitSpheres3;
|
||||
public static int _CascadeShadowSplitSphereRadii;
|
||||
public static int _ShadowOffset0;
|
||||
public static int _ShadowOffset1;
|
||||
public static int _ShadowOffset2;
|
||||
public static int _ShadowOffset3;
|
||||
public static int _ShadowmapSize;
|
||||
}
|
||||
|
||||
const int k_MaxCascades = 4;
|
||||
const int k_ShadowmapBufferBits = 16;
|
||||
float m_CascadeBorder;
|
||||
float m_MaxShadowDistanceSq;
|
||||
int m_ShadowCasterCascadesCount;
|
||||
|
||||
RenderTargetHandle m_MainLightShadowmap;
|
||||
internal RenderTexture m_MainLightShadowmapTexture;
|
||||
|
||||
Matrix4x4[] m_MainLightShadowMatrices;
|
||||
ShadowSliceData[] m_CascadeSlices;
|
||||
Vector4[] m_CascadeSplitDistances;
|
||||
|
||||
bool m_CreateEmptyShadowmap;
|
||||
|
||||
ProfilingSampler m_ProfilingSetupSampler = new ProfilingSampler("Setup Main Shadowmap");
|
||||
|
||||
public MainLightShadowCasterPass(RenderPassEvent evt)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(MainLightShadowCasterPass));
|
||||
renderPassEvent = evt;
|
||||
|
||||
m_MainLightShadowMatrices = new Matrix4x4[k_MaxCascades + 1];
|
||||
m_CascadeSlices = new ShadowSliceData[k_MaxCascades];
|
||||
m_CascadeSplitDistances = new Vector4[k_MaxCascades];
|
||||
|
||||
MainLightShadowConstantBuffer._WorldToShadow = Shader.PropertyToID("_MainLightWorldToShadow");
|
||||
MainLightShadowConstantBuffer._ShadowParams = Shader.PropertyToID("_MainLightShadowParams");
|
||||
MainLightShadowConstantBuffer._CascadeShadowSplitSpheres0 = Shader.PropertyToID("_CascadeShadowSplitSpheres0");
|
||||
MainLightShadowConstantBuffer._CascadeShadowSplitSpheres1 = Shader.PropertyToID("_CascadeShadowSplitSpheres1");
|
||||
MainLightShadowConstantBuffer._CascadeShadowSplitSpheres2 = Shader.PropertyToID("_CascadeShadowSplitSpheres2");
|
||||
MainLightShadowConstantBuffer._CascadeShadowSplitSpheres3 = Shader.PropertyToID("_CascadeShadowSplitSpheres3");
|
||||
MainLightShadowConstantBuffer._CascadeShadowSplitSphereRadii = Shader.PropertyToID("_CascadeShadowSplitSphereRadii");
|
||||
MainLightShadowConstantBuffer._ShadowOffset0 = Shader.PropertyToID("_MainLightShadowOffset0");
|
||||
MainLightShadowConstantBuffer._ShadowOffset1 = Shader.PropertyToID("_MainLightShadowOffset1");
|
||||
MainLightShadowConstantBuffer._ShadowOffset2 = Shader.PropertyToID("_MainLightShadowOffset2");
|
||||
MainLightShadowConstantBuffer._ShadowOffset3 = Shader.PropertyToID("_MainLightShadowOffset3");
|
||||
MainLightShadowConstantBuffer._ShadowmapSize = Shader.PropertyToID("_MainLightShadowmapSize");
|
||||
|
||||
m_MainLightShadowmap.Init("_MainLightShadowmapTexture");
|
||||
}
|
||||
|
||||
public bool Setup(ref RenderingData renderingData)
|
||||
{
|
||||
using var profScope = new ProfilingScope(null, m_ProfilingSetupSampler);
|
||||
|
||||
if (!renderingData.shadowData.supportsMainLightShadows)
|
||||
return SetupForEmptyRendering(ref renderingData);
|
||||
|
||||
Clear();
|
||||
int shadowLightIndex = renderingData.lightData.mainLightIndex;
|
||||
if (shadowLightIndex == -1)
|
||||
return SetupForEmptyRendering(ref renderingData);
|
||||
|
||||
VisibleLight shadowLight = renderingData.lightData.visibleLights[shadowLightIndex];
|
||||
Light light = shadowLight.light;
|
||||
if (light.shadows == LightShadows.None)
|
||||
return SetupForEmptyRendering(ref renderingData);
|
||||
|
||||
if (shadowLight.lightType != LightType.Directional)
|
||||
{
|
||||
Debug.LogWarning("Only directional lights are supported as main light.");
|
||||
}
|
||||
|
||||
Bounds bounds;
|
||||
if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
|
||||
return SetupForEmptyRendering(ref renderingData);
|
||||
|
||||
m_ShadowCasterCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount;
|
||||
|
||||
int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth,
|
||||
renderingData.shadowData.mainLightShadowmapHeight, m_ShadowCasterCascadesCount);
|
||||
renderTargetWidth = renderingData.shadowData.mainLightShadowmapWidth;
|
||||
renderTargetHeight = (m_ShadowCasterCascadesCount == 2) ?
|
||||
renderingData.shadowData.mainLightShadowmapHeight >> 1 :
|
||||
renderingData.shadowData.mainLightShadowmapHeight;
|
||||
|
||||
for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
|
||||
{
|
||||
bool success = ShadowUtils.ExtractDirectionalLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
|
||||
shadowLightIndex, cascadeIndex, renderTargetWidth, renderTargetHeight, shadowResolution, light.shadowNearPlane,
|
||||
out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex]);
|
||||
|
||||
if (!success)
|
||||
return SetupForEmptyRendering(ref renderingData);
|
||||
}
|
||||
|
||||
m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits);
|
||||
m_MaxShadowDistanceSq = renderingData.cameraData.maxShadowDistance * renderingData.cameraData.maxShadowDistance;
|
||||
m_CascadeBorder = renderingData.shadowData.mainLightShadowCascadeBorder;
|
||||
m_CreateEmptyShadowmap = false;
|
||||
useNativeRenderPass = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetupForEmptyRendering(ref RenderingData renderingData)
|
||||
{
|
||||
if (!renderingData.cameraData.renderer.stripShadowsOffVariants)
|
||||
return false;
|
||||
|
||||
m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(1, 1, k_ShadowmapBufferBits);
|
||||
m_CreateEmptyShadowmap = true;
|
||||
useNativeRenderPass = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
|
||||
{
|
||||
ConfigureTarget(new RenderTargetIdentifier(m_MainLightShadowmapTexture), m_MainLightShadowmapTexture.depthStencilFormat, renderTargetWidth, renderTargetHeight, 1, true);
|
||||
if (m_CreateEmptyShadowmap)
|
||||
{
|
||||
ConfigureClear(ClearFlag.None, Color.black);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigureClear(ClearFlag.All, Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_CreateEmptyShadowmap)
|
||||
{
|
||||
SetEmptyMainLightCascadeShadowmap(ref context);
|
||||
return;
|
||||
}
|
||||
|
||||
RenderMainLightCascadeShadowmap(ref context, ref renderingData.cullResults, ref renderingData.lightData, ref renderingData.shadowData);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
if (m_MainLightShadowmapTexture)
|
||||
{
|
||||
RenderTexture.ReleaseTemporary(m_MainLightShadowmapTexture);
|
||||
m_MainLightShadowmapTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_MainLightShadowmapTexture = null;
|
||||
|
||||
for (int i = 0; i < m_MainLightShadowMatrices.Length; ++i)
|
||||
m_MainLightShadowMatrices[i] = Matrix4x4.identity;
|
||||
|
||||
for (int i = 0; i < m_CascadeSplitDistances.Length; ++i)
|
||||
m_CascadeSplitDistances[i] = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
for (int i = 0; i < m_CascadeSlices.Length; ++i)
|
||||
m_CascadeSlices[i].Clear();
|
||||
}
|
||||
|
||||
void SetEmptyMainLightCascadeShadowmap(ref ScriptableRenderContext context)
|
||||
{
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true);
|
||||
cmd.SetGlobalTexture(m_MainLightShadowmap.id, m_MainLightShadowmapTexture);
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowParams,
|
||||
new Vector4(1, 0, 1, 0));
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize,
|
||||
new Vector4(1f / m_MainLightShadowmapTexture.width, 1f / m_MainLightShadowmapTexture.height, m_MainLightShadowmapTexture.width, m_MainLightShadowmapTexture.height));
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
|
||||
{
|
||||
int shadowLightIndex = lightData.mainLightIndex;
|
||||
if (shadowLightIndex == -1)
|
||||
return;
|
||||
|
||||
VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
|
||||
|
||||
// NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
|
||||
// Currently there's an issue which results in mismatched markers.
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.MainLightShadow)))
|
||||
{
|
||||
var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);
|
||||
settings.useRenderingLayerMaskTest = UniversalRenderPipeline.asset.supportsLightLayers;
|
||||
|
||||
for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
|
||||
{
|
||||
settings.splitData = m_CascadeSlices[cascadeIndex].splitData;
|
||||
|
||||
Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
|
||||
ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.CastingPunctualLightShadow, false);
|
||||
ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
|
||||
ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
|
||||
}
|
||||
|
||||
shadowData.isKeywordSoftShadowsEnabled = shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows;
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, shadowData.mainLightShadowCascadesCount == 1);
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, shadowData.isKeywordSoftShadowsEnabled);
|
||||
|
||||
SetupMainLightShadowReceiverConstants(cmd, shadowLight, shadowData.supportsSoftShadows);
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
void SetupMainLightShadowReceiverConstants(CommandBuffer cmd, VisibleLight shadowLight, bool supportsSoftShadows)
|
||||
{
|
||||
Light light = shadowLight.light;
|
||||
bool softShadows = shadowLight.light.shadows == LightShadows.Soft && supportsSoftShadows;
|
||||
|
||||
int cascadeCount = m_ShadowCasterCascadesCount;
|
||||
for (int i = 0; i < cascadeCount; ++i)
|
||||
m_MainLightShadowMatrices[i] = m_CascadeSlices[i].shadowTransform;
|
||||
|
||||
// We setup and additional a no-op WorldToShadow matrix in the last index
|
||||
// because the ComputeCascadeIndex function in Shadows.hlsl can return an index
|
||||
// out of bounds. (position not inside any cascade) and we want to avoid branching
|
||||
Matrix4x4 noOpShadowMatrix = Matrix4x4.zero;
|
||||
noOpShadowMatrix.m22 = (SystemInfo.usesReversedZBuffer) ? 1.0f : 0.0f;
|
||||
for (int i = cascadeCount; i <= k_MaxCascades; ++i)
|
||||
m_MainLightShadowMatrices[i] = noOpShadowMatrix;
|
||||
|
||||
float invShadowAtlasWidth = 1.0f / renderTargetWidth;
|
||||
float invShadowAtlasHeight = 1.0f / renderTargetHeight;
|
||||
float invHalfShadowAtlasWidth = 0.5f * invShadowAtlasWidth;
|
||||
float invHalfShadowAtlasHeight = 0.5f * invShadowAtlasHeight;
|
||||
float softShadowsProp = softShadows ? 1.0f : 0.0f;
|
||||
|
||||
ShadowUtils.GetScaleAndBiasForLinearDistanceFade(m_MaxShadowDistanceSq, m_CascadeBorder, out float shadowFadeScale, out float shadowFadeBias);
|
||||
|
||||
cmd.SetGlobalTexture(m_MainLightShadowmap.id, m_MainLightShadowmapTexture);
|
||||
cmd.SetGlobalMatrixArray(MainLightShadowConstantBuffer._WorldToShadow, m_MainLightShadowMatrices);
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowParams,
|
||||
new Vector4(light.shadowStrength, softShadowsProp, shadowFadeScale, shadowFadeBias));
|
||||
|
||||
if (m_ShadowCasterCascadesCount > 1)
|
||||
{
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres0,
|
||||
m_CascadeSplitDistances[0]);
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres1,
|
||||
m_CascadeSplitDistances[1]);
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres2,
|
||||
m_CascadeSplitDistances[2]);
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres3,
|
||||
m_CascadeSplitDistances[3]);
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSphereRadii, new Vector4(
|
||||
m_CascadeSplitDistances[0].w * m_CascadeSplitDistances[0].w,
|
||||
m_CascadeSplitDistances[1].w * m_CascadeSplitDistances[1].w,
|
||||
m_CascadeSplitDistances[2].w * m_CascadeSplitDistances[2].w,
|
||||
m_CascadeSplitDistances[3].w * m_CascadeSplitDistances[3].w));
|
||||
}
|
||||
|
||||
// Inside shader soft shadows are controlled through global keyword.
|
||||
// If any additional light has soft shadows it will force soft shadows on main light too.
|
||||
// As it is not trivial finding out which additional light has soft shadows, we will pass main light properties if soft shadows are supported.
|
||||
// This workaround will be removed once we will support soft shadows per light.
|
||||
if (supportsSoftShadows)
|
||||
{
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset0,
|
||||
new Vector4(-invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset1,
|
||||
new Vector4(invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset2,
|
||||
new Vector4(-invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset3,
|
||||
new Vector4(invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
|
||||
|
||||
// Currently only used when !SHADER_API_MOBILE but risky to not set them as it's generic
|
||||
// enough so custom shaders might use it.
|
||||
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowAtlasWidth,
|
||||
invShadowAtlasHeight,
|
||||
renderTargetWidth, renderTargetHeight));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 51015cd4dddd59d4b95f01cf645067bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
using System;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
sealed class MotionVectorRenderPass : ScriptableRenderPass
|
||||
{
|
||||
#region Fields
|
||||
const string kPreviousViewProjectionMatrix = "_PrevViewProjMatrix";
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
const string kPreviousViewProjectionMatrixStero = "_PrevViewProjMStereo";
|
||||
#endif
|
||||
const string kMotionVectorTexture = "_MotionVectorTexture";
|
||||
const GraphicsFormat m_TargetFormat = GraphicsFormat.R16G16_SFloat;
|
||||
|
||||
static readonly string[] s_ShaderTags = new string[] { "MotionVectors" };
|
||||
|
||||
RenderTargetHandle m_MotionVectorHandle; //Move to UniversalRenderer like other passes?
|
||||
readonly Material m_CameraMaterial;
|
||||
readonly Material m_ObjectMaterial;
|
||||
|
||||
PreviousFrameData m_MotionData;
|
||||
ProfilingSampler m_ProfilingSampler = ProfilingSampler.Get(URPProfileId.MotionVectors);
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
internal MotionVectorRenderPass(Material cameraMaterial, Material objectMaterial)
|
||||
{
|
||||
renderPassEvent = RenderPassEvent.AfterRenderingSkybox;
|
||||
m_CameraMaterial = cameraMaterial;
|
||||
m_ObjectMaterial = objectMaterial;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region State
|
||||
internal void Setup(PreviousFrameData frameData)
|
||||
{
|
||||
m_MotionData = frameData;
|
||||
}
|
||||
|
||||
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
|
||||
{
|
||||
var rtd = cameraTextureDescriptor;
|
||||
rtd.graphicsFormat = m_TargetFormat;
|
||||
// Configure Render Target
|
||||
m_MotionVectorHandle.Init(kMotionVectorTexture);
|
||||
cmd.GetTemporaryRT(m_MotionVectorHandle.id, rtd, FilterMode.Point);
|
||||
ConfigureTarget(m_MotionVectorHandle.Identifier(), m_MotionVectorHandle.Identifier());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Execution
|
||||
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_CameraMaterial == null || m_ObjectMaterial == null)
|
||||
return;
|
||||
|
||||
// Get data
|
||||
var camera = renderingData.cameraData.camera;
|
||||
|
||||
// Never draw in Preview
|
||||
if (camera.cameraType == CameraType.Preview)
|
||||
return;
|
||||
|
||||
// Profiling command
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, m_ProfilingSampler))
|
||||
{
|
||||
ExecuteCommand(context, cmd);
|
||||
var cameraData = renderingData.cameraData;
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
if (cameraData.xr.enabled && cameraData.xr.singlePassEnabled)
|
||||
{
|
||||
m_CameraMaterial.SetMatrixArray(kPreviousViewProjectionMatrixStero, m_MotionData.previousViewProjectionMatrixStereo);
|
||||
m_ObjectMaterial.SetMatrixArray(kPreviousViewProjectionMatrixStero, m_MotionData.previousViewProjectionMatrixStereo);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Shader.SetGlobalMatrix(kPreviousViewProjectionMatrix, m_MotionData.previousViewProjectionMatrix);
|
||||
}
|
||||
|
||||
// These flags are still required in SRP or the engine won't compute previous model matrices...
|
||||
// If the flag hasn't been set yet on this camera, motion vectors will skip a frame.
|
||||
camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
|
||||
|
||||
// TODO: add option to only draw either one?
|
||||
DrawCameraMotionVectors(context, cmd, camera);
|
||||
DrawObjectMotionVectors(context, ref renderingData, camera);
|
||||
}
|
||||
ExecuteCommand(context, cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
DrawingSettings GetDrawingSettings(ref RenderingData renderingData)
|
||||
{
|
||||
var camera = renderingData.cameraData.camera;
|
||||
var sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque };
|
||||
var drawingSettings = new DrawingSettings(ShaderTagId.none, sortingSettings)
|
||||
{
|
||||
perObjectData = PerObjectData.MotionVectors,
|
||||
enableDynamicBatching = renderingData.supportsDynamicBatching,
|
||||
enableInstancing = true,
|
||||
};
|
||||
|
||||
for (int i = 0; i < s_ShaderTags.Length; ++i)
|
||||
{
|
||||
drawingSettings.SetShaderPassName(i, new ShaderTagId(s_ShaderTags[i]));
|
||||
}
|
||||
|
||||
// Material that will be used if shader tags cannot be found
|
||||
drawingSettings.fallbackMaterial = m_ObjectMaterial;
|
||||
|
||||
return drawingSettings;
|
||||
}
|
||||
|
||||
void DrawCameraMotionVectors(ScriptableRenderContext context, CommandBuffer cmd, Camera camera)
|
||||
{
|
||||
// Draw fullscreen quad
|
||||
cmd.DrawProcedural(Matrix4x4.identity, m_CameraMaterial, 0, MeshTopology.Triangles, 3, 1);
|
||||
ExecuteCommand(context, cmd);
|
||||
}
|
||||
|
||||
void DrawObjectMotionVectors(ScriptableRenderContext context, ref RenderingData renderingData, Camera camera)
|
||||
{
|
||||
var drawingSettings = GetDrawingSettings(ref renderingData);
|
||||
var filteringSettings = new FilteringSettings(RenderQueueRange.opaque, camera.cullingMask);
|
||||
var renderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
|
||||
|
||||
// Draw Renderers
|
||||
context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filteringSettings, ref renderStateBlock);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Cleanup
|
||||
public override void FrameCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
// Reset Render Target
|
||||
if (m_MotionVectorHandle != RenderTargetHandle.CameraTarget)
|
||||
{
|
||||
cmd.ReleaseTemporaryRT(m_MotionVectorHandle.id);
|
||||
m_MotionVectorHandle = RenderTargetHandle.CameraTarget;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CommandBufer
|
||||
void ExecuteCommand(ScriptableRenderContext context, CommandBuffer cmd)
|
||||
{
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 096294dfb309e47929b561541e4b087e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 858a96c3295017349ab0f956b9883bb9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Scripting.APIUpdating;
|
||||
|
||||
namespace UnityEngine.Experimental.Rendering.Universal
|
||||
{
|
||||
public class RenderObjectsPass : ScriptableRenderPass
|
||||
{
|
||||
RenderQueueType renderQueueType;
|
||||
FilteringSettings m_FilteringSettings;
|
||||
RenderObjects.CustomCameraSettings m_CameraSettings;
|
||||
string m_ProfilerTag;
|
||||
ProfilingSampler m_ProfilingSampler;
|
||||
|
||||
public Material overrideMaterial { get; set; }
|
||||
public int overrideMaterialPassIndex { get; set; }
|
||||
|
||||
List<ShaderTagId> m_ShaderTagIdList = new List<ShaderTagId>();
|
||||
|
||||
public void SetDetphState(bool writeEnabled, CompareFunction function = CompareFunction.Less)
|
||||
{
|
||||
m_RenderStateBlock.mask |= RenderStateMask.Depth;
|
||||
m_RenderStateBlock.depthState = new DepthState(writeEnabled, function);
|
||||
}
|
||||
|
||||
public void SetStencilState(int reference, CompareFunction compareFunction, StencilOp passOp, StencilOp failOp, StencilOp zFailOp)
|
||||
{
|
||||
StencilState stencilState = StencilState.defaultValue;
|
||||
stencilState.enabled = true;
|
||||
stencilState.SetCompareFunction(compareFunction);
|
||||
stencilState.SetPassOperation(passOp);
|
||||
stencilState.SetFailOperation(failOp);
|
||||
stencilState.SetZFailOperation(zFailOp);
|
||||
|
||||
m_RenderStateBlock.mask |= RenderStateMask.Stencil;
|
||||
m_RenderStateBlock.stencilReference = reference;
|
||||
m_RenderStateBlock.stencilState = stencilState;
|
||||
}
|
||||
|
||||
RenderStateBlock m_RenderStateBlock;
|
||||
|
||||
public RenderObjectsPass(string profilerTag, RenderPassEvent renderPassEvent, string[] shaderTags, RenderQueueType renderQueueType, int layerMask, RenderObjects.CustomCameraSettings cameraSettings)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(RenderObjectsPass));
|
||||
|
||||
m_ProfilerTag = profilerTag;
|
||||
m_ProfilingSampler = new ProfilingSampler(profilerTag);
|
||||
this.renderPassEvent = renderPassEvent;
|
||||
this.renderQueueType = renderQueueType;
|
||||
this.overrideMaterial = null;
|
||||
this.overrideMaterialPassIndex = 0;
|
||||
RenderQueueRange renderQueueRange = (renderQueueType == RenderQueueType.Transparent)
|
||||
? RenderQueueRange.transparent
|
||||
: RenderQueueRange.opaque;
|
||||
m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);
|
||||
|
||||
if (shaderTags != null && shaderTags.Length > 0)
|
||||
{
|
||||
foreach (var passName in shaderTags)
|
||||
m_ShaderTagIdList.Add(new ShaderTagId(passName));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ShaderTagIdList.Add(new ShaderTagId("SRPDefaultUnlit"));
|
||||
m_ShaderTagIdList.Add(new ShaderTagId("UniversalForward"));
|
||||
m_ShaderTagIdList.Add(new ShaderTagId("UniversalForwardOnly"));
|
||||
}
|
||||
|
||||
m_RenderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
|
||||
m_CameraSettings = cameraSettings;
|
||||
}
|
||||
|
||||
internal RenderObjectsPass(URPProfileId profileId, RenderPassEvent renderPassEvent, string[] shaderTags, RenderQueueType renderQueueType, int layerMask, RenderObjects.CustomCameraSettings cameraSettings)
|
||||
: this(profileId.GetType().Name, renderPassEvent, shaderTags, renderQueueType, layerMask, cameraSettings)
|
||||
{
|
||||
m_ProfilingSampler = ProfilingSampler.Get(profileId);
|
||||
}
|
||||
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
SortingCriteria sortingCriteria = (renderQueueType == RenderQueueType.Transparent)
|
||||
? SortingCriteria.CommonTransparent
|
||||
: renderingData.cameraData.defaultOpaqueSortFlags;
|
||||
|
||||
DrawingSettings drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, sortingCriteria);
|
||||
drawingSettings.overrideMaterial = overrideMaterial;
|
||||
drawingSettings.overrideMaterialPassIndex = overrideMaterialPassIndex;
|
||||
|
||||
ref CameraData cameraData = ref renderingData.cameraData;
|
||||
Camera camera = cameraData.camera;
|
||||
|
||||
// In case of camera stacking we need to take the viewport rect from base camera
|
||||
Rect pixelRect = renderingData.cameraData.pixelRect;
|
||||
float cameraAspect = (float)pixelRect.width / (float)pixelRect.height;
|
||||
|
||||
// NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
|
||||
// Currently there's an issue which results in mismatched markers.
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, m_ProfilingSampler))
|
||||
{
|
||||
if (m_CameraSettings.overrideCamera)
|
||||
{
|
||||
if (cameraData.xr.enabled)
|
||||
{
|
||||
Debug.LogWarning("RenderObjects pass is configured to override camera matrices. While rendering in stereo camera matrices cannot be overridden.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix4x4 projectionMatrix = Matrix4x4.Perspective(m_CameraSettings.cameraFieldOfView, cameraAspect,
|
||||
camera.nearClipPlane, camera.farClipPlane);
|
||||
projectionMatrix = GL.GetGPUProjectionMatrix(projectionMatrix, cameraData.IsCameraProjectionMatrixFlipped());
|
||||
|
||||
Matrix4x4 viewMatrix = cameraData.GetViewMatrix();
|
||||
Vector4 cameraTranslation = viewMatrix.GetColumn(3);
|
||||
viewMatrix.SetColumn(3, cameraTranslation + m_CameraSettings.offset);
|
||||
|
||||
RenderingUtils.SetViewAndProjectionMatrices(cmd, viewMatrix, projectionMatrix, false);
|
||||
}
|
||||
}
|
||||
|
||||
var activeDebugHandler = GetActiveDebugHandler(renderingData);
|
||||
if (activeDebugHandler != null)
|
||||
{
|
||||
activeDebugHandler.DrawWithDebugRenderState(context, cmd, ref renderingData, ref drawingSettings, ref m_FilteringSettings, ref m_RenderStateBlock,
|
||||
(ScriptableRenderContext ctx, ref RenderingData data, ref DrawingSettings ds, ref FilteringSettings fs, ref RenderStateBlock rsb) =>
|
||||
{
|
||||
ctx.DrawRenderers(data.cullResults, ref ds, ref fs, ref rsb);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ensure we flush our command-buffer before we render...
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
|
||||
// Render the objects...
|
||||
context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref m_FilteringSettings, ref m_RenderStateBlock);
|
||||
}
|
||||
|
||||
if (m_CameraSettings.overrideCamera && m_CameraSettings.restoreCamera && !cameraData.xr.enabled)
|
||||
{
|
||||
RenderingUtils.SetViewAndProjectionMatrices(cmd, cameraData.GetViewMatrix(), cameraData.GetGPUProjectionMatrix(), false);
|
||||
}
|
||||
}
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dbd10d839f22d4127aeb9851dfed8caa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves shadows in a screen space texture.
|
||||
/// </summary>
|
||||
public class ScreenSpaceShadowResolvePass : ScriptableRenderPass
|
||||
{
|
||||
Material m_ScreenSpaceShadowsMaterial;
|
||||
RenderTargetHandle m_ScreenSpaceShadowmap;
|
||||
RenderTextureDescriptor m_RenderTextureDescriptor;
|
||||
|
||||
public ScreenSpaceShadowResolvePass(RenderPassEvent evt, Material screenspaceShadowsMaterial)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(ScreenSpaceShadowResolvePass));
|
||||
|
||||
m_ScreenSpaceShadowsMaterial = screenspaceShadowsMaterial;
|
||||
m_ScreenSpaceShadowmap.Init("_ScreenSpaceShadowmapTexture");
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
|
||||
public void Setup(RenderTextureDescriptor baseDescriptor)
|
||||
{
|
||||
m_RenderTextureDescriptor = baseDescriptor;
|
||||
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;
|
||||
}
|
||||
|
||||
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
|
||||
{
|
||||
cmd.GetTemporaryRT(m_ScreenSpaceShadowmap.id, m_RenderTextureDescriptor, FilterMode.Bilinear);
|
||||
|
||||
RenderTargetIdentifier screenSpaceOcclusionTexture = m_ScreenSpaceShadowmap.Identifier();
|
||||
ConfigureTarget(screenSpaceOcclusionTexture);
|
||||
ConfigureClear(ClearFlag.All, Color.white);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_ScreenSpaceShadowsMaterial == null)
|
||||
{
|
||||
Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_ScreenSpaceShadowsMaterial, GetType().Name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (renderingData.lightData.mainLightIndex == -1)
|
||||
return;
|
||||
|
||||
Camera camera = renderingData.cameraData.camera;
|
||||
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.ResolveShadows)))
|
||||
{
|
||||
if (!renderingData.cameraData.xr.enabled)
|
||||
{
|
||||
cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
|
||||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_ScreenSpaceShadowsMaterial);
|
||||
cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Avoid setting and restoring camera view and projection matrices when in stereo.
|
||||
RenderTargetIdentifier screenSpaceOcclusionTexture = m_ScreenSpaceShadowmap.Identifier();
|
||||
Blit(cmd, screenSpaceOcclusionTexture, screenSpaceOcclusionTexture, m_ScreenSpaceShadowsMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
cmd.ReleaseTemporaryRT(m_ScreenSpaceShadowmap.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 129fea61da31162458736c967c9d98ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,590 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Unity.Collections;
|
||||
using UnityEngine.Scripting.APIUpdating;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal
|
||||
{
|
||||
/// <summary>
|
||||
/// Input requirements for <c>ScriptableRenderPass</c>.
|
||||
/// </summary>
|
||||
/// <seealso cref="ConfigureInput"/>
|
||||
[Flags]
|
||||
public enum ScriptableRenderPassInput
|
||||
{
|
||||
None = 0,
|
||||
Depth = 1 << 0,
|
||||
Normal = 1 << 1,
|
||||
Color = 1 << 2,
|
||||
Motion = 1 << 3
|
||||
}
|
||||
|
||||
// Note: Spaced built-in events so we can add events in between them
|
||||
// We need to leave room as we sort render passes based on event.
|
||||
// Users can also inject render pass events in a specific point by doing RenderPassEvent + offset
|
||||
/// <summary>
|
||||
/// Controls when the render pass executes.
|
||||
/// </summary>
|
||||
public enum RenderPassEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering any other passes in the pipeline.
|
||||
/// Camera matrices and stereo rendering are not setup this point.
|
||||
/// You can use this to draw to custom input textures used later in the pipeline, f.ex LUT textures.
|
||||
/// </summary>
|
||||
BeforeRendering = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering shadowmaps.
|
||||
/// Camera matrices and stereo rendering are not setup this point.
|
||||
/// </summary>
|
||||
BeforeRenderingShadows = 50,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering shadowmaps.
|
||||
/// Camera matrices and stereo rendering are not setup this point.
|
||||
/// </summary>
|
||||
AfterRenderingShadows = 100,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering prepasses, f.ex, depth prepass.
|
||||
/// Camera matrices and stereo rendering are already setup at this point.
|
||||
/// </summary>
|
||||
BeforeRenderingPrePasses = 150,
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Obsolete, to match the capital from 'Prepass' to 'PrePass' (UnityUpgradable) -> BeforeRenderingPrePasses")]
|
||||
BeforeRenderingPrepasses = 151,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering prepasses, f.ex, depth prepass.
|
||||
/// Camera matrices and stereo rendering are already setup at this point.
|
||||
/// </summary>
|
||||
AfterRenderingPrePasses = 200,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering gbuffer pass.
|
||||
/// </summary>
|
||||
BeforeRenderingGbuffer = 210,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering gbuffer pass.
|
||||
/// </summary>
|
||||
AfterRenderingGbuffer = 220,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering deferred shading pass.
|
||||
/// </summary>
|
||||
BeforeRenderingDeferredLights = 230,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering deferred shading pass.
|
||||
/// </summary>
|
||||
AfterRenderingDeferredLights = 240,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering opaque objects.
|
||||
/// </summary>
|
||||
BeforeRenderingOpaques = 250,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering opaque objects.
|
||||
/// </summary>
|
||||
AfterRenderingOpaques = 300,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering the sky.
|
||||
/// </summary>
|
||||
BeforeRenderingSkybox = 350,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering the sky.
|
||||
/// </summary>
|
||||
AfterRenderingSkybox = 400,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering transparent objects.
|
||||
/// </summary>
|
||||
BeforeRenderingTransparents = 450,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering transparent objects.
|
||||
/// </summary>
|
||||
AfterRenderingTransparents = 500,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> before rendering post-processing effects.
|
||||
/// </summary>
|
||||
BeforeRenderingPostProcessing = 550,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering post-processing effects but before final blit, post-processing AA effects and color grading.
|
||||
/// </summary>
|
||||
AfterRenderingPostProcessing = 600,
|
||||
|
||||
/// <summary>
|
||||
/// Executes a <c>ScriptableRenderPass</c> after rendering all effects.
|
||||
/// </summary>
|
||||
AfterRendering = 1000,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <c>ScriptableRenderPass</c> implements a logical rendering pass that can be used to extend Universal RP renderer.
|
||||
/// </summary>
|
||||
public abstract partial class ScriptableRenderPass
|
||||
{
|
||||
public RenderPassEvent renderPassEvent { get; set; }
|
||||
|
||||
public RenderTargetIdentifier[] colorAttachments
|
||||
{
|
||||
get => m_ColorAttachments;
|
||||
}
|
||||
|
||||
public RenderTargetIdentifier colorAttachment
|
||||
{
|
||||
get => m_ColorAttachments[0];
|
||||
}
|
||||
|
||||
public RenderTargetIdentifier depthAttachment
|
||||
{
|
||||
get => m_DepthAttachment;
|
||||
}
|
||||
|
||||
public RenderBufferStoreAction[] colorStoreActions
|
||||
{
|
||||
get => m_ColorStoreActions;
|
||||
}
|
||||
|
||||
public RenderBufferStoreAction depthStoreAction
|
||||
{
|
||||
get => m_DepthStoreAction;
|
||||
}
|
||||
|
||||
internal bool[] overriddenColorStoreActions
|
||||
{
|
||||
get => m_OverriddenColorStoreActions;
|
||||
}
|
||||
|
||||
internal bool overriddenDepthStoreAction
|
||||
{
|
||||
get => m_OverriddenDepthStoreAction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The input requirements for the <c>ScriptableRenderPass</c>, which has been set using <c>ConfigureInput</c>
|
||||
/// </summary>
|
||||
/// <seealso cref="ConfigureInput"/>
|
||||
public ScriptableRenderPassInput input
|
||||
{
|
||||
get => m_Input;
|
||||
}
|
||||
|
||||
public ClearFlag clearFlag
|
||||
{
|
||||
get => m_ClearFlag;
|
||||
}
|
||||
|
||||
public Color clearColor
|
||||
{
|
||||
get => m_ClearColor;
|
||||
}
|
||||
|
||||
RenderBufferStoreAction[] m_ColorStoreActions = new RenderBufferStoreAction[] { RenderBufferStoreAction.Store };
|
||||
RenderBufferStoreAction m_DepthStoreAction = RenderBufferStoreAction.Store;
|
||||
|
||||
// by default all store actions are Store. The overridden flags are used to keep track of explicitly requested store actions, to
|
||||
// help figuring out the correct final store action for merged render passes when using the RenderPass API.
|
||||
private bool[] m_OverriddenColorStoreActions = new bool[] { false };
|
||||
private bool m_OverriddenDepthStoreAction = false;
|
||||
|
||||
/// <summary>
|
||||
/// A ProfilingSampler for the entire render pass. Used as a profiling name by <c>ScriptableRenderer</c> when executing the pass.
|
||||
/// Default is <c>Unnamed_ScriptableRenderPass</c>.
|
||||
/// Set <c>base.profilingSampler</c> from the sub-class constructor to set a profiling name for a custom <c>ScriptableRenderPass</c>.
|
||||
/// </summary>
|
||||
protected internal ProfilingSampler profilingSampler { get; set; }
|
||||
internal bool overrideCameraTarget { get; set; }
|
||||
internal bool isBlitRenderPass { get; set; }
|
||||
|
||||
internal bool useNativeRenderPass { get; set; }
|
||||
|
||||
internal int renderTargetWidth { get; set; }
|
||||
internal int renderTargetHeight { get; set; }
|
||||
internal int renderTargetSampleCount { get; set; }
|
||||
|
||||
internal bool depthOnly { get; set; }
|
||||
// this flag is updated each frame to keep track of which pass is the last for the current camera
|
||||
internal bool isLastPass { get; set; }
|
||||
// index to track the position in the current frame
|
||||
internal int renderPassQueueIndex { get; set; }
|
||||
|
||||
internal NativeArray<int> m_ColorAttachmentIndices;
|
||||
internal NativeArray<int> m_InputAttachmentIndices;
|
||||
|
||||
internal GraphicsFormat[] renderTargetFormat { get; set; }
|
||||
RenderTargetIdentifier[] m_ColorAttachments = new RenderTargetIdentifier[] { BuiltinRenderTextureType.CameraTarget };
|
||||
internal RenderTargetIdentifier[] m_InputAttachments = new RenderTargetIdentifier[8];
|
||||
internal bool[] m_InputAttachmentIsTransient = new bool[8];
|
||||
RenderTargetIdentifier m_DepthAttachment = BuiltinRenderTextureType.CameraTarget;
|
||||
ScriptableRenderPassInput m_Input = ScriptableRenderPassInput.None;
|
||||
ClearFlag m_ClearFlag = ClearFlag.None;
|
||||
Color m_ClearColor = Color.black;
|
||||
|
||||
internal DebugHandler GetActiveDebugHandler(RenderingData renderingData)
|
||||
{
|
||||
var debugHandler = renderingData.cameraData.renderer.DebugHandler;
|
||||
if ((debugHandler != null) && debugHandler.IsActiveForCamera(ref renderingData.cameraData))
|
||||
return debugHandler;
|
||||
return null;
|
||||
}
|
||||
|
||||
public ScriptableRenderPass()
|
||||
{
|
||||
renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
|
||||
m_ColorAttachments = new RenderTargetIdentifier[] { BuiltinRenderTextureType.CameraTarget, 0, 0, 0, 0, 0, 0, 0 };
|
||||
m_InputAttachments = new RenderTargetIdentifier[] { -1, -1, -1, -1, -1, -1, -1, -1 };
|
||||
m_InputAttachmentIsTransient = new bool[] { false, false, false, false, false, false, false, false };
|
||||
m_DepthAttachment = BuiltinRenderTextureType.CameraTarget;
|
||||
m_ColorStoreActions = new RenderBufferStoreAction[] { RenderBufferStoreAction.Store, 0, 0, 0, 0, 0, 0, 0 };
|
||||
m_DepthStoreAction = RenderBufferStoreAction.Store;
|
||||
m_OverriddenColorStoreActions = new bool[] { false, false, false, false, false, false, false, false };
|
||||
m_OverriddenDepthStoreAction = false;
|
||||
m_ClearFlag = ClearFlag.None;
|
||||
m_ClearColor = Color.black;
|
||||
overrideCameraTarget = false;
|
||||
isBlitRenderPass = false;
|
||||
profilingSampler = new ProfilingSampler($"Unnamed_{nameof(ScriptableRenderPass)}");
|
||||
useNativeRenderPass = true;
|
||||
renderTargetWidth = -1;
|
||||
renderTargetHeight = -1;
|
||||
renderTargetSampleCount = -1;
|
||||
renderPassQueueIndex = -1;
|
||||
renderTargetFormat = new GraphicsFormat[]
|
||||
{
|
||||
GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None,
|
||||
GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None
|
||||
};
|
||||
depthOnly = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures Input Requirements for this render pass.
|
||||
/// This method should be called inside <c>ScriptableRendererFeature.AddRenderPasses</c>.
|
||||
/// </summary>
|
||||
/// <param name="passInput">ScriptableRenderPassInput containing information about what requirements the pass needs.</param>
|
||||
/// <seealso cref="ScriptableRendererFeature.AddRenderPasses"/>
|
||||
public void ConfigureInput(ScriptableRenderPassInput passInput)
|
||||
{
|
||||
m_Input = passInput;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the Store Action for a color attachment of this render pass.
|
||||
/// </summary>
|
||||
/// <param name="storeAction">RenderBufferStoreAction to use</param>
|
||||
/// <param name="attachmentIndex">Index of the color attachment</param>
|
||||
public void ConfigureColorStoreAction(RenderBufferStoreAction storeAction, uint attachmentIndex = 0)
|
||||
{
|
||||
m_ColorStoreActions[attachmentIndex] = storeAction;
|
||||
m_OverriddenColorStoreActions[attachmentIndex] = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the Store Actions for all the color attachments of this render pass.
|
||||
/// </summary>
|
||||
/// <param name="storeActions">Array of RenderBufferStoreActions to use</param>
|
||||
public void ConfigureColorStoreActions(RenderBufferStoreAction[] storeActions)
|
||||
{
|
||||
int count = Math.Min(storeActions.Length, m_ColorStoreActions.Length);
|
||||
for (uint i = 0; i < count; ++i)
|
||||
{
|
||||
m_ColorStoreActions[i] = storeActions[i];
|
||||
m_OverriddenColorStoreActions[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the Store Action for the depth attachment of this render pass.
|
||||
/// </summary>
|
||||
/// <param name="storeAction">RenderBufferStoreAction to use</param>
|
||||
public void ConfigureDepthStoreAction(RenderBufferStoreAction storeAction)
|
||||
{
|
||||
m_DepthStoreAction = storeAction;
|
||||
m_OverriddenDepthStoreAction = true;
|
||||
}
|
||||
|
||||
internal void ConfigureInputAttachments(RenderTargetIdentifier input, bool isTransient = false)
|
||||
{
|
||||
m_InputAttachments[0] = input;
|
||||
m_InputAttachmentIsTransient[0] = isTransient;
|
||||
}
|
||||
|
||||
internal void ConfigureInputAttachments(RenderTargetIdentifier[] inputs)
|
||||
{
|
||||
m_InputAttachments = inputs;
|
||||
}
|
||||
|
||||
internal void ConfigureInputAttachments(RenderTargetIdentifier[] inputs, bool[] isTransient)
|
||||
{
|
||||
ConfigureInputAttachments(inputs);
|
||||
m_InputAttachmentIsTransient = isTransient;
|
||||
}
|
||||
|
||||
internal void SetInputAttachmentTransient(int idx, bool isTransient)
|
||||
{
|
||||
m_InputAttachmentIsTransient[idx] = isTransient;
|
||||
}
|
||||
|
||||
internal bool IsInputAttachmentTransient(int idx)
|
||||
{
|
||||
return m_InputAttachmentIsTransient[idx];
|
||||
}
|
||||
/// <summary>
|
||||
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
|
||||
/// This method should be called inside Configure.
|
||||
/// </summary>
|
||||
/// <param name="colorAttachment">Color attachment identifier.</param>
|
||||
/// <param name="depthAttachment">Depth attachment identifier.</param>
|
||||
/// <seealso cref="Configure"/>
|
||||
public void ConfigureTarget(RenderTargetIdentifier colorAttachment, RenderTargetIdentifier depthAttachment)
|
||||
{
|
||||
m_DepthAttachment = depthAttachment;
|
||||
ConfigureTarget(colorAttachment);
|
||||
}
|
||||
|
||||
public void ConfigureTarget(RenderTargetIdentifier colorAttachment, RenderTargetIdentifier depthAttachment, GraphicsFormat format)
|
||||
{
|
||||
m_DepthAttachment = depthAttachment;
|
||||
ConfigureTarget(colorAttachment, format);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
|
||||
/// This method should be called inside Configure.
|
||||
/// </summary>
|
||||
/// <param name="colorAttachment">Color attachment identifier.</param>
|
||||
/// <param name="depthAttachment">Depth attachment identifier.</param>
|
||||
/// <seealso cref="Configure"/>
|
||||
public void ConfigureTarget(RenderTargetIdentifier[] colorAttachments, RenderTargetIdentifier depthAttachment)
|
||||
{
|
||||
overrideCameraTarget = true;
|
||||
|
||||
uint nonNullColorBuffers = RenderingUtils.GetValidColorBufferCount(colorAttachments);
|
||||
if (nonNullColorBuffers > SystemInfo.supportedRenderTargetCount)
|
||||
Debug.LogError("Trying to set " + nonNullColorBuffers + " renderTargets, which is more than the maximum supported:" + SystemInfo.supportedRenderTargetCount);
|
||||
|
||||
m_ColorAttachments = colorAttachments;
|
||||
m_DepthAttachment = depthAttachment;
|
||||
}
|
||||
|
||||
internal void ConfigureTarget(RenderTargetIdentifier[] colorAttachments, RenderTargetIdentifier depthAttachment, GraphicsFormat[] formats)
|
||||
{
|
||||
ConfigureTarget(colorAttachments, depthAttachment);
|
||||
for (int i = 0; i < formats.Length; ++i)
|
||||
renderTargetFormat[i] = formats[i];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
|
||||
/// This method should be called inside Configure.
|
||||
/// </summary>
|
||||
/// <param name="colorAttachment">Color attachment identifier.</param>
|
||||
/// <seealso cref="Configure"/>
|
||||
public void ConfigureTarget(RenderTargetIdentifier colorAttachment)
|
||||
{
|
||||
overrideCameraTarget = true;
|
||||
|
||||
m_ColorAttachments[0] = colorAttachment;
|
||||
for (int i = 1; i < m_ColorAttachments.Length; ++i)
|
||||
m_ColorAttachments[i] = 0;
|
||||
}
|
||||
|
||||
internal void ConfigureTarget(RenderTargetIdentifier colorAttachment, GraphicsFormat format, int width = -1, int height = -1, int sampleCount = -1, bool depth = false)
|
||||
{
|
||||
ConfigureTarget(colorAttachment);
|
||||
for (int i = 1; i < m_ColorAttachments.Length; ++i)
|
||||
renderTargetFormat[i] = GraphicsFormat.None;
|
||||
|
||||
if (depth == true && !GraphicsFormatUtility.IsDepthFormat(format))
|
||||
{
|
||||
throw new ArgumentException("When configuring a depth only target the passed in format must be a depth format.");
|
||||
}
|
||||
|
||||
renderTargetWidth = width;
|
||||
renderTargetHeight = height;
|
||||
renderTargetSampleCount = sampleCount;
|
||||
depthOnly = depth;
|
||||
renderTargetFormat[0] = format;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
|
||||
/// This method should be called inside Configure.
|
||||
/// </summary>
|
||||
/// <param name="colorAttachment">Color attachment identifier.</param>
|
||||
/// <seealso cref="Configure"/>
|
||||
public void ConfigureTarget(RenderTargetIdentifier[] colorAttachments)
|
||||
{
|
||||
ConfigureTarget(colorAttachments, BuiltinRenderTextureType.CameraTarget);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures clearing for the render targets for this render pass. Call this inside Configure.
|
||||
/// </summary>
|
||||
/// <param name="clearFlag">ClearFlag containing information about what targets to clear.</param>
|
||||
/// <param name="clearColor">Clear color.</param>
|
||||
/// <seealso cref="Configure"/>
|
||||
public void ConfigureClear(ClearFlag clearFlag, Color clearColor)
|
||||
{
|
||||
m_ClearFlag = clearFlag;
|
||||
m_ClearColor = clearColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by the renderer before rendering a camera
|
||||
/// Override this method if you need to to configure render targets and their clear state, and to create temporary render target textures.
|
||||
/// If a render pass doesn't override this method, this render pass renders to the active Camera's render target.
|
||||
/// You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
|
||||
/// </summary>
|
||||
/// <param name="cmd">CommandBuffer to enqueue rendering commands. This will be executed by the pipeline.</param>
|
||||
/// <param name="renderingData">Current rendering state information</param>
|
||||
/// <seealso cref="ConfigureTarget"/>
|
||||
/// <seealso cref="ConfigureClear"/>
|
||||
public virtual void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by the renderer before executing the render pass.
|
||||
/// Override this method if you need to to configure render targets and their clear state, and to create temporary render target textures.
|
||||
/// If a render pass doesn't override this method, this render pass renders to the active Camera's render target.
|
||||
/// You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
|
||||
/// </summary>
|
||||
/// <param name="cmd">CommandBuffer to enqueue rendering commands. This will be executed by the pipeline.</param>
|
||||
/// <param name="cameraTextureDescriptor">Render texture descriptor of the camera render target.</param>
|
||||
/// <seealso cref="ConfigureTarget"/>
|
||||
/// <seealso cref="ConfigureClear"/>
|
||||
public virtual void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
|
||||
{ }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called upon finish rendering a camera. You can use this callback to release any resources created
|
||||
/// by this render
|
||||
/// pass that need to be cleanup once camera has finished rendering.
|
||||
/// This method be called for all cameras in a camera stack.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Use this CommandBuffer to cleanup any generated data</param>
|
||||
public virtual void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called upon finish rendering a camera stack. You can use this callback to release any resources created
|
||||
/// by this render pass that need to be cleanup once all cameras in the stack have finished rendering.
|
||||
/// This method will be called once after rendering the last camera in the camera stack.
|
||||
/// Cameras that don't have an explicit camera stack are also considered stacked rendering.
|
||||
/// In that case the Base camera is the first and last camera in the stack.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Use this CommandBuffer to cleanup any generated data</param>
|
||||
public virtual void OnFinishCameraStackRendering(CommandBuffer cmd)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Execute the pass. This is where custom rendering occurs. Specific details are left to the implementation
|
||||
/// </summary>
|
||||
/// <param name="context">Use this render context to issue any draw commands during execution</param>
|
||||
/// <param name="renderingData">Current rendering state information</param>
|
||||
public abstract void Execute(ScriptableRenderContext context, ref RenderingData renderingData);
|
||||
|
||||
/// <summary>
|
||||
/// Add a blit command to the context for execution. This changes the active render target in the ScriptableRenderer to
|
||||
/// destination.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Command buffer to record command for execution.</param>
|
||||
/// <param name="source">Source texture or target identifier to blit from.</param>
|
||||
/// <param name="destination">Destination texture or target identifier to blit into. This becomes the renderer active render target.</param>
|
||||
/// <param name="material">Material to use.</param>
|
||||
/// <param name="passIndex">Shader pass to use. Default is 0.</param>
|
||||
/// <seealso cref="ScriptableRenderer"/>
|
||||
public void Blit(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material = null, int passIndex = 0)
|
||||
{
|
||||
ScriptableRenderer.SetRenderTarget(cmd, destination, BuiltinRenderTextureType.CameraTarget, clearFlag, clearColor);
|
||||
cmd.Blit(source, destination, material, passIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a blit command to the context for execution. This applies the material to the color target.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Command buffer to record command for execution.</param>
|
||||
/// <param name="data">RenderingData to access the active renderer.</param>
|
||||
/// <param name="material">Material to use.</param>
|
||||
/// <param name="passIndex">Shader pass to use. Default is 0.</param>
|
||||
public void Blit(CommandBuffer cmd, ref RenderingData data, Material material, int passIndex = 0)
|
||||
{
|
||||
var renderer = data.cameraData.renderer;
|
||||
|
||||
Blit(cmd, renderer.cameraColorTarget, renderer.GetCameraColorFrontBuffer(cmd), material, passIndex);
|
||||
renderer.SwapColorBuffer(cmd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates <c>DrawingSettings</c> based on current the rendering state.
|
||||
/// </summary>
|
||||
/// <param name="shaderTagId">Shader pass tag to render.</param>
|
||||
/// <param name="renderingData">Current rendering state.</param>
|
||||
/// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="DrawingSettings"/>
|
||||
public DrawingSettings CreateDrawingSettings(ShaderTagId shaderTagId, ref RenderingData renderingData, SortingCriteria sortingCriteria)
|
||||
{
|
||||
Camera camera = renderingData.cameraData.camera;
|
||||
SortingSettings sortingSettings = new SortingSettings(camera) { criteria = sortingCriteria };
|
||||
DrawingSettings settings = new DrawingSettings(shaderTagId, sortingSettings)
|
||||
{
|
||||
perObjectData = renderingData.perObjectData,
|
||||
mainLightIndex = renderingData.lightData.mainLightIndex,
|
||||
enableDynamicBatching = renderingData.supportsDynamicBatching,
|
||||
|
||||
// Disable instancing for preview cameras. This is consistent with the built-in forward renderer. Also fixes case 1127324.
|
||||
enableInstancing = camera.cameraType == CameraType.Preview ? false : true,
|
||||
};
|
||||
return settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates <c>DrawingSettings</c> based on current rendering state.
|
||||
/// </summary>
|
||||
/// /// <param name="shaderTagIdList">List of shader pass tag to render.</param>
|
||||
/// <param name="renderingData">Current rendering state.</param>
|
||||
/// <param name="sortingCriteria">Criteria to sort objects being rendered.</param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="DrawingSettings"/>
|
||||
public DrawingSettings CreateDrawingSettings(List<ShaderTagId> shaderTagIdList,
|
||||
ref RenderingData renderingData, SortingCriteria sortingCriteria)
|
||||
{
|
||||
if (shaderTagIdList == null || shaderTagIdList.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("ShaderTagId list is invalid. DrawingSettings is created with default pipeline ShaderTagId");
|
||||
return CreateDrawingSettings(new ShaderTagId("UniversalPipeline"), ref renderingData, sortingCriteria);
|
||||
}
|
||||
|
||||
DrawingSettings settings = CreateDrawingSettings(shaderTagIdList[0], ref renderingData, sortingCriteria);
|
||||
for (int i = 1; i < shaderTagIdList.Count; ++i)
|
||||
settings.SetShaderPassName(i, shaderTagIdList[i]);
|
||||
return settings;
|
||||
}
|
||||
|
||||
public static bool operator <(ScriptableRenderPass lhs, ScriptableRenderPass rhs)
|
||||
{
|
||||
return lhs.renderPassEvent < rhs.renderPassEvent;
|
||||
}
|
||||
|
||||
public static bool operator >(ScriptableRenderPass lhs, ScriptableRenderPass rhs)
|
||||
{
|
||||
return lhs.renderPassEvent > rhs.renderPassEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: edba24b6007b9dd41824b4656ed8ebcf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Calculate min and max depth per screen tile for tiled-based deferred shading.
|
||||
/// </summary>
|
||||
internal class TileDepthRangePass : ScriptableRenderPass
|
||||
{
|
||||
DeferredLights m_DeferredLights;
|
||||
int m_PassIndex = 0;
|
||||
|
||||
public TileDepthRangePass(RenderPassEvent evt, DeferredLights deferredLights, int passIndex)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(TileDepthRangePass));
|
||||
base.renderPassEvent = evt;
|
||||
m_DeferredLights = deferredLights;
|
||||
m_PassIndex = passIndex;
|
||||
}
|
||||
|
||||
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
|
||||
{
|
||||
RenderTargetHandle outputTex;
|
||||
RenderTextureDescriptor desc;
|
||||
|
||||
if (m_PassIndex == 0 && m_DeferredLights.HasTileDepthRangeExtraPass())
|
||||
{
|
||||
int alignment = 1 << DeferredConfig.kTileDepthInfoIntermediateLevel;
|
||||
int depthInfoWidth = (m_DeferredLights.RenderWidth + alignment - 1) >> DeferredConfig.kTileDepthInfoIntermediateLevel;
|
||||
int depthInfoHeight = (m_DeferredLights.RenderHeight + alignment - 1) >> DeferredConfig.kTileDepthInfoIntermediateLevel;
|
||||
|
||||
outputTex = m_DeferredLights.DepthInfoTexture;
|
||||
desc = new RenderTextureDescriptor(depthInfoWidth, depthInfoHeight, UnityEngine.Experimental.Rendering.GraphicsFormat.R32_UInt, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int tileDepthRangeWidth = m_DeferredLights.GetTiler(0).TileXCount;
|
||||
int tileDepthRangeHeight = m_DeferredLights.GetTiler(0).TileYCount;
|
||||
|
||||
outputTex = m_DeferredLights.TileDepthInfoTexture;
|
||||
desc = new RenderTextureDescriptor(tileDepthRangeWidth, tileDepthRangeHeight, UnityEngine.Experimental.Rendering.GraphicsFormat.R32_UInt, 0);
|
||||
}
|
||||
cmd.GetTemporaryRT(outputTex.id, desc, FilterMode.Point);
|
||||
base.ConfigureTarget(outputTex.Identifier());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (m_PassIndex == 0)
|
||||
m_DeferredLights.ExecuteTileDepthInfoPass(context, ref renderingData);
|
||||
else
|
||||
m_DeferredLights.ExecuteDownsampleBitmaskPass(context, ref renderingData);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
|
||||
cmd.ReleaseTemporaryRT(m_DeferredLights.TileDepthInfoTexture.id);
|
||||
m_DeferredLights.TileDepthInfoTexture = RenderTargetHandle.CameraTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1d810d5a4f691954cbcd67a3a1bb2fda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
namespace UnityEngine.Rendering.Universal
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies relevant settings before rendering transparent objects
|
||||
/// </summary>
|
||||
|
||||
internal class TransparentSettingsPass : ScriptableRenderPass
|
||||
{
|
||||
bool m_shouldReceiveShadows;
|
||||
|
||||
const string m_ProfilerTag = "Transparent Settings Pass";
|
||||
private static readonly ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
|
||||
|
||||
public TransparentSettingsPass(RenderPassEvent evt, bool shadowReceiveSupported)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(TransparentSettingsPass));
|
||||
renderPassEvent = evt;
|
||||
m_shouldReceiveShadows = shadowReceiveSupported;
|
||||
}
|
||||
|
||||
public bool Setup(ref RenderingData renderingData)
|
||||
{
|
||||
// Currently we only need to enqueue this pass when the user
|
||||
// doesn't want transparent objects to receive shadows
|
||||
return !m_shouldReceiveShadows;
|
||||
}
|
||||
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
// Get a command buffer...
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, m_ProfilingSampler))
|
||||
{
|
||||
// Toggle light shadows enabled based on the renderer setting set in the constructor
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, m_shouldReceiveShadows);
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, m_shouldReceiveShadows);
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, m_shouldReceiveShadows);
|
||||
}
|
||||
|
||||
// Execute and release the command buffer...
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: faf05873da6e6fb489aa73a76d780c5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
|
||||
using System;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal
|
||||
{
|
||||
/// <summary>
|
||||
/// Draw the XR occlusion mesh into the current depth buffer when XR is enabled.
|
||||
/// </summary>
|
||||
public class XROcclusionMeshPass : ScriptableRenderPass
|
||||
{
|
||||
bool isDepth;
|
||||
public XROcclusionMeshPass(RenderPassEvent evt)
|
||||
{
|
||||
base.profilingSampler = new ProfilingSampler(nameof(XROcclusionMeshPass));
|
||||
renderPassEvent = evt;
|
||||
}
|
||||
|
||||
public void Setup(bool isDepth)
|
||||
{
|
||||
this.isDepth = isDepth;
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
if (isDepth)
|
||||
{
|
||||
RenderTextureDescriptor desc = renderingData.cameraData.cameraTargetDescriptor;
|
||||
|
||||
// When depth priming is in use the camera target should not be overridden so the Camera's MSAA depth attachment is used.
|
||||
if (renderingData.cameraData.renderer.useDepthPriming && (renderingData.cameraData.renderType == CameraRenderType.Base || renderingData.cameraData.clearDepth))
|
||||
{
|
||||
ConfigureTarget(renderingData.cameraData.renderer.cameraDepthTarget, desc.depthStencilFormat, desc.width, desc.height, 1, true);
|
||||
|
||||
ConfigureClear(ClearFlag.Depth, Color.black);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigureClear(ClearFlag.None, Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
if (!renderingData.cameraData.xr.enabled)
|
||||
return;
|
||||
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
|
||||
renderingData.cameraData.xr.RenderOcclusionMesh(cmd);
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
public override void OnCameraCleanup(CommandBuffer cmd)
|
||||
{
|
||||
if (cmd == null)
|
||||
throw new ArgumentNullException("cmd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fc46a25201ce7e743bfdca7d07707357
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Add table
Add a link
Reference in a new issue