You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
297 lines
14 KiB
297 lines
14 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.Rendering.RenderGraphModule;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
public partial class HDRenderPipeline
|
|
{
|
|
// Internal targets.
|
|
private RTHandle m_LineColorBufferRT;
|
|
private RTHandle m_LineDepthBufferRT;
|
|
private RTHandle m_LineMVBufferRT;
|
|
|
|
private TextureHandle m_LineColorBuffer;
|
|
private TextureHandle m_LineDepthBuffer;
|
|
private TextureHandle m_LineMVBuffer;
|
|
|
|
// Compute Utility
|
|
private GPUSort m_Sorter;
|
|
private GPUPrefixSum m_PrefixSum;
|
|
|
|
// Misc.
|
|
private Material m_LineCompositePass;
|
|
private int m_LineCompositePassAllIndex;
|
|
private int m_LineCompositePassColorIndex;
|
|
private int m_LineCompositePassDepthMovecIndex;
|
|
private static bool s_SupportLineRendering;
|
|
|
|
void InitializeLineRendering()
|
|
{
|
|
s_SupportLineRendering = asset.currentPlatformRenderPipelineSettings.supportHighQualityLineRendering;
|
|
|
|
if (!s_SupportLineRendering)
|
|
return;
|
|
|
|
m_LineCompositePass = CoreUtils.CreateEngineMaterial(runtimeShaders.lineCompositePS);
|
|
m_LineCompositePassAllIndex = m_LineCompositePass.FindPass("CompositeAll");
|
|
m_LineCompositePassColorIndex = m_LineCompositePass.FindPass("CompositeColorOnly");
|
|
m_LineCompositePassDepthMovecIndex = m_LineCompositePass.FindPass("CompositeDepthMovecOnly");
|
|
|
|
m_PrefixSum = new GPUPrefixSum(new GPUPrefixSum.SystemResources
|
|
{
|
|
computeAsset = runtimeShaders.gpuPrefixSumCS
|
|
});
|
|
|
|
m_Sorter = new GPUSort(new GPUSort.SystemResources
|
|
{
|
|
computeAsset = runtimeShaders.gpuSortCS
|
|
});
|
|
|
|
LineRendering.Instance.Initialize(new LineRendering.SystemResources
|
|
{
|
|
// Due to a lack of a "Core Resource" concept, we pass along the kernel assets as initialization parameters.
|
|
stagePrepareCS = runtimeShaders.lineStagePrepareCS,
|
|
stageSetupSegmentCS = runtimeShaders.lineStageSetupSegmentCS,
|
|
stageShadingSetupCS = runtimeShaders.lineStageShadingSetupCS,
|
|
stageRasterBinCS = runtimeShaders.lineStageRasterBinCS,
|
|
stageWorkQueue = runtimeShaders.lineStageWorkQueueCS,
|
|
stageRasterFineCS = runtimeShaders.lineStageRasterFineCS,
|
|
|
|
// Misc. Compute Utility
|
|
gpuSort = m_Sorter,
|
|
gpuPrefixSum = m_PrefixSum
|
|
});
|
|
|
|
m_LineColorBufferRT = RTHandles.Alloc(Vector2.one, format:GraphicsFormat.R32G32B32A32_SFloat, slices: TextureXR.slices, dimension: TextureXR.dimension,
|
|
useMipMap: false, autoGenerateMips: false, enableRandomWrite: true, useDynamicScale: true, name: "LineColorBuffer");
|
|
m_LineDepthBufferRT = RTHandles.Alloc(Vector2.one, format: GraphicsFormat.R32_SFloat, slices: TextureXR.slices, dimension: TextureXR.dimension,
|
|
useMipMap: false, autoGenerateMips: false, enableRandomWrite: true, useDynamicScale: true, name: "LineDepthBuffer");
|
|
m_LineMVBufferRT = RTHandles.Alloc(Vector2.one, format: Builtin.GetMotionVectorFormat(), slices: TextureXR.slices, dimension: TextureXR.dimension,
|
|
useMipMap: false, autoGenerateMips: false, enableRandomWrite: true, useDynamicScale: true, name: "LineMVBuffer");
|
|
}
|
|
|
|
void CleanupLineRendering()
|
|
{
|
|
if (!s_SupportLineRendering)
|
|
return;
|
|
|
|
CoreUtils.Destroy(m_LineCompositePass);
|
|
|
|
m_LineColorBufferRT?.Release();
|
|
m_LineDepthBufferRT?.Release();
|
|
m_LineMVBufferRT?.Release();
|
|
|
|
m_LineColorBuffer = TextureHandle.nullHandle;
|
|
m_LineDepthBuffer = TextureHandle.nullHandle;
|
|
m_LineMVBuffer = TextureHandle.nullHandle;
|
|
|
|
LineRendering.Instance.Cleanup();
|
|
}
|
|
|
|
void ImportLineRenderingTargetsToRenderGraphIfNeeded()
|
|
{
|
|
if (!m_LineColorBuffer.IsValid())
|
|
m_LineColorBuffer = m_RenderGraph.ImportTexture(m_LineColorBufferRT);
|
|
|
|
if (!m_LineDepthBuffer.IsValid())
|
|
m_LineDepthBuffer = m_RenderGraph.ImportTexture(m_LineDepthBufferRT);
|
|
|
|
if (!m_LineMVBuffer.IsValid())
|
|
m_LineMVBuffer = m_RenderGraph.ImportTexture(m_LineMVBufferRT);
|
|
}
|
|
|
|
class LineRendererSetupData
|
|
{
|
|
public BufferHandle lightListCluster;
|
|
public BufferHandle perVoxelOffset;
|
|
public BufferHandle perTileLogBaseTweak;
|
|
|
|
public TextureHandle targetColor;
|
|
public TextureHandle targetDepth;
|
|
public TextureHandle targetMV;
|
|
}
|
|
|
|
class LineRendererCompositeData
|
|
{
|
|
public Material compositePass;
|
|
|
|
public TextureHandle mainTargetColor;
|
|
public TextureHandle mainTargetDepth;
|
|
public TextureHandle mainTargetMV;
|
|
|
|
public TextureHandle lineTargetColor;
|
|
public TextureHandle lineTargetDepth;
|
|
public TextureHandle lineTargetMV;
|
|
|
|
public float writeDepthAndMovecAlphaTreshold;
|
|
}
|
|
|
|
internal static bool LineRenderingIsEnabled(HDCamera hdCamera, out HighQualityLineRenderingVolumeComponent settings)
|
|
{
|
|
settings = hdCamera.volumeStack.GetComponent<HighQualityLineRenderingVolumeComponent>();
|
|
|
|
if (!s_SupportLineRendering)
|
|
return false;
|
|
|
|
if (!settings.enable.value)
|
|
return false;
|
|
|
|
if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.HighQualityLineRendering))
|
|
return false;
|
|
|
|
#if UNITY_EDITOR
|
|
// TODO: This is a temporary fix to disable hq line rendering on preview cameras until the following error is fixed:
|
|
// PPtr cast failed when dereferencing! Casting from Texture2DArray to RenderTexture!
|
|
if (hdCamera.camera.cameraType == CameraType.Preview)
|
|
return false;
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
void RenderLines(RenderGraph renderGraph, TextureHandle depthPrepassTexture, HDCamera hdCamera, BuildGPULightListOutput lightLists)
|
|
{
|
|
if (!LineRenderingIsEnabled(hdCamera, out var settings))
|
|
return;
|
|
|
|
ImportLineRenderingTargetsToRenderGraphIfNeeded();
|
|
|
|
// Here we need to bind some SRP-specific buffers and clear the internal targets.
|
|
using (var builder = renderGraph.AddUnsafePass<LineRendererSetupData>("Setup Line Rendering", out var passData, ProfilingSampler.Get(HDProfileId.LineRenderingSetup)))
|
|
{
|
|
passData.lightListCluster = lightLists.perVoxelLightLists;
|
|
builder.UseBuffer(passData.lightListCluster, AccessFlags.Read);
|
|
passData.perVoxelOffset = lightLists.perVoxelOffset;
|
|
builder.UseBuffer(passData.perVoxelOffset, AccessFlags.Read);
|
|
passData.perTileLogBaseTweak = lightLists.perTileLogBaseTweak;
|
|
builder.UseBuffer(passData.perTileLogBaseTweak, AccessFlags.Read);
|
|
|
|
passData.targetColor = m_LineColorBuffer;
|
|
builder.UseTexture(passData.targetColor, AccessFlags.Write);
|
|
passData.targetDepth = m_LineDepthBuffer;
|
|
builder.UseTexture(passData.targetDepth, AccessFlags.Write);
|
|
passData.targetMV = m_LineMVBuffer;
|
|
builder.UseTexture(passData.targetMV, AccessFlags.Write);
|
|
|
|
builder.SetRenderFunc((LineRendererSetupData data, UnsafeGraphContext ctx) =>
|
|
{
|
|
var natCmd = CommandBufferHelpers.GetNativeCommandBuffer(ctx.cmd);
|
|
|
|
// Bind the light lists (required for the light loop to work with offscreen shading).
|
|
{
|
|
natCmd.SetGlobalBuffer(HDShaderIDs.g_vLightListCluster, data.lightListCluster);
|
|
|
|
// Next two are only for cluster rendering. PerTileLogBaseTweak is only when using depth buffer so can be invalid as well.
|
|
if (data.perVoxelOffset.IsValid())
|
|
natCmd.SetGlobalBuffer(HDShaderIDs.g_vLayeredOffsetsBuffer, data.perVoxelOffset);
|
|
if (data.perTileLogBaseTweak.IsValid())
|
|
natCmd.SetGlobalBuffer(HDShaderIDs.g_logBaseBuffer, data.perTileLogBaseTweak);
|
|
|
|
CoreUtils.SetKeyword(natCmd, "USE_FPTL_LIGHTLIST", false);
|
|
CoreUtils.SetKeyword(natCmd, "USE_CLUSTERED_LIGHTLIST", true);
|
|
}
|
|
|
|
// Clear the internal targets.
|
|
CoreUtils.SetRenderTarget(natCmd, data.targetColor, ClearFlag.Color, Color.black);
|
|
CoreUtils.SetRenderTarget(natCmd, data.targetDepth, ClearFlag.Color, Color.black);
|
|
CoreUtils.SetRenderTarget(natCmd, data.targetMV, ClearFlag.Color, Color.clear);
|
|
});
|
|
}
|
|
|
|
var systemSettings = new LineRendering.SystemSettings
|
|
{
|
|
clusterCount = settings.clusterCount.value,
|
|
compositionMode = settings.compositionMode.value,
|
|
sortingQuality = settings.sortingQuality.value,
|
|
tileOpacityThreshold = settings.tileOpacityThreshold.value,
|
|
executeAsync = hdCamera.frameSettings.HighQualityLinesRunsAsync(),
|
|
memoryBudget = asset.currentPlatformRenderPipelineSettings.highQualityLineRenderingMemoryBudget,
|
|
|
|
// Patch in the debug mode to request from the line renderer (if any).
|
|
debugMode = debugDisplaySettings.data.fullScreenDebugMode != FullScreenDebugMode.HighQualityLines ? -1 : (int)debugDisplaySettings.data.lineRenderingDebugMode
|
|
};
|
|
|
|
var targets = new LineRendering.RenderTargets
|
|
{
|
|
color = m_LineColorBuffer,
|
|
depth = m_LineDepthBuffer,
|
|
motion = m_LineMVBuffer
|
|
};
|
|
|
|
LineRendering.Instance.Draw(new LineRendering.Arguments
|
|
{
|
|
camera = hdCamera.camera,
|
|
cameraPosition = hdCamera.camera.transform.position,
|
|
cameraFrustum = hdCamera.frustum,
|
|
renderGraph = renderGraph,
|
|
depthTexture = depthPrepassTexture,
|
|
settings = systemSettings,
|
|
shadingAtlas = LineRendering.Instance.GetShadingAtlas(renderGraph, hdCamera.camera),
|
|
viewport = new Vector2(hdCamera.actualWidth, hdCamera.actualHeight),
|
|
matrixIVP = hdCamera.mainViewConstants.nonJitteredViewProjMatrix.inverse,
|
|
targets = targets,
|
|
viewCount = hdCamera.viewCount
|
|
});
|
|
|
|
PushFullScreenDebugTexture(renderGraph, m_LineColorBuffer, FullScreenDebugMode.HighQualityLines);
|
|
}
|
|
|
|
void ComposeLines(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle colorBuffer, TextureHandle depthBuffer, TextureHandle motionVectorBuffer, int compositionMode)
|
|
{
|
|
if (!LineRenderingIsEnabled(hdCamera, out var settings))
|
|
return;
|
|
|
|
if (compositionMode != -1 && compositionMode != (int)settings.compositionMode.value)
|
|
return;
|
|
|
|
ImportLineRenderingTargetsToRenderGraphIfNeeded();
|
|
|
|
using (var builder = renderGraph.AddUnsafePass<LineRendererCompositeData>("Composite Hair", out var passData, ProfilingSampler.Get(HDProfileId.LineRenderingComposite)))
|
|
{
|
|
passData.compositePass = m_LineCompositePass;
|
|
|
|
passData.mainTargetColor = colorBuffer;
|
|
builder.SetRenderAttachment(colorBuffer, 0);
|
|
passData.mainTargetDepth = depthBuffer;
|
|
builder.SetRenderAttachmentDepth(depthBuffer, AccessFlags.ReadWrite);
|
|
|
|
if (motionVectorBuffer.IsValid() && hdCamera.frameSettings.IsEnabled(FrameSettingsField.MotionVectors))
|
|
{
|
|
// The motion vectors may be invalid in case of material debug view. So don't bind it in that case.
|
|
passData.mainTargetMV = motionVectorBuffer;
|
|
builder.SetRenderAttachment(motionVectorBuffer, 1);
|
|
}
|
|
else
|
|
passData.mainTargetMV = TextureHandle.nullHandle;
|
|
|
|
passData.lineTargetColor = m_LineColorBuffer;
|
|
builder.UseTexture(passData.lineTargetColor, AccessFlags.Read);
|
|
passData.lineTargetDepth = m_LineDepthBuffer;
|
|
builder.UseTexture(passData.lineTargetDepth, AccessFlags.Read);
|
|
passData.lineTargetMV = m_LineMVBuffer;
|
|
builder.UseTexture(passData.lineTargetMV, AccessFlags.Read);
|
|
passData.writeDepthAndMovecAlphaTreshold = settings.writeDepthAlphaThreshold.value;
|
|
|
|
builder.SetRenderFunc((LineRendererCompositeData passData, UnsafeGraphContext ctx) =>
|
|
{
|
|
var natCmd = CommandBufferHelpers.GetNativeCommandBuffer(ctx.cmd);
|
|
passData.compositePass.SetTexture(HDShaderIDs._LineColorTexture, passData.lineTargetColor);
|
|
passData.compositePass.SetTexture(HDShaderIDs._LineDepthTexture, passData.lineTargetDepth);
|
|
passData.compositePass.SetTexture(HDShaderIDs._LineMotionTexture, passData.lineTargetMV);
|
|
passData.compositePass.SetFloat(HDShaderIDs._LineAlphaDepthWriteThreshold, passData.writeDepthAndMovecAlphaTreshold );
|
|
if (passData.writeDepthAndMovecAlphaTreshold > 0)
|
|
{
|
|
HDUtils.DrawFullScreen(natCmd, passData.compositePass, new RenderTargetIdentifier[] { passData.mainTargetColor}, passData.mainTargetDepth, null, m_LineCompositePassColorIndex); //color composite
|
|
HDUtils.DrawFullScreen(natCmd, passData.compositePass, new RenderTargetIdentifier[] { passData.mainTargetMV }, passData.mainTargetDepth, null, m_LineCompositePassDepthMovecIndex); //depth & movec composite
|
|
}
|
|
else
|
|
{
|
|
HDUtils.DrawFullScreen(natCmd, passData.compositePass, new RenderTargetIdentifier[] { passData.mainTargetColor, passData.mainTargetMV }, passData.mainTargetDepth, null, m_LineCompositePassAllIndex); //composite all
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|