浏览代码

Merge pull request #892 from Unity-Technologies/feature/ReflectionRefraction

Use fullscreen depth/color pyramids
/main
GitHub 7 年前
当前提交
9f5cddad
共有 12 个文件被更改,包括 476 次插入178 次删除
  1. 15
      ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugItemHandler.cs
  2. 61
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  3. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDAssetFactory.cs
  4. 190
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset
  6. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute
  7. 209
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/BufferPyramid.cs
  8. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/BufferPyramid.cs.meta
  9. 144
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/ColorPyramid.compute
  10. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/ColorPyramid.compute.meta
  11. 0
      /ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute.meta
  12. 0
      /ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute

15
ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugItemHandler.cs


{
protected uint m_Min = 0;
protected uint m_Max = 1;
protected Func<uint> m_MinGetter = null;
protected Func<uint> m_MaxGetter = null;
public uint min { get { return m_MinGetter != null ? m_MinGetter() : m_Min; } }
public uint max { get { return m_MaxGetter != null ? m_MaxGetter() : m_Max; } }
public DebugItemHandlerUIntMinMax(uint min, uint max)
{

public DebugItemHandlerUIntMinMax(Func<uint> minGetter, Func<uint> maxGetter)
{
m_MinGetter = minGetter;
m_MaxGetter = maxGetter;
}
setter(Math.Min(m_Max, Math.Max(m_Min, (uint)getter())));
setter(Math.Min(max, Math.Max(min, (uint)getter())));
}
#if UNITY_EDITOR

EditorGUI.BeginChangeCheck();
int value = EditorGUILayout.IntSlider(m_DebugItem.name, (int)(uint)m_DebugItem.GetValue(), (int)m_Min, (int)m_Max);
int value = EditorGUILayout.IntSlider(m_DebugItem.name, (int)(uint)m_DebugItem.GetValue(), (int)min, (int)max);
if (EditorGUI.EndChangeCheck())
{
m_DebugItem.SetValue((uint)value);

61
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs


DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>(kShadowMinValueDebug, () => lightingDebugSettings.shadowMinValue, (value) => lightingDebugSettings.shadowMinValue = (float)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>(kShadowMaxValueDebug, () => lightingDebugSettings.shadowMaxValue, (value) => lightingDebugSettings.shadowMaxValue = (float)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, int>(kFullScreenDebugMode, () => (int)fullScreenDebugMode, (value) => fullScreenDebugMode = (FullScreenDebugMode)value, DebugItemFlag.None, new DebugItemHandlerIntEnum(DebugDisplaySettings.lightingFullScreenDebugStrings, DebugDisplaySettings.lightingFullScreenDebugValues));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>(kFullScreenDebugMip, () => fullscreenDebugMip, value => fullscreenDebugMip = (float)value, DebugItemFlag.None, new DebugItemHandlerFloatMinMax(0f, 1f));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>(
kFullScreenDebugMip,
() =>
{
var id = 0;
switch (fullScreenDebugMode)
{
default:
case FullScreenDebugMode.DepthPyramid:
id = HDShaderIDs._DepthPyramidMipSize;
break;
case FullScreenDebugMode.FinalColorPyramid:
case FullScreenDebugMode.PreRefractionColorPyramid:
id = HDShaderIDs._GaussianPyramidColorMipSize;
break;
}
var size = Shader.GetGlobalVector(id);
var lodCount = Mathf.FloorToInt(Mathf.Log(Mathf.Min(size.x, size.y), 2f));
return (uint)(fullscreenDebugMip * lodCount);
},
value =>
{
var id = 0;
switch (fullScreenDebugMode)
{
default:
case FullScreenDebugMode.DepthPyramid:
id = HDShaderIDs._DepthPyramidMipSize;
break;
case FullScreenDebugMode.FinalColorPyramid:
case FullScreenDebugMode.PreRefractionColorPyramid:
id = HDShaderIDs._GaussianPyramidColorMipSize;
break;
}
var size = Shader.GetGlobalVector(id);
var lodCount = Mathf.Floor(Mathf.Log(Mathf.Min(size.x, size.y), 2f));
fullscreenDebugMip = (float)Convert.ChangeType(value, typeof(Single)) / lodCount;
},
DebugItemFlag.None,
new DebugItemHandlerUIntMinMax(() => 0,
() =>
{
var id = 0;
switch (fullScreenDebugMode)
{
default:
case FullScreenDebugMode.DepthPyramid:
id = HDShaderIDs._DepthPyramidMipSize;
break;
case FullScreenDebugMode.FinalColorPyramid:
case FullScreenDebugMode.PreRefractionColorPyramid:
id = HDShaderIDs._GaussianPyramidColorMipSize;
break;
}
var size = Shader.GetGlobalVector(id);
var lodCount = Mathf.FloorToInt(Mathf.Log(Mathf.Min(size.x, size.y), 2f));
return (uint)lodCount;
})
);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, DebugLightingMode>(kLightingDebugMode, () => lightingDebugSettings.debugLightingMode, (value) => SetDebugLightingMode((DebugLightingMode)value));
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, bool>(kOverrideSmoothnessDebug, () => lightingDebugSettings.overrideSmoothness, (value) => lightingDebugSettings.overrideSmoothness = (bool)value);
DebugMenuManager.instance.AddDebugItem<LightingDebugPanel, float>(kOverrideSmoothnessValueDebug, () => lightingDebugSettings.overrideSmoothnessValue, (value) => lightingDebugSettings.overrideSmoothnessValue = (float)value, DebugItemFlag.None, new DebugItemHandlerFloatMinMax(0.0f, 1.0f));

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


newAsset.debugColorPickerShader = Load<Shader>(HDRenderPipelinePath + "Debug/DebugColorPicker.Shader");
newAsset.deferredShader = Load<Shader>(HDRenderPipelinePath + "Lighting/Deferred.Shader");
newAsset.gaussianPyramidCS = Load<ComputeShader>(PostProcessingPath + "Shaders/Builtins/GaussianDownsample.compute");
newAsset.depthPyramidCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/DepthDownsample.compute");
newAsset.gaussianPyramidCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ColorPyramid.compute");
newAsset.depthPyramidCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/DepthPyramid.compute");
newAsset.copyChannelCS = Load<ComputeShader>(CorePath + "Resources/GPUCopy.compute");
newAsset.applyDistortionCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ApplyDistorsion.compute");

190
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


RendererConfiguration m_currentRendererConfigurationBakedLighting = HDUtils.k_RendererConfigurationBakedLighting;
Material m_CopyStencilForNoLighting;
GPUCopy m_GPUCopy;
BufferPyramid m_BufferPyramid;
ComputeShader m_GaussianPyramidCS { get { return m_Asset.renderPipelineResources.gaussianPyramidCS; } }
int m_GaussianPyramidKernel;
ComputeShader m_DepthPyramidCS { get { return m_Asset.renderPipelineResources.depthPyramidCS; } }
int m_DepthPyramidKernel;
ComputeShader m_applyDistortionCS { get { return m_Asset.renderPipelineResources.applyDistortionCS; } }
int m_applyDistortionKernel;

readonly RenderTargetIdentifier m_DistortionBufferRT;
readonly RenderTargetIdentifier m_GaussianPyramidColorBufferRT;
readonly RenderTargetIdentifier m_DepthPyramidBufferRT;
RenderTextureDescriptor m_GaussianPyramidColorBufferDesc;
RenderTextureDescriptor m_DepthPyramidBufferDesc;
readonly RenderTargetIdentifier m_DeferredShadowBufferRT;

m_Asset = asset;
m_GPUCopy = new GPUCopy(asset.renderPipelineResources.copyChannelCS);
m_BufferPyramid = new BufferPyramid(
asset.renderPipelineResources.gaussianPyramidCS,
HDShaderIDs._GaussianPyramidColorMips,
asset.renderPipelineResources.depthPyramidCS,
m_GPUCopy,
HDShaderIDs._DepthPyramidMips);
EncodeBC6H.DefaultInstance = EncodeBC6H.DefaultInstance ?? new EncodeBC6H(asset.renderPipelineResources.encodeBC6HCS);
m_ReflectionProbeCullResults = new ReflectionProbeCullResults(asset.reflectionSystemParameters);

m_DistortionBuffer = HDShaderIDs._DistortionTexture;
m_DistortionBufferRT = new RenderTargetIdentifier(m_DistortionBuffer);
m_GaussianPyramidKernel = m_GaussianPyramidCS.FindKernel("KMain");
m_GaussianPyramidColorBufferDesc = new RenderTextureDescriptor(2, 2, RenderTextureFormat.ARGBHalf, 0)
{
useMipMap = true,
autoGenerateMips = false
};
m_DepthPyramidKernel = m_DepthPyramidCS.FindKernel("KMain");
m_DepthPyramidBufferDesc = new RenderTextureDescriptor(2, 2, RenderTextureFormat.RFloat, 0)
{
useMipMap = true,
autoGenerateMips = false
};
m_DeferredShadowBuffer = HDShaderIDs._DeferredShadowTexture;
m_DeferredShadowBufferRT = new RenderTargetIdentifier(m_DeferredShadowBuffer);

}
using (new ProfilingSample(cmd, "Gaussian Pyramid Color", CustomSamplerId.GaussianPyramidColor.GetSampler()))
{
var colorPyramidDesc = m_GaussianPyramidColorBufferDesc;
var pyramidSideSize = GetPyramidSize(colorPyramidDesc);
// The Gaussian pyramid compute works in blocks of 8x8 so make sure the last lod has a
// minimum size of 8x8
int lodCount = Mathf.FloorToInt(Mathf.Log(pyramidSideSize, 2f) - 3f);
if (lodCount > HDShaderIDs._GaussianPyramidColorMips.Length)
{
Debug.LogWarningFormat("Cannot compute all mipmaps of the color pyramid, max texture size supported: {0}", (2 << HDShaderIDs._GaussianPyramidColorMips.Length).ToString());
lodCount = HDShaderIDs._GaussianPyramidColorMips.Length;
}
cmd.SetGlobalVector(HDShaderIDs._GaussianPyramidColorMipSize, new Vector4(pyramidSideSize, pyramidSideSize, lodCount, 0));
cmd.SetGlobalTexture(HDShaderIDs._BlitTexture, m_CameraColorBufferRT);
CoreUtils.DrawFullScreen(cmd, m_Blit, m_GaussianPyramidColorBufferRT, null, 1); // Bilinear filtering
var last = m_GaussianPyramidColorBuffer;
colorPyramidDesc.sRGB = false;
colorPyramidDesc.enableRandomWrite = true;
colorPyramidDesc.useMipMap = false;
for (int i = 0; i < lodCount; i++)
{
colorPyramidDesc.width = colorPyramidDesc.width >> 1;
colorPyramidDesc.height = colorPyramidDesc.height >> 1;
// TODO: Add proper stereo support to the compute job
cmd.ReleaseTemporaryRT(HDShaderIDs._GaussianPyramidColorMips[i + 1]);
cmd.GetTemporaryRT(HDShaderIDs._GaussianPyramidColorMips[i + 1], colorPyramidDesc, FilterMode.Bilinear);
cmd.SetComputeTextureParam(m_GaussianPyramidCS, m_GaussianPyramidKernel, "_Source", last);
cmd.SetComputeTextureParam(m_GaussianPyramidCS, m_GaussianPyramidKernel, "_Result", HDShaderIDs._GaussianPyramidColorMips[i + 1]);
cmd.SetComputeVectorParam(m_GaussianPyramidCS, "_Size", new Vector4(colorPyramidDesc.width, colorPyramidDesc.height, 1f / colorPyramidDesc.width, 1f / colorPyramidDesc.height));
cmd.DispatchCompute(m_GaussianPyramidCS, m_GaussianPyramidKernel, colorPyramidDesc.width / 8, colorPyramidDesc.height / 8, 1);
cmd.CopyTexture(HDShaderIDs._GaussianPyramidColorMips[i + 1], 0, 0, m_GaussianPyramidColorBufferRT, 0, i + 1);
last = HDShaderIDs._GaussianPyramidColorMips[i + 1];
}
PushFullScreenDebugTextureMip(cmd, m_GaussianPyramidColorBufferRT, lodCount, m_GaussianPyramidColorBufferDesc, hdCamera, isPreRefraction ? FullScreenDebugMode.PreRefractionColorPyramid : FullScreenDebugMode.FinalColorPyramid);
m_BufferPyramid.RenderColorPyramid(hdCamera, cmd, renderContext, m_CameraColorBufferRT, m_GaussianPyramidColorBufferRT);
cmd.SetGlobalTexture(HDShaderIDs._GaussianPyramidColorTexture, m_GaussianPyramidColorBuffer);
for (int i = 0; i < lodCount; i++)
cmd.ReleaseTemporaryRT(HDShaderIDs._GaussianPyramidColorMips[i + 1]);
// TODO: Why don't we use _GaussianPyramidColorMips[0]?
}
var size = new Vector4(m_BufferPyramid.colorRenderTextureDescriptor.width, m_BufferPyramid.colorRenderTextureDescriptor.height, m_BufferPyramid.colorUsedMipMapCount, 0);
cmd.SetGlobalVector(HDShaderIDs._GaussianPyramidColorMipSize, size);
PushFullScreenDebugTextureMip(cmd, m_GaussianPyramidColorBufferRT, m_BufferPyramid.colorUsedMipMapCount, m_BufferPyramid.colorRenderTextureDescriptor, hdCamera, isPreRefraction ? FullScreenDebugMode.PreRefractionColorPyramid : FullScreenDebugMode.FinalColorPyramid);
}
void RenderPyramidDepth(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, FullScreenDebugMode debugMode)

using (new ProfilingSample(cmd, "Pyramid Depth", CustomSamplerId.PyramidDepth.GetSampler()))
{
var depthPyramidDesc = m_DepthPyramidBufferDesc;
var pyramidSideSize = GetPyramidSize(depthPyramidDesc);
m_BufferPyramid.RenderDepthPyramid(hdCamera, cmd, renderContext, GetDepthTexture(), m_DepthPyramidBufferRT);
// The gaussian pyramid compute works in blocks of 8x8 so make sure the last lod has a
// minimum size of 8x8
int lodCount = Mathf.FloorToInt(Mathf.Log(pyramidSideSize, 2f) - 3f);
if (lodCount > HDShaderIDs._DepthPyramidMips.Length)
{
Debug.LogWarningFormat("Cannot compute all mipmaps of the depth pyramid, max texture size supported: {0}", (2 << HDShaderIDs._DepthPyramidMips.Length).ToString());
lodCount = HDShaderIDs._DepthPyramidMips.Length;
}
var depthSize = new Vector4(m_BufferPyramid.depthRenderTextureDescriptor.width, m_BufferPyramid.depthRenderTextureDescriptor.height, m_BufferPyramid.depthUsedMipMapCount, 0);
cmd.SetGlobalVector(HDShaderIDs._DepthPyramidMipSize, depthSize);
PushFullScreenDebugDepthMip(cmd, m_DepthPyramidBufferRT, m_BufferPyramid.depthUsedMipMapCount, m_BufferPyramid.depthRenderTextureDescriptor, hdCamera, debugMode);
cmd.SetGlobalVector(HDShaderIDs._DepthPyramidMipSize, new Vector4(pyramidSideSize, pyramidSideSize, lodCount, 0));
cmd.ReleaseTemporaryRT(HDShaderIDs._DepthPyramidMips[0]);
depthPyramidDesc.sRGB = false;
depthPyramidDesc.enableRandomWrite = true;
depthPyramidDesc.useMipMap = false;
cmd.GetTemporaryRT(HDShaderIDs._DepthPyramidMips[0], depthPyramidDesc, FilterMode.Bilinear);
m_GPUCopy.SampleCopyChannel_xyzw2x(cmd, GetDepthTexture(), HDShaderIDs._DepthPyramidMips[0], new Vector2(depthPyramidDesc.width, depthPyramidDesc.height));
cmd.CopyTexture(HDShaderIDs._DepthPyramidMips[0], 0, 0, m_DepthPyramidBufferRT, 0, 0);
for (int i = 0; i < lodCount; i++)
{
var srcMipWidth = depthPyramidDesc.width;
var srcMipHeight = depthPyramidDesc.height;
depthPyramidDesc.width = srcMipWidth >> 1;
depthPyramidDesc.height = srcMipHeight >> 1;
cmd.ReleaseTemporaryRT(HDShaderIDs._DepthPyramidMips[i + 1]);
cmd.GetTemporaryRT(HDShaderIDs._DepthPyramidMips[i + 1], depthPyramidDesc, FilterMode.Bilinear);
cmd.SetComputeTextureParam(m_DepthPyramidCS, m_DepthPyramidKernel, "_Source", HDShaderIDs._DepthPyramidMips[i]);
cmd.SetComputeTextureParam(m_DepthPyramidCS, m_DepthPyramidKernel, "_Result", HDShaderIDs._DepthPyramidMips[i + 1]);
cmd.SetComputeVectorParam(m_DepthPyramidCS, "_SrcSize", new Vector4(srcMipWidth, srcMipHeight, 1f / srcMipWidth, 1f / srcMipHeight));
cmd.DispatchCompute(m_DepthPyramidCS, m_DepthPyramidKernel, depthPyramidDesc.width / 8, depthPyramidDesc.height / 8, 1);
cmd.CopyTexture(HDShaderIDs._DepthPyramidMips[i + 1], 0, 0, m_DepthPyramidBufferRT, 0, i + 1);
}
PushFullScreenDebugDepthMip(cmd, m_DepthPyramidBufferRT, lodCount, m_DepthPyramidBufferDesc, hdCamera, debugMode);
cmd.SetGlobalTexture(HDShaderIDs._PyramidDepthTexture, m_DepthPyramidBuffer);
for (int i = 0; i < lodCount + 1; i++)
cmd.ReleaseTemporaryRT(HDShaderIDs._DepthPyramidMips[i]);
}
cmd.SetGlobalTexture(HDShaderIDs._PyramidDepthTexture, m_DepthPyramidBuffer);
}
void RenderPostProcess(HDCamera hdcamera, CommandBuffer cmd, PostProcessLayer layer)

}
// Color and depth pyramids
m_GaussianPyramidColorBufferDesc = BuildPyramidDescriptor(hdCamera, PyramidType.Color, m_FrameSettings.enableStereo);
m_BufferPyramid.Initialize(hdCamera, m_FrameSettings.enableStereo);
cmd.GetTemporaryRT(m_GaussianPyramidColorBuffer, m_GaussianPyramidColorBufferDesc, FilterMode.Trilinear);
cmd.GetTemporaryRT(m_GaussianPyramidColorBuffer, m_BufferPyramid.colorRenderTextureDescriptor, FilterMode.Trilinear);
m_DepthPyramidBufferDesc = BuildPyramidDescriptor(hdCamera, PyramidType.Depth, m_FrameSettings.enableStereo);
m_BufferPyramid.Initialize(hdCamera, m_FrameSettings.enableStereo);
cmd.GetTemporaryRT(m_DepthPyramidBuffer, m_DepthPyramidBufferDesc, FilterMode.Trilinear);
cmd.GetTemporaryRT(m_DepthPyramidBuffer, m_BufferPyramid.depthRenderTextureDescriptor, FilterMode.Trilinear);
// End
if (!m_FrameSettings.enableForwardRenderingOnly)

}
// END TEMP
}
}
static int CalculatePyramidSize(int w, int h)
{
return Mathf.ClosestPowerOfTwo(Mathf.Min(w, h));
}
static int GetPyramidSize(RenderTextureDescriptor pyramidDesc)
{
// The monoscopic pyramid texture has both the width and height
// matching, so the pyramid size could be either dimension.
// However, with stereo double-wide rendering, we will arrange
// two pyramid textures next to each other inside the double-wide
// texture. The whole texture width will no longer be representative
// of the pyramid size, but the height still corresponds to the pyramid.
return pyramidDesc.height;
}
public enum PyramidType
{
Color = 0,
Depth = 1
}
static RenderTextureDescriptor BuildPyramidDescriptor(HDCamera hdCamera, PyramidType pyramidType, bool stereoEnabled)
{
var desc = hdCamera.renderTextureDesc;
desc.colorFormat = (pyramidType == PyramidType.Color) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.RFloat;
desc.depthBufferBits = 0;
desc.useMipMap = true;
desc.autoGenerateMips = false;
desc.msaaSamples = 1; // These are approximation textures, they don't need MSAA
var pyramidSize = CalculatePyramidSize((int)hdCamera.screenSize.x, (int)hdCamera.screenSize.y);
// for stereo double-wide, each half of the texture will represent a single eye's pyramid
//var widthModifier = 1;
//if (stereoEnabled && (desc.dimension != TextureDimension.Tex2DArray))
// widthModifier = 2; // double-wide
//desc.width = pyramidSize * widthModifier;
desc.width = pyramidSize;
desc.height = pyramidSize;
return desc;
}
}
}

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


