浏览代码

wip buffered RTHandle system for cameras

/main
Frédéric Vauchelles 6 年前
当前提交
70ed0378
共有 10 个文件被更改,包括 233 次插入57 次删除
  1. 25
      ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandleSystem.cs
  2. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDAdditionalCameraData.cs
  3. 34
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  4. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDCustomSamplerId.cs
  5. 48
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  6. 80
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/BufferPyramid.cs
  7. 53
      ScriptableRenderPipeline/Core/CoreRP/Textures/BufferedRTHandleSystem.cs
  8. 11
      ScriptableRenderPipeline/Core/CoreRP/Textures/BufferedRTHandleSystem.cs.meta
  9. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCameraFrameHistoryType.cs
  10. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCameraFrameHistoryType.cs.meta

25
ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandleSystem.cs


using System.Collections.Generic;
using System;
using System.Collections.Generic;
using UnityEngine.Assertions;
using UnityEngine.Rendering;

public partial class RTHandleSystem
public partial class RTHandleSystem : IDisposable
{
internal enum RTCategory
{

public int maxWidth { get { return GetMaxWidth(m_ScaledRTCurrentCategory); } }
public int maxHeight { get { return GetMaxHeight(m_ScaledRTCurrentCategory); } }
internal RTHandleSystem()
public RTHandleSystem()
{
m_AutoSizedRTs = new List<RTHandle>();
for (int i = 0; i < (int)RTCategory.Count; ++i)

}
}
public void Dispose()
{
Dispose(true);
}
// Call this once to set the initial size and allow msaa targets or not.

int GetMaxWidth(RTCategory category) { return m_MaxWidths[(int)category]; }
int GetMaxHeight(RTCategory category) { return m_MaxHeights[(int)category]; }
void Dispose(bool disposing)
{
if (disposing)
{
for (int i = 0, c = m_AutoSizedRTs.Count; i < c; ++i)
{
var rt = m_AutoSizedRTs[i];
Release(rt);
}
m_AutoSizedRTs.Clear();
}
}
void Resize(int width, int height, RTCategory category, MSAASamples msaaSamples)
{

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDAdditionalCameraData.cs


bool m_IsDebugRegistered = false;
string m_CameraRegisterName;
BufferedRTHandleSystem m_HistoryRTSystem;
public BufferedRTHandleSystem historyRTSystem { get { return m_HistoryRTSystem; } }
// This is the function use outside to access FrameSettings. It return the current state of FrameSettings for the camera
// taking into account the customization via the debug menu
public FrameSettings GetFrameSettings()

}
}
void Awake()
{
m_HistoryRTSystem = new BufferedRTHandleSystem();
}
void OnEnable()
{
// Be sure legacy HDR option is disable on camera as it cause banding in SceneView. Yes, it is a contradiction, but well, Unity...

void OnDisable()
{
UnRegisterDebug();
}
void OnDestroy()
{
m_HistoryRTSystem.Dispose();
m_HistoryRTSystem = null;
}
public void OnBeforeSerialize()

34
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs


HDAdditionalCameraData m_AdditionalCameraData;
public BufferedRTHandleSystem historyRTSystem
{
get { return m_AdditionalCameraData != null ? m_AdditionalCameraData.historyRTSystem : null; }
}
public HDCamera(Camera cam)
{
camera = cam;

// Unfortunately sometime (like in the HDCameraEditor) HDUtils.hdrpSettings can be null because of scripts that change the current pipeline...
m_msaaSamples = HDUtils.hdrpSettings != null ? HDUtils.hdrpSettings.msaaSampleCount : MSAASamples.None;
RTHandles.SetReferenceSize(m_ActualWidth, m_ActualHeight, frameSettings.enableMSAA, m_msaaSamples);
historyRTSystem.SetReferenceSize(m_ActualWidth, m_ActualHeight, frameSettings.enableMSAA, m_msaaSamples);
historyRTSystem.Swap();
int maxWidth = RTHandles.maxWidth;
int maxHeight = RTHandles.maxHeight;

cmd.SetComputeVectorParam(cs, HDShaderIDs._ScreenParams, Shader.GetGlobalVector(HDShaderIDs._ScreenParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._ZBufferParams, Shader.GetGlobalVector(HDShaderIDs._ZBufferParams));
cmd.SetComputeVectorParam(cs, HDShaderIDs._WorldSpaceCameraPos, Shader.GetGlobalVector(HDShaderIDs._WorldSpaceCameraPos));
}
public RTHandleSystem.RTHandle GetPreviousFrameRT(int id)
{
if (m_AdditionalCameraData == null)
return null;
return m_AdditionalCameraData.historyRTSystem.GetFrameRT(id, 1);
}
public RTHandleSystem.RTHandle GetCurrentFrameRT(int id)
{
if (m_AdditionalCameraData == null)
return null;
return m_AdditionalCameraData.historyRTSystem.GetFrameRT(id, 0);
}
// Allocate buffers frames and return current frame
public RTHandleSystem.RTHandle AllocHistoryFrameRT(int id, Func<RTHandleSystem, RTHandleSystem.RTHandle> allocator)
{
if (m_AdditionalCameraData == null)
return null;
m_AdditionalCameraData.historyRTSystem.AllocBuffer(id, allocator, 2);
return m_AdditionalCameraData.historyRTSystem.GetFrameRT(id, 0);
}
}
}

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDCustomSamplerId.cs


