|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public struct ActiveRenderTarget |
|
|
|
{ |
|
|
|
public RenderTargetIdentifier colorRT; |
|
|
|
public RenderTargetIdentifier depthRT; |
|
|
|
} |
|
|
|
|
|
|
|
public struct ShadowSliceData |
|
|
|
{ |
|
|
|
public Matrix4x4 shadowTransform; |
|
|
|
|
|
|
private int m_ShadowMapTexture; |
|
|
|
private int m_CameraColorTexture; |
|
|
|
private int m_CameraDepthTexture; |
|
|
|
private int m_CameraCopyDepthTexture; |
|
|
|
private ActiveRenderTarget m_ActiveRenderTargets; |
|
|
|
private RenderTargetIdentifier m_CameraCopyDepthRT; |
|
|
|
|
|
|
|
private bool m_RenderToIntermediateTarget = false; |
|
|
|
private bool m_IntermediateTextureArray = false; |
|
|
|
|
|
|
|
|
|
|
private CameraComparer m_CameraComparer = new CameraComparer(); |
|
|
|
|
|
|
|
private Mesh m_BlitQuad = null; |
|
|
|
private Material m_BlitMaterial = null; |
|
|
|
private Mesh m_BlitQuad; |
|
|
|
private Material m_BlitMaterial; |
|
|
|
private Material m_CopyDepthMaterial; |
|
|
|
|
|
|
|
private CopyTextureSupport m_CopyTextureSupport; |
|
|
|
|
|
|
|
public LightweightPipeline(LightweightPipelineAsset asset) |
|
|
|
{ |
|
|
|
|
|
|
PerCameraBuffer._AdditionalLightSpotDir = Shader.PropertyToID("_AdditionalLightSpotDir"); |
|
|
|
|
|
|
|
m_ShadowMapTexture = Shader.PropertyToID("_ShadowMap"); |
|
|
|
m_CameraColorTexture = Shader.PropertyToID("_CameraRT"); |
|
|
|
m_CameraColorTexture = Shader.PropertyToID("_CameraColorTexture"); |
|
|
|
m_CameraCopyDepthTexture = Shader.PropertyToID("_CameraCopyDepthTexture"); |
|
|
|
m_CameraCopyDepthRT = new RenderTargetIdentifier(m_CameraCopyDepthTexture); |
|
|
|
|
|
|
|
m_CopyTextureSupport = SystemInfo.copyTextureSupport; |
|
|
|
|
|
|
|
// Let engine know we have MSAA on for cases where we support MSAA backbuffer
|
|
|
|
if (QualitySettings.antiAliasing != m_Asset.MSAASampleCount) |
|
|
|
|
|
|
{ |
|
|
|
hideFlags = HideFlags.HideAndDontSave |
|
|
|
}; |
|
|
|
|
|
|
|
m_CopyDepthMaterial = new Material(m_Asset.CopyDepthShader) |
|
|
|
{ |
|
|
|
hideFlags = HideFlags.HideAndDontSave |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
public override void Dispose() |
|
|
|
|
|
|
|
|
|
|
LightData lightData; |
|
|
|
InitializeLightData(visibleLights, out lightData); |
|
|
|
|
|
|
|
|
|
|
|
ShadowPass(visibleLights, ref context, ref lightData); |
|
|
|
ForwardPass(visibleLights, ref context, ref lightData, stereoEnabled); |
|
|
|
|
|
|
|
|
|
|
cmd.ReleaseTemporaryRT(m_CameraColorTexture); |
|
|
|
cmd.ReleaseTemporaryRT(m_CameraDepthTexture); |
|
|
|
cmd.ReleaseTemporaryRT(m_CameraCopyDepthTexture); |
|
|
|
context.ExecuteCommandBuffer(cmd); |
|
|
|
CommandBufferPool.Release(cmd); |
|
|
|
|
|
|
|
|
|
|
private void ForwardPass(VisibleLight[] visibleLights, ref ScriptableRenderContext context, ref LightData lightData, bool stereoEnabled) |
|
|
|
{ |
|
|
|
RenderingConfiguration renderingConfig = SetupRendering(); |
|
|
|
|
|
|
|
SetupIntermediateResources(renderingConfig, ref context); |
|
|
|
|
|
|
|
CommandBuffer cmd = CommandBufferPool.Get("SetupShaderConstants"); |
|
|
|
SetupShaderLightConstants(cmd, visibleLights, ref lightData, ref m_CullResults, ref context); |
|
|
|
|
|
|
|
|
|
|
private void AfterOpaque(ref ScriptableRenderContext context, RenderingConfiguration settings) |
|
|
|
{ |
|
|
|
bool requiredDepth = LightweightUtils.HasFlag(settings, RenderingConfiguration.RequireDepth); |
|
|
|
bool postProcessEnabled = LightweightUtils.HasFlag(settings, RenderingConfiguration.PostProcess); |
|
|
|
|
|
|
|
m_ActiveRenderTargets.depthRT = BuiltinRenderTextureType.None; |
|
|
|
|
|
|
|
if (!postProcessEnabled && !requiredDepth) |
|
|
|
if (!LightweightUtils.HasFlag(settings, RenderingConfiguration.RequireDepth)) |
|
|
|
// If require depth was on we need to reset render target with colorRT only.
|
|
|
|
if (requiredDepth) |
|
|
|
SetupRenderTargets(cmd); |
|
|
|
// When soft particles are enabled we have to copy depth to another RT so we can read and write to depth
|
|
|
|
if (m_Asset.SupportsSoftParticles) |
|
|
|
{ |
|
|
|
RenderTargetIdentifier colorRT = (m_CurrCamera.targetTexture != null) ? BuiltinRenderTextureType.CameraTarget : m_CameraColorRT; |
|
|
|
CopyTexture(cmd, m_CameraDepthRT, m_CameraCopyDepthTexture); |
|
|
|
SetupRenderTargets(cmd, colorRT, m_CameraCopyDepthRT); |
|
|
|
} |
|
|
|
if (postProcessEnabled) |
|
|
|
// Only takes effect if custom BeforeTransparent PostProcessing effects are active
|
|
|
|
if (LightweightUtils.HasFlag(settings, RenderingConfiguration.PostProcess)) |
|
|
|
|
|
|
|
context.ExecuteCommandBuffer(cmd); |
|
|
|
CommandBufferPool.Release(cmd); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
private RenderingConfiguration SetupRendering() |
|
|
|
{ |
|
|
|
bool intermediateTexture = (m_CurrCamera.targetTexture != null || m_Asset.RenderScale < 1.0f || m_CurrCamera.allowHDR); |
|
|
|
if (XRSettings.eyeTextureDesc.dimension == TextureDimension.Tex2DArray) |
|
|
|
renderingConfig |= RenderingConfiguration.IntermediateTextureArray; |
|
|
|
if (XRSettings.enabled && XRSettings.eyeTextureDesc.dimension == TextureDimension.Tex2DArray) |
|
|
|
m_IntermediateTextureArray = true; |
|
|
|
else |
|
|
|
m_IntermediateTextureArray = false; |
|
|
|
bool intermediateTexture = m_CurrCamera.targetTexture != null || m_CurrCamera.cameraType == CameraType.SceneView || |
|
|
|
m_Asset.RenderScale < 1.0f || m_CurrCamera.allowHDR; |
|
|
|
|
|
|
|
m_ColorFormat = m_CurrCamera.allowHDR ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32; |
|
|
|
|
|
|
|
m_CameraPostProcessLayer = m_CurrCamera.GetComponent<PostProcessLayer>(); |
|
|
|
|
|
|
else |
|
|
|
renderingConfig |= RenderingConfiguration.DefaultViewport; |
|
|
|
|
|
|
|
if (intermediateTexture && !LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.IntermediateTextureArray)) |
|
|
|
if (intermediateTexture) |
|
|
|
private void SetupIntermediateResources(RenderingConfiguration renderingConfig, ref ScriptableRenderContext context) |
|
|
|
{ |
|
|
|
CommandBuffer cmd = CommandBufferPool.Get("Setup Intermediate Resources"); |
|
|
|
|
|
|
|
float renderScale = (m_CurrCamera.cameraType == CameraType.Game) ? m_Asset.RenderScale : 1.0f; |
|
|
|
int rtWidth = (int)((float)m_CurrCamera.pixelWidth * renderScale); |
|
|
|
int rtHeight = (int)((float)m_CurrCamera.pixelHeight * renderScale); |
|
|
|
int msaaSamples = (LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.Msaa)) ? m_Asset.MSAASampleCount : 1; |
|
|
|
|
|
|
|
if (LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.IntermediateTexture)) |
|
|
|
{ |
|
|
|
if (LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.Stereo)) |
|
|
|
{ |
|
|
|
RenderTextureDescriptor rtDesc = new RenderTextureDescriptor(); |
|
|
|
rtDesc = XRSettings.eyeTextureDesc; |
|
|
|
rtDesc.colorFormat = m_ColorFormat; |
|
|
|
rtDesc.msaaSamples = msaaSamples; |
|
|
|
|
|
|
|
cmd.GetTemporaryRT(m_CameraColorTexture, rtDesc, FilterMode.Bilinear); |
|
|
|
} |
|
|
|
else if (m_CurrCamera.targetTexture == null) |
|
|
|
{ |
|
|
|
cmd.GetTemporaryRT(m_CameraColorTexture, rtWidth, rtHeight, kCameraDepthBufferBits, |
|
|
|
FilterMode.Bilinear, m_ColorFormat, RenderTextureReadWrite.Default, msaaSamples); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.RequireDepth)) |
|
|
|
{ |
|
|
|
cmd.GetTemporaryRT(m_CameraDepthTexture, rtWidth, rtHeight, kCameraDepthBufferBits, FilterMode.Bilinear, RenderTextureFormat.Depth); |
|
|
|
if (m_Asset.SupportsSoftParticles) |
|
|
|
cmd.GetTemporaryRT(m_CameraCopyDepthTexture, rtWidth, rtHeight, kCameraDepthBufferBits, FilterMode.Bilinear, RenderTextureFormat.Depth); |
|
|
|
} |
|
|
|
|
|
|
|
context.ExecuteCommandBuffer(cmd); |
|
|
|
CommandBufferPool.Release(cmd); |
|
|
|
} |
|
|
|
|
|
|
|
private void InitializeLightData(VisibleLight[] visibleLights, out LightData lightData) |
|
|
|
{ |
|
|
|
int visibleLightsCount = visibleLights.Length; |
|
|
|
|
|
|
|
|
|
|
private void BeginForwardRendering(ref ScriptableRenderContext context, RenderingConfiguration renderingConfig) |
|
|
|
{ |
|
|
|
m_ActiveRenderTargets.colorRT = BuiltinRenderTextureType.CameraTarget; |
|
|
|
m_ActiveRenderTargets.depthRT = BuiltinRenderTextureType.None; |
|
|
|
RenderTargetIdentifier colorRT = BuiltinRenderTextureType.CameraTarget; |
|
|
|
RenderTargetIdentifier depthRT = BuiltinRenderTextureType.None; |
|
|
|
// When postprocess is enabled, msaa is forced to be disabled due to lack of depth resolve.
|
|
|
|
int msaaSamples = (LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.Msaa)) ? m_Asset.MSAASampleCount : 1; |
|
|
|
if (LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.Stereo)) |
|
|
|
context.StartMultiEye(m_CurrCamera); |
|
|
|
var cmd = CommandBufferPool.Get("SetCameraRenderTarget"); |
|
|
|
CommandBuffer cmd = CommandBufferPool.Get("SetCameraRenderTarget"); |
|
|
|
float renderScale = (m_CurrCamera.cameraType == CameraType.Game) ? m_Asset.RenderScale : 1.0f; |
|
|
|
int rtWidth = (int)((float)m_CurrCamera.pixelWidth * renderScale); |
|
|
|
int rtHeight = (int)((float)m_CurrCamera.pixelHeight * renderScale); |
|
|
|
|
|
|
|
if (m_CurrCamera.targetTexture == null || m_CurrCamera.cameraType == CameraType.SceneView) |
|
|
|
{ |
|
|
|
RenderTextureDescriptor rtDesc = new RenderTextureDescriptor(); |
|
|
|
if (LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.Stereo)) |
|
|
|
{ |
|
|
|
context.StartMultiEye(m_CurrCamera); |
|
|
|
rtDesc = XRSettings.eyeTextureDesc; |
|
|
|
rtDesc.colorFormat = m_ColorFormat; |
|
|
|
rtDesc.msaaSamples = msaaSamples; |
|
|
|
|
|
|
|
cmd.GetTemporaryRT(m_CameraColorTexture, rtDesc, FilterMode.Bilinear); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
cmd.GetTemporaryRT(m_CameraColorTexture, rtWidth, rtHeight, kCameraDepthBufferBits, |
|
|
|
FilterMode.Bilinear, m_ColorFormat, RenderTextureReadWrite.Default, msaaSamples); |
|
|
|
} |
|
|
|
|
|
|
|
m_ActiveRenderTargets.colorRT = m_CameraColorRT; |
|
|
|
} |
|
|
|
|
|
|
|
if (m_CurrCamera.targetTexture == null) |
|
|
|
colorRT = m_CameraColorRT; |
|
|
|
|
|
|
|
{ |
|
|
|
cmd.GetTemporaryRT(m_CameraDepthTexture, rtWidth, rtHeight, kCameraDepthBufferBits, FilterMode.Bilinear, RenderTextureFormat.Depth); |
|
|
|
m_ActiveRenderTargets.depthRT = m_CameraDepthRT; |
|
|
|
} |
|
|
|
depthRT = m_CameraDepthRT; |
|
|
|
SetupRenderTargets(cmd); |
|
|
|
SetupRenderTargets(cmd, colorRT, depthRT); |
|
|
|
|
|
|
|
// Clear RenderTarget to avoid tile initialization on mobile GPUs
|
|
|
|
// https://community.arm.com/graphics/b/blog/posts/mali-performance-2-how-to-correctly-handle-framebuffers
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
var cmd = CommandBufferPool.Get("Blit"); |
|
|
|
if (LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.IntermediateTextureArray)) |
|
|
|
if (m_IntermediateTextureArray) |
|
|
|
cmd.Blit(m_ActiveRenderTargets.colorRT, BuiltinRenderTextureType.CurrentActive); |
|
|
|
cmd.Blit(m_CameraColorRT, BuiltinRenderTextureType.CurrentActive); |
|
|
|
// If PostProcessing is enabled, it is already blitted to CameraTarget.
|
|
|
|
// If PostProcessing is enabled, it is already blit to CameraTarget.
|
|
|
|
Blit(cmd, renderingConfig, m_ActiveRenderTargets.colorRT, BuiltinRenderTextureType.CameraTarget); |
|
|
|
Blit(cmd, renderingConfig, BuiltinRenderTextureType.CurrentActive, BuiltinRenderTextureType.CameraTarget); |
|
|
|
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); |
|
|
|
SetupRenderTargets(cmd, BuiltinRenderTextureType.CameraTarget, BuiltinRenderTextureType.None); |
|
|
|
|
|
|
|
context.ExecuteCommandBuffer(cmd); |
|
|
|
CommandBufferPool.Release(cmd); |
|
|
|
|
|
|
return settings; |
|
|
|
} |
|
|
|
|
|
|
|
private void SetupRenderTargets(CommandBuffer cmd) |
|
|
|
private void SetupRenderTargets(CommandBuffer cmd, RenderTargetIdentifier colorRT, RenderTargetIdentifier depthRT) |
|
|
|
if (m_ActiveRenderTargets.depthRT != BuiltinRenderTextureType.None) |
|
|
|
cmd.SetRenderTarget(m_ActiveRenderTargets.colorRT, m_ActiveRenderTargets.depthRT, 0, CubemapFace.Unknown, depthSlice); |
|
|
|
if (depthRT != BuiltinRenderTextureType.None) |
|
|
|
cmd.SetRenderTarget(colorRT, depthRT, 0, CubemapFace.Unknown, depthSlice); |
|
|
|
cmd.SetRenderTarget(m_ActiveRenderTargets.colorRT, 0, CubemapFace.Unknown, depthSlice); |
|
|
|
cmd.SetRenderTarget(colorRT, 0, CubemapFace.Unknown, depthSlice); |
|
|
|
} |
|
|
|
|
|
|
|
private void RenderPostProcess(CommandBuffer cmd, bool opaqueOnly) |
|
|
|
|
|
|
cmd.SetViewport(m_CurrCamera.pixelRect); |
|
|
|
cmd.DrawMesh(m_BlitQuad, Matrix4x4.identity, m_BlitMaterial); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void CopyTexture(CommandBuffer cmd, RenderTargetIdentifier sourceRT, RenderTargetIdentifier destRT) |
|
|
|
{ |
|
|
|
if (m_CopyTextureSupport != CopyTextureSupport.None) |
|
|
|
cmd.CopyTexture(m_CameraDepthRT, m_CameraCopyDepthRT); |
|
|
|
else |
|
|
|
cmd.Blit(m_CameraDepthRT, m_CameraCopyDepthRT, m_CopyDepthMaterial); |
|
|
|
} |
|
|
|
} |
|
|
|
} |