debugColorPickerShader: {fileID: 4800000, guid: 8137b807709e178498f22ed710864bb0,
type: 3}
deferredShader: {fileID: 4800000, guid: 00dd221e34a6ab349a1196b0f2fab693, type: 3}
gaussianPyramidCS: {fileID: 7200000, guid: 6dba4103d23a7904fbc49099355aff3e, type: 3}
gaussianPyramidCS: {fileID: 7200000, guid: 4e3267a1135742441a14298d8dcac04a, type: 3}
depthPyramidCS: {fileID: 7200000, guid: 64a553bb564274041906f78ffba955e4, type: 3}
copyChannelCS: {fileID: 7200000, guid: a4d45eda75e8e474dbe24a31f741f3b4, type: 3}
applyDistortionCS: {fileID: 7200000, guid: 2fa6c0e3fe6dc3145a4156f21913fe5c, type: 3}

9
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
Texture2D<float> _Source;
RWTexture2D<float> _Result;

float4 _SrcSize;
CBUFFER_END
#pragma kernel KMain
[numthreads(8, 8, 1)]
void KMain(uint2 groupId : SV_GroupID, uint2 groupThreadId : SV_GroupThreadID, uint2 dispatchThreadId : SV_DispatchThreadID)
[numthreads(KERNEL_SIZE, KERNEL_SIZE, 1)]
void KERNEL_NAME(uint2 groupId : SV_GroupID, uint2 groupThreadId : SV_GroupThreadID, uint2 dispatchThreadId : SV_DispatchThreadID)
{
// Upper-left pixel coordinate of quad that this thread will read
int2 threadUL = dispatchThreadId;

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


using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
class BufferPyramid
{
static readonly int _Size = Shader.PropertyToID("_Size");
static readonly int _Source = Shader.PropertyToID("_Source");
static readonly int _Result = Shader.PropertyToID("_Result");
static readonly int _SrcSize = Shader.PropertyToID("_SrcSize");
const int k_DepthBlockSize = 4;
GPUCopy m_GPUCopy;
ComputeShader m_ColorPyramidCS;
RenderTextureDescriptor m_ColorRenderTextureDescriptor;
int[] m_ColorPyramidMips = new int[0];
int m_ColorPyramidKernel;
ComputeShader m_DepthPyramidCS;
RenderTextureDescriptor m_DepthRenderTextureDescriptor;
int[] m_DepthPyramidMips = new int[0];
int m_DepthPyramidKernel_8;
int m_DepthPyramidKernel_1;
public RenderTextureDescriptor colorRenderTextureDescriptor { get { return m_ColorRenderTextureDescriptor; } }
public int colorUsedMipMapCount { get { return Mathf.Min(colorBufferMipMapCount, m_ColorPyramidMips.Length); } }
public int colorBufferMipMapCount
{
get
{
var minSize = Mathf.Min(colorRenderTextureDescriptor.width, colorRenderTextureDescriptor.height);
return Mathf.FloorToInt(Mathf.Log(minSize, 2f));
}
}
public RenderTextureDescriptor depthRenderTextureDescriptor { get { return m_DepthRenderTextureDescriptor; } }
public int depthUsedMipMapCount { get { return Mathf.Min(depthBufferMipMapCount, m_DepthPyramidMips.Length); } }
public int depthBufferMipMapCount
{
get
{
var minSize = Mathf.Min(depthRenderTextureDescriptor.width, depthRenderTextureDescriptor.height);
return Mathf.FloorToInt(Mathf.Log(minSize, 2f));
}
}
public BufferPyramid(
ComputeShader colorPyramidCS, int[] colorMipIds,
ComputeShader depthPyramidCS, GPUCopy gpuCopy, int[] depthMipIds)
{
m_ColorPyramidCS = colorPyramidCS;
m_ColorPyramidKernel = m_ColorPyramidCS.FindKernel("KMain");
m_ColorPyramidMips = colorMipIds;
m_DepthPyramidCS = depthPyramidCS;
m_GPUCopy = gpuCopy;
m_DepthPyramidMips = depthMipIds;
m_DepthPyramidKernel_8 = m_DepthPyramidCS.FindKernel("KMain_8");
m_DepthPyramidKernel_1 = m_DepthPyramidCS.FindKernel("KMain_1");
}
public void RenderDepthPyramid(
HDCamera hdCamera,
CommandBuffer cmd,
ScriptableRenderContext renderContext,
RenderTargetIdentifier depthTexture,
RenderTargetIdentifier targetTexture)
{
var depthPyramidDesc = m_DepthRenderTextureDescriptor;
var lodCount = depthBufferMipMapCount;
if (lodCount > m_DepthPyramidMips.Length)
{
Debug.LogWarningFormat("Cannot compute all mipmaps of the depth pyramid, max texture size supported: {0}", (2 << m_DepthPyramidMips.Length).ToString());
lodCount = m_DepthPyramidMips.Length;
}
cmd.ReleaseTemporaryRT(m_DepthPyramidMips[0]);
depthPyramidDesc.sRGB = false;
depthPyramidDesc.enableRandomWrite = true;
depthPyramidDesc.useMipMap = false;
cmd.GetTemporaryRT(m_DepthPyramidMips[0], depthPyramidDesc, FilterMode.Bilinear);
m_GPUCopy.SampleCopyChannel_xyzw2x(cmd, depthTexture, m_DepthPyramidMips[0], new Vector2(depthPyramidDesc.width, depthPyramidDesc.height));
cmd.CopyTexture(m_DepthPyramidMips[0], 0, 0, targetTexture, 0, 0);
for (var i = 0; i < lodCount; i++)
{
var srcMipWidth = depthPyramidDesc.width;
var srcMipHeight = depthPyramidDesc.height;
depthPyramidDesc.width = srcMipWidth >> 1;
depthPyramidDesc.height = srcMipHeight >> 1;
var kernel = m_DepthPyramidKernel_8;
var kernelBlockSize = 8f;
if (depthPyramidDesc.width < 4 * k_DepthBlockSize
|| depthPyramidDesc.height < 4 * k_DepthBlockSize)
{
kernel = m_DepthPyramidKernel_1;
kernelBlockSize = 1;
}
cmd.ReleaseTemporaryRT(m_DepthPyramidMips[i + 1]);
cmd.GetTemporaryRT(m_DepthPyramidMips[i + 1], depthPyramidDesc, FilterMode.Bilinear);
cmd.SetComputeTextureParam(m_DepthPyramidCS, kernel, _Source, m_DepthPyramidMips[i]);
cmd.SetComputeTextureParam(m_DepthPyramidCS, kernel, _Result, m_DepthPyramidMips[i + 1]);
cmd.SetComputeVectorParam(m_DepthPyramidCS, _SrcSize, new Vector4(srcMipWidth, srcMipHeight, 1f / srcMipWidth, 1f / srcMipHeight));
cmd.DispatchCompute(
m_DepthPyramidCS,
kernel,
Mathf.CeilToInt(depthPyramidDesc.width / kernelBlockSize),
Mathf.CeilToInt(depthPyramidDesc.height / kernelBlockSize),
1);
cmd.CopyTexture(m_DepthPyramidMips[i + 1], 0, 0, targetTexture, 0, i + 1);
}
for (int i = 0; i < lodCount + 1; i++)
cmd.ReleaseTemporaryRT(m_DepthPyramidMips[i]);
}
public void RenderColorPyramid(
HDCamera hdCamera,
CommandBuffer cmd,
ScriptableRenderContext renderContext,
RenderTargetIdentifier colorTexture,
RenderTargetIdentifier targetTexture)
{
var colorPyramidDesc = colorRenderTextureDescriptor;
var lodCount = colorBufferMipMapCount;
if (lodCount > m_ColorPyramidMips.Length)
{
Debug.LogWarningFormat("Cannot compute all mipmaps of the color pyramid, max texture size supported: {0}", (2 << m_ColorPyramidMips.Length).ToString());
lodCount = m_ColorPyramidMips.Length;
}
// Copy mip 0
cmd.CopyTexture(colorTexture, 0, 0, targetTexture, 0, 0);
var last = colorTexture;
colorPyramidDesc.sRGB = false;
colorPyramidDesc.enableRandomWrite = true;
colorPyramidDesc.useMipMap = false;
for (var i = 0; i < lodCount; i++)
{
colorPyramidDesc.width = colorPyramidDesc.width >> 1;
colorPyramidDesc.height = colorPyramidDesc.height >> 1;
// TODO: Add proper stereo support to the compute job
cmd.ReleaseTemporaryRT(m_ColorPyramidMips[i + 1]);
cmd.GetTemporaryRT(m_ColorPyramidMips[i + 1], colorPyramidDesc, FilterMode.Bilinear);
cmd.SetComputeTextureParam(m_ColorPyramidCS, m_ColorPyramidKernel, _Source, last);
cmd.SetComputeTextureParam(m_ColorPyramidCS, m_ColorPyramidKernel, _Result, m_ColorPyramidMips[i + 1]);
cmd.SetComputeVectorParam(m_ColorPyramidCS, _Size, new Vector4(colorPyramidDesc.width, colorPyramidDesc.height, 1f / colorPyramidDesc.width, 1f / colorPyramidDesc.height));
cmd.DispatchCompute(
m_ColorPyramidCS,
m_ColorPyramidKernel,
Mathf.CeilToInt(colorPyramidDesc.width / 8f),
Mathf.CeilToInt(colorPyramidDesc.height / 8f),
1);
cmd.CopyTexture(m_ColorPyramidMips[i + 1], 0, 0, targetTexture, 0, i + 1);
last = m_ColorPyramidMips[i + 1];
}
for (int i = 0; i < lodCount; i++)
cmd.ReleaseTemporaryRT(m_ColorPyramidMips[i + 1]);
}
public void Initialize(HDCamera hdCamera, bool enableStereo)
{
var colorDesc = CalculateRenderTextureDescriptor(hdCamera, enableStereo);
colorDesc.colorFormat = RenderTextureFormat.ARGBHalf;
m_ColorRenderTextureDescriptor = colorDesc;
var depthDesc = CalculateRenderTextureDescriptor(hdCamera, enableStereo);
depthDesc.colorFormat = RenderTextureFormat.RFloat;
m_DepthRenderTextureDescriptor = depthDesc;
}
public static RenderTextureDescriptor CalculateRenderTextureDescriptor(HDCamera hdCamera, bool enableStereo)
{
var desc = hdCamera.renderTextureDesc;
desc.depthBufferBits = 0;
desc.useMipMap = true;
desc.autoGenerateMips = false;
desc.msaaSamples = 1; // These are approximation textures, they don't need MSAA
// for stereo double-wide, each half of the texture will represent a single eye's pyramid
//var widthModifier = 1;
//if (stereoEnabled && (desc.dimension != TextureDimension.Tex2DArray))
// widthModifier = 2; // double-wide
//desc.width = pyramidSize * widthModifier;
desc.width = (int)hdCamera.screenSize.x;
desc.height = (int)hdCamera.screenSize.y;
return desc;
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/BufferPyramid.cs.meta


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

144
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/ColorPyramid.compute


//
// This is a modified version of the BlurCS compute shader from Microsoft's MiniEngine
// library. The copyright notice from the original version is included below.
//
// The original source code of MiniEngine is available on GitHub.
// https://github.com/Microsoft/DirectX-Graphics-Samples
//
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
// Developed by Minigraph
//
// Author: Bob Brown
//
#include "CoreRP/ShaderLibrary/Common.hlsl"
Texture2D<float4> _Source;
RWTexture2D<float4> _Result;
SamplerState sampler_LinearClamp;
CBUFFER_START(cb)
float4 _Size;
CBUFFER_END
// 16x16 pixels with an 8x8 center that we will be blurring writing out. Each uint is two color
// channels packed together.
// The reason for separating channels is to reduce bank conflicts in the local data memory
// controller. A large stride will cause more threads to collide on the same memory bank.
groupshared uint gs_cacheR[128];
groupshared uint gs_cacheG[128];
groupshared uint gs_cacheB[128];
groupshared uint gs_cacheA[128];
float4 BlurPixels(float4 a, float4 b, float4 c, float4 d, float4 e, float4 f, float4 g, float4 h, float4 i)
{
return 0.27343750 * (e )
+ 0.21875000 * (d + f)
+ 0.10937500 * (c + g)
+ 0.03125000 * (b + h)
+ 0.00390625 * (a + i);
}
void Store2Pixels(uint index, float4 pixel1, float4 pixel2)
{
gs_cacheR[index] = f32tof16(pixel1.r) | f32tof16(pixel2.r) << 16;
gs_cacheG[index] = f32tof16(pixel1.g) | f32tof16(pixel2.g) << 16;
gs_cacheB[index] = f32tof16(pixel1.b) | f32tof16(pixel2.b) << 16;
gs_cacheA[index] = f32tof16(pixel1.a) | f32tof16(pixel2.a) << 16;
}
void Load2Pixels(uint index, out float4 pixel1, out float4 pixel2)
{
uint rr = gs_cacheR[index];
uint gg = gs_cacheG[index];
uint bb = gs_cacheB[index];
uint aa = gs_cacheA[index];
pixel1 = float4(f16tof32(rr ), f16tof32(gg ), f16tof32(bb ), f16tof32(aa ));
pixel2 = float4(f16tof32(rr >> 16), f16tof32(gg >> 16), f16tof32(bb >> 16), f16tof32(aa >> 16));
}
void Store1Pixel(uint index, float4 pixel)
{
gs_cacheR[index] = asuint(pixel.r);
gs_cacheG[index] = asuint(pixel.g);
gs_cacheB[index] = asuint(pixel.b);
gs_cacheA[index] = asuint(pixel.a);
}
void Load1Pixel(uint index, out float4 pixel)
{
pixel = asfloat(uint4(gs_cacheR[index], gs_cacheG[index], gs_cacheB[index], gs_cacheA[index]));
}
// Blur two pixels horizontally. This reduces LDS reads and pixel unpacking.
void BlurHorizontally(uint outIndex, uint leftMostIndex)
{
float4 s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
Load2Pixels(leftMostIndex + 0, s0, s1);
Load2Pixels(leftMostIndex + 1, s2, s3);
Load2Pixels(leftMostIndex + 2, s4, s5);
Load2Pixels(leftMostIndex + 3, s6, s7);
Load2Pixels(leftMostIndex + 4, s8, s9);
Store1Pixel(outIndex , BlurPixels(s0, s1, s2, s3, s4, s5, s6, s7, s8));
Store1Pixel(outIndex + 1, BlurPixels(s1, s2, s3, s4, s5, s6, s7, s8, s9));
}
void BlurVertically(uint2 pixelCoord, uint topMostIndex)
{
float4 s0, s1, s2, s3, s4, s5, s6, s7, s8;
Load1Pixel(topMostIndex , s0);
Load1Pixel(topMostIndex + 8, s1);
Load1Pixel(topMostIndex + 16, s2);
Load1Pixel(topMostIndex + 24, s3);
Load1Pixel(topMostIndex + 32, s4);
Load1Pixel(topMostIndex + 40, s5);
Load1Pixel(topMostIndex + 48, s6);
Load1Pixel(topMostIndex + 56, s7);
Load1Pixel(topMostIndex + 64, s8);
float4 blurred = BlurPixels(s0, s1, s2, s3, s4, s5, s6, s7, s8);
// Write to the final target
_Result[pixelCoord] = blurred;
}
#pragma kernel KMain
[numthreads(8, 8, 1)]
void KMain(uint2 groupId : SV_GroupID, uint2 groupThreadId : SV_GroupThreadID, uint2 dispatchThreadId : SV_DispatchThreadID)
{
// Upper-left pixel coordinate of quad that this thread will read
int2 threadUL = (groupThreadId << 1) + (groupId << 3) - 4;
// Downsample the block
float2 offset = float2(threadUL);
float4 p00 = _Source.SampleLevel(sampler_LinearClamp, (offset + 0.5) * _Size.zw, 0.0);
float4 p10 = _Source.SampleLevel(sampler_LinearClamp, (offset + float2(1.0, 0.0) + 0.5) * _Size.zw, 0.0);
float4 p01 = _Source.SampleLevel(sampler_LinearClamp, (offset + float2(0.0, 1.0) + 0.5) * _Size.zw, 0.0);
float4 p11 = _Source.SampleLevel(sampler_LinearClamp, (offset + float2(1.0, 1.0) + 0.5) * _Size.zw, 0.0);
// Store the 4 downsampled pixels in LDS
uint destIdx = groupThreadId.x + (groupThreadId.y << 4u);
Store2Pixels(destIdx , p00, p10);
Store2Pixels(destIdx + 8u, p01, p11);
GroupMemoryBarrierWithGroupSync();
// Horizontally blur the pixels in LDS
uint row = groupThreadId.y << 4u;
BlurHorizontally(row + (groupThreadId.x << 1u), row + groupThreadId.x + (groupThreadId.x & 4u));
GroupMemoryBarrierWithGroupSync();
// Vertically blur the pixels in LDS and write the result to memory
BlurVertically(dispatchThreadId, (groupThreadId.y << 3u) + groupThreadId.x);
}

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/ColorPyramid.compute.meta


fileFormatVersion: 2
guid: 4e3267a1135742441a14298d8dcac04a
timeCreated: 1503754250
licenseType: Pro
ComputeShaderImporter:
currentAPIMask: 131076
userData:
assetBundleName:
assetBundleVariant:

/ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthDownsample.compute.meta → /ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute.meta

/ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthDownsample.compute → /ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute

正在加载...
取消
保存