浏览代码

Merge pull request #1505 from Unity-Technologies/normal-buffer-support

Add export of normal+Roughness during depth prepass for forward
/main
GitHub 6 年前
当前提交
84c9e15c
共有 27 个文件被更改,包括 375 次插入82 次删除
  1. 5
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/CommonMaterial.hlsl
  2. 16
      com.unity.render-pipelines.high-definition/HDRP/Editor/Material/Lit/LitShaderPreprocessor.cs
  3. 24
      com.unity.render-pipelines.high-definition/HDRP/Lighting/DeferredDirectionalShadow.compute
  4. 8
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs
  5. 12
      com.unity.render-pipelines.high-definition/HDRP/Material/LayeredLit/LayeredLit.shader
  6. 12
      com.unity.render-pipelines.high-definition/HDRP/Material/LayeredLit/LayeredLitTessellation.shader
  7. 62
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl
  8. 12
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.shader
  9. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/LitBuiltinData.hlsl
  10. 12
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/LitTessellation.shader
  11. 27
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
  12. 4
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.shader
  13. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitData.hlsl
  14. 4
      com.unity.render-pipelines.high-definition/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl
  15. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/Unlit/Unlit.hlsl
  16. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/Unlit/Unlit.shader
  17. 64
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs
  18. 8
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDStringConstants.cs
  19. 15
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassDepthOnly.hlsl
  20. 2
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassForward.hlsl
  21. 2
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassForwardUnlit.hlsl
  22. 2
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassGBuffer.hlsl
  23. 2
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassLightTransport.hlsl
  24. 55
      com.unity.render-pipelines.high-definition/HDRP/Material/NormalBuffer.hlsl
  25. 9
      com.unity.render-pipelines.high-definition/HDRP/Material/NormalBuffer.hlsl.meta
  26. 81
      com.unity.render-pipelines.high-definition/HDRP/Material/NormalBufferManager.cs
  27. 11
      com.unity.render-pipelines.high-definition/HDRP/Material/NormalBufferManager.cs.meta

5
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/CommonMaterial.hlsl


