|
|
|
|
|
|
private RenderTargetIdentifier m_CopyDepth; |
|
|
|
private RenderTargetIdentifier m_Color; |
|
|
|
private RenderTargetIdentifier m_OpaqueRT; |
|
|
|
private float[] m_OpaqueScalerValues = {1.0f, 0.5f, 0.25f}; |
|
|
|
|
|
|
|
private bool m_IntermediateTextureArray; |
|
|
|
private bool m_RequireDepthTexture; |
|
|
|
|
|
|
cmd.ReleaseTemporaryRT(CameraRenderTargetID.depth); |
|
|
|
cmd.ReleaseTemporaryRT(CameraRenderTargetID.color); |
|
|
|
cmd.ReleaseTemporaryRT(CameraRenderTargetID.copyColor); |
|
|
|
cmd.ReleaseTemporaryRT(CameraRenderTargetID.opaque); |
|
|
|
|
|
|
|
cmd.EndSample("LightweightPipeline.Render"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void OpaqueTexturePass(ref ScriptableRenderContext context, FrameRenderingConfiguration frameRenderingConfiguration) |
|
|
|
{ |
|
|
|
RenderTextureDescriptor opaqueDesc; |
|
|
|
if (LightweightUtils.HasFlag(frameRenderingConfiguration, FrameRenderingConfiguration.Stereo)) |
|
|
|
opaqueDesc = XRSettings.eyeTextureDesc; |
|
|
|
else |
|
|
|
opaqueDesc = new RenderTextureDescriptor(m_CurrCamera.pixelWidth, m_CurrCamera.pixelHeight); |
|
|
|
|
|
|
|
float renderScale = (m_CurrCamera.cameraType == CameraType.Game) ? m_Asset.RenderScale : 1.0f; |
|
|
|
|
|
|
|
var opaqueScaler = m_OpaqueScalerValues[(int)m_Asset.OpaqueTextureScale]; |
|
|
|
RenderTextureDescriptor opaqueDesc = CreateRTDesc(frameRenderingConfiguration, opaqueScaler); |
|
|
|
|
|
|
|
cmd.GetTemporaryRT(CameraRenderTargetID.opaque, opaqueDesc, FilterMode.Bilinear); |
|
|
|
case TextureScale.One: |
|
|
|
cmd.Blit(m_CurrCameraColorRT, CameraRenderTargetID.opaque); |
|
|
|
break; |
|
|
|
opaqueDesc.width = (int)((float)opaqueDesc.width * renderScale * 0.5f); |
|
|
|
opaqueDesc.height = (int)((float)opaqueDesc.height * renderScale * 0.5f); |
|
|
|
cmd.GetTemporaryRT(CameraRenderTargetID.opaque, opaqueDesc, FilterMode.Bilinear); |
|
|
|
opaqueDesc.width = (int)((float)opaqueDesc.width * renderScale * 0.25f); |
|
|
|
opaqueDesc.height = (int)((float)opaqueDesc.height * renderScale * 0.25f); |
|
|
|
cmd.GetTemporaryRT(CameraRenderTargetID.opaque, opaqueDesc, FilterMode.Bilinear); |
|
|
|
break; |
|
|
|
default: |
|
|
|
opaqueDesc.width = (int)((float)opaqueDesc.width * renderScale); |
|
|
|
opaqueDesc.height = (int)((float)opaqueDesc.height * renderScale); |
|
|
|
cmd.GetTemporaryRT(CameraRenderTargetID.opaque, opaqueDesc, FilterMode.Bilinear); |
|
|
|
cmd.Blit(m_CurrCameraColorRT, CameraRenderTargetID.opaque); |
|
|
|
break; |
|
|
|
} |
|
|
|
SetRenderTarget(cmd, m_CurrCameraColorRT, m_DepthRT); |
|
|
|
|
|
|
|
|
|
|
private void AfterOpaque(ref ScriptableRenderContext context, FrameRenderingConfiguration config) |
|
|
|
{ |
|
|
|
if (!m_RequireDepthTexture) |
|
|
|
return; |
|
|
|
|
|
|
|
CommandBuffer cmd = CommandBufferPool.Get("After Opaque"); |
|
|
|
cmd.SetGlobalTexture(CameraRenderTargetID.depth, m_DepthRT); |
|
|
|
if (m_RequireDepthTexture) |
|
|
|
{ |
|
|
|
CommandBuffer cmd = CommandBufferPool.Get("After Opaque"); |
|
|
|
cmd.SetGlobalTexture(CameraRenderTargetID.depth, m_DepthRT); |
|
|
|
bool setRenderTarget = false; |
|
|
|
RenderTargetIdentifier depthRT = m_DepthRT; |
|
|
|
bool setRenderTarget = false; |
|
|
|
RenderTargetIdentifier depthRT = m_DepthRT; |
|
|
|
// TODO: There's currently an issue in the PostFX stack that has a one frame delay when an effect is enabled/disabled
|
|
|
|
// when an effect is disabled, HasOpaqueOnlyEffects returns true in the first frame, however inside render the effect
|
|
|
|
// state is update, causing RenderPostProcess here to not blit to FinalColorRT. Until the next frame the RT will have garbage.
|
|
|
|
if (LightweightUtils.HasFlag(config, FrameRenderingConfiguration.BeforeTransparentPostProcess)) |
|
|
|
{ |
|
|
|
// When only have one effect in the stack we blit to a work RT then blit it back to active color RT.
|
|
|
|
// This seems like an extra blit but it saves us a depth copy/blit which has some corner cases like msaa depth resolve.
|
|
|
|
if (m_RequireCopyColor) |
|
|
|
// TODO: There's currently an issue in the PostFX stack that has a one frame delay when an effect is enabled/disabled
|
|
|
|
// when an effect is disabled, HasOpaqueOnlyEffects returns true in the first frame, however inside render the effect
|
|
|
|
// state is update, causing RenderPostProcess here to not blit to FinalColorRT. Until the next frame the RT will have garbage.
|
|
|
|
if (LightweightUtils.HasFlag(config, FrameRenderingConfiguration.BeforeTransparentPostProcess)) |
|
|
|
RenderPostProcess(cmd, m_CurrCameraColorRT, m_CopyColorRT, true); |
|
|
|
cmd.Blit(m_CopyColorRT, m_CurrCameraColorRT); |
|
|
|
// When only have one effect in the stack we blit to a work RT then blit it back to active color RT.
|
|
|
|
// This seems like an extra blit but it saves us a depth copy/blit which has some corner cases like msaa depth resolve.
|
|
|
|
if (m_RequireCopyColor) |
|
|
|
{ |
|
|
|
RenderPostProcess(cmd, m_CurrCameraColorRT, m_CopyColorRT, true); |
|
|
|
cmd.Blit(m_CopyColorRT, m_CurrCameraColorRT); |
|
|
|
} |
|
|
|
else |
|
|
|
RenderPostProcess(cmd, m_CurrCameraColorRT, m_CurrCameraColorRT, true); |
|
|
|
|
|
|
|
setRenderTarget = true; |
|
|
|
SetRenderTarget(cmd, m_CurrCameraColorRT, m_DepthRT); |
|
|
|
else |
|
|
|
RenderPostProcess(cmd, m_CurrCameraColorRT, m_CurrCameraColorRT, true); |
|
|
|
setRenderTarget = true; |
|
|
|
SetRenderTarget(cmd, m_CurrCameraColorRT, m_DepthRT); |
|
|
|
} |
|
|
|
if (LightweightUtils.HasFlag(config, FrameRenderingConfiguration.DepthCopy)) |
|
|
|
{ |
|
|
|
CopyTexture(cmd, m_DepthRT, m_CopyDepth, m_CopyDepthMaterial); |
|
|
|
depthRT = m_CopyDepth; |
|
|
|
setRenderTarget = true; |
|
|
|
} |
|
|
|
if (LightweightUtils.HasFlag(config, FrameRenderingConfiguration.DepthCopy)) |
|
|
|
{ |
|
|
|
CopyTexture(cmd, m_DepthRT, m_CopyDepth, m_CopyDepthMaterial); |
|
|
|
depthRT = m_CopyDepth; |
|
|
|
setRenderTarget = true; |
|
|
|
if (setRenderTarget) |
|
|
|
SetRenderTarget(cmd, m_CurrCameraColorRT, depthRT); |
|
|
|
context.ExecuteCommandBuffer(cmd); |
|
|
|
CommandBufferPool.Release(cmd); |
|
|
|
|
|
|
|
if (setRenderTarget) |
|
|
|
SetRenderTarget(cmd, m_CurrCameraColorRT, depthRT); |
|
|
|
context.ExecuteCommandBuffer(cmd); |
|
|
|
CommandBufferPool.Release(cmd); |
|
|
|
|
|
|
|
if(m_Asset.RequireOpaqueTexture) |
|
|
|
{ |
|
|
|
|
|
|
configuration |= FrameRenderingConfiguration.IntermediateTexture; |
|
|
|
} |
|
|
|
|
|
|
|
private RenderTextureDescriptor CreateRTDesc(FrameRenderingConfiguration renderingConfig, float scaler = 1.0f) |
|
|
|
{ |
|
|
|
RenderTextureDescriptor desc; |
|
|
|
if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo)) |
|
|
|
desc = XRSettings.eyeTextureDesc; |
|
|
|
else |
|
|
|
desc = new RenderTextureDescriptor(m_CurrCamera.pixelWidth, m_CurrCamera.pixelHeight); |
|
|
|
|
|
|
|
float renderScale = (m_CurrCamera.cameraType == CameraType.Game) ? m_Asset.RenderScale : 1.0f; |
|
|
|
desc.width = (int)((float)desc.width * renderScale * scaler); |
|
|
|
desc.height = (int)((float)desc.height * renderScale * scaler); |
|
|
|
return desc; |
|
|
|
} |
|
|
|
|
|
|
|
private void SetupIntermediateResources(FrameRenderingConfiguration renderingConfig, ref ScriptableRenderContext context) |
|
|
|
{ |
|
|
|
CommandBuffer cmd = CommandBufferPool.Get("Setup Intermediate Resources"); |
|
|
|
|
|
|
|
|
|
|
private void SetupIntermediateRenderTextures(CommandBuffer cmd, FrameRenderingConfiguration renderingConfig, int msaaSamples) |
|
|
|
{ |
|
|
|
RenderTextureDescriptor baseDesc; |
|
|
|
if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo)) |
|
|
|
baseDesc = XRSettings.eyeTextureDesc; |
|
|
|
else |
|
|
|
baseDesc = new RenderTextureDescriptor(m_CurrCamera.pixelWidth, m_CurrCamera.pixelHeight); |
|
|
|
|
|
|
|
float renderScale = (m_CurrCamera.cameraType == CameraType.Game) ? m_Asset.RenderScale : 1.0f; |
|
|
|
baseDesc.width = (int)((float)baseDesc.width * renderScale); |
|
|
|
baseDesc.height = (int)((float)baseDesc.height * renderScale); |
|
|
|
|
|
|
|
RenderTextureDescriptor baseDesc = CreateRTDesc(renderingConfig); |
|
|
|
|
|
|
|
if (m_RequireDepthTexture) |
|
|
|
{ |
|
|
|