public bool AddDiffusionProfile(DiffusionProfileSettings profile) { if (diffusionProfileSettingsList.Length < 15) { int index = diffusionProfileSettingsList.Length; Array.Resize(ref diffusionProfileSettingsList, index + 1); diffusionProfileSettingsList[index] = profile; return(true); } else { Debug.LogError("There are too many diffusion profile settings in your HDRP. Please remove one before adding a new one."); return(false); } }
public void InitializeSubsurfaceScattering() { // Disney SSS (compute + combine) string kernelName = asset.currentPlatformRenderPipelineSettings.increaseSssSampleCount ? "SubsurfaceScatteringHQ" : "SubsurfaceScatteringMQ"; string kernelNameMSAA = asset.currentPlatformRenderPipelineSettings.increaseSssSampleCount ? "SubsurfaceScatteringHQ_MSAA" : "SubsurfaceScatteringMQ_MSAA"; m_SubsurfaceScatteringCS = asset.renderPipelineResources.shaders.subsurfaceScatteringCS; m_SubsurfaceScatteringKernel = m_SubsurfaceScatteringCS.FindKernel(kernelName); m_SubsurfaceScatteringKernelMSAA = m_SubsurfaceScatteringCS.FindKernel(kernelNameMSAA); m_CombineLightingPass = CoreUtils.CreateEngineMaterial(asset.renderPipelineResources.shaders.combineLightingPS); m_CombineLightingPass.SetInt(HDShaderIDs._StencilMask, (int)HDRenderPipeline.StencilBitMask.LightingMask); m_SSSCopyStencilForSplitLighting = CoreUtils.CreateEngineMaterial(asset.renderPipelineResources.shaders.copyStencilBufferPS); m_SSSCopyStencilForSplitLighting.SetInt(HDShaderIDs._StencilRef, (int)StencilLightingUsage.SplitLighting); m_SSSCopyStencilForSplitLighting.SetInt(HDShaderIDs._StencilMask, (int)HDRenderPipeline.StencilBitMask.LightingMask); m_SSSDefaultDiffusionProfile = asset.renderPipelineResources.assets.defaultDiffusionProfile; }
void SetDiffusionProfileAtIndex(DiffusionProfileSettings settings, int index) { // if the diffusion profile was already set and it haven't changed then there is nothing to upgrade if (setDiffusionProfiles[index] == settings && diffusionProfileUpdate[index] == settings.updateCount) { return; } // if the settings have not yet been initialized if (settings.profile.filterKernelNearField == null) { return; } thicknessRemaps[index] = settings.thicknessRemaps; shapeParams[index] = settings.shapeParams; transmissionTintsAndFresnel0[index] = settings.transmissionTintsAndFresnel0; disabledTransmissionTintsAndFresnel0[index] = settings.disabledTransmissionTintsAndFresnel0; worldScales[index] = settings.worldScales; for (int j = 0, n = DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++) { filterKernels[n * index + j].x = settings.profile.filterKernelNearField[j].x; filterKernels[n * index + j].y = settings.profile.filterKernelNearField[j].y; if (j < DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD) { filterKernels[n * index + j].z = settings.profile.filterKernelFarField[j].x; filterKernels[n * index + j].w = settings.profile.filterKernelFarField[j].y; } } diffusionProfileHashes[index] = HDShadowUtils.Asfloat(settings.profile.hash); // Erase previous value (This need to be done here individually as in the SSS editor we edit individual component) uint mask = 1u << index; texturingModeFlags &= ~mask; transmissionFlags &= ~mask; texturingModeFlags |= (uint)settings.profile.texturingMode << index; transmissionFlags |= (uint)settings.profile.transmissionMode << index; setDiffusionProfiles[index] = settings; diffusionProfileUpdate[index] = settings.updateCount; }
public void PushGlobalParams(HDCamera hdCamera, CommandBuffer cmd, DiffusionProfileSettings sssParameters) { // Broadcast SSS parameters to all shaders. cmd.SetGlobalInt(HDShaderIDs._EnableSubsurfaceScattering, hdCamera.frameSettings.enableSubsurfaceScattering ? 1 : 0); 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; uint transmissionFlags = sssParameters.transmissionFlags; cmd.SetGlobalFloat(HDShaderIDs._TexturingModeFlags, *(float *)&texturingModeFlags); cmd.SetGlobalFloat(HDShaderIDs._TransmissionFlags, *(float *)&transmissionFlags); } cmd.SetGlobalVectorArray(HDShaderIDs._ThicknessRemaps, sssParameters.thicknessRemaps); cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParams, sssParameters.shapeParams); // To disable transmission, we simply nullify the transmissionTint cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTintsAndFresnel0, hdCamera.frameSettings.enableTransmission ? sssParameters.transmissionTintsAndFresnel0 : sssParameters.disabledTransmissionTintsAndFresnel0); cmd.SetGlobalVectorArray(HDShaderIDs._WorldScales, sssParameters.worldScales); }
// Combines specular lighting and diffuse lighting with subsurface scattering. public void SubsurfaceScatteringPass(HDCamera hdCamera, CommandBuffer cmd, DiffusionProfileSettings sssParameters, RTHandleSystem.RTHandle colorBufferRT, RTHandleSystem.RTHandle diffuseBufferRT, RTHandleSystem.RTHandle depthStencilBufferRT, RTHandleSystem.RTHandle depthTextureRT) { if (sssParameters == null || !hdCamera.frameSettings.enableSubsurfaceScattering) { return; } // TODO: For MSAA, at least initially, we can only support Jimenez, because we can't // create MSAA + UAV render targets. using (new ProfilingSample(cmd, "Subsurface Scattering", CustomSamplerId.SubsurfaceScattering.GetSampler())) { // For Jimenez we always need an extra buffer, for Disney it depends on platform if (ShaderConfig.k_UseDisneySSS == 0 || NeedTemporarySubsurfaceBuffer()) { // Clear the SSS filtering target using (new ProfilingSample(cmd, "Clear SSS filtering target", CustomSamplerId.ClearSSSFilteringTarget.GetSampler())) { HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraFilteringBuffer, ClearFlag.Color, CoreUtils.clearColorAllBlack); } } if (ShaderConfig.s_UseDisneySSS == 1) // use static here to quiet the compiler warning { using (new ProfilingSample(cmd, "HTile for SSS", CustomSamplerId.HTileForSSS.GetSampler())) { // 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. // Clear the HTile texture. TODO: move this to ClearBuffers(). Clear operations must be batched! HDUtils.SetRenderTarget(cmd, hdCamera, m_HTile, ClearFlag.Color, CoreUtils.clearColorAllBlack); HDUtils.SetRenderTarget(cmd, hdCamera, depthStencilBufferRT); // No need for color buffer here cmd.SetRandomWriteTarget(1, m_HTile); // This need to be done AFTER SetRenderTarget // 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, null, 2); cmd.ClearRandomWriteTargets(); } 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, depthTextureRT); cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._SSSHTile, m_HTile); cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._IrradianceSource, diffuseBufferRT); for (int i = 0; i < sssBufferCount; ++i) { cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._SSSBufferTexture[i], GetSSSBuffer(i)); } if (NeedTemporarySubsurfaceBuffer()) { cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraFilteringBuffer, m_CameraFilteringBuffer); // 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_CameraFilteringBuffer); // Cannot set a RT on a material // Additively blend diffuse and specular lighting into 'm_CameraColorBufferRT'. CoreUtils.DrawFullScreen(cmd, m_CombineLightingPass, colorBufferRT, depthStencilBufferRT); } else { cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraColorTexture, colorBufferRT); // Perform the SSS filtering pass which performs an in-place update of 'colorBuffer'. cmd.DispatchCompute(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1); } } else { for (int i = 0; i < sssBufferCount; ++i) { cmd.SetGlobalTexture(HDShaderIDs._SSSBufferTexture[i], GetSSSBuffer(i)); } cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, diffuseBufferRT); // 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_CameraFilteringBuffer, depthStencilBufferRT); cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBuffer); // 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, colorBufferRT, depthStencilBufferRT); } } }
// Combines specular lighting and diffuse lighting with subsurface scattering. public void SubsurfaceScatteringPass(HDCamera hdCamera, CommandBuffer cmd, DiffusionProfileSettings sssParameters, FrameSettings frameSettings, RenderTargetIdentifier colorBufferRT, RenderTargetIdentifier diffuseBufferRT, RenderTargetIdentifier depthStencilBufferRT, RenderTargetIdentifier depthTextureRT) { if (sssParameters == null || !frameSettings.enableSubsurfaceScattering) { return; } using (new ProfilingSample(cmd, "Subsurface Scattering", CustomSamplerId.SubsurfaceScattering.GetSampler())) { // For Jimenez we always need an extra buffer, for Disney it depends on platform if (ShaderConfig.k_UseDisneySSS == 0 || NeedTemporarySubsurfaceBuffer()) { // Caution: must be same format as m_CameraSssDiffuseLightingBuffer cmd.ReleaseTemporaryRT(m_CameraFilteringBuffer); CoreUtils.CreateCmdTemporaryRT(cmd, m_CameraFilteringBuffer, hdCamera.renderTextureDesc, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV // Clear the SSS filtering target using (new ProfilingSample(cmd, "Clear SSS filtering target", CustomSamplerId.ClearSSSFilteringTarget.GetSampler())) { CoreUtils.SetRenderTarget(cmd, m_CameraFilteringBufferRT, ClearFlag.Color, CoreUtils.clearColorAllBlack); } } if (ShaderConfig.s_UseDisneySSS == 1) // use static here to quiet the compiler warning { using (new ProfilingSample(cmd, "HTile for SSS", CustomSamplerId.HTileForSSS.GetSampler())) { // 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. CoreUtils.SetRenderTarget(cmd, m_HTileRT, ClearFlag.Color, CoreUtils.clearColorAllBlack); cmd.SetRandomWriteTarget(1, m_HTile); // 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.SetRenderTarget(cmd, depthStencilBufferRT); // No need for color buffer here CoreUtils.DrawFullScreen(cmd, m_CopyStencilForSplitLighting, 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, depthTextureRT); cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._SSSHTile, m_HTileRT); cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._IrradianceSource, diffuseBufferRT); for (int i = 0; i < sssBufferCount; ++i) { cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._SSSBufferTexture[i], 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 macro tile. 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, colorBufferRT, depthStencilBufferRT); } else { cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraColorTexture, colorBufferRT); // Perform the SSS filtering pass which performs an in-place update of 'colorBuffer'. // We dispatch 4x swizzled 16x16 groups per a 32x32 macro tile. 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 < sssBufferCount; ++i) { cmd.SetGlobalTexture(HDShaderIDs._SSSBufferTexture[i], GetSSSBuffers(i)); } cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, diffuseBufferRT); // 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, depthStencilBufferRT); 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, colorBufferRT, depthStencilBufferRT); } } }