return sqrt(roughness);
}
real RoughnessToPerceptualSmoothness(real roughness)
{
return 1.0 - sqrt(roughness);
}
real PerceptualSmoothnessToRoughness(real perceptualSmoothness)
{
return (1.0 - perceptualSmoothness) * (1.0 - perceptualSmoothness);

16
com.unity.render-pipelines.high-definition/HDRP/Editor/Material/Lit/LitShaderPreprocessor.cs


using UnityEditor.Build;
using UnityEditor.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline

protected ShaderKeyword m_WriteNormalBuffer;
public LitShaderPreprocessor()
{
m_WriteNormalBuffer = new ShaderKeyword("WRITE_NORMAL_BUFFER");
}
bool LitShaderStripper(HDRenderPipelineAsset hdrpAsset, Shader shader, ShaderSnippetData snippet, ShaderCompilerData inputData)
{
if (CommonShaderStripper(hdrpAsset, shader, snippet, inputData))

bool isForwardPass = snippet.passName == "Forward";
bool isDepthOnlyPass = snippet.passName == "DepthOnly";
bool isTransparentForwardPass = snippet.passName == "TransparentDepthPostpass" || snippet.passName == "TransparentBackface" || snippet.passName == "TransparentDepthPrepass";
// When using forward only, we never need GBuffer pass (only Forward)

// When we are in deferred (i.e !hdrpAsset.renderPipelineSettings.supportOnlyForward), we only support tile lighting
if (!hdrpAsset.renderPipelineSettings.supportOnlyForward && inputData.shaderKeywordSet.IsEnabled(m_ClusterLighting))
return true;
if (isDepthOnlyPass)
{
// When we are full forward, we don't have depth prepass without writeNormalBuffer
if (hdrpAsset.renderPipelineSettings.supportOnlyForward && !inputData.shaderKeywordSet.IsEnabled(m_WriteNormalBuffer))
return true;
}
if (!hdrpAsset.renderPipelineSettings.supportOnlyForward)
{

24
com.unity.render-pipelines.high-definition/HDRP/Lighting/DeferredDirectionalShadow.compute


// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel DeferredDirectionalShadow DEFERRED_DIRECTIONAL=DeferredDirectionalShadow
#pragma kernel DeferredDirectionalShadow_Contact DEFERRED_DIRECTIONAL=DeferredDirectionalShadow_Contact ENABLE_CONTACT_SHADOWS
#pragma kernel DeferredDirectionalShadow_Normals DEFERRED_DIRECTIONAL=DeferredDirectionalShadow_Normals ENABLE_NORMALS
#pragma kernel DeferredDirectionalShadow_Contact_Normals DEFERRED_DIRECTIONAL=DeferredDirectionalShadow_Contact_Normals ENABLE_CONTACT_SHADOWS ENABLE_NORMALS
#ifdef ENABLE_NORMALS
# define LIGHTLOOP_TILE_PASS 1
# define USE_FPTL_LIGHTLIST 1 // deferred opaque always use FPTL
# define UNITY_MATERIAL_LIT
#else
# define SHADOW_USE_ONLY_VIEW_BASED_BIASING 1 // Enable only light view vector based biasing. If undefined, biasing will be based on the normal and calling code must provide a valid normal.
#endif
#ifdef SHADER_API_PSSL
# pragma argument( scheduler=minpressure ) // instruct the shader compiler to prefer minimizing vgpr usage

#include "../ShaderVariables.hlsl"
#include "../Material/NormalBuffer.hlsl"
#include "Lighting.hlsl"
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch

PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, tileCoord);
#ifdef ENABLE_NORMALS
BSDFData bsdfData;
BakeLightingData unused;
DECODE_FROM_GBUFFER(posInput.positionSS, UINT_MAX, bsdfData, unused.bakeDiffuseLighting);
float3 nrm = bsdfData.normalWS;
#else
float3 nrm = 0.0.xxx;
#endif
NormalData normalData;
DecodeFromNormalBuffer(posInput.positionSS, normalData);
float3 normalWS = normalData.normalWS;
float shadow = GetDirectionalShadowAttenuation(shadowContext, posInput.positionWS, nrm, _DirectionalShadowIndex, _LightDirection);
float shadow = GetDirectionalShadowAttenuation(shadowContext, posInput.positionWS, normalWS, _DirectionalShadowIndex, _LightDirection);
#ifdef ENABLE_CONTACT_SHADOWS
float contactShadow = 1.0f;

8
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs


static int s_deferredDirectionalShadowKernel;
static int s_deferredDirectionalShadow_Contact_Kernel;
static int s_deferredDirectionalShadow_Normals_Kernel;
static int s_deferredDirectionalShadow_Contact_Normals_Kernel;
static ComputeBuffer s_LightVolumeDataBuffer = null;
static ComputeBuffer s_ConvexBoundsBuffer = null;

s_deferredDirectionalShadowKernel = deferredDirectionalShadowComputeShader.FindKernel("DeferredDirectionalShadow");
s_deferredDirectionalShadow_Contact_Kernel = deferredDirectionalShadowComputeShader.FindKernel("DeferredDirectionalShadow_Contact");
s_deferredDirectionalShadow_Normals_Kernel = deferredDirectionalShadowComputeShader.FindKernel("DeferredDirectionalShadow_Normals");
s_deferredDirectionalShadow_Contact_Normals_Kernel = deferredDirectionalShadowComputeShader.FindKernel("DeferredDirectionalShadow_Contact_Normals");
for (int variant = 0; variant < LightDefinitions.s_NumFeatureVariants; variant++)
{

bool enableContactShadows = m_FrameSettings.enableContactShadows && contactShadows.enable && contactShadows.length > 0.0f;
int kernel;
if (enableContactShadows)
kernel = m_FrameSettings.enableForwardRenderingOnly ? s_deferredDirectionalShadow_Contact_Kernel : s_deferredDirectionalShadow_Contact_Normals_Kernel;
kernel = s_deferredDirectionalShadow_Contact_Kernel;
kernel = m_FrameSettings.enableForwardRenderingOnly ? s_deferredDirectionalShadowKernel : s_deferredDirectionalShadow_Normals_Kernel;
kernel = s_deferredDirectionalShadowKernel;
m_ShadowMgr.BindResources(cmd, deferredDirectionalShadowComputeShader, kernel);

12
com.unity.render-pipelines.high-definition/HDRP/Material/LayeredLit/LayeredLit.shader


ZWrite On
ColorMask 0
HLSLPROGRAM
HLSLPROGRAM
// In deferred, depth only pass don't output anything.
// In forward it output the normal buffer
#pragma multi_compile _ WRITE_NORMAL_BUFFER
#ifdef WRITE_NORMAL_BUFFER // If enabled we need all regular interpolator
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#else
#endif
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

12
com.unity.render-pipelines.high-definition/HDRP/Material/LayeredLit/LayeredLitTessellation.shader


ZWrite On
ColorMask 0
// In deferred, depth only pass don't output anything.
// In forward it output the normal buffer
#pragma multi_compile _ WRITE_NORMAL_BUFFER
#ifdef WRITE_NORMAL_BUFFER // If enabled we need all regular interpolator
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#else
#endif
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

62
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl


// SurfaceData is define in Lit.cs which generate Lit.cs.hlsl
#include "Lit.cs.hlsl"
#include "../SubsurfaceScattering/SubsurfaceScattering.hlsl"
#include "../NormalBuffer.hlsl"
#include "CoreRP/ShaderLibrary/VolumeRendering.hlsl"
//-----------------------------------------------------------------------------

#define CLEAR_COAT_IETA (1.0 / CLEAR_COAT_IOR) // IETA is the inverse eta which is the ratio of IOR of two interface
#define CLEAR_COAT_F0 0.04 // IORToFresnel0(CLEAR_COAT_IOR)
#define CLEAR_COAT_ROUGHNESS 0.001
#define CLEAR_COAT_PERCEPTUAL_SMOOTHNESS RoughnessToPerceptualSmoothness(CLEAR_COAT_ROUGHNESS)
#define CLEAR_COAT_PERCEPTUAL_ROUGHNESS RoughnessToPerceptualRoughness(CLEAR_COAT_ROUGHNESS)
//-----------------------------------------------------------------------------

// #define LIT_DISPLAY_REFERENCE_AREA
// #define LIT_DISPLAY_REFERENCE_IBL
#endif
// In forward we can chose between reading the normal from the normalBufferTexture or computing it again
// This is tradeoff between performance and quality. As we store the normal conpressed, recomputing again is higher quality.
// Uncomment this to get speed (to measure), let it comment to get quality
// #define FORWARD_MATERIAL_READ_FROM_WRITTEN_NORMAL_BUFFER
//-----------------------------------------------------------------------------
// Ligth and material classification for the deferred rendering path

return sssData;
}
NormalData ConvertSurfaceDataToNormalData(SurfaceData surfaceData)
{
NormalData normalData;
// Note: We can't handle clear coat material here, we have only one slot to store smoothness
// and the buffer is the GBuffer1.
normalData.normalWS = surfaceData.normalWS;
normalData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness);
return normalData;
}
void UpdateSurfaceDataFromNormalData(uint2 positionSS, inout BSDFData bsdfData)
{
NormalData normalData;
DecodeFromNormalBuffer(positionSS, normalData);
bsdfData.normalWS = normalData.normalWS;
bsdfData.perceptualRoughness = normalData.perceptualRoughness;
}
BSDFData ConvertSurfaceDataToBSDFData(SurfaceData surfaceData)
BSDFData ConvertSurfaceDataToBSDFData(uint2 positionSS, SurfaceData surfaceData)
{
BSDFData bsdfData;
ZERO_INITIALIZE(BSDFData, bsdfData);

bsdfData.normalWS = surfaceData.normalWS;
bsdfData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness);
// Check if we read value of normal and roughness from buffer. This is a tradeoff
#ifdef FORWARD_MATERIAL_READ_FROM_WRITTEN_NORMAL_BUFFER
#if (SHADERPASS == SHADERPASS_FORWARD) && !defined(_SURFACE_TYPE_TRANSPARENT)
UpdateSurfaceDataFromNormalData(positionSS, bsdfData);
#endif
#endif
// There is no metallic with SSS and specular color mode
float metallic = HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION) ? 0.0 : surfaceData.metallic;

