浏览代码

Merge remote-tracking branch 'refs/remotes/origin/Unity-2017.3' into Add-support-of-vertex-displacement

/stochastic_alpha_test
sebastienlagarde 7 年前
当前提交
54f30000
共有 13 个文件被更改,包括 353 次插入185 次删除
  1. 2
      SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood.mat
  2. 6
      SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Wood.mat
  3. 97
      SampleScenes/HDTest/HDRenderLoopTest.unity
  4. 309
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  5. 4
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowSampling.hlsl
  6. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Deferred.compute
  7. 23
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl
  8. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  9. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl
  10. 5
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/builddispatchindirect.compute
  11. 24
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  12. 55
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  13. 7
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl

2
SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood.mat


- _Glossiness: 0.5
- _GlossyReflections: 1
- _HeightAmplitude: 1
- _HeightCenter: 0.5
- _HeightCenter: 1
- _HeightMax: 100
- _HeightMin: 0
- _HorizonFade: 1

6
SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Wood.mat


m_Name: Tessellation - Wood
m_Shader: {fileID: 4800000, guid: 756bac9090102564582875f4c7e30202, type: 3}
m_ShaderKeywords: _HEIGHTMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE _TESSELLATION_DISPLACEMENT
_TESSELLATION_TILING_SCALE
_TESSELLATION_OBJECT_SCALE _TESSELLATION_TILING_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

- _Glossiness: 0.5
- _GlossyReflections: 1
- _HeightAmplitude: 1
- _HeightCenter: 0.5
- _HeightCenter: 1
- _HeightMax: 100
- _HeightMin: 0
- _HorizonFade: 1

- _TessellationFactorMinDistance: 20
- _TessellationFactorTriangleSize: 100
- _TessellationMode: 1
- _TessellationObjectScale: 0
- _TessellationObjectScale: 1
- _TessellationShapeFactor: 0.75
- _TessellationTilingScale: 1
- _TexWorldScale: 1

97
SampleScenes/HDTest/HDRenderLoopTest.unity


m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 122368350}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -6.918895, y: 15.827157, z: 12.172683}
m_LocalPosition: {x: -10, y: 0, z: 0}
m_LocalScale: {x: -1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 874252442}

format: 0
data:
shadowDatas: []
--- !u!1 &195260445
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 195260446}
- component: {fileID: 195260449}
- component: {fileID: 195260448}
- component: {fileID: 195260447}
m_Layer: 0
m_Name: Cube
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &195260446
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 195260445}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -5, y: -0.5, z: 5.5}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 874252442}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!23 &195260447
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 195260445}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 73c176f402d2c2f4d929aa5da7585d17, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!65 &195260448
BoxCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 195260445}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!33 &195260449
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 195260445}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &209784732
GameObject:
m_ObjectHideFlags: 0

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 874252441}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 4, y: -15, z: -25}
m_LocalPosition: {x: 10, y: 1, z: -14}
- {fileID: 195260446}
m_Father: {fileID: 0}
m_RootOrder: 13
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 885480687}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 3.0811052, y: 15.577157, z: 12.172683}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 874252442}

m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1950745465}
m_LocalRotation: {x: 0.0125774685, y: 0.9800875, z: -0.18686625, w: 0.0659644}
m_LocalPosition: {x: -1.9188948, y: 17.577156, z: 12.172683}
m_LocalScale: {x: 20, y: 12.000023, z: 1}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -5, y: 2, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 874252442}
m_RootOrder: 0

309
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl


// calc TCs
float2 posTC = posNDC * 0.5 + 0.5;
closestSampleNDC = (floor(posTC * sd.textureSize.zw) + 0.5) * sd.texelSizeRcp.zw * 2.0 - 1.0.xx;
return (posTC * sd.scaleOffset.xy + sd.scaleOffset.zw) * sd.textureSize.xy;
return uint2( (posTC * sd.scaleOffset.xy + sd.scaleOffset.zw) * sd.textureSize.xy );
}
int EvalShadow_GetCubeFaceID( float3 dir )