TransparentDepthPostpass,
ObjectsVelocity,
CameraVelocity,
GaussianPyramidColor,
PyramidDepth,
ColorPyramid,
DepthPyramid,
PostProcessing,
RenderDebug,
ClearBuffers,

48
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


if (m_Asset.renderPipelineSettings.supportDBuffer)
m_DbufferManager.CreateBuffers();
m_BufferPyramid.CreateBuffers();
m_SSSBufferManager.InitSSSBuffers(m_GbufferManager, m_Asset.renderPipelineSettings);
m_CameraColorBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGBHalf, sRGB : false, enableRandomWrite: true, enableMSAA: true, name : "CameraColor");

var ssReflection = VolumeManager.instance.stack.GetComponent<ScreenSpaceReflection>()
?? ScreenSpaceReflection.@default;
ssReflection.PushShaderParameters(cmd);
var previousDepthPyramidRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.DepthPyramid);
if (previousDepthPyramidRT != null)
cmd.SetGlobalTexture(HDShaderIDs._DepthPyramidTexture, previousDepthPyramidRT);
var previousColorPyramidRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorPyramid);
if (previousColorPyramidRT != null)
cmd.SetGlobalTexture(HDShaderIDs._ColorPyramidTexture, previousColorPyramidRT);
}
}

// In both forward and deferred, everything opaque should have been rendered at this point so we can safely copy the depth buffer for later processing.
CopyDepthBufferIfNeeded(cmd);
RenderPyramidDepth(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);
RenderDepthPyramid(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);
RenderCameraVelocity(m_CullResults, hdCamera, renderContext, cmd);

RenderForward(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.PreRefraction);
RenderForwardError(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.PreRefraction);
RenderGaussianPyramidColor(hdCamera, cmd, renderContext, true);
RenderColorPyramid(hdCamera, cmd, renderContext, true);
RenderForward(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.OpaqueSSReflection);
// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.

// Fill depth buffer to reduce artifact for transparent object during postprocess
RenderTransparentDepthPostpass(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Transparent);
RenderGaussianPyramidColor(hdCamera, cmd, renderContext, false);
RenderColorPyramid(hdCamera, cmd, renderContext, false);
AccumulateDistortion(m_CullResults, hdCamera, renderContext, cmd);
RenderDistortion(cmd, m_Asset.renderPipelineResources, hdCamera);

using (new ProfilingSample(cmd, "ApplyDistortion", CustomSamplerId.ApplyDistortion.GetSampler()))
{
Vector2 pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera);
var colorPyramidRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorPyramid);
var pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera, colorPyramidRT);
// Need to account for the fact that the gaussian pyramid is actually rendered inside the camera viewport in a square texture so we mutiply by the PyramidToScreen scale
var size = new Vector4(hdCamera.screenSize.x, hdCamera.screenSize.y, pyramidScale.x / hdCamera.screenSize.x, pyramidScale.y / hdCamera.screenSize.y);