// Warning: the contents are later overwritten for Standard and SSS!
outGBuffer0 = float4(surfaceData.baseColor, surfaceData.specularOcclusion);
// The sign of the Z component of the normal MUST round-trip through the G-Buffer, otherwise
// the reconstruction of the tangent frame for anisotropic GGX creates a seam along the Z axis.
// The constant was eye-balled to not cause artifacts.
// TODO: find a proper solution. E.g. we could re-shuffle the faces of the octahedron
// s.t. the sign of the Z component round-trips.
const float seamThreshold = 1.0/1024.0;
surfaceData.normalWS.z = CopySign(max(seamThreshold, abs(surfaceData.normalWS.z)), surfaceData.normalWS.z);
// RT1 - 8:8:8:8
// Our tangent encoding is based on our normal.
float2 octNormalWS = PackNormalOctQuadEncode(surfaceData.normalWS);
float3 packNormalWS = PackFloat2To888(saturate(octNormalWS * 0.5 + 0.5));
// We store perceptualRoughness instead of roughness because it is perceptually linear.
outGBuffer1 = float4(packNormalWS, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));
// This encode normalWS and PerceptualSmoothness into GBuffer1
EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), positionSS, outGBuffer1);
// RT2 - 8:8:8:8
uint materialFeatureId;

