浏览代码

Fixed Depth/Color pyramid after last merge

/main
Julien Ignace 7 年前
当前提交
a4625b1c
共有 7 个文件被更改,包括 130 次插入239 次删除
  1. 2
      ScriptableRenderPipeline/Core/CoreRP/Resources/GPUCopy.compute
  2. 6
      ScriptableRenderPipeline/Core/CoreRP/Resources/GPUCopy.cs
  3. 2
      ScriptableRenderPipeline/Core/CoreRP/Resources/GPUCopyAsset.cs
  4. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  5. 130
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  6. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  7. 219
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/BufferPyramid.cs

2
ScriptableRenderPipeline/Core/CoreRP/Resources/GPUCopy.compute


[numthreads(8, 8, 1)]
void KSampleCopy4_1_x(uint2 dispatchThreadId : SV_DispatchThreadID)
{
_Result1[dispatchThreadId] = SAMPLE_TEXTURE2D_LOD(_Source4, sampler_LinearClamp, float2(dispatchThreadId) * _Size.zw, 0.0).x;
_Result1[dispatchThreadId] = LOAD_TEXTURE2D(_Source4, dispatchThreadId).x;
}

6
ScriptableRenderPipeline/Core/CoreRP/Resources/GPUCopy.cs


static readonly int _Result1 = Shader.PropertyToID("_Result1");
static readonly int _Source4 = Shader.PropertyToID("_Source4");
static readonly int _Size = Shader.PropertyToID("_Size");
public void SampleCopyChannel_xyzw2x(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, Vector2 kernelSize, Vector2 targetSize)
public void SampleCopyChannel_xyzw2x(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, Vector2 size)
var s = new Vector4(targetSize.x, targetSize.y, 1f / targetSize.x, 1f / targetSize.y);
var s = new Vector4(size.x, size.y, 1f / size.x, 1f / size.y);
cmd.DispatchCompute(m_Shader, k_SampleKernel_xyzw2x, (int)Mathf.Max((kernelSize.x) / 8, 1), (int)Mathf.Max((kernelSize.y) / 8, 1), 1);
cmd.DispatchCompute(m_Shader, k_SampleKernel_xyzw2x, (int)Mathf.Max((size.x) / 8, 1), (int)Mathf.Max((size.y) / 8, 1), 1);
}
}

2
ScriptableRenderPipeline/Core/CoreRP/Resources/GPUCopyAsset.cs


k_KernelSize.ToString(), k_KernelSize.ToString()));
cck.AppendLine(string.Format(@"void {0}(uint2 dispatchThreadId : SV_DispatchThreadID)", kernelName));
cck.AppendLine("{");
cck.AppendLine(string.Format(" _Result{0}[dispatchThreadId] = SAMPLE_TEXTURE2D_LOD(_Source{1}, sampler_LinearClamp, float2(dispatchThreadId) * _Size.zw, 0.0).{2};",
cck.AppendLine(string.Format(" _Result{0}[dispatchThreadId] = LOAD_TEXTURE2D(_Source{1}, dispatchThreadId).{2};",
o.targetChannel.ToString(), o.sourceChannel.ToString(), o.subscript));
cck.AppendLine("}");
cck.AppendLine();

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


break;
}
var size = Shader.GetGlobalVector(id);
var lodCount = Mathf.FloorToInt(Mathf.Log(Mathf.Min(size.x, size.y), 2f));
var lodCount = size.z;
return (uint)(fullscreenDebugMip * lodCount);
},

break;
}
var size = Shader.GetGlobalVector(id);
var lodCount = Mathf.Floor(Mathf.Log(Mathf.Min(size.x, size.y), 2f));
var lodCount = size.z;
fullscreenDebugMip = (float)Convert.ChangeType(value, typeof(Single)) / lodCount;
},
DebugItemFlag.None,

break;
}
var size = Shader.GetGlobalVector(id);
var lodCount = Mathf.FloorToInt(Mathf.Log(Mathf.Min(size.x, size.y), 2f));
var lodCount = size.z;
return (uint)lodCount;
})
);

130
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using System;
using System.Diagnostics;
using System.Linq;

