浏览代码

Merge pull request #1137 from Unity-Technologies/feature/PyramidBuffer

Pyramid buffer viewport support
/main
GitHub 7 年前
当前提交
b357f4bf
共有 15 个文件被更改,包括 415 次插入78 次删除
  1. 4
      CHANGELOG.md
  2. 15
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopy.compute
  3. 81
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopy.cs
  4. 108
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopyAsset.cs
  5. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDAssetFactory.cs
  6. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  7. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.asset
  8. 109
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/BufferPyramid.cs
  9. 58
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute
  10. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset
  11. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/RenderPipelineResources.cs
  12. 44
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/TexturePadding.compute
  13. 8
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/TexturePadding.compute.meta
  14. 46
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/TexturePadding.cs
  15. 11
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/TexturePadding.cs.meta

4
CHANGELOG.md


The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Changed
- Depth and color pyramid are properly computed and sampled when the camera renders inside a viewport of a RTHandle.
## [0.1.6] - 2018-xx-yy
### Changelog starting

15
ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopy.compute


#include "../ShaderLibrary/Common.hlsl"
#pragma only_renderers d3d11 ps4 xboxone vulkan metal
CBUFFER_START (UnityCBuffer)
uint2 _RectOffset;
CBUFFER_END
#pragma kernel KSampleCopy4_1_x
[numthreads(8, 8, 1)]
void KSampleCopy4_1_x(uint2 dispatchThreadId : SV_DispatchThreadID)
#pragma kernel KSampleCopy4_1_x_8 KERNEL_NAME=KSampleCopy4_1_x_8 KERNEL_SIZE=8
#pragma kernel KSampleCopy4_1_x_1 KERNEL_NAME=KSampleCopy4_1_x_1 KERNEL_SIZE=1
[numthreads(KERNEL_SIZE, KERNEL_SIZE, 1)]
void KERNEL_NAME(uint2 dispatchThreadId : SV_DispatchThreadID)
_Result1[dispatchThreadId] = LOAD_TEXTURE2D(_Source4, dispatchThreadId).x;
_Result1[_RectOffset + dispatchThreadId] = LOAD_TEXTURE2D(_Source4, _RectOffset + dispatchThreadId).x;
}

81
ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopy.cs