// Decompress feature-agnostic data from the G-Buffer.
float3 baseColor = inGBuffer0.rgb;
float3 packNormalWS = inGBuffer1.rgb;
float2 octNormalWS = Unpack888ToFloat2(packNormalWS);
bsdfData.normalWS = UnpackNormalOctQuadEncode(octNormalWS * 2.0 - 1.0);
bsdfData.perceptualRoughness = inGBuffer1.a;
NormalData normalData;
DecodeFromNormalBuffer(inGBuffer1, positionSS, normalData);
bsdfData.normalWS = normalData.normalWS;
bsdfData.perceptualRoughness = normalData.perceptualRoughness;
bakeDiffuseLighting = inGBuffer3.rgb;

12
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.shader


ZWrite On
ColorMask 0
HLSLPROGRAM
HLSLPROGRAM
// In deferred, depth only pass don't output anything.
// In forward it output the normal buffer
#pragma multi_compile _ WRITE_NORMAL_BUFFER
#ifdef WRITE_NORMAL_BUFFER // If enabled we need all regular interpolator
#include "ShaderPass/LitSharePass.hlsl"
#else
#endif
#include "LitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

2
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/LitBuiltinData.hlsl


// It is safe to call this function here as surfaceData have been filled
// We want to know if we must enable transmission on GI for SSS material, if the material have no SSS, this code will be remove by the compiler.
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// For now simply recall the function with inverted normal, the compiler should be able to optimize the lightmap case to not resample the directional lightmap

12
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/LitTessellation.shader


ZWrite On
ColorMask 0
// In deferred, depth only pass don't output anything.
// In forward it output the normal buffer
#pragma multi_compile _ WRITE_NORMAL_BUFFER
#ifdef WRITE_NORMAL_BUFFER // If enabled we need all regular interpolator
#include "ShaderPass/LitSharePass.hlsl"
#else
#endif
#include "LitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

27
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl


// SurfaceData is defined in StackLit.cs which generates StackLit.cs.hlsl
#include "StackLit.cs.hlsl"
#include "../SubsurfaceScattering/SubsurfaceScattering.hlsl"
#include "../NormalBuffer.hlsl"
//#include "CoreRP/ShaderLibrary/VolumeRendering.hlsl"
//NEWLITTODO : wireup CBUFFERs for ambientocclusion, and other uniforms and samplers used:

//-----------------------------------------------------------------------------
// Definition
//-----------------------------------------------------------------------------
// Required for SSS
#define GBufferType0 float4
// Needed for MATERIAL_FEATURE_MASK_FLAGS.
#include "../../Lighting/LightLoop/LightLoop.cs.hlsl"