RTHandle m_AmbientOcclusionBuffer;
RTHandle m_DistortionBuffer;
RTHandle m_GaussianPyramidColorBuffer;
List<RTHandle> m_GaussianPyramidColorMips = new List<RTHandle>();
RTHandle m_DepthPyramidBuffer;
List<RTHandle> m_DepthPyramidMips = new List<RTHandle>();
// The pass "SRPDefaultUnlit" is a fall back to legacy unlit rendering and is required to support unity 2d + unity UI that render in the scene.
ShaderPassName[] m_ForwardAndForwardOnlyPassNames = { new ShaderPassName(), new ShaderPassName(), HDShaderPassNames.s_SRPDefaultUnlitName };
ShaderPassName[] m_ForwardOnlyPassNames = { new ShaderPassName(), HDShaderPassNames.s_SRPDefaultUnlitName };

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

InitializeRenderStateBlocks();
}
int GetPyramidSize(HDCamera camera)
{
// 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.
// Additionnaly, since we may not use the full size of the texture we need to return the size corresponding to the current camera.
return m_GaussianPyramidColorBuffer.GetScaledSize(new Vector2Int(camera.actualWidth, camera.actualHeight)).y;
}
// Pyramid might not be rendered in the full render target. Code that samples it must account for this by scaling UVs with this factor.
float GetGaussianPyramidScale(HDCamera camera)
{
return (float)GetPyramidSize(camera) / m_GaussianPyramidColorBuffer.rt.height;
}
Vector2Int CalculatePyramidSize(Vector2Int size)
{
// for stereo double-wide, each half of the texture will represent a single eye's pyramid
var widthModifier = 1;
//if (m_Asset.renderPipelineSettings.supportsStereo && (desc.dimension != TextureDimension.Tex2DArray))
// widthModifier = 2; // double-wide
int pyramidSize = (int)Mathf.ClosestPowerOfTwo(Mathf.Min(size.x, size.y));
return new Vector2Int(pyramidSize * widthModifier, pyramidSize);
}
Vector2Int CalculatePyramidMipSize(Vector2Int baseMipSize, int mipIndex)
{
return new Vector2Int(baseMipSize.x >> mipIndex, baseMipSize.y >> mipIndex);
}
int GetPyramidLodCount(HDCamera camera)
{
var pyramidSideSize = GetPyramidSize(camera);
// The Gaussian pyramid compute works in blocks of 8x8 so make sure the last lod has a
// minimum size of 8x8
return Mathf.FloorToInt(Mathf.Log(pyramidSideSize, 2f) - 3f);
}
void UpdatePyramidMips(HDCamera camera, RenderTextureFormat format, List<RTHandle> mipList)
{
int lodCount = GetPyramidLodCount(camera);
int currentLodCount = mipList.Count;
if (lodCount > currentLodCount)
{
for (int i = currentLodCount; i < lodCount; ++i)
{
int localCopy = i; // Don't remove this copy! It's important for the value to be correctly captured by the lambda.
RTHandle newMip = RTHandle.Alloc(size => CalculatePyramidMipSize(CalculatePyramidSize(size), localCopy + 1), colorFormat: format, sRGB: false, enableRandomWrite: true, useMipMap: false, filterMode: FilterMode.Bilinear);
mipList.Add(newMip);
}
}
}
void InitializeRenderTextures()
{
// Initial state of the RTHandle system.

if(m_Asset.renderPipelineSettings.supportDBuffer)
m_DbufferManager.CreateBuffers();
m_BufferPyramid.CreateBuffers();
m_SSSBufferManager.InitSSSBuffers(m_GbufferManager, m_Asset.renderPipelineSettings);

// TODO: For MSAA, we'll need to add a Draw path in order to support MSAA properly
m_DeferredShadowBuffer = RTHandle.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGB32, sRGB: false, enableRandomWrite: true);
m_GaussianPyramidColorBuffer = RTHandle.Alloc(size => CalculatePyramidSize(size), filterMode: FilterMode.Trilinear, colorFormat: RenderTextureFormat.ARGBHalf, sRGB: true, useMipMap: true, autoGenerateMips: false);
m_DepthPyramidBuffer = RTHandle.Alloc(size => CalculatePyramidSize(size), filterMode: FilterMode.Trilinear, colorFormat: RenderTextureFormat.RFloat, sRGB: false, useMipMap: true, autoGenerateMips: false, enableRandomWrite: true); // Need randomReadWrite because we downsample the first mip with a compute shader.
if (Debug.isDebugBuild)
{
m_DebugColorPickerBuffer = RTHandle.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGBHalf, sRGB: false);