public class GPUCopy
{
ComputeShader m_Shader;
int k_SampleKernel_xyzw2x;
int k_SampleKernel_xyzw2x_8;
int k_SampleKernel_xyzw2x_1;
k_SampleKernel_xyzw2x = m_Shader.FindKernel("KSampleCopy4_1_x");
k_SampleKernel_xyzw2x_8 = m_Shader.FindKernel("KSampleCopy4_1_x_8");
k_SampleKernel_xyzw2x_1 = m_Shader.FindKernel("KSampleCopy4_1_x_1");
static readonly int _RectOffset = Shader.PropertyToID("_RectOffset");
public void SampleCopyChannel_xyzw2x(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, Vector2 size)
void SampleCopyChannel(
CommandBuffer cmd,
RectInt rect,
int _source,
RenderTargetIdentifier source,
int _target,
RenderTargetIdentifier target,
int kernel8,
int kernel1)
{
RectInt main, topRow, rightCol, topRight;
unsafe
cmd.SetComputeTextureParam(m_Shader, k_SampleKernel_xyzw2x, _Source4, source);
cmd.SetComputeTextureParam(m_Shader, k_SampleKernel_xyzw2x, _Result1, target);
cmd.DispatchCompute(m_Shader, k_SampleKernel_xyzw2x, (int)Mathf.Max((size.x) / 8, 1), (int)Mathf.Max((size.y) / 8, 1), 1);
RectInt* dispatch1Rects = stackalloc RectInt[3];
int dispatch1RectCount = 0;
RectInt dispatch8Rect = RectInt.zero;
if (TileLayoutUtils.TryLayoutByTiles(
rect,
8,
out main,
out topRow,
out rightCol,
out topRight))
{
if (topRow.width > 0 && topRow.height > 0)
{
dispatch1Rects[dispatch1RectCount] = topRow;
++dispatch1RectCount;
}
if (rightCol.width > 0 && rightCol.height > 0)
{
dispatch1Rects[dispatch1RectCount] = rightCol;
++dispatch1RectCount;
}
if (topRight.width > 0 && topRight.height > 0)
{
dispatch1Rects[dispatch1RectCount] = topRight;
++dispatch1RectCount;
}
dispatch8Rect = main;
}
else if (rect.width > 0 && rect.height > 0)
{
dispatch1Rects[dispatch1RectCount] = rect;
++dispatch1RectCount;
}
cmd.SetComputeTextureParam(m_Shader, kernel8, _source, source);
cmd.SetComputeTextureParam(m_Shader, kernel1, _source, source);
cmd.SetComputeTextureParam(m_Shader, kernel8, _target, target);
cmd.SetComputeTextureParam(m_Shader, kernel1, _target, target);
if (dispatch8Rect.width > 0 && dispatch8Rect.height > 0)
{
var r = dispatch8Rect;
cmd.SetComputeIntParams(m_Shader, _RectOffset, (int)r.x, (int)r.y);
cmd.DispatchCompute(m_Shader, kernel8, (int)Mathf.Max(r.width / 8, 1), (int)Mathf.Max(r.height / 8, 1), 1);
}
for (int i = 0, c = dispatch1RectCount; i < c; ++i)
{
var r = dispatch1Rects[i];
cmd.SetComputeIntParams(m_Shader, _RectOffset, (int)r.x, (int)r.y);
cmd.DispatchCompute(m_Shader, kernel1, (int)Mathf.Max(r.width, 1), (int)Mathf.Max(r.height, 1), 1);
}
}
public void SampleCopyChannel_xyzw2x(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, RectInt rect)
{
SampleCopyChannel(cmd, rect, _Source4, source, _Result1, target, k_SampleKernel_xyzw2x_8, k_SampleKernel_xyzw2x_1);
}
}
}

108
ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopyAsset.cs


}
ccp.AppendLine();
ccp.AppendLine("CBUFFER_START (UnityCBuffer)");
ccp.AppendLine(" uint2 _RectOffset;");
ccp.AppendLine("CBUFFER_END");
ccp.AppendLine();
csm.AppendLine(" static readonly int _RectOffset = Shader.PropertyToID(\"_RectOffset\");");
ccp.AppendLine();
ccp.AppendLine();
csm.AppendLine(@" void SampleCopyChannel(
CommandBuffer cmd,
RectInt rect,
int _source,
RenderTargetIdentifier source,
int _target,
RenderTargetIdentifier target,
int kernel8,
int kernel1)
{
RectInt main, topRow, rightCol, topRight;
unsafe
{
RectInt* dispatch1Rects = stackalloc RectInt[3];
int dispatch1RectCount = 0;
RectInt dispatch8Rect = RectInt.zero;
if (TileLayoutUtils.TryLayoutByTiles(
rect,
8,
out main,
out topRow,
out rightCol,
out topRight))
{
if (topRow.width > 0 && topRow.height > 0)
{
dispatch1Rects[dispatch1RectCount] = topRow;
++dispatch1RectCount;
}
if (rightCol.width > 0 && rightCol.height > 0)
{
dispatch1Rects[dispatch1RectCount] = rightCol;
++dispatch1RectCount;
}
if (topRight.width > 0 && topRight.height > 0)
{
dispatch1Rects[dispatch1RectCount] = topRight;
++dispatch1RectCount;
}
dispatch8Rect = main;
}
else if (rect.width > 0 && rect.height > 0)
{
dispatch1Rects[dispatch1RectCount] = rect;
++dispatch1RectCount;
}
cmd.SetComputeTextureParam(m_Shader, kernel8, _source, source);
cmd.SetComputeTextureParam(m_Shader, kernel1, _source, source);
cmd.SetComputeTextureParam(m_Shader, kernel8, _target, target);
cmd.SetComputeTextureParam(m_Shader, kernel1, _target, target);
if (dispatch8Rect.width > 0 && dispatch8Rect.height > 0)
{
var r = dispatch8Rect;
cmd.SetComputeIntParams(m_Shader, _RectOffset, (int)r.x, (int)r.y);
cmd.DispatchCompute(m_Shader, kernel8, (int)Mathf.Max(r.width / 8, 1), (int)Mathf.Max(r.height / 8, 1), 1);
}
for (int i = 0, c = dispatch1RectCount; i < c; ++i)
{
var r = dispatch1Rects[i];
cmd.SetComputeIntParams(m_Shader, _RectOffset, (int)r.x, (int)r.y);
cmd.DispatchCompute(m_Shader, kernel1, (int)Mathf.Max(r.width, 1), (int)Mathf.Max(r.height, 1), 1);
}
}
}");
csc.AppendLine(" public GPUCopy(ComputeShader shader)");
csc.AppendLine(" {");

