浏览代码

Full screen color pyramid

/feature-ScreenSpaceProjection
Frédéric Vauchelles 6 年前
当前提交
2fd72ffd
共有 11 个文件被更改,包括 221 次插入74 次删除
  1. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDAssetFactory.cs
  2. 33
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  3. 49
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/ColorPyramid.cs
  4. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.cs
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset
  6. 144
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/ColorPyramid.compute
  7. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/ColorPyramid.compute.meta
  8. 26
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/PyramidUtils.cs
  9. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/PyramidUtils.cs.meta
  10. 0
      /ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute
  11. 0
      /ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.compute.meta

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");

33
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


IBLFilterGGX m_IBLFilterGGX = null;
ComputeShader m_GaussianPyramidCS { get { return m_Asset.renderPipelineResources.gaussianPyramidCS; } }
int m_GaussianPyramidKernel;
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;
readonly RenderTargetIdentifier m_DeferredShadowBufferRT;

m_Asset = asset;
m_GPUCopy = new GPUCopy(asset.renderPipelineResources.copyChannelCS);
m_DepthPyramid = new DepthPyramid(asset.renderPipelineResources.depthPyramidCS, m_GPUCopy, HDShaderIDs._DepthPyramidMips);
m_DepthPyramid = new DepthPyramid(
asset.renderPipelineResources.depthPyramidCS,
m_GPUCopy,
HDShaderIDs._DepthPyramidMips);
m_ColorPyramid = new ColorPyramid(
asset.renderPipelineResources.gaussianPyramidCS,
HDShaderIDs._GaussianPyramidColorMips);
EncodeBC6H.DefaultInstance = EncodeBC6H.DefaultInstance ?? new EncodeBC6H(asset.renderPipelineResources.encodeBC6HCS);

InitializeDebugMaterials();
// Require m_Blit in InitializeDebugMaterials();
m_ColorPyramid = new ColorPyramid(
asset.renderPipelineResources.gaussianPyramidCS,
m_GPUCopy,
m_Blit,
HDShaderIDs._BlitTexture,
HDShaderIDs._GaussianPyramidColorMips);
m_VelocityBuffer = HDShaderIDs._VelocityTexture;
m_VelocityBufferRT = new RenderTargetIdentifier(m_VelocityBuffer);

m_GaussianPyramidKernel = m_GaussianPyramidCS.FindKernel("KMain");
m_GaussianPyramidColorBufferDesc = new RenderTextureDescriptor(2, 2, RenderTextureFormat.ARGBHalf, 0)
{
useMipMap = true,
autoGenerateMips = false
};
m_DepthPyramidBuffer = HDShaderIDs._PyramidDepthTexture;
m_DepthPyramidBufferRT = new RenderTargetIdentifier(m_DepthPyramidBuffer);

var size = new Vector4(m_ColorPyramid.renderTextureDescriptor.width, m_ColorPyramid.renderTextureDescriptor.height, m_ColorPyramid.usedMipMapCount, 0);
cmd.SetGlobalVector(HDShaderIDs._GaussianPyramidColorMipSize, size);
PushFullScreenDebugTextureMip(cmd, m_GaussianPyramidColorBufferRT, m_ColorPyramid.usedMipMapCount, m_GaussianPyramidColorBufferDesc, hdCamera, isPreRefraction ? FullScreenDebugMode.PreRefractionColorPyramid : FullScreenDebugMode.FinalColorPyramid);
PushFullScreenDebugTextureMip(cmd, m_GaussianPyramidColorBufferRT, m_ColorPyramid.usedMipMapCount, m_ColorPyramid.renderTextureDescriptor, hdCamera, isPreRefraction ? FullScreenDebugMode.PreRefractionColorPyramid : FullScreenDebugMode.FinalColorPyramid);
}
void RenderPyramidDepth(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, FullScreenDebugMode debugMode)

}
// Color and depth pyramids
m_GaussianPyramidColorBufferDesc = BuildPyramidDescriptor(hdCamera, PyramidType.Color, m_FrameSettings.enableStereo);
m_ColorPyramid.Initialize(hdCamera, m_FrameSettings.enableStereo);
cmd.GetTemporaryRT(m_GaussianPyramidColorBuffer, m_GaussianPyramidColorBufferDesc, FilterMode.Trilinear);
cmd.GetTemporaryRT(m_GaussianPyramidColorBuffer, m_ColorPyramid.renderTextureDescriptor, FilterMode.Trilinear);
cmd.ReleaseTemporaryRT(m_DepthPyramidBuffer);
cmd.GetTemporaryRT(m_DepthPyramidBuffer, m_DepthPyramid.renderTextureDescriptor, FilterMode.Trilinear);
// End

49
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/ColorPyramid.cs


{
class ColorPyramid
{
const int k_ColorBlockSize = 4;
static readonly int _Size = Shader.PropertyToID("_Size");
static readonly int _Source = Shader.PropertyToID("_Source");
static readonly int _Result = Shader.PropertyToID("_Result");
GPUCopy m_GPUCopy;
Material m_Blit;
int m_BlitTextureId;
RenderTextureDescriptor m_RenderTextureDescriptor;
int[] m_ColorPyramidMips = new int[0];

}
}
public ColorPyramid(ComputeShader colorPyramidCS, GPUCopy gpuCopy, Material blit, int blitTextureId, int[] mipIds)
public ColorPyramid(ComputeShader colorPyramidCS, int[] mipIds)
m_GPUCopy = gpuCopy;
m_Blit = blit;
m_BlitTextureId = blitTextureId;
m_ColorPyramidKernel = m_ColorPyramidCS.FindKernel("KMain");
m_ColorPyramidMips = mipIds;

lodCount = m_ColorPyramidMips.Length;
}
cmd.SetGlobalTexture(m_BlitTextureId, colorTexture);
CoreUtils.DrawFullScreen(cmd, m_Blit, colorTexture, null, 1); // Bilinear filtering
// Copy mip 0
cmd.CopyTexture(colorTexture, 0, 0, targetTexture, 0, 0);
var last = colorTexture;
colorPyramidDesc.sRGB = false;

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, colorPyramidDesc.width / 8, colorPyramidDesc.height / 8, 1);
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];

public void Initialize(HDCamera hdCamera, bool enableStereo)
{
var desc = hdCamera.renderTextureDesc;
desc.colorFormat = RenderTextureFormat.RFloat;
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;
var desc = PyramidUtils.CalculateRenderTextureDescriptor(hdCamera, enableStereo);
desc.colorFormat = RenderTextureFormat.ARGBHalf;
m_RenderTextureDescriptor = desc;
}
}

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/DepthPyramid.cs


public void Initialize(HDCamera hdCamera, bool enableStereo)
{
var desc = hdCamera.renderTextureDesc;
var desc = PyramidUtils.CalculateRenderTextureDescriptor(hdCamera, enableStereo);
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;
m_RenderTextureDescriptor = 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}

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:

26
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/PyramidUtils.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public static class PyramidUtils
{
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/PyramidUtils.cs.meta


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

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

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

正在加载...
取消
保存