{
m_GbufferManager.DestroyBuffers();
m_DbufferManager.DestroyBuffers();
m_BufferPyramid.DestroyBuffers();
RTHandle.Release(m_CameraColorBuffer);
RTHandle.Release(m_CameraSssDiffuseLightingBuffer);

RTHandle.Release(m_DistortionBuffer);
RTHandle.Release(m_DeferredShadowBuffer);
RTHandle.Release(m_GaussianPyramidColorBuffer);
RTHandle.Release(m_DepthPyramidBuffer);
foreach (var rth in m_GaussianPyramidColorMips)
{
RTHandle.Release(rth);
}
foreach (var rth in m_DepthPyramidMips)
{
RTHandle.Release(rth);
}
}

using (new ProfilingSample(cmd, "ApplyDistortion", CustomSamplerId.ApplyDistortion.GetSampler()))
{
float scale = GetGaussianPyramidScale(hdCamera);
var size = new Vector4(hdCamera.screenSize.x, hdCamera.screenSize.y, scale / hdCamera.screenSize.x, scale / hdCamera.screenSize.y);
var size = new Vector4(hdCamera.screenSize.x, hdCamera.screenSize.y, hdCamera.scaleBias.x / hdCamera.screenSize.x, hdCamera.scaleBias.y / hdCamera.screenSize.y);
cmd.SetComputeTextureParam(m_applyDistortionCS, m_applyDistortionKernel, HDShaderIDs._GaussianPyramidColorTexture, m_GaussianPyramidColorBuffer);
cmd.SetComputeTextureParam(m_applyDistortionCS, m_applyDistortionKernel, HDShaderIDs._GaussianPyramidColorTexture, m_BufferPyramid.colorPyramid);
cmd.SetComputeVectorParam(m_applyDistortionCS, HDShaderIDs._GaussianPyramidColorMipSize, Shader.GetGlobalVector(HDShaderIDs._GaussianPyramidColorMipSize));
cmd.DispatchCompute(m_applyDistortionCS, m_applyDistortionKernel, Mathf.CeilToInt(size.x / x), Mathf.CeilToInt(size.y / y), 1);
}

}
using (new ProfilingSample(cmd, "Gaussian Pyramid Color", CustomSamplerId.GaussianPyramidColor.GetSampler()))
m_BufferPyramid.RenderColorPyramid(hdCamera, cmd, renderContext, m_CameraColorBufferRT, m_GaussianPyramidColorBufferRT);
m_BufferPyramid.RenderColorPyramid(hdCamera, cmd, renderContext, m_CameraColorBuffer);
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);
}
PushFullScreenDebugTextureMip(cmd, m_BufferPyramid.colorPyramid, m_BufferPyramid.GetPyramidLodCount(hdCamera), 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()))
m_BufferPyramid.RenderDepthPyramid(hdCamera, cmd, renderContext, GetDepthTexture(), m_DepthPyramidBufferRT);
m_BufferPyramid.RenderDepthPyramid(hdCamera, cmd, renderContext, GetDepthTexture());
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);
PushFullScreenDebugTextureMip(cmd, m_BufferPyramid.depthPyramid, m_BufferPyramid.GetPyramidLodCount(hdCamera), hdCamera, debugMode);
cmd.SetGlobalTexture(HDShaderIDs._PyramidDepthTexture, m_DepthPyramidBuffer);
}
cmd.SetGlobalTexture(HDShaderIDs._PyramidDepthTexture, m_BufferPyramid.depthPyramid);
}
void RenderPostProcess(HDCamera hdcamera, CommandBuffer cmd, PostProcessLayer layer)
{

}
}
void PushPyramidDebugTextureMip(CommandBuffer cmd, RTHandle texture, int lodCount, HDCamera hdCamera, float scale, FullScreenDebugMode debugMode)
{
if (debugMode == m_CurrentDebugDisplaySettings.fullScreenDebugMode)
{
var mipIndex = Mathf.FloorToInt(m_CurrentDebugDisplaySettings.fullscreenDebugMip * (lodCount));
m_FullScreenDebugPushed = true; // We need this flag because otherwise if no full screen debug is pushed (like for example if the corresponding pass is disabled), when we render the result in RenderDebug m_DebugFullScreenTempBuffer will contain potential garbage
HDUtils.BlitCameraTexture(cmd, hdCamera, texture, m_DebugFullScreenTempBuffer, new Vector4(scale, scale, 0.0f, 0.0f), mipIndex);
}
}
void PushDepthPyramidDebugDepthMip(CommandBuffer cmd, RTHandle texture, int lodCount, HDCamera hdCamera, float scale, FullScreenDebugMode debugMode)
void PushFullScreenDebugTextureMip(CommandBuffer cmd, RTHandle texture, int lodCount, HDCamera hdCamera, FullScreenDebugMode debugMode)
//m_FullScreenDebugPushed = true; // We need this flag because otherwise if no full screen debug is pushed (like for example if the corresponding pass is disabled), when we render the result in RenderDebug m_DebugFullScreenTempBuffer will contain potential garbage
//cmd.CopyTexture(texture, 0, mipIndex, m_DebugFullScreenTempBuffer, 0, 0); // TODO: Support tex arrays
HDUtils.BlitCameraTexture(cmd, hdCamera, texture, m_DebugFullScreenTempBuffer, new Vector4(scale, scale, 0.0f, 0.0f), mipIndex);
HDUtils.BlitCameraTexture(cmd, hdCamera, texture, m_DebugFullScreenTempBuffer, mipIndex);
}
}

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