//
#define kMaxShadowCascades 4
#define SHADOW_REPEAT_CASCADE( _x ) _x, _x, _x, _x
int EvalShadow_GetSplitSphereIndexForDirshadows( float3 positionWS, float4 dirShadowSplitSpheres[4], out float relDistance )
{

payloadOffset++;
float4 borders = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
float border = borders[shadowSplitIndex];
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
// normal based bias

/* Be careful of this code, we need it here before the if statement otherwise the compiler screws up optimizing dirShadowSplitSpheres VGPRs away */
float border = borders[shadowSplitIndex];
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
float4 splitSphere = dirShadowSplitSpheres[shadowSplitIndex];
float3 cascadeDir = normalize( -splitSphere.xyz + dirShadowSplitSpheres[min(3,shadowSplitIndex+1)].xyz );
float3 wposDir = normalize( -splitSphere.xyz + positionWS );
// Be careful of this code, we need it here before the if statement otherwise the compiler screws up optimizing dirShadowSplitSpheres VGPRs away
float3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
float3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz );
float3 wposDir = normalize( -splitSphere + positionWS );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
// sample the texture
uint texIdx, sampIdx;
float slice;

UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
float shadow1 = 1.0;
float shadow1 = 1.0;
[branch]
if( alpha > 0.0 )
{
sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];

UnpackShadowmapId( sd.id, slice );
[branch]
if( all( abs( posNDC.xy ) <= (1.0 - sd.texelSizeRcp.zw * 0.5) ) )
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}

}
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
float relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
if( shadowSplitIndex < 0 ) \
return 1.0; \
\
float4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
float3 orig_pos = positionWS; \
uint orig_payloadOffset = payloadOffset; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
\
/* Be careful of this code, we need it here before the if statement otherwise the compiler screws up optimizing dirShadowSplitSpheres VGPRs away */ \
float border = borders[shadowSplitIndex]; \
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
float4 splitSphere = dirShadowSplitSpheres[shadowSplitIndex]; \
float3 cascadeDir = normalize( -splitSphere.xyz + dirShadowSplitSpheres[min(kMaxShadowCascades-1,shadowSplitIndex+1)].xyz ); \
float3 wposDir = normalize( -splitSphere.xyz + positionWS ); \
float cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
/* get shadowmap texcoords */ \
float3 posNDC; \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
\
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
\
shadowSplitIndex++; \
float shadow1 = 1.0; \
if( shadowSplitIndex < kMaxShadowCascades ) \
{ \
shadow1 = shadow; \
\
[branch] \
if( alpha > 0.0 ) \
{ \
sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, false ); \
/* sample the texture */ \
UnpackShadowmapId( sd.id, slice ); \
\
if( all( abs( posNDC.xy ) <= (1.0 - sd.texelSizeRcp.zw * 0.5) ) ) \
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
} \
} \
shadow = lerp( shadow, shadow1, alpha ); \
return shadow; \
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
float relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
if( shadowSplitIndex < 0 ) \
return 1.0; \
\
float4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float border = borders[shadowSplitIndex]; \
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
\
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
float3 orig_pos = positionWS; \
uint orig_payloadOffset = payloadOffset; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
/* Be careful of this code, we need it here before the if statement otherwise the compiler screws up optimizing dirShadowSplitSpheres VGPRs away */ \
float3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
float3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz ); \
float3 wposDir = normalize( -splitSphere + positionWS ); \
float cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
/* get shadowmap texcoords */ \
float3 posNDC; \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
\
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
\
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
float shadow1 = 1.0; \
\
shadowSplitIndex++; \
if( shadowSplitIndex < kMaxShadowCascades ) \
{ \
shadow1 = shadow; \
\
if( alpha > 0.0 ) \
{ \
sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, false ); \
/* sample the texture */ \
UnpackShadowmapId( sd.id, slice ); \
\
[branch] \
if( all( abs( posNDC.xy ) <= (1.0 - sd.texelSizeRcp.zw * 0.5) ) ) \
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
} \
} \
shadow = lerp( shadow, shadow1, alpha ); \
return shadow; \
} \
\
float EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
uint shadowAlgorithms[kMaxShadowCascades] = { SHADOW_REPEAT_CASCADE( shadowAlgorithm ) }; \
return EvalShadow_CascadedDepth_Blend( shadowContext, shadowAlgorithms, tex, samp, positionWS, normalWS, index, L ); \
EvalShadow_CascadedDepth_( SamplerComparisonState )
EvalShadow_CascadedDepth_( SamplerState )
#undef EvalShadow_CascadedDepth_

float EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
float4 dirShadowSplitSpheres[kMaxShadowCascades];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
float relDistance;
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance );

float3 posNDC;
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true );
if( shadowSplitIndex < (kMaxShadowCascades-1) )
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 );
float3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
float3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( 3, shadowSplitIndex + 1 )].xyz );
float3 wposDir = normalize( -splitSphere + positionWS );
float cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
if( shadowSplitIndex < nextSplit && step( EvalShadow_hash12( posTC.xy ), alpha ) )
float4 splitSphere = dirShadowSplitSpheres[shadowSplitIndex];
float3 cascadeDir = normalize( -splitSphere.xyz + dirShadowSplitSpheres[shadowSplitIndex+1].xyz );
float3 wposDir = normalize( -splitSphere.xyz + positionWS );
float cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
if( step( EvalShadow_hash12( posTC.xy ), alpha ) )
{
shadowSplitIndex++;
sd = shadowContext.shadowDatas[index + 2 + shadowSplitIndex];
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex+1] * sd.texelSizeRcp.zw, sd.normalBias );
posTC = EvalShadow_GetTexcoords( sd, positionWS );
}
sd = shadowContext.shadowDatas[index + 1 + nextSplit];
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[nextSplit] * sd.texelSizeRcp.zw, sd.normalBias );
posTC = EvalShadow_GetTexcoords( sd, positionWS );
}
// sample the texture
uint texIdx, sampIdx;

return shadowSplitIndex < (kMaxShadowCascades-1) ? shadow : lerp( shadow, 1.0, alpha );
}
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
float relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
if( shadowSplitIndex < 0 ) \
return 1.0; \
\
float4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float border = borders[shadowSplitIndex]; \
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
\
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
float3 orig_pos = positionWS; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posNDC; \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
\
if( shadowSplitIndex < (kMaxShadowCascades-1) ) \
{ \
float4 splitSphere = dirShadowSplitSpheres[shadowSplitIndex]; \
float3 cascadeDir = normalize( -splitSphere.xyz + dirShadowSplitSpheres[shadowSplitIndex+1].xyz ); \
float3 wposDir = normalize( -splitSphere.xyz + positionWS ); \
float cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
if( step( EvalShadow_hash12( posTC.xy ), alpha ) ) \
{ \
sd = shadowContext.shadowDatas[index + 2 + shadowSplitIndex]; \
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex+1] * sd.texelSizeRcp.zw, sd.normalBias ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
} \
} \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
return shadowSplitIndex < (kMaxShadowCascades-1) ? shadow : lerp( shadow, 1.0, alpha ); \
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
float relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
if( shadowSplitIndex < 0 ) \
return 1.0; \
\
float4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
float border = borders[shadowSplitIndex]; \
float alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
\
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
float3 orig_pos = positionWS; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posNDC; \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
\
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 ); \
float3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
float3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[nextSplit].xyz ); \
float3 wposDir = normalize( -splitSphere + positionWS ); \
float cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
if( shadowSplitIndex != nextSplit && step( EvalShadow_hash12( posTC.xy ), alpha ) ) \
{ \
sd = shadowContext.shadowDatas[index + 1 + nextSplit]; \
positionWS = orig_pos + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[nextSplit] * sd.texelSizeRcp.zw, sd.normalBias ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
} \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
float shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
return shadowSplitIndex < (kMaxShadowCascades-1) ? shadow : lerp( shadow, 1.0, alpha ); \
} \
\
float EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
uint shadowAlgorithms[kMaxShadowCascades] = { SHADOW_REPEAT_CASCADE( shadowAlgorithm ) }; \
return EvalShadow_CascadedDepth_Dither( shadowContext, shadowAlgorithms, tex, samp, positionWS, normalWS, index, L ); \
EvalShadow_CascadedDepth_( SamplerComparisonState )
EvalShadow_CascadedDepth_( SamplerState )
#undef EvalShadow_CascadedDepth_

float4 closestWS = mul( closestNDC, sd.shadowToWorld );
return closestWS.xyz / closestWS.w;
}
float3 EvalShadow_GetClosestSample_Cascade( ShadowContext shadowContext, Texture2DArray tex, float3 positionWS, float3 normalWS, int index, float4 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
float relDistance;
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance );
if( shadowSplitIndex < 0 )
return 1.0;
float4 scales = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
float4 borders = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
float4 closestNDC = { 0,0,0,1 };
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
// load the texel
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, slice, 0 ).x;
// reconstruct depth position
float4 closestWS = mul( closestNDC, sd.shadowToWorld );
return closestWS.xyz / closestWS.w;
}

4
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowSampling.hlsl


float2 fetchesUV[9];
SampleShadow_ComputeSamples_Tent_5x5(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
for (int i = 0; i < 9; i++)
for( int i = 0; i < 9; i++ )
return shadow;
}

2
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Deferred.compute