return sssData;
}
NormalData ConvertSurfaceDataToNormalData(SurfaceData surfaceData)
{
NormalData normalData;
// When using clear cloat we want to use the coat normal for the various deferred effect
// as it is the most dominant one
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT))
{
normalData.normalWS = surfaceData.coatNormalWS;
normalData.perceptualRoughness = surfaceData.coatPerceptualSmoothness;
}
else
{
normalData.normalWS = surfaceData.normalWS;
// Do average mix in case of dual lobe
normalData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(lerp(surfaceData.perceptualSmoothnessA, surfaceData.perceptualSmoothnessB, surfaceData.lobeMix));
}
return normalData;
}
BSDFData ConvertSurfaceDataToBSDFData(SurfaceData surfaceData)
BSDFData ConvertSurfaceDataToBSDFData(uint2 positionSS, SurfaceData surfaceData)
{
BSDFData bsdfData;
ZERO_INITIALIZE(BSDFData, bsdfData);

4
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.shader


HLSLPROGRAM
#define WRITE_NORMAL_BUFFER
#include "ShaderPass/StackLitDepthPass.hlsl"
// As we enabled WRITE_NORMAL_BUFFER we need all regular interpolator
#include "ShaderPass/StackLitSharePass.hlsl"
#include "StackLitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"

2
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitData.hlsl


// It is safe to call this function here as surfaceData have been filled
// We want to know if we must enable transmission on GI for SSS material, if the material have no SSS, this code will be remove by the compiler.
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_TRANSMISSION))
{
// For now simply recall the function with inverted normal, the compiler should be able to optimize the lightmap case to not resample the directional lightmap

4
com.unity.render-pipelines.high-definition/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl


uint diffusionProfile;
};
#define SSSBufferType0 float4
#define SSSBufferType0 float4 // Must match GBufferType0 in deferred
// SSSBuffer texture declaration
TEXTURE2D(_SSSBufferTexture0);

}
// OUTPUT_SSSBUFFER start from SV_Target2 as SV_Target0 and SV_Target1 are used for lighting buffer
#define OUTPUT_SSSBUFFER(NAME) out GBufferType0 MERGE_NAME(NAME, 0) : SV_Target2
#define OUTPUT_SSSBUFFER(NAME) out SSSBufferType0 MERGE_NAME(NAME, 0) : SV_Target2
#define ENCODE_INTO_SSSBUFFER(SURFACE_DATA, UNPOSITIONSS, NAME) EncodeIntoSSSBuffer(ConvertSurfaceDataToSSSData(SURFACE_DATA), UNPOSITIONSS, MERGE_NAME(NAME, 0))
#define DECODE_FROM_SSSBUFFER(UNPOSITIONSS, SSS_DATA) DecodeFromSSSBuffer(UNPOSITIONSS, SSS_DATA)

2
com.unity.render-pipelines.high-definition/HDRP/Material/Unlit/Unlit.hlsl


// conversion function for forward
//-----------------------------------------------------------------------------
BSDFData ConvertSurfaceDataToBSDFData(SurfaceData data)
BSDFData ConvertSurfaceDataToBSDFData(uint2 positionSS, SurfaceData data)
{
BSDFData output;
output.color = data.color;

2
com.unity.render-pipelines.high-definition/HDRP/Material/Unlit/Unlit.shader


ZWrite On
ColorMask 0 // We don't have WRITE_NORMAL_BUFFER for unlit, but as we bind a buffer we shouldn't write into it.
HLSLPROGRAM
#define SHADERPASS SHADERPASS_DEPTH_ONLY

64
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs


readonly GBufferManager m_GbufferManager;
readonly DBufferManager m_DbufferManager;
readonly SubsurfaceScatteringManager m_SSSBufferManager = new SubsurfaceScatteringManager();
readonly NormalBufferManager m_NormalBufferManager = new NormalBufferManager();
// Renderer Bake configuration can vary depends on if shadow mask is enabled or no
RendererConfiguration m_currentRendererConfigurationBakedLighting = HDUtils.k_RendererConfigurationBakedLighting;

m_DbufferManager = new DBufferManager();
m_SSSBufferManager.Build(asset);
m_NormalBufferManager.Build(asset);
// Initialize various compute shader resources
m_applyDistortionKernel = m_applyDistortionCS.FindKernel("KMain");

m_DbufferManager.CreateBuffers();
m_SSSBufferManager.InitSSSBuffers(m_GbufferManager, m_Asset.renderPipelineSettings);
m_NormalBufferManager.InitNormalBuffers(m_GbufferManager, m_Asset.renderPipelineSettings);
m_CameraColorBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGBHalf, sRGB: false, enableRandomWrite: true, enableMSAA: true, name: "CameraColor");
m_CameraSssDiffuseLightingBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.RGB111110Float, sRGB: false, enableRandomWrite: true, enableMSAA: true, name: "CameraSSSDiffuseLighting");

CoreUtils.Destroy(m_ErrorMaterial);
m_SSSBufferManager.Cleanup();
m_NormalBufferManager.Cleanup();
m_SkyManager.Cleanup();
m_VolumetricLightingSystem.Cleanup();
m_IBLFilterGGX.Cleanup();

RenderGBuffer(m_CullResults, hdCamera, enableBakeShadowMask, renderContext, cmd);
// We can now bind the normal buffer to be use by any effect
m_NormalBufferManager.BindNormalBuffers(cmd);
// In both forward and deferred, everything opaque should have been rendered at this point so we can safely copy the depth buffer for later processing.
CopyDepthBufferIfNeeded(cmd);
RenderDepthPyramid(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);

