浏览代码

Add normal buffer to directional shadow and forwar

+ add poistion input to prototype of ConvertSurfaceDataToBSDFData
/main
Sebastien Lagarde 7 年前
当前提交
4d25d4a1
共有 15 个文件被更改,包括 53 次插入40 次删除
  1. 24
      com.unity.render-pipelines.high-definition/HDRP/Lighting/DeferredDirectionalShadow.compute
  2. 8
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs
  3. 31
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl
  4. 4
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.shader
  5. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/LitBuiltinData.hlsl
  6. 5
      com.unity.render-pipelines.high-definition/HDRP/Material/NormalBuffer.hlsl
  7. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
  8. 1
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.shader
  9. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitData.hlsl
  10. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/Unlit/Unlit.hlsl
  11. 4
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassDepthOnly.hlsl
  12. 2
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassForward.hlsl
  13. 2
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassForwardUnlit.hlsl
  14. 2
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassGBuffer.hlsl
  15. 2
      com.unity.render-pipelines.high-definition/HDRP/ShaderPass/ShaderPassLightTransport.hlsl

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

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


return normalData;
}
void UpdateSurfaceDataFromNormalData(uint2 positionSS, inout SurfaceData surfaceData)
{
NormalData normalData;
DecodeFromNormalBuffer(positionSS, normalData);
surfaceData.normalWS = normalData.normalWS;
// If we have store clear coat smoothness in the texture, don't override perceptualSmoothness
// Note: Compiler is always able to optimize this code as we are in forward, so with static flag
// so the condition will be remove and the read texture will correctly happen instead of all the code
// to provide perceptualSmoothness
if (!HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
surfaceData.perceptualSmoothness = normalData.perceptualSmoothness;
}
}
BSDFData ConvertSurfaceDataToBSDFData(SurfaceData surfaceData)
BSDFData ConvertSurfaceDataToBSDFData(uint2 positionSS, SurfaceData surfaceData)
// In forward we can chose between reading the normal from the normalBufferTexture or computing it again
// Reading normal will suffer from compression, thus using following code depends on tradeoff between performance and quality.
// Test it for your project
// #define READ_FORWARD_NORMAL_FROM_TEXTURE
#ifdef READ_FORWARD_NORMAL_FROM_TEXTURE
#if SHADERPASS == SHADERPASS_FORWARD
UpdateSurfaceDataFromNormalData(positionSS, surfaceData);
#endif
#endif
// IMPORTANT: In case of foward or gbuffer pass all enable flags are statically know at compile time, so the compiler can do compile time optimization
bsdfData.materialFeatures = surfaceData.materialFeatures;

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


ZWrite On
//ColorMask 0
#pragma multi_compile _ OUTPUT_NORMAL_BUFFER
#pragma multi_compile _ WRITE_NORMAL_BUFFER
#define SHADERPASS SHADERPASS_DEPTH_ONLY
#include "../../ShaderVariables.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

5
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
// ----------------------------------------------------------------------------

}
// OUTPUT_NORMAL_NORMALBUFFER start from SV_Target0 as it is used during depth prepass where there is no color buffer
#define OUTPUT_NORMAL_NORMALBUFFER(NAME) out NormalBufferType0 MERGE_NAME(NAME, 0) : SV_Target0
#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)

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


// conversion function for forward
//-----------------------------------------------------------------------------
BSDFData ConvertSurfaceDataToBSDFData(SurfaceData surfaceData)
BSDFData ConvertSurfaceDataToBSDFData(uint2 positionSS, SurfaceData surfaceData)
{
BSDFData bsdfData;
ZERO_INITIALIZE(BSDFData, bsdfData);

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


HLSLPROGRAM
#define WRITE_NORMAL_BUFFER
#define SHADERPASS SHADERPASS_DEPTH_ONLY
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.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

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;

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


#endif // TESSELLATION_ON
void Frag( PackedVaryingsToPS packedInput,
#ifdef OUTPUT_NORMAL_BUFFER
#ifdef WRITE_NORMAL_BUFFER
OUTPUT_NORMALBUFFER(outNormalBuffer)
#else
out float4 outColor : SV_Target

outputDepth = posInput.deviceDepth;
#endif
#ifdef OUTPUT_NORMAL_BUFFER
#ifdef WRITE_NORMAL_BUFFER
ENCODE_INTO_NORMALBUFFER(surfaceData, posInput.positionSS, outNormalBuffer);
#elif defined(SCENESELECTIONPASS)
// We use depth prepass for scene selection in the editor, this code allow to output the outline correctly

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

正在加载...
取消
保存