var o = operations[i];
// Compute kernel
var kernelName = string.Format("KSampleCopy{0}_{1}_{2}", o.sourceChannel.ToString(), o.targetChannel.ToString(), o.subscript);
cck.AppendLine(string.Format("#pragma kernel {0}", kernelName));
cck.AppendLine(string.Format(@"[numthreads({0}, {0}, 1)]",
k_KernelSize.ToString(), k_KernelSize.ToString()));
cck.AppendLine(string.Format(@"void {0}(uint2 dispatchThreadId : SV_DispatchThreadID)", kernelName));
var kernelName8 = string.Format("KSampleCopy{0}_{1}_{2}_8", o.sourceChannel.ToString(), o.targetChannel.ToString(), o.subscript);
var kernelName1 = string.Format("KSampleCopy{0}_{1}_{2}_1", o.sourceChannel.ToString(), o.targetChannel.ToString(), o.subscript);
cck.AppendLine(string.Format("#pragma kernel {0} KERNEL_NAME={0} KERNEL_SIZE=8", kernelName8));
cck.AppendLine(string.Format("#pragma kernel {0} KERNEL_NAME={0} KERNEL_SIZE=1", kernelName1));
cck.AppendLine(@"[numthreads(KERNEL_SIZE, KERNEL_SIZE, 1)]");
cck.AppendLine(@"void KERNEL_NAME(uint2 dispatchThreadId : SV_DispatchThreadID)");
cck.AppendLine(string.Format(" _Result{0}[dispatchThreadId] = LOAD_TEXTURE2D(_Source{1}, dispatchThreadId).{2};",
cck.AppendLine(string.Format(" _Result{0}[_RectOffset + dispatchThreadId] = LOAD_TEXTURE2D(_Source{1}, _RectOffset + dispatchThreadId).{2};",
o.targetChannel.ToString(), o.sourceChannel.ToString(), o.subscript));
cck.AppendLine("}");
cck.AppendLine();

var kernelIndexName = string.Format("k_SampleKernel_{0}2{1}", channelName, o.subscript);
csp.AppendLine(string.Format(" int {0};", kernelIndexName));
var kernelIndexName8 = string.Format("k_SampleKernel_{0}2{1}_8", channelName, o.subscript);
var kernelIndexName1 = string.Format("k_SampleKernel_{0}2{1}_1", channelName, o.subscript);
csp.AppendLine(string.Format(" int {0};", kernelIndexName8));
csp.AppendLine(string.Format(" int {0};", kernelIndexName1));
csc.AppendLine(string.Format(" {0} = m_Shader.FindKernel(\"{1}\");", kernelIndexName, kernelName));
csc.AppendLine(string.Format(" {0} = m_Shader.FindKernel(\"{1}\");", kernelIndexName8, kernelName8));
csc.AppendLine(string.Format(" {0} = m_Shader.FindKernel(\"{1}\");", kernelIndexName1, kernelName1));
csm.AppendLine(string.Format(@" public void SampleCopyChannel_{0}2{1}(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, Vector2 size)", channelName, o.subscript));
csm.AppendLine(" {");
csm.AppendLine(string.Format(" cmd.SetComputeTextureParam(m_Shader, {0}, _Source{1}, source);", kernelIndexName, o.sourceChannel.ToString()));
csm.AppendLine(string.Format(" cmd.SetComputeTextureParam(m_Shader, {0}, _Result{1}, target);", kernelIndexName, o.targetChannel.ToString()));
csm.AppendLine(string.Format(" cmd.DispatchCompute(m_Shader, {0}, (int)Mathf.Max((size.x) / {1}, 1), (int)Mathf.Max((size.y) / {1}, 1), 1);", kernelIndexName, k_KernelSize.ToString()));
csm.AppendLine(" }");
csm.AppendLine(string.Format(@" public void SampleCopyChannel_{0}2{1}(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, RectInt rect)", channelName, o.subscript));
csm.AppendLine (" {");
csm.AppendLine(string.Format(" SampleCopyChannel(cmd, rect, _Source{0}, source, _Result{1}, target, {2}, {3});", o.sourceChannel.ToString(), o.targetChannel.ToString(), kernelIndexName8, kernelIndexName1));
csm.AppendLine (" }");
}
csc.AppendLine(" }");

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDAssetFactory.cs


newAsset.colorPyramidCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ColorPyramid.compute");
newAsset.depthPyramidCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/DepthPyramid.compute");
newAsset.copyChannelCS = Load<ComputeShader>(CorePath + "CoreResources/GPUCopy.compute");
newAsset.texturePaddingCS = Load<ComputeShader>(CorePath + "CoreResources/TexturePadding.compute");
newAsset.applyDistortionCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ApplyDistorsion.compute");
newAsset.clearDispatchIndirectShader = Load<ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/cleardispatchindirect.compute");

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


m_BufferPyramid = new BufferPyramid(
asset.renderPipelineResources.colorPyramidCS,
asset.renderPipelineResources.depthPyramidCS,
m_GPUCopy);
m_GPUCopy,
new TexturePadding(asset.renderPipelineResources.texturePaddingCS)
);
EncodeBC6H.DefaultInstance = EncodeBC6H.DefaultInstance ?? new EncodeBC6H(asset.renderPipelineResources.encodeBC6HCS);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.asset