// by using the pass "ForwardOnly". In this case the .shader should not have "Forward" but only a "ForwardOnly" pass.
// It must also have a "DepthForwardOnly" and no "DepthOnly" pass as forward material (either deferred or forward only rendering) have always a depth pass.
// If a forward material have no depth prepass, then lighting can be incorrect (deferred sahdowing, SSAO), this may be acceptable depends on usage
bool addFullDepthPrepass = forcePrepass || hdCamera.frameSettings.enableForwardRenderingOnly || hdCamera.frameSettings.enableDepthPrepassWithDeferredRendering;
using (new ProfilingSample(cmd, !addFullDepthPrepass ? "Depth Prepass alpha test" : "Depth Prepass", CustomSamplerId.DepthPrepass.GetSampler()))
// Whatever the configuration we always render first the opaque object as opaque alpha tested are more costly to render and could be reject by early-z
// (but not Hi-z as it is disable with clip instruction). This is handled automatically with the RenderQueue value (OpaqueAlphaTested have a different value and thus are sorted after Opaque)
// Forward material always output normal buffer (unless they don't participate to shading)
// Deferred material never output normal buffer
// Note: Unlit object use a ForwardOnly pass and don't have normal, they will write 0 in the normal buffer. This should be safe
// as they will not use the result of lighting anyway. However take care of effect that will try to filter normal buffer.
// TODO: maybe we can use a stencil to tag when Forward unlit touch normal buffer
if (hdCamera.frameSettings.enableForwardRenderingOnly)
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraDepthStencilBuffer);
if (addFullDepthPrepass) // Always true in case of forward rendering, use in case of deferred rendering if requesting a full depth prepass
using (new ProfilingSample(cmd, "Depth Prepass (forward)", CustomSamplerId.DepthPrepass.GetSampler()))
// We render first the opaque object as opaque alpha tested are more costly to render and could be reject by early-z (but not Hi-z as it is disable with clip instruction)
// This is handled automatically with the RenderQueue value (OpaqueAlphaTested have a different value and thus are sorted after Opaque)
cmd.EnableShaderKeyword("WRITE_NORMAL_BUFFER");
HDUtils.SetRenderTarget(cmd, hdCamera, m_NormalBufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer);
// Full forward: Output normal buffer for both forward and forwardOnly
else // Deferred rendering with partial depth prepass
}
else if (hdCamera.frameSettings.enableDepthPrepassWithDeferredRendering || forcePrepass)
{
using (new ProfilingSample(cmd, "Depth Prepass (deferred)", CustomSamplerId.DepthPrepass.GetSampler()))
// We always do a DepthForwardOnly pass with all the opaque (including alpha test)
cmd.DisableShaderKeyword("WRITE_NORMAL_BUFFER"); // Note: This only disable the output of normal buffer for Lit shader, not the other shader that don't use multicompile
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraDepthStencilBuffer);
// First deferred material
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
HDUtils.SetRenderTarget(cmd, hdCamera, m_NormalBufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer);
// Then forward only material that output normal buffer
}
}
else // Deferred with partial depth prepass
{
using (new ProfilingSample(cmd, "Depth Prepass (deferred incomplete)", CustomSamplerId.DepthPrepass.GetSampler()))
{
cmd.DisableShaderKeyword("WRITE_NORMAL_BUFFER");
// Alpha tested materials always have a prepass.
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraDepthStencilBuffer);
// First deferred alpha tested materials. Alpha tested object have always a prepass even if enableDepthPrepassWithDeferredRendering is disabled
HDUtils.SetRenderTarget(cmd, hdCamera, m_NormalBufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer);
// Then forward only material that output normal buffer
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
}
}