#pragma kernel Deferred_Indirect_Fptl_Variant23 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Fptl_Variant23 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=23
#pragma kernel Deferred_Indirect_Fptl_Variant24 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Fptl_Variant24 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=24
#pragma kernel Deferred_Indirect_Fptl_Variant25 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Fptl_Variant25 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=25
#pragma kernel Deferred_Indirect_Fptl_Variant26 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Fptl_Variant26 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=26
/* Tag: SUPPORT_COMPUTE_CLUSTER_OPAQUE - Uncomment this if you want to do cluster opaque with compute shader (by default we support only fptl on opaque)
#pragma kernel Deferred_Indirect_Clustered_Variant0 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Clustered_Variant0 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=0

#pragma kernel Deferred_Indirect_Clustered_Variant23 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Clustered_Variant23 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=23
#pragma kernel Deferred_Indirect_Clustered_Variant24 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Clustered_Variant24 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=24
#pragma kernel Deferred_Indirect_Clustered_Variant25 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Clustered_Variant25 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=25
#pragma kernel Deferred_Indirect_Clustered_Variant26 SHADE_OPAQUE_ENTRY=Deferred_Indirect_Clustered_Variant26 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=26
*/
#define LIGHTLOOP_TILE_PASS 1

23
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl


// and that on the C# side the shadowContext bindDelegate binds the correct resource to the correct texture id.
#define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL // enables hardcoded resources and algorithm for directional lights
#define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL // enables hardcoded resources and algorithm for punctual lights
//#define SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS // enables separate resources and algorithms for spot and point lights
#define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL // enables hardcoded resources and algorithm for directional lights
#define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL // enables hardcoded resources and algorithm for punctual lights
//#define SHADOW_DISPATCH_USE_SEPARATE_CASCADE_ALGOS // enables separate cascade sampling variants for each cascade
//#define SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS // enables separate resources and algorithms for spot and point lights
#define SHADOW_DISPATCH_DIR_ALG GPUSHADOWALGORITHM_PCF_TENT_5X5
#define SHADOW_DISPATCH_DIR_ALG GPUSHADOWALGORITHM_PCF_TENT_5X5 // all cascades
#define SHADOW_DISPATCH_DIR_ALG_0 GPUSHADOWALGORITHM_PCF_TENT_7X7 // 1st cascade
#define SHADOW_DISPATCH_DIR_ALG_1 GPUSHADOWALGORITHM_PCF_TENT_5X5 // 2nd cascade
#define SHADOW_DISPATCH_DIR_ALG_2 GPUSHADOWALGORITHM_PCF_TENT_3X3 // 3rd cascade
#define SHADOW_DISPATCH_DIR_ALG_3 GPUSHADOWALGORITHM_PCF_1TAP // 4th cascade
// point
#define SHADOW_DISPATCH_POINT_TEX 3
#define SHADOW_DISPATCH_POINT_SMP 0

{
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_DIR_TEX];
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_DIR_SMP];
uint algo = SHADOW_DISPATCH_DIR_ALG;
#ifdef SHADOW_DISPATCH_USE_SEPARATE_CASCADE_ALGOS
uint algo[kMaxShadowCascades] = { SHADOW_DISPATCH_DIR_ALG_0, SHADOW_DISPATCH_DIR_ALG_1, SHADOW_DISPATCH_DIR_ALG_2, SHADOW_DISPATCH_DIR_ALG_3 };
#else
uint algo = SHADOW_DISPATCH_DIR_ALG;
#endif
return EvalShadow_CascadedDepth_Blend( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}

#undef SHADOW_DISPATCH_DIR_TEX
#undef SHADOW_DISPATCH_DIR_SMP
#undef SHADOW_DISPATCH_DIR_ALG
#undef SHADOW_DISPATCH_DIR_ALG_0
#undef SHADOW_DISPATCH_DIR_ALG_1
#undef SHADOW_DISPATCH_DIR_ALG_2
#undef SHADOW_DISPATCH_DIR_ALG_3
#undef SHADOW_DISPATCH_POINT_TEX
#undef SHADOW_DISPATCH_POINT_SMP
#undef SHADOW_DISPATCH_POINT_ALG

2
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


public static int s_TileSizeClustered = 32;
// feature variants
public static int s_NumFeatureVariants = 26;
public static int s_NumFeatureVariants = 27;
// Following define the maximum number of bits use in each feature category.
public static uint s_LightFeatureMaskFlags = 0xFF00;

2
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl


#define USE_LEFT_HAND_CAMERA_SPACE (1)
#define TILE_SIZE_FPTL (16)
#define TILE_SIZE_CLUSTERED (32)
#define NUM_FEATURE_VARIANTS (26)
#define NUM_FEATURE_VARIANTS (27)
#define LIGHT_FEATURE_MASK_FLAGS (65280)
#define MATERIAL_FEATURE_MASK_FLAGS (255)

