浏览代码

Add a copy-free fast path for the Disney SSS

/Yibing-Project-2
Evgenii Golubev 7 年前
当前提交
c7cb0506
共有 3 个文件被更改,包括 76 次插入32 次删除
  1. 63
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  3. 43
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute

63
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


bool NeedDepthBufferCopy()
{
// For now we consider only PS4 to be able to read from a bound depth buffer. Need to test/implement for other platforms.
// For now we consider only PS4 to be able to read from a bound depth buffer.
// TODO: test/implement for other platforms.
return SystemInfo.graphicsDeviceType != GraphicsDeviceType.PlayStation4;
}

{
// Currently, Unity does not offer a way to access the GCN HTile even on PS4 and Xbox One.
// Therefore, it's computed in a pixel shader, and optimized to only contain the SSS bit.
return m_CurrentDebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission;
return m_CurrentDebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission && sssSettings.useDisneySSS;
}
bool NeedTemporarySubsurfaceBuffer()
{
// Typed UAV loads from FORMAT_R16G16B16A16_FLOAT is an optional feature of Direct3D 11.
// Most modern GPUs support it. We can avoid performing a costly copy in this case.
// TODO: test/implement for other platforms.
return m_CurrentDebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission && (!sssSettings.useDisneySSS || (
SystemInfo.graphicsDeviceType != GraphicsDeviceType.PlayStation4 &&
SystemInfo.graphicsDeviceType != GraphicsDeviceType.XboxOne &&
SystemInfo.graphicsDeviceType != GraphicsDeviceType.XboxOneD3D12));
}
RenderTargetIdentifier GetDepthTexture()

cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._FilterKernels, sssParameters.filterKernels);
cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._ShapeParams, sssParameters.shapeParams);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture0, m_GbufferManager.GetGBuffers()[0]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture1, m_GbufferManager.GetGBuffers()[1]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture2, m_GbufferManager.GetGBuffers()[2]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture3, m_GbufferManager.GetGBuffers()[3]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._DepthTexture, GetDepthTexture());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._StencilTexture, GetStencilTexture());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._HTile, GetHTile());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._IrradianceSource, m_CameraSssDiffuseLightingBufferRT);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraColorTexture, m_CameraColorBufferRT);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraFilteringBuffer, m_CameraFilteringBufferRT);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture0, m_GbufferManager.GetGBuffers()[0]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture1, m_GbufferManager.GetGBuffers()[1]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture2, m_GbufferManager.GetGBuffers()[2]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture3, m_GbufferManager.GetGBuffers()[3]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._DepthTexture, GetDepthTexture());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._StencilTexture, GetStencilTexture());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._HTile, GetHTile());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._IrradianceSource, m_CameraSssDiffuseLightingBufferRT);
// Perform the SSS filtering pass which fills 'm_CameraFilteringBufferRT'.
cmd.DispatchCompute(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1);
if (NeedTemporarySubsurfaceBuffer())
{
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraFilteringBuffer, m_CameraFilteringBufferRT);
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material
// Perform the SSS filtering pass which fills 'm_CameraFilteringBufferRT'.
cmd.DispatchCompute(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1);
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material
// Combine diffuse and specular lighting into 'm_CameraColorBufferRT'.
CoreUtils.DrawFullScreen(cmd, m_CombineLightingPass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
// Additively blend diffuse and specular lighting into 'm_CameraColorBufferRT'.
CoreUtils.DrawFullScreen(cmd, m_CombineLightingPass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
}
else
{
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraColorTexture, m_CameraColorBufferRT);
// Perform the SSS filtering pass which performs an in-place update of 'm_CameraColorBufferRT'.
cmd.DispatchCompute(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1);
}
}
else
{

cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraSssDiffuseLightingBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraFilteringBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
if (NeedTemporarySubsurfaceBuffer())
{
cmd.GetTemporaryRT(m_CameraFilteringBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
}
// Color and depth pyramids
int s = CalculatePyramidSize(w, h);

}
// Old SSS Model >>>
if (!sssSettings.useDisneySSS)
if (NeedTemporarySubsurfaceBuffer())
{
// Clear the SSS filtering target
using (new ProfilingSample(cmd, "Clear SSS filtering target"))

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


#define GBufferType1 uint4
// TODO: How to abstract that ? We would like to avoid this PS4 test here
#ifdef SHADER_API_PS4
#ifdef SHADER_API_PSSL
// On PS4 we need to specify manually the format of the output render target, output type is not enough
#pragma PSSL_target_output_format(target 0 FMT_UINT16_ABGR)
#pragma PSSL_target_output_format(target 1 FMT_UINT16_ABGR)

43
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute


#define TEXTURE_CACHE_BORDER 2
#define TEXTURE_CACHE_SIZE_1D (GROUP_SIZE_1D + 2 * TEXTURE_CACHE_BORDER)
// TODO: query the format support more precisely.
#if defined(SHADER_API_PSSL) || defined(SHADER_API_XBOXONE)
#define TYPED_UAV_LOAD_FORMAT_R16G16B16A16_FLOAT
#endif
//--------------------------------------------------------------------------------------------------
// Included headers
//--------------------------------------------------------------------------------------------------

float4 _WorldScales[SSS_N_PROFILES]; // Size of the world unit in meters (only the X component is used)
float4 _FilterKernels[SSS_N_PROFILES][SSS_N_SAMPLES_NEAR_FIELD]; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF
DECLARE_GBUFFER_TEXTURE(_GBufferTexture); // Contains the albedo and SSS parameters
TEXTURE2D(_DepthTexture); // Z-buffer
TEXTURE2D(_StencilTexture); // DXGI_FORMAT_R8_UINT is not supported by Unity
TEXTURE2D(_HTile); // DXGI_FORMAT_R8_UINT is not supported by Unity
TEXTURE2D(_IrradianceSource); // Includes transmitted light
RW_TEXTURE2D(float4, _CameraFilteringTexture); // Target texture
DECLARE_GBUFFER_TEXTURE(_GBufferTexture); // Contains the albedo and SSS parameters
TEXTURE2D(_DepthTexture); // Z-buffer
TEXTURE2D(_StencilTexture); // DXGI_FORMAT_R8_UINT is not supported by Unity
TEXTURE2D(_HTile); // DXGI_FORMAT_R8_UINT is not supported by Unity
TEXTURE2D(_IrradianceSource); // Includes transmitted light
#ifdef TYPED_UAV_LOAD_FORMAT_R16G16B16A16_FLOAT
RW_TEXTURE2D(float4, _CameraColorTexture); // Target texture
#else
RW_TEXTURE2D(float4, _CameraFilteringTexture); // Target texture
#endif
//--------------------------------------------------------------------------------------------------
// Implementation

}
}
void WriteResult(uint2 pixelCoord, float3 irradiance)
{
#ifdef TYPED_UAV_LOAD_FORMAT_R16G16B16A16_FLOAT
_CameraColorTexture[pixelCoord] += float4(irradiance, 0);
#else
_CameraFilteringTexture[pixelCoord] = float4(irradiance, 1);
#endif
}
#pragma kernel SubsurfaceScattering
[numthreads(GROUP_SIZE_2D, 1, 1)]

[branch] if (distScale == 0 || maxDistInPixels < 1)
{
#if SSS_DEBUG_LOD
_CameraFilteringTexture[pixelCoord] = float4(0, 0, 1, 1);
WriteResult(pixelCoord, float3(0, 0, 1));
_CameraFilteringTexture[pixelCoord] = float4(albedo * centerIrradiance, 1);
WriteResult(pixelCoord, albedo * centerIrradiance);
#endif
return;
}

float3 viewDirVS = normalize(centerPosVS);
if (dot(normalVS, viewDirVS) >= 0)
{
_CameraFilteringTexture[pixelCoord] = float4(1, 1, 1, 1);
WriteResult(pixelCoord, float3(1, 1, 1));
return;
}
#endif

#if SSS_DEBUG_LOD
_CameraFilteringTexture[pixelCoord] = useNearFieldKernel ? float4(1, 0, 0, 1) : float4(0.5, 0.5, 0, 1);
WriteResult(pixelCoord, useNearFieldKernel ? float3(1, 0, 0) : float3(0.5, 0.5, 0);
return;
#endif

[branch] if (!useNearFieldKernel)
{
_CameraFilteringTexture[pixelCoord] = float4(albedo * totalIrradiance / totalWeight, 1);
WriteResult(pixelCoord, albedo * totalIrradiance / totalWeight);
return;
}

totalIrradiance, totalWeight);
}
_CameraFilteringTexture[pixelCoord] = float4(albedo * totalIrradiance / totalWeight, 1);
WriteResult(pixelCoord, albedo * totalIrradiance / totalWeight);
}
正在加载...
取消
保存