skyReflectionSize: 256
skyLightingOverrideLayerMask:
serializedVersion: 2
m_Bits: 256
m_Bits: 0
shadowInitParams:
shadowAtlasWidth: 4096
shadowAtlasHeight: 4096

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


const int k_DepthBlockSize = 4;
GPUCopy m_GPUCopy;
TexturePadding m_TexturePadding;
ComputeShader m_ColorPyramidCS;
RTHandle m_ColorPyramidBuffer;

ComputeShader m_DepthPyramidCS;
RTHandle m_DepthPyramidBuffer;
List<RTHandle> m_DepthPyramidMips = new List<RTHandle>();
int m_DepthPyramidKernel_8;
int m_DepthPyramidKernel_1;
int[] m_DepthKernels = null;
int depthKernel8 { get { return m_DepthKernels[0]; } }
int depthKernel1 { get { return m_DepthKernels[1]; } }
public RTHandle colorPyramid { get { return m_ColorPyramidBuffer; } }
public RTHandle depthPyramid { get { return m_DepthPyramidBuffer; } }

ComputeShader depthPyramidCS, GPUCopy gpuCopy)
ComputeShader depthPyramidCS,
GPUCopy gpuCopy,
TexturePadding texturePadding
)
{
m_ColorPyramidCS = colorPyramidCS;
m_ColorPyramidKernel = m_ColorPyramidCS.FindKernel("KMain");

m_DepthPyramidKernel_8 = m_DepthPyramidCS.FindKernel("KMain_8");
m_DepthPyramidKernel_1 = m_DepthPyramidCS.FindKernel("KMain_1");
m_DepthKernels = new int[]
{
m_DepthPyramidCS.FindKernel("KDepthDownSample8"),
m_DepthPyramidCS.FindKernel("KDepthDownSample1")
};
m_TexturePadding = texturePadding;
}
float GetXRscale()