// In case of forward SSS we will bind all the required target. It is up to the shader to write into it or not.
if (hdCamera.frameSettings.enableSubsurfaceScattering)
{
RenderTargetIdentifier[] m_MRTWithSSS =
new RenderTargetIdentifier[2 + m_SSSBufferManager.sssBufferCount];
RenderTargetIdentifier[] m_MRTWithSSS = new RenderTargetIdentifier[2 + m_SSSBufferManager.sssBufferCount];
m_MRTWithSSS[0] = m_CameraColorBuffer; // Store the specular color
m_MRTWithSSS[1] = m_CameraSssDiffuseLightingBuffer;
for (int i = 0; i < m_SSSBufferManager.sssBufferCount; ++i)

8
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDStringConstants.cs


Shader.PropertyToID("_SSSBufferTexture3"),
};
public static readonly int[] _NormalBufferTexture =
{
Shader.PropertyToID("_NormalBufferTexture0"),
Shader.PropertyToID("_NormalBufferTexture1"),
Shader.PropertyToID("_NormalBufferTexture2"),
Shader.PropertyToID("_NormalBufferTexture3"),
};
public static readonly int _SSRefractionRayMarchBehindObjects = Shader.PropertyToID("_SSRefractionRayMarchBehindObjects");
public static readonly int _SSRefractionRayMaxScreenDistance = Shader.PropertyToID("_SSRefractionRayMaxScreenDistance");
public static readonly int _SSRefractionRayBlendScreenDistance = Shader.PropertyToID("_SSRefractionRayBlendScreenDistance");

15
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassDepthOnly.hlsl


#endif // TESSELLATION_ON
void Frag( PackedVaryingsToPS packedInput,
#ifdef WRITE_NORMAL_BUFFER
OUTPUT_NORMALBUFFER(outNormalBuffer)
#else
#endif
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif

BuiltinData builtinData;
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
// TODO: handle cubemap shadow
outColor = float4(0.0, 0.0, 0.0, 0.0);
#ifdef WRITE_NORMAL_BUFFER
ENCODE_INTO_NORMALBUFFER(surfaceData, posInput.positionSS, outNormalBuffer);
#elif defined(SCENESELECTIONPASS)
#ifdef SCENESELECTIONPASS
outColor = float4(_ObjectId, _PassValue, 1, 1);
outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);
#else
outColor = float4(0.0, 0.0, 0.0, 0.0);
#endif
}

2
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassForward.hlsl


ApplyDebugToSurfaceData(input.worldToTangent, surfaceData);
#endif
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);

2
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassForwardUnlit.hlsl


GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
// Not lit here (but emissive is allowed)
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
// TODO: we must not access bsdfData here, it break the genericity of the code!
float4 outColor = ApplyBlendMode(bsdfData.color + builtinData.emissiveColor, builtinData.opacity);

2
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassGBuffer.hlsl


ApplyDebugToSurfaceData(input.worldToTangent, surfaceData);
#endif
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);

2
com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassLightTransport.hlsl


// no debug apply during light transport pass
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
LightTransportData lightTransportData = GetLightTransportData(surfaceData, builtinData, bsdfData);
// This shader is call two times. Once for getting emissiveColor, the other time to get diffuseColor

55
com.unity.render-pipelines.high-definition/HDRP/Material/NormalBuffer.hlsl


#include "CoreRP/ShaderLibrary/Packing.hlsl"
#include "CoreRP/ShaderLibrary/CommonMaterial.hlsl"
// ----------------------------------------------------------------------------
// Encoding/decoding normal buffer functions
// ----------------------------------------------------------------------------
struct NormalData
{
float3 normalWS;
float perceptualRoughness;
};
#define NormalBufferType0 float4 // Must match GBufferType1 in deferred
// SSSBuffer texture declaration
TEXTURE2D(_NormalBufferTexture0);
void EncodeIntoNormalBuffer(NormalData normalData, uint2 positionSS, out NormalBufferType0 outNormalBuffer0)
{
// The sign of the Z component of the normal MUST round-trip through the G-Buffer, otherwise
// the reconstruction of the tangent frame for anisotropic GGX creates a seam along the Z axis.
// The constant was eye-balled to not cause artifacts.
// TODO: find a proper solution. E.g. we could re-shuffle the faces of the octahedron
// s.t. the sign of the Z component round-trips.
const float seamThreshold = 1.0 / 1024.0;
normalData.normalWS.z = CopySign(max(seamThreshold, abs(normalData.normalWS.z)), normalData.normalWS.z);
// RT1 - 8:8:8:8
// Our tangent encoding is based on our normal.
float2 octNormalWS = PackNormalOctQuadEncode(normalData.normalWS);
float3 packNormalWS = PackFloat2To888(saturate(octNormalWS * 0.5 + 0.5));
// We store perceptualRoughness instead of roughness because it is perceptually linear.
outNormalBuffer0 = float4(packNormalWS, normalData.perceptualRoughness);
}
void DecodeFromNormalBuffer(float4 normalBuffer, uint2 positionSS, out NormalData normalData)
{
float3 packNormalWS = normalBuffer.rgb;
float2 octNormalWS = Unpack888ToFloat2(packNormalWS);
normalData.normalWS = UnpackNormalOctQuadEncode(octNormalWS * 2.0 - 1.0);
normalData.perceptualRoughness = normalBuffer.a;
}
void DecodeFromNormalBuffer(uint2 positionSS, out NormalData normalData)
{
float4 normalBuffer = LOAD_TEXTURE2D(_NormalBufferTexture0, positionSS);
DecodeFromNormalBuffer(normalBuffer, positionSS, normalData);
}
// OUTPUT_NORMAL_NORMALBUFFER start from SV_Target0 as it is used during depth prepass where there is no color buffer
#define OUTPUT_NORMALBUFFER(NAME) out NormalBufferType0 MERGE_NAME(NAME, 0) : SV_Target0
#define ENCODE_INTO_NORMALBUFFER(SURFACE_DATA, UNPOSITIONSS, NAME) EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(SURFACE_DATA), UNPOSITIONSS, MERGE_NAME(NAME, 0))
#define DECODE_FROM_NORMALBUFFER(UNPOSITIONSS, NORMAL_DATA) DecodeFromNormalBuffer(UNPOSITIONSS, NORMAL_DATA)