TEXTURE2D(_PyramidDepthTexture);
CBUFFER_START(UnityGaussianPyramidParameters)
float4 _GaussianPyramidColorMipSize;
float4 _GaussianPyramidColorMipSize; // z = lodCount
float4 _PyramidDepthMipSize;
CBUFFER_END

}
// Map the roughness to the correct mip map level of the color pyramid
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, refractedBackPointNDC * _GaussianPyramidColorMipSize.ww, preLightData.transparentSSMipLevel).rgb;
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, refractedBackPointNDC * _ScreenToTargetScale.xy, preLightData.transparentSSMipLevel).rgb;
// Beer-Lamber law for absorption
lighting.specularTransmitted *= preLightData.transparentTransmittance;

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


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

GPUCopy m_GPUCopy;
ComputeShader m_ColorPyramidCS;
RenderTextureDescriptor m_ColorRenderTextureDescriptor;
int[] m_ColorPyramidMips = new int[0];
RTHandle m_ColorPyramidBuffer;
List<RTHandle> m_ColorPyramidMips = new List<RTHandle>();
RenderTextureDescriptor m_DepthRenderTextureDescriptor;
int[] m_DepthPyramidMips = new int[0];
RTHandle m_DepthPyramidBuffer;
List<RTHandle> m_DepthPyramidMips = new List<RTHandle>();
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 RTHandle colorPyramid { get { return m_ColorPyramidBuffer; } }
public RTHandle depthPyramid { get { return m_DepthPyramidBuffer; } }
ComputeShader colorPyramidCS, int[] colorMipIds,
ComputeShader depthPyramidCS, GPUCopy gpuCopy, int[] depthMipIds)
ComputeShader colorPyramidCS,
ComputeShader depthPyramidCS, GPUCopy gpuCopy)
m_ColorPyramidMips = colorMipIds;
m_DepthPyramidMips = depthMipIds;
public void RenderDepthPyramid(
HDCamera hdCamera,
CommandBuffer cmd,
ScriptableRenderContext renderContext,
RenderTargetIdentifier depthTexture,
RenderTargetIdentifier targetTexture)
public int GetPyramidLodCount(HDCamera camera)
var depthPyramidDesc = m_DepthRenderTextureDescriptor;
var minSize = Mathf.Min(camera.actualWidth, camera.actualHeight);
return Mathf.FloorToInt(Mathf.Log(minSize, 2f));
}
var lodCount = depthBufferMipMapCount;
if (lodCount > m_DepthPyramidMips.Length)
Vector2Int CalculatePyramidMipSize(Vector2Int baseMipSize, int mipIndex)
{
float scale = GetXRscale();
return new Vector2Int((int)(baseMipSize.x * scale) >> mipIndex, baseMipSize.y >> mipIndex);
}
void UpdatePyramidMips(HDCamera camera, RenderTextureFormat format, List<RTHandle> mipList, int lodCount)
{
int currentLodCount = mipList.Count;
if (lodCount > currentLodCount)
Debug.LogWarningFormat("Cannot compute all mipmaps of the depth pyramid, max texture size supported: {0}", (2 << m_DepthPyramidMips.Length).ToString());
lodCount = m_DepthPyramidMips.Length;
for (int i = currentLodCount; i < lodCount; ++i)
{
int mipIndexCopy = i + 1; // Don't remove this copy! It's important for the value to be correctly captured by the lambda.
RTHandle newMip = RTHandle.Alloc(size => CalculatePyramidMipSize(size, mipIndexCopy), colorFormat: format, sRGB: false, enableRandomWrite: true, useMipMap: false, filterMode: FilterMode.Bilinear);
mipList.Add(newMip);
}
}
cmd.ReleaseTemporaryRT(m_DepthPyramidMips[0]);
public void RenderDepthPyramid(
HDCamera hdCamera,
CommandBuffer cmd,
ScriptableRenderContext renderContext,
RTHandle depthTexture)
{
int lodCount = GetPyramidLodCount(hdCamera);
UpdatePyramidMips(hdCamera, m_DepthPyramidBuffer.rt.format, m_DepthPyramidMips, lodCount);
depthPyramidDesc.sRGB = false;
depthPyramidDesc.enableRandomWrite = true;
depthPyramidDesc.useMipMap = false;
cmd.SetGlobalVector(HDShaderIDs._DepthPyramidMipSize, new Vector4(hdCamera.actualWidth, hdCamera.actualHeight, lodCount, 0.0f));
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);
m_GPUCopy.SampleCopyChannel_xyzw2x(cmd, depthTexture, m_DepthPyramidBuffer, new Vector2(hdCamera.actualWidth, hdCamera.actualHeight));
RTHandle src = m_DepthPyramidBuffer;
var srcMipWidth = depthPyramidDesc.width;
var srcMipHeight = depthPyramidDesc.height;
depthPyramidDesc.width = srcMipWidth >> 1;
depthPyramidDesc.height = srcMipHeight >> 1;
RTHandle dest = m_DepthPyramidMips[i];
var srcMipWidth = hdCamera.actualWidth >> i;
var srcMipHeight = hdCamera.actualHeight >> i;
var dstMipWidth = srcMipWidth >> 1;
var dstMipHeight = srcMipHeight >> 1;
if (depthPyramidDesc.width < 4 * k_DepthBlockSize
|| depthPyramidDesc.height < 4 * k_DepthBlockSize)
if (dstMipWidth < 4 * k_DepthBlockSize
|| dstMipHeight < 4 * k_DepthBlockSize)
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.SetComputeTextureParam(m_DepthPyramidCS, kernel, _Source, src);
cmd.SetComputeTextureParam(m_DepthPyramidCS, kernel, _Result, dest);
cmd.SetComputeVectorParam(m_DepthPyramidCS, _SrcSize, new Vector4(srcMipWidth, srcMipHeight, hdCamera.scaleBias.x / srcMipWidth, hdCamera.scaleBias.y / srcMipHeight));
Mathf.CeilToInt(depthPyramidDesc.width / kernelBlockSize),
Mathf.CeilToInt(depthPyramidDesc.height / kernelBlockSize),
Mathf.CeilToInt(dstMipWidth / kernelBlockSize),
Mathf.CeilToInt(dstMipHeight / kernelBlockSize),
cmd.CopyTexture(m_DepthPyramidMips[i + 1], 0, 0, targetTexture, 0, i + 1);
// If we could bind texture mips as UAV we could avoid this copy...(which moreover copies more than the needed viewport if not fullscreen)
cmd.CopyTexture(m_DepthPyramidMips[i], 0, 0, m_DepthPyramidBuffer, 0, i + 1);
src = dest;
for (int i = 0; i < lodCount + 1; i++)
cmd.ReleaseTemporaryRT(m_DepthPyramidMips[i]);
cmd.SetGlobalTexture(HDShaderIDs._PyramidDepthTexture, m_DepthPyramidBuffer);
}
public void RenderColorPyramid(

RenderTargetIdentifier colorTexture,
RenderTargetIdentifier targetTexture)
RTHandle colorTexture)
var colorPyramidDesc = colorRenderTextureDescriptor;
int lodCount = GetPyramidLodCount(hdCamera);
UpdatePyramidMips(hdCamera, m_ColorPyramidBuffer.rt.format, m_ColorPyramidMips, lodCount);
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;
}
cmd.SetGlobalVector(HDShaderIDs._GaussianPyramidColorMipSize, new Vector4(hdCamera.actualWidth, hdCamera.actualHeight, lodCount, 0.0f));
cmd.CopyTexture(colorTexture, 0, 0, targetTexture, 0, 0);
var last = colorTexture;
HDUtils.BlitCameraTexture(cmd, hdCamera, colorTexture, m_ColorPyramidBuffer); // true : bilinear
colorPyramidDesc.sRGB = false;
colorPyramidDesc.enableRandomWrite = true;
colorPyramidDesc.useMipMap = false;
RTHandle src = m_ColorPyramidBuffer;
colorPyramidDesc.width = colorPyramidDesc.width >> 1;
colorPyramidDesc.height = colorPyramidDesc.height >> 1;
RTHandle dest = m_ColorPyramidMips[i];
var srcMipWidth = hdCamera.actualWidth >> i;
var srcMipHeight = hdCamera.actualHeight >> i;
var dstMipWidth = srcMipWidth >> 1;
var dstMipHeight = srcMipHeight >> 1;
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.SetComputeTextureParam(m_ColorPyramidCS, m_ColorPyramidKernel, _Source, src);
cmd.SetComputeTextureParam(m_ColorPyramidCS, m_ColorPyramidKernel, _Result, dest);
// _Size is used as a scale inside the whole render target so here we need to keep the full size (and not the scaled size depending on the current camera)
cmd.SetComputeVectorParam(m_ColorPyramidCS, _Size, new Vector4(dest.rt.width, dest.rt.height, 1f / dest.rt.width, 1f / dest.rt.height));
Mathf.CeilToInt(colorPyramidDesc.width / 8f),
Mathf.CeilToInt(colorPyramidDesc.height / 8f),
Mathf.CeilToInt(dstMipWidth / 8f),
Mathf.CeilToInt(dstMipHeight / 8f),
cmd.CopyTexture(m_ColorPyramidMips[i + 1], 0, 0, targetTexture, 0, i + 1);
// If we could bind texture mips as UAV we could avoid this copy...(which moreover copies more than the needed viewport if not fullscreen)
cmd.CopyTexture(m_ColorPyramidMips[i], 0, 0, m_ColorPyramidBuffer, 0, i + 1);
last = m_ColorPyramidMips[i + 1];
src = dest;
for (int i = 0; i < lodCount; i++)
cmd.ReleaseTemporaryRT(m_ColorPyramidMips[i + 1]);
cmd.SetGlobalTexture(HDShaderIDs._GaussianPyramidColorTexture, m_ColorPyramidBuffer);
public void Initialize(HDCamera hdCamera, bool enableStereo)
float GetXRscale()
var colorDesc = CalculateRenderTextureDescriptor(hdCamera, enableStereo);
colorDesc.colorFormat = RenderTextureFormat.ARGBHalf;
m_ColorRenderTextureDescriptor = colorDesc;
var depthDesc = CalculateRenderTextureDescriptor(hdCamera, enableStereo);
depthDesc.colorFormat = RenderTextureFormat.RFloat;
m_DepthRenderTextureDescriptor = depthDesc;
float scale = 1.0f;
//if (m_Asset.renderPipelineSettings.supportsStereo && (desc.dimension != TextureDimension.Tex2DArray))
// scale = 2.0f; // double-wide
return scale;
public static RenderTextureDescriptor CalculateRenderTextureDescriptor(HDCamera hdCamera, bool enableStereo)
public void CreateBuffers()
var desc = hdCamera.renderTextureDesc;
desc.depthBufferBits = 0;
desc.useMipMap = true;
desc.autoGenerateMips = false;
Vector2 sizeScale = Vector2.one;
sizeScale.x *= GetXRscale();
desc.msaaSamples = 1; // These are approximation textures, they don't need MSAA
m_ColorPyramidBuffer = RTHandle.Alloc(sizeScale, filterMode: FilterMode.Trilinear, colorFormat: RenderTextureFormat.ARGBHalf, sRGB: true, useMipMap: true, autoGenerateMips: false);
m_DepthPyramidBuffer = RTHandle.Alloc(sizeScale, filterMode: FilterMode.Trilinear, colorFormat: RenderTextureFormat.RFloat, sRGB: false, useMipMap: true, autoGenerateMips: false, enableRandomWrite: true); // Need randomReadWrite because we downsample the first mip with a compute shader.
}
// 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
public void DestroyBuffers()
{
RTHandle.Release(m_ColorPyramidBuffer);
RTHandle.Release(m_DepthPyramidBuffer);
//desc.width = pyramidSize * widthModifier;
desc.width = (int)hdCamera.screenSize.x;
desc.height = (int)hdCamera.screenSize.y;
foreach (var rth in m_ColorPyramidMips)
{
RTHandle.Release(rth);
}
return desc;
foreach (var rth in m_DepthPyramidMips)
{
RTHandle.Release(rth);
}
}
}
}
正在加载...
取消
保存