public void CreateBuffers()
{
m_ColorPyramidBuffer = RTHandle.Alloc(size => CalculatePyramidSize(size), filterMode: FilterMode.Trilinear, colorFormat: RenderTextureFormat.ARGBHalf, sRGB: false, useMipMap: true, autoGenerateMips: false, name: "ColorPymarid");
m_DepthPyramidBuffer = RTHandle.Alloc(size => CalculatePyramidSize(size), filterMode: FilterMode.Trilinear, colorFormat: RenderTextureFormat.RFloat, sRGB: false, useMipMap: true, autoGenerateMips: false, enableRandomWrite: true, name: "DepthPyramid"); // Need randomReadWrite because we downsample the first mip with a compute shader.
m_DepthPyramidBuffer = RTHandle.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.
}
public void DestroyBuffers()

cmd.SetGlobalVector(HDShaderIDs._DepthPyramidMipSize, new Vector4(hdCamera.actualWidth, hdCamera.actualHeight, lodCount, 0.0f));
m_GPUCopy.SampleCopyChannel_xyzw2x(cmd, depthTexture, m_DepthPyramidBuffer, new Vector2(hdCamera.actualWidth, hdCamera.actualHeight));
m_GPUCopy.SampleCopyChannel_xyzw2x(cmd, depthTexture, m_DepthPyramidBuffer, new RectInt(0, 0, hdCamera.actualWidth, hdCamera.actualHeight));
Vector2 scale = GetPyramidToScreenScale(hdCamera);

RTHandle dest = m_DepthPyramidMips[i];
var srcMipWidth = hdCamera.actualWidth >> i;
var srcMipHeight = hdCamera.actualHeight >> i;
var dstMipWidth = srcMipWidth >> 1;
var dstMipHeight = srcMipHeight >> 1;
var srcMip = new RectInt(0, 0, hdCamera.actualWidth >> i, hdCamera.actualHeight >> i);
var dstMip = new RectInt(0, 0, srcMip.width >> 1, srcMip.height >> 1);
var kernel = depthKernel1;
var kernelSize = 1;
var srcWorkMip = srcMip;
var dstWorkMip = dstMip;
if (dstWorkMip.width >= 8 && dstWorkMip.height >= 8)
{
srcWorkMip.width = Mathf.CeilToInt(srcWorkMip.width / 16.0f) * 16;
srcWorkMip.height = Mathf.CeilToInt(srcWorkMip.height / 16.0f) * 16;
dstWorkMip.width = srcWorkMip.width >> 1;
dstWorkMip.height = srcWorkMip.height >> 1;
var kernel = m_DepthPyramidKernel_8;
var kernelBlockSize = 8f;
if (dstMipWidth < 4 * k_DepthBlockSize
|| dstMipHeight < 4 * k_DepthBlockSize)
m_TexturePadding.Pad(cmd, src, srcMip, srcWorkMip);
kernel = depthKernel8;
kernelSize = 8;
}
else
kernel = m_DepthPyramidKernel_1;
kernelBlockSize = 1;
m_TexturePadding.Pad(cmd, src, srcMip, new RectInt(0, 0, src.rt.width, src.rt.height));
cmd.SetComputeVectorParam(m_DepthPyramidCS, _SrcSize, new Vector4(srcMipWidth, srcMipHeight, (1.0f / srcMipWidth) * scale.x, (1.0f / srcMipHeight) * scale.y));
cmd.SetComputeVectorParam(m_DepthPyramidCS, _SrcSize, new Vector4(
srcWorkMip.width, srcWorkMip.height,
(1.0f / srcWorkMip.width) * scale.x, (1.0f / srcWorkMip.height) * scale.y)
);
Mathf.CeilToInt(dstMipWidth / kernelBlockSize),
Mathf.CeilToInt(dstMipHeight / kernelBlockSize),
1);
Mathf.CeilToInt(dstWorkMip.width / (float)kernelSize),
Mathf.CeilToInt(dstWorkMip.height / (float)kernelSize),
1
);
var dstMipWidthToCopy = Mathf.Min(dest.rt.width, dstWorkMip.width);
var dstMipHeightToCopy = Mathf.Min(dest.rt.height, dstWorkMip.height);
cmd.CopyTexture(m_DepthPyramidMips[i], 0, 0, 0, 0, dstMipWidth, dstMipHeight, m_DepthPyramidBuffer, 0, i + 1, 0, 0);
cmd.CopyTexture(m_DepthPyramidMips[i], 0, 0, 0, 0, dstMipWidthToCopy, dstMipHeightToCopy, m_DepthPyramidBuffer, 0, i + 1, 0, 0);
src = dest;
}