5
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/builddispatchindirect.compute


uint tileY = (dispatchThreadId + 0.5f) / (float)g_NumTilesX; // Integer division is extremely expensive, so we better avoid it
uint tileX = dispatchThreadId - tileY * g_NumTilesX;
// Check if there is no light or no material (mean we are sky/background pixel) / Both test as we can enable/disable light/material classification
if ((featureFlags & LIGHT_FEATURE_MASK_FLAGS) != 0 && (featureFlags & MATERIAL_FEATURE_MASK_FLAGS) != 0)
// Check if there is no material (means it is a sky/background pixel).
// Note that we can have no lights, yet we still need to render geometry with precomputed illumination.
if ((featureFlags & MATERIAL_FEATURE_MASK_FLAGS) != 0)
{
uint variant = FeatureFlagsToTileVariant(featureFlags);
uint offset;

24
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs


private class StylesLayer
{
public readonly Color[] layerColors =
{
Color.white,
Color.red,
Color.green,
Color.blue
};
public readonly GUIContent[] layerLabels =
{
new GUIContent("Main layer"),

public StylesLayer()
{
layerLabelColors[0].normal.textColor = Color.white;
layerLabelColors[1].normal.textColor = Color.red;
layerLabelColors[2].normal.textColor = Color.green;
layerLabelColors[3].normal.textColor = Color.blue;
layerLabelColors[0].normal.textColor = layerColors[0];
layerLabelColors[1].normal.textColor = layerColors[1];
layerLabelColors[2].normal.textColor = layerColors[2];
layerLabelColors[3].normal.textColor = layerColors[3];
}
}

bool layersChanged = false;
Material material = m_MaterialEditor.target as Material;
Color originalContentColor = GUI.contentColor;
GUI.contentColor = styles.layerColors[layerIndex];
SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex, false);
SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex, true);
GUI.contentColor = originalContentColor;
GUILayout.BeginHorizontal();
{

55
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


// Combination need to be define in increasing "comlexity" order as define by FeatureFlagsToTileVariant
static const uint kFeatureVariantFlags[NUM_FEATURE_VARIANTS] =
{
// Precomputed illumination (no dynamic lights) for all material types (except for the clear coat)
/* 0 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_ENV | (MATERIAL_FEATURE_MASK_FLAGS & (~MATERIALFEATUREFLAGS_LIT_CLEAR_COAT)),
/* 0 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 1 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 2 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 3 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 4 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 1 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 2 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 3 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 4 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 5 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 5 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS,
/* 6 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_SSS,
/* 7 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SSS,
/* 8 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SSS,
/* 9 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_SSS,
/* 6 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS,
/* 7 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_SSS,
/* 8 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SSS,
/* 9 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SSS,
/* 10 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_SSS,
/* 10 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 11 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 12 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 13 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 14 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 11 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 12 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 13 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 14 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 15 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 15 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 16 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 17 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 18 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 19 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 16 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 17 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 18 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 19 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 20 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 20 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 21 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 22 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 23 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 24 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 21 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 22 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 23 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 24 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 25 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 25 */ LIGHT_FEATURE_MASK_FLAGS | MATERIAL_FEATURE_MASK_FLAGS, // Catch all case with MATERIAL_FEATURE_MASK_FLAGS is needed in case we disable material classification
/* 26 */ LIGHT_FEATURE_MASK_FLAGS | MATERIAL_FEATURE_MASK_FLAGS, // Catch all case with MATERIAL_FEATURE_MASK_FLAGS is needed in case we disable material classification
};
uint FeatureFlagsToTileVariant(uint featureFlags)

7
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseNormal1, _InheritBaseNormal2, _InheritBaseNormal3, weights) * influenceMask;
// We will add smoothly the contribution of the normal map by lerping between vertex normal ( (0,0,1) in tangent space) and the actual normal from the main layer depending on the influence factor.
// Note: that we don't take details map into account here.
float3 mainNormalTS = lerp(float3(0.0, 0.0, 1.0), normalTS0, influenceFactor);
#ifdef SURFACE_GRADIENT
float3 neutralNormalTS = float3(0.0, 0.0, 0.0);
#else
float3 neutralNormalTS = float3(0.0, 0.0, 1.0);
#endif
float3 mainNormalTS = lerp(neutralNormalTS, normalTS0, influenceFactor);
// Add on our regular normal a bit of Main Layer normal base on influence factor. Note that this affect only the "visible" normal.
#ifdef SURFACE_GRADIENT

正在加载...
取消
保存