|
|
|
|
|
|
using System; |
|
|
|
using UnityEngine.Rendering; |
|
|
|
using UnityEngine.Rendering.PostProcessing; |
|
|
|
using UnityEngine.XR; |
|
|
|
|
|
|
|
namespace UnityEngine.Experimental.Rendering.LightweightPipeline |
|
|
|
|
|
|
private Vector4[] m_LightAttenuations = new Vector4[kMaxVisibleLights]; |
|
|
|
private Vector4[] m_LightSpotDirections = new Vector4[kMaxVisibleLights]; |
|
|
|
|
|
|
|
private Camera m_CurrCamera = null; |
|
|
|
|
|
|
|
private int m_LightIndicesCount = 0; |
|
|
|
private ComputeBuffer m_LightIndexListBuffer; |
|
|
|
|
|
|
|
|
|
|
private static readonly ShaderPassName m_LitPassName = new ShaderPassName("LightweightForward"); |
|
|
|
private static readonly ShaderPassName m_UnlitPassName = new ShaderPassName("SRPDefaultUnlit"); |
|
|
|
|
|
|
|
private RenderTextureFormat m_ColorFormat = RenderTextureFormat.ARGB32; |
|
|
|
private PostProcessRenderContext m_PostProcessRenderContext; |
|
|
|
|
|
|
|
public LightweightPipeline(LightweightPipelineAsset asset) |
|
|
|
{ |
|
|
|
m_Asset = asset; |
|
|
|
|
|
|
m_CameraRTProperty = Shader.PropertyToID("_CameraRT"); |
|
|
|
m_ShadowMapRTID = new RenderTargetIdentifier(m_ShadowMapProperty); |
|
|
|
m_CameraRTID = new RenderTargetIdentifier(m_CameraRTProperty); |
|
|
|
m_PostProcessRenderContext = new PostProcessRenderContext(); |
|
|
|
|
|
|
|
// Let engine know we have MSAA on for cases where we support MSAA backbuffer
|
|
|
|
if (QualitySettings.antiAliasing != m_Asset.MSAASampleCount) |
|
|
|
|
|
|
|
|
|
|
foreach (Camera camera in cameras) |
|
|
|
{ |
|
|
|
m_CurrCamera = camera; |
|
|
|
|
|
|
|
if (!CullResults.GetCullingParameters(camera, stereoEnabled, out cullingParameters)) |
|
|
|
if (!CullResults.GetCullingParameters(m_CurrCamera, stereoEnabled, out cullingParameters)) |
|
|
|
cullingParameters.shadowDistance = Mathf.Min(m_ShadowSettings.maxShadowDistance, camera.farClipPlane); |
|
|
|
cullingParameters.shadowDistance = Mathf.Min(m_ShadowSettings.maxShadowDistance, m_CurrCamera.farClipPlane); |
|
|
|
CullResults.Cull(ref cullingParameters, context,ref m_CullResults); |
|
|
|
|
|
|
|
VisibleLight[] visibleLights = m_CullResults.visibleLights.ToArray(); |
|
|
|
|
|
|
lightData.shadowsRendered = RenderShadows(ref m_CullResults, ref visibleLights[lightData.shadowLightIndex], lightData.shadowLightIndex, ref context); |
|
|
|
|
|
|
|
// Setup camera matrices and RT
|
|
|
|
context.SetupCameraProperties(camera, stereoEnabled); |
|
|
|
context.SetupCameraProperties(m_CurrCamera, stereoEnabled); |
|
|
|
|
|
|
|
// Setup light and shadow shader constants
|
|
|
|
SetupShaderLightConstants(visibleLights, ref lightData, ref m_CullResults, ref context); |
|
|
|
|
|
|
if (!lightData.isSingleDirectionalLight) |
|
|
|
configuration |= RendererConfiguration.PerObjectLightIndices8; |
|
|
|
|
|
|
|
BeginForwardRendering(camera, ref context, stereoEnabled); |
|
|
|
|
|
|
|
PostProcessLayer postProcessLayer = GetCurrCameraPostProcessLayer(); |
|
|
|
bool postProcessEnabled = postProcessLayer != null && postProcessLayer.enabled; |
|
|
|
m_RenderToIntermediateTarget = postProcessEnabled || GetRenderToIntermediateTarget(); |
|
|
|
|
|
|
|
BeginForwardRendering(ref context, stereoEnabled); |
|
|
|
var litSettings = new DrawRendererSettings(m_CullResults, camera, m_LitPassName); |
|
|
|
var litSettings = new DrawRendererSettings(m_CullResults, m_CurrCamera, m_LitPassName); |
|
|
|
var unlitSettings = new DrawRendererSettings(m_CullResults, camera, m_UnlitPassName); |
|
|
|
var unlitSettings = new DrawRendererSettings(m_CullResults, m_CurrCamera, m_UnlitPassName); |
|
|
|
unlitSettings.sorting.flags = SortFlags.CommonTransparent; |
|
|
|
unlitSettings.inputFilter.SetQueuesTransparent(); |
|
|
|
|
|
|
|
|
|
|
context.DrawSkybox(camera); |
|
|
|
context.DrawSkybox(m_CurrCamera); |
|
|
|
|
|
|
|
RenderStateBlock renderStateBlock = new RenderStateBlock(); |
|
|
|
context.DrawRenderers(ref litSettings, renderStateBlock); |
|
|
|
|
|
|
|
EndForwardRendering(camera, ref context, stereoEnabled); |
|
|
|
if (postProcessEnabled) |
|
|
|
RenderPostProcess(ref context, postProcessLayer); |
|
|
|
EndForwardRendering(ref context, stereoEnabled, postProcessEnabled); |
|
|
|
|
|
|
|
// Release temporary RT
|
|
|
|
var discardRT = CommandBufferPool.Get(); |
|
|
|
discardRT.ReleaseTemporaryRT(m_ShadowMapProperty); |
|
|
|
|
|
|
return (type == LightType.Directional || type == LightType.Spot); |
|
|
|
} |
|
|
|
|
|
|
|
private void BeginForwardRendering(Camera camera, ref ScriptableRenderContext context, bool stereoEnabled) |
|
|
|
private void BeginForwardRendering(ref ScriptableRenderContext context, bool stereoEnabled) |
|
|
|
context.StartMultiEye(camera); |
|
|
|
|
|
|
|
m_RenderToIntermediateTarget = GetRenderToIntermediateTarget(camera); |
|
|
|
context.StartMultiEye(m_CurrCamera); |
|
|
|
if (camera.activeTexture == null) |
|
|
|
if (m_CurrCamera.activeTexture == null) |
|
|
|
{ |
|
|
|
m_IntermediateTextureArray = false; |
|
|
|
if (stereoEnabled) |
|
|
|
|
|
|
xrDesc.colorFormat = RenderTextureFormat.ARGB32; |
|
|
|
xrDesc.colorFormat = m_ColorFormat; |
|
|
|
xrDesc.msaaSamples = m_Asset.MSAASampleCount; |
|
|
|
|
|
|
|
m_IntermediateTextureArray = (xrDesc.dimension == TextureDimension.Tex2DArray); |
|
|
|
|
|
|
else |
|
|
|
{ |
|
|
|
cmd.GetTemporaryRT(m_CameraRTProperty, Screen.width, Screen.height, kCameraDepthBufferBits, |
|
|
|
FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, m_Asset.MSAASampleCount); |
|
|
|
FilterMode.Bilinear, m_ColorFormat, RenderTextureReadWrite.Default, m_Asset.MSAASampleCount); |
|
|
|
} |
|
|
|
|
|
|
|
if (m_IntermediateTextureArray) |
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
cmd.SetRenderTarget(new RenderTargetIdentifier(camera.activeTexture)); |
|
|
|
cmd.SetRenderTarget(new RenderTargetIdentifier(m_CurrCamera.activeTexture)); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
if (camera.clearFlags != CameraClearFlags.Nothing) |
|
|
|
if (m_CurrCamera.clearFlags != CameraClearFlags.Nothing) |
|
|
|
bool clearDepth = (camera.clearFlags != CameraClearFlags.Nothing); |
|
|
|
bool clearColor = (camera.clearFlags == CameraClearFlags.Color); |
|
|
|
cmd.ClearRenderTarget(clearDepth, clearColor, camera.backgroundColor); |
|
|
|
|
|
|
|
bool clearDepth = (m_CurrCamera.clearFlags != CameraClearFlags.Nothing); |
|
|
|
bool clearColor = (m_CurrCamera.clearFlags == CameraClearFlags.Color); |
|
|
|
cmd.ClearRenderTarget(clearDepth, clearColor, m_CurrCamera.backgroundColor); |
|
|
|
} |
|
|
|
|
|
|
|
context.ExecuteCommandBuffer(cmd); |
|
|
|
|
|
|
private void EndForwardRendering(Camera camera, ref ScriptableRenderContext context, bool stereoEnabled) |
|
|
|
private void EndForwardRendering(ref ScriptableRenderContext context, bool stereoEnabled, bool postProcessing) |
|
|
|
if (m_RenderToIntermediateTarget) |
|
|
|
|
|
|
|
if (m_RenderToIntermediateTarget || postProcessing) |
|
|
|
{ |
|
|
|
var cmd = CommandBufferPool.Get("Blit"); |
|
|
|
if (m_IntermediateTextureArray) |
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
// If PostProcessing is enabled, it is already blitted to CameraTarget.
|
|
|
|
else if (!postProcessing) |
|
|
|
if (camera.cameraType == CameraType.SceneView) |
|
|
|
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); |
|
|
|
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); |
|
|
|
context.ExecuteCommandBuffer(cmd); |
|
|
|
CommandBufferPool.Release(cmd); |
|
|
|
} |
|
|
|
|
|
|
context.StopMultiEye(camera); |
|
|
|
context.StereoEndRender(camera); |
|
|
|
context.StopMultiEye(m_CurrCamera); |
|
|
|
context.StereoEndRender(m_CurrCamera); |
|
|
|
private bool GetRenderToIntermediateTarget(Camera camera) |
|
|
|
private void RenderPostProcess(ref ScriptableRenderContext renderContext, PostProcessLayer postProcessLayer) |
|
|
|
bool allowMSAA = camera.allowMSAA && m_Asset.MSAASampleCount > 1 && !PlatformSupportsMSAABackBuffer(); |
|
|
|
if (camera.cameraType == CameraType.SceneView || allowMSAA || camera.activeTexture != null) |
|
|
|
var postProcessCommand = CommandBufferPool.Get("Post Processing"); |
|
|
|
m_PostProcessRenderContext.Reset(); |
|
|
|
m_PostProcessRenderContext.camera = m_CurrCamera; |
|
|
|
m_PostProcessRenderContext.source = BuiltinRenderTextureType.CurrentActive; |
|
|
|
m_PostProcessRenderContext.sourceFormat = m_ColorFormat; |
|
|
|
m_PostProcessRenderContext.destination = BuiltinRenderTextureType.CameraTarget; |
|
|
|
m_PostProcessRenderContext.command = postProcessCommand; |
|
|
|
m_PostProcessRenderContext.flip = true; |
|
|
|
|
|
|
|
postProcessLayer.Render(m_PostProcessRenderContext); |
|
|
|
renderContext.ExecuteCommandBuffer(postProcessCommand); |
|
|
|
CommandBufferPool.Release(postProcessCommand); |
|
|
|
} |
|
|
|
|
|
|
|
private bool GetRenderToIntermediateTarget() |
|
|
|
{ |
|
|
|
bool allowMSAA = m_CurrCamera.allowMSAA && m_Asset.MSAASampleCount > 1 && !PlatformSupportsMSAABackBuffer(); |
|
|
|
if (m_CurrCamera.cameraType == CameraType.SceneView || allowMSAA || m_CurrCamera.activeTexture != null) |
|
|
|
} |
|
|
|
|
|
|
|
private PostProcessLayer GetCurrCameraPostProcessLayer() |
|
|
|
{ |
|
|
|
return m_CurrCamera.GetComponent<PostProcessLayer>(); |
|
|
|
} |
|
|
|
|
|
|
|
private bool PlatformSupportsMSAABackBuffer() |
|
|
|