{
RTHandle dest = m_ColorPyramidMips[i];
var srcMipWidth = hdCamera.actualWidth >> i;
var srcMipHeight = hdCamera.actualHeight >> i;
var dstMipWidth = srcMipWidth >> 1;
var dstMipHeight = srcMipHeight >> 1;
var srcMip = new RectInt(0, 0, hdCamera.actualWidth >> i, hdCamera.actualHeight >> i);
var dstMip = new RectInt(0, 0, srcMip.width >> 1, srcMip.height >> 1);
var srcWorkMip = new RectInt(
0,
0,
Mathf.CeilToInt(srcMip.width / 16.0f) * 16,
Mathf.CeilToInt(srcMip.height / 16.0f) * 16
);
var dstWorkMip = new RectInt(0, 0, srcWorkMip.width >> 1, srcWorkMip.height >> 1);
m_TexturePadding.Pad(cmd, src, srcMip, srcWorkMip);
// TODO: Add proper stereo support to the compute job

cmd.SetComputeVectorParam(m_ColorPyramidCS, _Size, new Vector4(dest.rt.width, dest.rt.height, 1f / dest.rt.width, 1f / dest.rt.height));
cmd.SetComputeVectorParam(
m_ColorPyramidCS,
_Size,
new Vector4(dest.rt.width, dest.rt.height, 1f / dest.rt.width, 1f / dest.rt.height)
);
Mathf.CeilToInt(dstMipWidth / 8f),
Mathf.CeilToInt(dstMipHeight / 8f),
1);
dstWorkMip.width / 8,
dstWorkMip.height / 8,
1
);
var dstMipWidthToCopy = Mathf.Min(dest.rt.width, dstWorkMip.width);
var dstMipHeightToCopy = Mathf.Min(dest.rt.height, dstWorkMip.height);
cmd.CopyTexture(m_ColorPyramidMips[i], 0, 0, 0, 0, dstMipWidth, dstMipHeight, m_ColorPyramidBuffer, 0, i + 1, 0, 0);
cmd.CopyTexture(
m_ColorPyramidMips[i],
0, 0, 0, 0,
dstMipWidthToCopy, dstMipHeightToCopy, m_ColorPyramidBuffer, 0, i + 1, 0, 0
);
src = dest;
}

58
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute


#include "CoreRP/ShaderLibrary/Common.hlsl"
#pragma kernel KMain_8 KERNEL_SIZE=8 KERNEL_NAME=KMain_8
#pragma kernel KMain_1 KERNEL_SIZE=1 KERNEL_NAME=KMain_1
// ------------------------------------------------
// Algorithm
// ------------------------------------------------
// Downsample a depth texture by taking min value of sampled pixels
// ------------------------------------------------
// Variants
// ------------------------------------------------
#pragma kernel KDepthDownSample8 KERNEL_SIZE=8 KERNEL_NAME=KDepthDownSample8
#pragma kernel KDepthDownSample1 KERNEL_SIZE=1 KERNEL_NAME=KDepthDownSample1
Texture2D<float> _Source;
RWTexture2D<float> _Result;
// ------------------------------------------------
// Texture buffers
// ------------------------------------------------
Texture2D<float2> _Source;
RW_TEXTURE2D(float2, _Result);
// ------------------------------------------------
// Constant buffers
// ------------------------------------------------
int2 _RectOffset; // Offset in source texture
// ------------------------------------------------
// Kernel
// ------------------------------------------------
#if UNITY_REVERSED_Z
# define MIN_DEPTH(l, r) max(l, r)
# define MAX_DEPTH(l, r) min(l, r)
#else
# define MIN_DEPTH(l, r) min(l, r)
# define MAX_DEPTH(l, r) max(l, r)
#endif
int2 threadUL = dispatchThreadId;
uint2 srcPixelUL = _RectOffset + (dispatchThreadId << 1);
// Offset by 0.5 so sampling get the proper pixels
float2 offset = float2(srcPixelUL) + 0.5;
// Downsample the block
float2 offset = float2(threadUL) * 2.0f + 1.0f;
float4 depths = GATHER_RED_TEXTURE2D(_Source, sampler_PointClamp, offset * _SrcSize.zw, 0.0);
float4 depths = GATHER_RED_TEXTURE2D(_Source, sampler_PointClamp, offset * _SrcSize.zw, 0.0).wzxy;
// Downsample the block
float p00 = SAMPLE_TEXTURE2D_LOD(_Source, sampler_PointClamp, (offset) * _SrcSize.zw, 0.0).x;
float p10 = SAMPLE_TEXTURE2D_LOD(_Source, sampler_PointClamp, (offset + float2(1.0, 0.0)) * _SrcSize.zw, 0.0).x;
float p01 = SAMPLE_TEXTURE2D_LOD(_Source, sampler_PointClamp, (offset + float2(0.0, 1.0)) * _SrcSize.zw, 0.0).x;

// Select the nearest sample
#if UNITY_REVERSED_Z
float minDepth = max(max(depths.x, depths.y), max(depths.z, depths.w));
#else
float minDepth = min(min(depths.x, depths.y), min(depths.z, depths.w));
#endif
float minDepth = MIN_DEPTH(MIN_DEPTH(depths.x, depths.y), MIN_DEPTH(depths.z, depths.w));
float maxDepth = MAX_DEPTH(MAX_DEPTH(depths.x, depths.y), MAX_DEPTH(depths.z, depths.w));
_Result[dispatchThreadId] = minDepth;
uint2 dstPixel = (_RectOffset >> 1) + dispatchThreadId;
_Result[dstPixel] = float2(minDepth, maxDepth);
#undef MIN_DEPTH
#undef MAX_DEPTH

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset


colorPyramidCS: {fileID: 7200000, guid: 4e3267a1135742441a14298d8dcac04a, type: 3}
depthPyramidCS: {fileID: 7200000, guid: 64a553bb564274041906f78ffba955e4, type: 3}
copyChannelCS: {fileID: 7200000, guid: a4d45eda75e8e474dbe24a31f741f3b4, type: 3}
texturePaddingCS: {fileID: 7200000, guid: 6736f53014c69f84aa2130aeae99730b, type: 3}
applyDistortionCS: {fileID: 7200000, guid: 2fa6c0e3fe6dc3145a4156f21913fe5c, type: 3}
clearDispatchIndirectShader: {fileID: 7200000, guid: fc1f553acb80a6446a32d33e403d0656,
type: 3}

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/RenderPipelineResources.cs


public ComputeShader colorPyramidCS;
public ComputeShader depthPyramidCS;
public ComputeShader copyChannelCS;
public ComputeShader texturePaddingCS;
public ComputeShader applyDistortionCS;
// Lighting tile pass resources

44
ScriptableRenderPipeline/Core/CoreRP/CoreResources/TexturePadding.compute