cmd.SetComputeTextureParam(m_applyDistortionCS, m_applyDistortionKernel, HDShaderIDs._ColorPyramidTexture, m_BufferPyramid.colorPyramid);
cmd.SetComputeTextureParam(m_applyDistortionCS, m_applyDistortionKernel, HDShaderIDs._ColorPyramidTexture, colorPyramidRT);
cmd.SetComputeTextureParam(m_applyDistortionCS, m_applyDistortionKernel, HDShaderIDs._CameraColorTexture, m_CameraColorBuffer);
cmd.SetComputeVectorParam(m_applyDistortionCS, HDShaderIDs._Size, size);
cmd.SetComputeVectorParam(m_applyDistortionCS, HDShaderIDs._ZBufferParams, Shader.GetGlobalVector(HDShaderIDs._ZBufferParams));

}
}
void RenderGaussianPyramidColor(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, bool isPreRefraction)
void RenderColorPyramid(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, bool isPreRefraction)
{
if (isPreRefraction)
{

return;
}
using (new ProfilingSample(cmd, "Gaussian Pyramid Color", CustomSamplerId.GaussianPyramidColor.GetSampler()))
m_BufferPyramid.RenderColorPyramid(hdCamera, cmd, renderContext, m_CameraColorBuffer);
var cameraRT = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.ColorPyramid)
?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.ColorPyramid, m_BufferPyramid.AllocColorRT);
Vector2 pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera);
PushFullScreenDebugTextureMip(cmd, m_BufferPyramid.colorPyramid, m_BufferPyramid.GetPyramidLodCount(hdCamera), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), hdCamera, isPreRefraction ? FullScreenDebugMode.PreRefractionColorPyramid : FullScreenDebugMode.FinalColorPyramid);
using (new ProfilingSample(cmd, "Color Pyramid", CustomSamplerId.ColorPyramid.GetSampler()))
m_BufferPyramid.RenderColorPyramid(hdCamera, cmd, renderContext, m_CameraColorBuffer, cameraRT);
Vector2 pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera, cameraRT);
PushFullScreenDebugTextureMip(cmd, cameraRT, m_BufferPyramid.GetPyramidLodCount(hdCamera), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), hdCamera, isPreRefraction ? FullScreenDebugMode.PreRefractionColorPyramid : FullScreenDebugMode.FinalColorPyramid);
void RenderPyramidDepth(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, FullScreenDebugMode debugMode)
void RenderDepthPyramid(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, FullScreenDebugMode debugMode)
using (new ProfilingSample(cmd, "Pyramid Depth", CustomSamplerId.PyramidDepth.GetSampler()))
m_BufferPyramid.RenderDepthPyramid(hdCamera, cmd, renderContext, GetDepthTexture());
var cameraRT = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.DepthPyramid)
?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.DepthPyramid, m_BufferPyramid.AllocDepthRT);
using (new ProfilingSample(cmd, "Depth Pyramid", CustomSamplerId.DepthPyramid.GetSampler()))
m_BufferPyramid.RenderDepthPyramid(hdCamera, cmd, renderContext, GetDepthTexture(), cameraRT);
Vector2 pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera);
PushFullScreenDebugTextureMip(cmd, m_BufferPyramid.depthPyramid, m_BufferPyramid.GetPyramidLodCount(hdCamera), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), hdCamera, debugMode);
Vector2 pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera, cameraRT);
PushFullScreenDebugTextureMip(cmd, cameraRT, m_BufferPyramid.GetPyramidLodCount(hdCamera), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), hdCamera, debugMode);
}
void RenderPostProcess(HDCamera hdcamera, CommandBuffer cmd, PostProcessLayer layer)

