您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
157 行
9.3 KiB
157 行
9.3 KiB
using UnityEngine.Rendering;
|
|
using System;
|
|
|
|
namespace UnityEngine.Experimental.Rendering.HDPipeline
|
|
{
|
|
public class SubsurfaceScatteringManager
|
|
{
|
|
// Currently we only support SSSBuffer with one buffer. If the shader code change, it may require to update the shader manager
|
|
public const int k_MaxSSSBuffer = 1;
|
|
|
|
readonly int m_SSSBuffer0;
|
|
readonly RenderTargetIdentifier m_SSSBuffer0RT;
|
|
|
|
public int sssBufferCount { get { return k_MaxSSSBuffer; } }
|
|
|
|
RenderTargetIdentifier[] m_ColorMRTs;
|
|
RenderTargetIdentifier[] m_RTIDs = new RenderTargetIdentifier[k_MaxSSSBuffer];
|
|
|
|
public SubsurfaceScatteringManager()
|
|
{
|
|
m_SSSBuffer0RT = new RenderTargetIdentifier(m_SSSBuffer0);
|
|
}
|
|
|
|
// In case of deferred, we must be in sync with SubsurfaceScattering.hlsl and lit.hlsl files and setup the correct buffers
|
|
// for SSS
|
|
public void InitGBuffers(int width, int height, GBufferManager gbufferManager, CommandBuffer cmd)
|
|
{
|
|
m_RTIDs[0] = gbufferManager.GetGBuffers()[0];
|
|
}
|
|
|
|
// In case of full forward we must allocate the render target for forward SSS (or reuse one already existing)
|
|
// TODO: Provide a way to reuse a render target
|
|
public void InitGBuffers(int width, int height, CommandBuffer cmd)
|
|
{
|
|
m_RTIDs[0] = m_SSSBuffer0RT;
|
|
|
|
cmd.ReleaseTemporaryRT(m_SSSBuffer0);
|
|
cmd.GetTemporaryRT(m_SSSBuffer0, width, height, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
|
|
}
|
|
|
|
public RenderTargetIdentifier GetSSSBuffers(int index)
|
|
{
|
|
Debug.Assert(index < sssBufferCount);
|
|
return m_RTIDs[index];
|
|
}
|
|
|
|
|
|
public void CreateSssMaterials()
|
|
{
|
|
m_SubsurfaceScatteringKernel = m_SubsurfaceScatteringCS.FindKernel("SubsurfaceScattering");
|
|
|
|
CoreUtils.Destroy(m_CombineLightingPass);
|
|
m_CombineLightingPass = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineLighting");
|
|
|
|
// Old SSS Model >>>
|
|
CoreUtils.Destroy(m_SssVerticalFilterPass);
|
|
m_SssVerticalFilterPass = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/SubsurfaceScattering");
|
|
m_SssVerticalFilterPass.DisableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
|
|
m_SssVerticalFilterPass.SetFloat(HDShaderIDs._DstBlend, (float)BlendMode.Zero);
|
|
|
|
CoreUtils.Destroy(m_SssHorizontalFilterAndCombinePass);
|
|
m_SssHorizontalFilterAndCombinePass = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/SubsurfaceScattering");
|
|
m_SssHorizontalFilterAndCombinePass.EnableKeyword("SSS_FILTER_HORIZONTAL_AND_COMBINE");
|
|
m_SssHorizontalFilterAndCombinePass.SetFloat(HDShaderIDs._DstBlend, (float)BlendMode.One);
|
|
// <<< Old SSS Model
|
|
}
|
|
|
|
// Combines specular lighting and diffuse lighting with subsurface scattering.
|
|
void SubsurfaceScatteringPass(HDCamera hdCamera, CommandBuffer cmd, SubsurfaceScatteringSettings sssParameters)
|
|
{
|
|
if (!m_CurrentDebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission)
|
|
return;
|
|
|
|
using (new ProfilingSample(cmd, "Subsurface Scattering", GetSampler(CustomSamplerId.SubsurfaceScattering)))
|
|
{
|
|
if (sssSettings.useDisneySSS)
|
|
{
|
|
using (new ProfilingSample(cmd, "HTile for SSS", GetSampler(CustomSamplerId.HTileForSSS)))
|
|
{
|
|
CoreUtils.SetRenderTarget(cmd, m_HTileRT, ClearFlag.Color, CoreUtils.clearColorAllBlack);
|
|
|
|
cmd.SetRandomWriteTarget(1, GetHTile());
|
|
// Generate HTile for the split lighting stencil usage. Don't write into stencil texture (shaderPassId = 2)
|
|
// Use ShaderPassID 1 => "Pass 2 - Export HTILE for stencilRef to output"
|
|
CoreUtils.DrawFullScreen(cmd, m_CopyStencilForSplitLighting, m_CameraStencilBufferCopyRT, m_CameraDepthStencilBufferRT, null, 2);
|
|
cmd.ClearRandomWriteTargets();
|
|
}
|
|
|
|
// TODO: Remove this once fix, see comment inside the function
|
|
hdCamera.SetupComputeShader(m_SubsurfaceScatteringCS, cmd);
|
|
|
|
unsafe
|
|
{
|
|
// Warning: Unity is not able to losslessly transfer integers larger than 2^24 to the shader system.
|
|
// Therefore, we bitcast uint to float in C#, and bitcast back to uint in the shader.
|
|
uint texturingModeFlags = sssParameters.texturingModeFlags;
|
|
cmd.SetComputeFloatParam(m_SubsurfaceScatteringCS, HDShaderIDs._TexturingModeFlags, *(float*)&texturingModeFlags);
|
|
}
|
|
|
|
cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._WorldScales, sssParameters.worldScales);
|
|
cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._FilterKernels, sssParameters.filterKernels);
|
|
cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._ShapeParams, sssParameters.shapeParams);
|
|
|
|
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._DepthTexture, GetDepthTexture());
|
|
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._HTile, GetHTile());
|
|
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._IrradianceSource, m_CameraSssDiffuseLightingBufferRT);
|
|
|
|
for (int i = 0; i < m_SSSBufferManager.sssBufferCount; ++i)
|
|
{
|
|
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._SSSBufferTexture[i], m_SSSBufferManager.GetSSSBuffers(i));
|
|
}
|
|
|
|
if (NeedTemporarySubsurfaceBuffer())
|
|
{
|
|
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraFilteringBuffer, m_CameraFilteringBufferRT);
|
|
|
|
// Perform the SSS filtering pass which fills 'm_CameraFilteringBufferRT'.
|
|
// We dispatch 4x swizzled 16x16 groups per a 32x32 macrotile.
|
|
cmd.DispatchCompute(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, 4, ((int)hdCamera.screenSize.x + 31) / 32, ((int)hdCamera.screenSize.y + 31) / 32);
|
|
|
|
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material
|
|
|
|
// 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'.
|
|
// We dispatch 4x swizzled 16x16 groups per a 32x32 macrotile.
|
|
cmd.DispatchCompute(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, 4, ((int)hdCamera.screenSize.x + 31) / 32, ((int)hdCamera.screenSize.y + 31) / 32);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < m_SSSBufferManager.sssBufferCount; ++i)
|
|
{
|
|
cmd.SetGlobalTexture(HDShaderIDs._SSSBufferTexture[i], m_SSSBufferManager.GetSSSBuffers(i));
|
|
}
|
|
|
|
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraSssDiffuseLightingBufferRT); // Cannot set a RT on a material
|
|
m_SssVerticalFilterPass.SetVectorArray(HDShaderIDs._FilterKernelsBasic, sssParameters.filterKernelsBasic);
|
|
m_SssVerticalFilterPass.SetVectorArray(HDShaderIDs._HalfRcpWeightedVariances, sssParameters.halfRcpWeightedVariances);
|
|
// Perform the vertical SSS filtering pass which fills 'm_CameraFilteringBufferRT'.
|
|
CoreUtils.DrawFullScreen(cmd, m_SssVerticalFilterPass, m_CameraFilteringBufferRT, m_CameraDepthStencilBufferRT);
|
|
|
|
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material
|
|
m_SssHorizontalFilterAndCombinePass.SetVectorArray(HDShaderIDs._FilterKernelsBasic, sssParameters.filterKernelsBasic);
|
|
m_SssHorizontalFilterAndCombinePass.SetVectorArray(HDShaderIDs._HalfRcpWeightedVariances, sssParameters.halfRcpWeightedVariances);
|
|
// Perform the horizontal SSS filtering pass, and combine diffuse and specular lighting into 'm_CameraColorBufferRT'.
|
|
CoreUtils.DrawFullScreen(cmd, m_SssHorizontalFilterAndCombinePass, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|