#include "CoreRP/ShaderLibrary/Common.hlsl"
#define DIRECTION_TOPRIGHT 0
#define DIRECTION_TOP 1
#define DIRECTION_RIGHT 2
#pragma kernel KMainTopRight KERNEL_NAME=KMainTopRight DIRECTION=DIRECTION_TOPRIGHT
#pragma kernel KMainTop KERNEL_NAME=KMainTop DIRECTION=DIRECTION_TOP
#pragma kernel KMainRight KERNEL_NAME=KMainRight DIRECTION=DIRECTION_RIGHT
#pragma only_renderers d3d11 ps4 xboxone vulkan metal
// ------------------------------------------------
// Texture buffers
// ------------------------------------------------
RW_TEXTURE2D(float4, _Source);
// ------------------------------------------------
// Constant buffers
// ------------------------------------------------
CBUFFER_START(cb)
int2 _RectOffset;
CBUFFER_END
// ------------------------------------------------
// Kernel
// ------------------------------------------------
[numthreads(1, 1, 1)]
void KERNEL_NAME(uint2 dispatchThreadId : SV_DispatchThreadID)
{
const int2 targetId = _RectOffset + dispatchThreadId;
#if DIRECTION == DIRECTION_TOPRIGHT
const int2 loadId = targetId - int2(1 + dispatchThreadId.x, 1 + dispatchThreadId.y);
#elif DIRECTION == DIRECTION_TOP
const int2 loadId = targetId - int2(0, 1 + dispatchThreadId.y);
#elif DIRECTION == DIRECTION_RIGHT
const int2 loadId = targetId - int2(1 + dispatchThreadId.x, 0);
#endif
_Source[targetId] = LOAD_TEXTURE2D_LOD(_Source, loadId, 0);
}

8
ScriptableRenderPipeline/Core/CoreRP/CoreResources/TexturePadding.compute.meta


fileFormatVersion: 2
guid: 6736f53014c69f84aa2130aeae99730b
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 262148
userData:
assetBundleName:
assetBundleVariant:

46
ScriptableRenderPipeline/Core/CoreRP/CoreResources/TexturePadding.cs


using System;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering
{
public class TexturePadding
{
static readonly int _RectOffset = Shader.PropertyToID("_RectOffset");
static readonly int _Source = Shader.PropertyToID("_Source");
ComputeShader m_CS;
int m_KMainTopRight;
int m_KMainTop;
int m_KMainRight;
public TexturePadding(ComputeShader cs)
{
m_CS = cs;
m_KMainTopRight = m_CS.FindKernel("KMainTopRight");
m_KMainTop = m_CS.FindKernel("KMainTop");
m_KMainRight = m_CS.FindKernel("KMainRight");
}
public void Pad(CommandBuffer cmd, RTHandle source, RectInt from, RectInt to)
{
if (from.width < to.width)
{
cmd.SetComputeIntParams(m_CS, _RectOffset, from.width, 0);
cmd.SetComputeTextureParam(m_CS, m_KMainRight, _Source, source);
cmd.DispatchCompute(m_CS, m_KMainRight, to.width - from.width, from.height, 1);
}
if (from.height < to.height)
{
cmd.SetComputeIntParams(m_CS, _RectOffset, 0, from.height);
cmd.SetComputeTextureParam(m_CS, m_KMainTop, _Source, source);
cmd.DispatchCompute(m_CS, m_KMainTop, from.width, to.height - from.height, 1);
}
if (from.width < to.width && from.height < to.height)
{
cmd.SetComputeIntParams(m_CS, _RectOffset, from.width, from.height);
cmd.SetComputeTextureParam(m_CS, m_KMainTopRight, _Source, source);
cmd.DispatchCompute(m_CS, m_KMainTopRight, to.width - from.width, to.height - from.height, 1);
}
}
}
}

11
ScriptableRenderPipeline/Core/CoreRP/CoreResources/TexturePadding.cs.meta


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