// (i.e. we have perform a flip, we need to flip the input texture)
m_DebugFullScreen.SetFloat(HDShaderIDs._RequireToFlipInputTexture, hdCamera.camera.cameraType != CameraType.SceneView ? 1.0f : 0.0f);
m_DebugFullScreen.SetBuffer(HDShaderIDs._DebugScreenSpaceTracingData, m_DebugScreenSpaceTracingData);
m_DebugFullScreen.SetTexture(HDShaderIDs._DepthPyramidTexture, m_BufferPyramid.depthPyramid);
m_DebugFullScreen.SetTexture(HDShaderIDs._DepthPyramidTexture, hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.DepthPyramid));
HDUtils.DrawFullScreen(cmd, hdCamera, m_DebugFullScreen, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);
PushColorPickerDebugTexture(cmd, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget, hdCamera);

80
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/BufferPyramid.cs


using System.Collections.Generic;
using System;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline

RTHandleSystem.RTHandle m_ColorPyramidBuffer;
RTHandleSystem.RTHandle m_DepthPyramidBuffer;
public RTHandleSystem.RTHandle colorPyramid { get { return m_ColorPyramidBuffer; } }
public RTHandleSystem.RTHandle depthPyramid { get { return m_DepthPyramidBuffer; } }
BufferPyramidProcessor m_Processor;

return scale;
}
public void CreateBuffers()
{
m_ColorPyramidBuffer = RTHandles.Alloc(size => CalculatePyramidSize(size), filterMode: FilterMode.Trilinear, colorFormat: RenderTextureFormat.ARGBHalf, sRGB: false, useMipMap: true, autoGenerateMips: false, enableRandomWrite: true, name: "ColorPyramid");
m_DepthPyramidBuffer = RTHandles.Alloc(size => CalculatePyramidSize(size), filterMode: FilterMode.Trilinear, colorFormat: RenderTextureFormat.RGFloat, sRGB: false, useMipMap: true, autoGenerateMips: false, enableRandomWrite: true, name: "DepthPyramid"); // Need randomReadWrite because we downsample the first mip with a compute shader.
}
RTHandles.Release(m_ColorPyramidBuffer);
RTHandles.Release(m_DepthPyramidBuffer);
{
}
{
}
}
public int GetPyramidLodCount(HDCamera camera)

}
}
public Vector2 GetPyramidToScreenScale(HDCamera camera)
public Vector2 GetPyramidToScreenScale(HDCamera camera, RTHandleSystem.RTHandle rth)
return new Vector2((float)camera.actualWidth / m_DepthPyramidBuffer.rt.width, (float)camera.actualHeight / m_DepthPyramidBuffer.rt.height);
return new Vector2((float)camera.actualWidth / rth.rt.width, (float)camera.actualHeight / rth.rt.height);
}
public void RenderDepthPyramid(

RTHandleSystem.RTHandle depthTexture)
RTHandleSystem.RTHandle sourceDepthTexture,
RTHandleSystem.RTHandle targetDepthTexture)
UpdatePyramidMips(hdCamera, m_DepthPyramidBuffer.rt.format, m_DepthPyramidMips, lodCount);
UpdatePyramidMips(hdCamera, targetDepthTexture.rt.format, m_DepthPyramidMips, lodCount);
Vector2 scale = GetPyramidToScreenScale(hdCamera);
Vector2 scale = GetPyramidToScreenScale(hdCamera, targetDepthTexture);
cmd.SetGlobalVector(HDShaderIDs._DepthPyramidSize, new Vector4(hdCamera.actualWidth, hdCamera.actualHeight, 1f / hdCamera.actualWidth, 1f / hdCamera.actualHeight));
cmd.SetGlobalVector(HDShaderIDs._DepthPyramidScale, new Vector4(scale.x, scale.y, lodCount, 0.0f));