9
com.unity.render-pipelines.high-definition/HDRP/Material/NormalBuffer.hlsl.meta


fileFormatVersion: 2
guid: c575b09819842744aa411a49f5a26660
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

81
com.unity.render-pipelines.high-definition/HDRP/Material/NormalBufferManager.cs


using UnityEngine.Rendering;
using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class NormalBufferManager
{
// Currently we only support NormalBuffer with one buffer. If the shader code change, it may require to update the shader manager
public const int k_MaxNormalBuffer = 1;
public int normalBufferCount { get { return k_MaxNormalBuffer; } }
RTHandleSystem.RTHandle[] m_ColorMRTs = new RTHandleSystem.RTHandle[k_MaxNormalBuffer];
protected RenderTargetIdentifier[] m_RTIDs = new RenderTargetIdentifier[k_MaxNormalBuffer];
bool[] m_ExternalBuffer = new bool[k_MaxNormalBuffer];
RTHandleSystem.RTHandle m_HTile;
public NormalBufferManager()
{
}
public void InitNormalBuffers(GBufferManager gbufferManager, RenderPipelineSettings settings)
{
if (settings.supportOnlyForward)
{
// In case of full forward we must allocate the render target for normal buffer (or reuse one already existing)
// TODO: Provide a way to reuse a render target
m_ColorMRTs[0] = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: RenderTextureFormat.ARGB32, sRGB: false, name: "NormalBuffer");
m_ExternalBuffer[0] = false;
}
else
{
// In case of deferred, we must be in sync with NormalBuffer.hlsl and lit.hlsl files and setup the correct buffers
m_ColorMRTs[0] = gbufferManager.GetBuffer(1); // Normal + Roughness is GBuffer(1)
m_ExternalBuffer[0] = true;
}
}
public RenderTargetIdentifier[] GetBuffersRTI()
{
// nameID can change from one frame to another depending on the msaa flag so so we need to update this array to be sure it's up to date.
for (int i = 0; i < normalBufferCount; ++i)
{
m_RTIDs[i] = m_ColorMRTs[i].nameID;
}
return m_RTIDs;
}
public RTHandleSystem.RTHandle GetNormalBuffer(int index)
{
Debug.Assert(index < normalBufferCount);
return m_ColorMRTs[index];
}
public void Build(HDRenderPipelineAsset hdAsset)
{
}
public void Cleanup()
{
for (int i = 0; i < k_MaxNormalBuffer; ++i)
{
if (!m_ExternalBuffer[i])
{
RTHandles.Release(m_ColorMRTs[i]);
}
}
}
public void BindNormalBuffers(CommandBuffer cmd)
{
// NormalBuffer can be access in forward shader, so need to set global texture
for (int i = 0; i < normalBufferCount; ++i)
{
cmd.SetGlobalTexture(HDShaderIDs._NormalBufferTexture[i], GetNormalBuffer(i));
}
}
}
}

11
com.unity.render-pipelines.high-definition/HDRP/Material/NormalBufferManager.cs.meta


fileFormatVersion: 2
guid: 37fd75386a4957c43b0e2d0311efe2c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存