depthTexture,
m_DepthPyramidBuffer,
sourceDepthTexture,
targetDepthTexture,
cmd.SetGlobalTexture(HDShaderIDs._DepthPyramidTexture, m_DepthPyramidBuffer);
cmd.SetGlobalTexture(HDShaderIDs._DepthPyramidTexture, targetDepthTexture);
}
public void RenderColorPyramid(

RTHandleSystem.RTHandle colorTexture)
RTHandleSystem.RTHandle sourceColorTexture,
RTHandleSystem.RTHandle targetColorTexture)
UpdatePyramidMips(hdCamera, m_ColorPyramidBuffer.rt.format, m_ColorPyramidMips, lodCount);
UpdatePyramidMips(hdCamera, targetColorTexture.rt.format, m_ColorPyramidMips, lodCount);
Vector2 scale = GetPyramidToScreenScale(hdCamera);
Vector2 scale = GetPyramidToScreenScale(hdCamera, targetColorTexture);
cmd.SetGlobalVector(HDShaderIDs._ColorPyramidSize, new Vector4(hdCamera.actualWidth, hdCamera.actualHeight, 1f / hdCamera.actualWidth, 1f / hdCamera.actualHeight));
cmd.SetGlobalVector(HDShaderIDs._ColorPyramidScale, new Vector4(scale.x, scale.y, lodCount, 0.0f));

colorTexture,
m_ColorPyramidBuffer,
sourceColorTexture,
targetColorTexture,
cmd.SetGlobalTexture(HDShaderIDs._ColorPyramidTexture, m_ColorPyramidBuffer);
cmd.SetGlobalTexture(HDShaderIDs._ColorPyramidTexture, targetColorTexture);
}
public RTHandleSystem.RTHandle AllocColorRT(RTHandleSystem rtHandleSystem)
{
return rtHandleSystem.Alloc(
size => CalculatePyramidSize(size),
filterMode: FilterMode.Trilinear,
colorFormat: RenderTextureFormat.ARGBHalf,
sRGB: false,
useMipMap: true,
autoGenerateMips: false,
enableRandomWrite: true,
name: "ColorPyramid"
);
}
public RTHandleSystem.RTHandle AllocDepthRT(RTHandleSystem rtHandleSystem)
{
return rtHandleSystem.Alloc(
size => CalculatePyramidSize(size),
filterMode: FilterMode.Trilinear,
colorFormat: RenderTextureFormat.RGFloat,
sRGB: false,
useMipMap: true,
autoGenerateMips: false,
enableRandomWrite: true,
name: "DepthPyramid"
); // Need randomReadWrite because we downsample the first mip with a compute shader.
}
}
}

53
ScriptableRenderPipeline/Core/CoreRP/Textures/BufferedRTHandleSystem.cs


using System;
using System.Collections.Generic;
using UnityEngine.Assertions;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering
{
public class BufferedRTHandleSystem : IDisposable
{
Dictionary<int, RTHandleSystem.RTHandle[]> m_RTHandles = new Dictionary<int, RTHandleSystem.RTHandle[]>();
RTHandleSystem m_RTHandleSystem = new RTHandleSystem();
bool m_DisposedValue = false;
public RTHandleSystem.RTHandle GetFrameRT(int id, int index)
{
if (!m_RTHandles.ContainsKey(id))
return null;
Assert.IsTrue(index >= 0 && index < m_RTHandles[id].Length);
return m_RTHandles[id][index];
}
public void AllocBuffer(
int id,
Func<RTHandleSystem, RTHandleSystem.RTHandle> allocator,
int bufferSize
)
{
m_RTHandles.Add(id, new RTHandleSystem.RTHandle[bufferSize]);
}
void Dispose(bool disposing)
{
if (!m_DisposedValue)
{
if (disposing)
{
m_RTHandleSystem.Dispose();
m_RTHandleSystem = null;
}
m_DisposedValue = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
}

11
ScriptableRenderPipeline/Core/CoreRP/Textures/BufferedRTHandleSystem.cs.meta


fileFormatVersion: 2
guid: cc56f4b85f1be9749add0bb4a25a4e4b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCameraFrameHistoryType.cs


using UnityEngine.Serialization;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public enum HDCameraFrameHistoryType
{
DepthPyramid,
ColorPyramid
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCameraFrameHistoryType.cs.meta


fileFormatVersion: 2
guid: 1f3be30cb97279146bc83ceb83fff369
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存