浏览代码

Merge branch 'master' into debug-menu-refactor

/main
Thomas 7 年前
当前提交
44dd9f42
共有 140 个文件被更改,包括 1934 次插入1075 次删除
  1. 3
      .gitmodules
  2. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_0.mat
  3. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_1.mat
  4. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_2.mat
  5. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_3.mat
  6. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_4.mat
  7. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_5.mat
  8. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_6.mat
  9. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_7.mat
  10. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_8.mat
  11. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_9.mat
  12. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth1_0.mat
  13. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_0.mat
  14. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_1.mat
  15. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_2.mat
  16. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_3.mat
  17. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_4.mat
  18. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_5.mat
  19. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_6.mat
  20. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_7.mat
  21. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_8.mat
  22. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_9.mat
  23. 16
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric1_0.mat
  24. 8
      ScriptableRenderPipeline/Core/CoreRP/Editor/CoreEditorUtils.cs
  25. 7
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/API/D3D11.hlsl
  26. 7
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/API/PSSL.hlsl
  27. 20
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/API/Validate.hlsl
  28. 7
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/API/XBoxOne.hlsl
  29. 8
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/AreaLighting.hlsl
  30. 108
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/BSDF.hlsl
  31. 28
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/CommonMaterial.hlsl
  32. 74
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/Shadow.hlsl
  33. 819
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  34. 262
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/ShadowSampling.hlsl
  35. 36
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/ShadowTexFetch.hlsl
  36. 15
      ScriptableRenderPipeline/Core/CoreRP/Shadow/AdditionalShadowData.cs
  37. 168
      ScriptableRenderPipeline/Core/CoreRP/Shadow/Shadow.cs
  38. 35
      ScriptableRenderPipeline/Core/CoreRP/Shadow/ShadowBase.cs
  39. 57
      ScriptableRenderPipeline/Core/CoreRP/Shadow/ShadowBase.cs.hlsl
  40. 45
      ScriptableRenderPipeline/Core/CoreRP/Shadow/ShadowUtilities.cs
  41. 8
      ScriptableRenderPipeline/Core/CoreRP/TextureCache.cs
  42. 2
      ScriptableRenderPipeline/Core/package.json
  43. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDAdditionalCameraData.cs
  44. 44
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  45. 18
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraUI.cs
  46. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/SerializedHDCamera.cs
  47. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDAssetFactory.cs
  48. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRenderPipelineMenuItems.cs
  49. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.Styles.cs
  50. 58
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.cs
  51. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditorUtility.cs
  52. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/LayeredLit/LayeredLitUI.cs
  53. 44
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/LitUI.cs
  54. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/GlobalLightLoopSettingsUI.cs
  55. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedGlobalLightLoopSettings.cs
  56. 48
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  57. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.asset
  58. 38
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/DeferredDirectionalShadow.compute
  59. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl
  60. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/GlobalLightLoopSettings.cs
  61. 48
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  62. 26
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.hlsl
  63. 29
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Shadow.hlsl
  64. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-bigtile.compute
  65. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-clustered.compute
  66. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild.compute
  67. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/materialflags.compute
  68. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/PlanarReflectionProbeCache.cs
  69. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionProbeCache.cs
  70. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/Resources/VolumetricLighting.compute
  71. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VBuffer.hlsl
  72. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLit.shader
  73. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl
  74. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitTessellation.shader
  75. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs
  76. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl
  77. 125
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  78. 13
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.shader
  79. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataDisplacement.hlsl
  80. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataIndividualLayer.hlsl
  81. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitProperties.hlsl
  82. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitTessellation.shader
  83. 22
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.compute
  84. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.shader
  85. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Unlit/Unlit.shader
  86. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset
  87. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/RenderPipelineResources.cs
  88. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyManager.cs
  89. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyRenderingContext.cs
  90. 4
      ScriptableRenderPipeline/HDRenderPipeline/package.json
  91. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/LightweightLightEditor.cs
  92. 4
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightShaderGUI.cs
  93. 34
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  94. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs
  95. 16
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl
  96. 31
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl
  97. 31
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassShadow.hlsl
  98. 15
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl
  99. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightCopyDepth.shader
  100. 8
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader

3
.gitmodules


path = PostProcessing
url = https://github.com/Unity-Technologies/PostProcessing
branch = v2
[submodule "ShaderGraph"]
path = ShaderGraph
url = https://github.com/Unity-Technologies/ShaderGraph

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_0.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_0
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_1.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_1
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_2.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_2
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_3.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_3
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_4.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_4
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_5.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_5
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_6.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_6
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_7.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_7
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_8.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_8
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth0_9.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth0_9
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smooth1_0.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smooth1_0
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 1
- _Metallic: 1
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_0.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_0
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_1.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_1
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_2.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_2
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_3.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_3
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_4.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_4
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_5.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_5
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_6.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_6
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_7.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_7
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_8.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_8
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric0_9.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric0_9
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

16
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Coat_smoothdielectric1_0.mat


m_PrefabInternal: {fileID: 0}
m_Name: Mat_Coat_smoothdielectric1_0
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _MATERIAL_FEATURE_IRIDESCENCE _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _MATERIAL_FEATURE_CLEAR_COAT _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _Ior: 1
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _MaterialID: 3
- _MaterialID: 1
- _Metalic: 0
- _Metallic: 0
- _Mode: 0

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}

8
ScriptableRenderPipeline/Core/CoreRP/Editor/CoreEditorUtils.cs


material.shaderKeywords = null;
}
public static T[] GetAdditionalData<T>(params UnityEngine.Object[] targets)
public static T[] GetAdditionalData<T>(UnityEngine.Object[] targets, Action<T> initDefault = null)
where T : Component
{
// Handles multi-selection

for (int i = 0; i < data.Length; i++)
{
if (data[i] == null)
{
if (initDefault != null)
{
initDefault(data[i]);
}
}
}
return data;

7
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/API/D3D11.hlsl


#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;

7
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/API/PSSL.hlsl


#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;

20
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/API/Validate.hlsl


REQUIRE_DEFINED(INITIALIZE_OUTPUT)
*/
// Default values for things that have not been defined in the platform headers
// default flow control attributes
#ifndef UNITY_BRANCH
# define UNITY_BRANCH
#endif
#ifndef UNITY_FLATTEN
# define UNITY_FLATTEN
#endif
#ifndef UNITY_UNROLL
# define UNITY_UNROLL
#endif
#ifndef UNITY_UNROLLX
# define UNITY_UNROLLX(_x)
#endif
#ifndef UNITY_LOOP
# define UNITY_LOOP
#endif

7
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/API/XBoxOne.hlsl


#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;

8
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/AreaLighting.hlsl


real e = sinSqSigma * cosOmega;
[branch]
UNITY_BRANCH
if (omega < HALF_PI - sigma)
{
// No horizon occlusion (case #1).

#else // Ref: Moving Frostbite to Physically Based Rendering, page 47 (2015, optimized).
real cosSqOmega = cosOmega * cosOmega; // y^2
[branch]
UNITY_BRANCH
if (cosSqOmega > sinSqSigma) // (y^2)>x
{
return saturate(sinSqSigma * cosOmega); // Clip[x*y,{0,1}]

real PolygonIrradiance(real4x3 L)
{
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
[unroll]
UNITY_UNROLL
for (uint i = 0; i < 4; i++)
{
L[i] = normalize(L[i]);

[unroll]
UNITY_UNROLL
for (uint edge = 0; edge < 4; edge++)
{
real3 V1 = L[edge];

108
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/BSDF.hlsl


// Fresnel dieletric / dielectric
real F_Fresnel(real ior, real u)
{
float g = sqrt(Sq(ior) + Sq(u) - 1.0);
real g = sqrt(Sq(ior) + Sq(u) - 1.0);
return 0.5 * Sq((g - u) / (g + u)) * (1.0 + Sq(((g + u) * u - 1.0) / ((g - u) * u + 1.0)));
}

{
// Note that we could save 2 cycles by inlining the multiplication by INV_PI.
return INV_PI * DiffuseGGXNoPI(albedo, NdotV, NdotL, NdotH, LdotV, roughness);
}
//-----------------------------------------------------------------------------
// Conversion FO/IOR
//-----------------------------------------------------------------------------
// ior is a value between 1.0 and 3.0. 1.0 is air interface
real IorToFresnel0(real transmittedIor, real incidentIor = 1.0)
{
return Sq((transmittedIor - incidentIor) / (transmittedIor + incidentIor));
}
// Assume air interface for top
// Note: Don't handle the case fresnel0 == 1
real Fresnel0ToIor(real fresnel0)
{
real sqrtF0 = sqrt(fresnel0);
return (1.0 + sqrtF0) / (1.0 - sqrtF0);
}
// This function is a coarse approximation of computing fresnel0 for a different top than air (here clear coat of IOR 1.5) when we only have fresnel0 with air interface
// This function is equivalent to IorToFresnel0(Fresnel0ToIor(fresnel0), 1.5)
// mean
// real sqrtF0 = sqrt(fresnel0);
// return Sq(1.0 - 5.0 * sqrtF0) / Sq(5.0 - sqrtF0);
// Optimization: Fit of the function (3 mad) for range [0.04 (should return 0), 1 (should return 1)]
TEMPLATE_1_REAL(ConvertF0ForAirInterfaceToF0ForClearCoat15, fresnel0, return saturate(-0.0256868 + fresnel0 * (0.326846 + (0.978946 - 0.283835 * fresnel0) * fresnel0)))
//-----------------------------------------------------------------------------
// Iridescence
//-----------------------------------------------------------------------------
// Ref: https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html
// Evaluation XYZ sensitivity curves in Fourier space
real3 EvalSensitivity(real opd, real shift)
{
// Use Gaussian fits, given by 3 parameters: val, pos and var
real phase = 2.0 * PI * opd * 1e-6;
real3 val = real3(5.4856e-13, 4.4201e-13, 5.2481e-13);
real3 pos = real3(1.6810e+06, 1.7953e+06, 2.2084e+06);
real3 var = real3(4.3278e+09, 9.3046e+09, 6.6121e+09);
real3 xyz = val * sqrt(2.0 * PI * var) * cos(pos * phase + shift) * exp(-var * phase * phase);
xyz.x += 9.7470e-14 * sqrt(2.0 * PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift) * exp(-4.5282e+09 * phase * phase);
return xyz / 1.0685e-7;
}
// Evaluate the reflectance for a thin-film layer on top of a dielectric medum.
real3 EvalIridescence(real eta_1, real cosTheta1, real iridescenceThickness, real baseLayerFresnel0)
{
// iridescenceThickness unit is micrometer for this equation here. Mean 0.5 is 500nm.
real Dinc = 3.0 * iridescenceThickness;
// Note: Unlike the code provide with the paper, here we use schlick approximation
// Schlick is a very poor approximation when dealing with iridescence to the Fresnel
// term and there is no "neutral" value in this unlike in the original paper.
// We use Iridescence mask here to allow to have neutral value
// Hack: In order to use only one parameter (DInc), we deduced the ior of iridescence from current Dinc iridescenceThickness
// and we use mask instead to fade out the effect
real eta_2 = lerp(2.0, 1.0, iridescenceThickness);
// Following line from original code is not needed for us, it create a discontinuity
// Force eta_2 -> eta_1 when Dinc -> 0.0
// real eta_2 = lerp(eta_1, eta_2, smoothstep(0.0, 0.03, Dinc));
// Evaluate the cosTheta on the base layer (Snell law)
real cosTheta2 = sqrt(1.0 - Sq(eta_1 / eta_2) * (1.0 - Sq(cosTheta1)));
// First interface
real R0 = IorToFresnel0(eta_2, eta_1);
real R12 = F_Schlick(R0, cosTheta1);
real R21 = R12;
real T121 = 1.0 - R12;
real phi12 = 0.0;
real phi21 = PI - phi12;
// Second interface
real3 R23 = F_Schlick(baseLayerFresnel0, cosTheta2);
real phi23 = 0.0;
// Phase shift
real OPD = Dinc * cosTheta2;
real phi = phi21 + phi23;
// Compound terms
real3 R123 = R12 * R23;
real3 r123 = sqrt(R123);
real3 Rs = Sq(T121) * R23 / (real3(1.0, 1.0, 1.0) - R123);
// Reflectance term for m = 0 (DC term amplitude)
real3 C0 = R12 + Rs;
real3 I = C0;
// Reflectance term for m > 0 (pairs of diracs)
real3 Cm = Rs - T121;
for (int m = 1; m <= 2; ++m)
{
Cm *= r123;
real3 Sm = 2.0 * EvalSensitivity(m * OPD, m * phi);
//vec3 SmP = 2.0 * evalSensitivity(m*OPD, m*phi2.y);
I += Cm * Sm;
}
// Convert back to RGB reflectance
//I = clamp(mul(I, XYZ_TO_RGB), real3(0.0, 0.0, 0.0), real3(1.0, 1.0, 1.0));
//I = mul(XYZ_TO_RGB, I);
return I;
}
#endif // UNITY_BSDF_INCLUDED

28
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/CommonMaterial.hlsl


return sqrt(2.0 / (variance + 2.0));
}
// ior is a value between 1.0 and 2.5
// Assume air interface for top
real IorToFresnel0(real ior)
{
return Sq((ior - 1.0) / (ior + 1.0));
}
real IorToFresnel0(real baseIor, real topIor)
{
return Sq((baseIor - topIor) / (baseIor + topIor));
}
// Assume air interface for top
// Note: Don't handle the case fresnel0 == 1
real Fresnel0ToIor(real fresnel0)
{
real sqrtF0 = sqrt(fresnel0);
return (1.0 + sqrtF0) / (1.0 - sqrtF0);
}
// This function is a coarse approximation of computing fresnel0 for a different top than air (here clear coat of IOR 1.5) when we only have fresnel0 with air interface
// This function is equivalent to IorToFresnel0(Fresnel0ToIor(fresnel0), 1.5)
// mean
// real sqrtF0 = sqrt(fresnel0);
// return Sq(1.0 - 5.0 * sqrtF0) / Sq(5.0 - sqrtF0);
// Optimization: Fit of the function (3 mad) for range [0.04 (should return 0), 1 (should return 1)]
TEMPLATE_1_REAL(ConvertF0ForAirInterfaceToF0ForClearCoat15, fresnel0, return saturate(-0.0256868 + fresnel0 * (0.326846 + (0.978946 - 0.283835 * fresnel0) * fresnel0)) )
// same as regular refract except there is not the test for total internal reflection + the vector is flipped for processing
real3 CoatRefract(real3 X, real3 N, real ieta)
{

74
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/Shadow.hlsl


*/
/* Default values for optional defines:
#define SHADOW_SUPPORTS_DYNAMIC_INDEXING 0 // Dynamic indexing only works on >= sm 5.1
#define SHADOW_OPTIMIZE_REGISTER_USAGE 0 // Redefine this as 1 in your ShadowContext.hlsl to optimize for register usage over instruction count
// #define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL // Enable custom implementations of GetPunctualShadowAttenuation. If not defined, a default implementation will be used.
// #define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL // Enable custom implementations of GetDirectionalShadowAttenuation. If not defined, a default implementation will be used.
#define SHADOW_SUPPORTS_DYNAMIC_INDEXING 0 // Dynamic indexing only works on >= sm 5.1
#define SHADOW_OPTIMIZE_REGISTER_USAGE 0 // Redefine this as 1 in your ShadowContext.hlsl to optimize for register usage over instruction count
#define SHADOW_USE_VIEW_BIAS_SCALING 0 // Enable view bias scaling to mitigate light leaking across edges. Uses the light vector if SHADOW_USE_ONLY_VIEW_BASED_BIASING is defined, otherwise uses the normal.
#define SHADOW_USE_ONLY_VIEW_BASED_BIASING 0 // Enable only light view vector based biasing. If undefined, biasing will be based on the normal and calling code must provide a valid normal.
#define SHADOW_USE_SAMPLE_BIASING 0 // Enable per sample biasing for wide multi-tap PCF filters. Incompatible with SHADOW_USE_ONLY_VIEW_BASED_BIASING.
#define SHADOW_USE_DEPTH_BIAS 0 // Enable clip space z biasing
// #define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL // Enable custom implementations of GetPunctualShadowAttenuation. If not defined, a default implementation will be used.
// #define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL // Enable custom implementations of GetDirectionalShadowAttenuation. If not defined, a default implementation will be used.
#define SHADOW_SUPPORTS_DYNAMIC_INDEXING 0
# define SHADOW_SUPPORTS_DYNAMIC_INDEXING 0
#define SHADOW_OPTIMIZE_REGISTER_USAGE 0
# define SHADOW_OPTIMIZE_REGISTER_USAGE 0
#endif
#ifndef SHADOW_USE_VIEW_BIAS_SCALING
# define SHADOW_USE_VIEW_BIAS_SCALING 0
#endif
#ifndef SHADOW_USE_SAMPLE_BIAS
# define SHADOW_USE_SAMPLE_BIAS 0
#endif
#ifndef SHADOW_USE_SAMPLE_BIAS
# define SHADOW_USE_SAMPLE_BIAS 0
#endif
#ifndef SHADOW_USE_DEPTH_BIAS
# define SHADOW_USE_DEPTH_BIAS 0
#endif
#if SHADOW_USE_ONLY_VIEW_BASED_BIASING != 0
# if SHADOW_USE_SAMPLE_BIASING != 0
# pragma message "Shadows: SHADOW_USE_SAMPLE_BIASING was enabled together with SHADOW_USE_ONLY_VIEW_BASED_BIASING. Sample biasing requires the normal. Disabling SHADOW_USE_SAMPLE_BIASING again."
# undef SHADOW_USE_SAMPLE_BIASING
# define SHADOW_USE_SAMPLE_BIASING 0
# endif
# pragma warning(disable : 3557) // loop only executes for 1 iteration(s)
# pragma warning( disable : 3557 ) // loop only executes for 1 iteration(s)
#include "ShadowTexFetch.hlsl" // Resource sampling definitions (don't modify)
#include "ShadowTexFetch.hlsl" // Resource sampling definitions (don't modify)
StructuredBuffer<ShadowData> shadowDatas;
StructuredBuffer<int4> payloads;
SHADOWCONTEXT_DECLARE_TEXTURES( SHADOWCONTEXT_MAX_TEX2DARRAY, SHADOWCONTEXT_MAX_TEXCUBEARRAY, SHADOWCONTEXT_MAX_COMPSAMPLER, SHADOWCONTEXT_MAX_SAMPLER )
StructuredBuffer<ShadowData> shadowDatas;
StructuredBuffer<int4> payloads;
SHADOWCONTEXT_DECLARE_TEXTURES( SHADOWCONTEXT_MAX_TEX2DARRAY, SHADOWCONTEXT_MAX_TEXCUBEARRAY, SHADOWCONTEXT_MAX_COMPSAMPLER, SHADOWCONTEXT_MAX_SAMPLER )
void UnpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx, out real slice )
{
texIdx = (shadowmapId >> 24) & 0xff;
sampIdx = (shadowmapId >> 16) & 0xff;
slice = (real)(shadowmapId & 0xffff);
}
void UnpackShadowmapId( uint shadowmapId, out real slice )
{
slice = (real)(shadowmapId & 0xffff);
}
void UnpackShadowType( uint packedShadowType, out uint shadowType, out uint shadowAlgorithm )
{
shadowType = packedShadowType >> 10;

}
// shadow sampling prototypes
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L );
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L, real2 positionSS );
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L, real L_dist );
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L, real L_dist, real2 positionSS );
// shadow sampling prototypes with screenspace info
real GetDirectionalShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L );

#include "ShadowAlgorithms.hlsl" // engine default algorithms (don't modify)
#ifndef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L )
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L, real L_dist )
return EvalShadow_PunctualDepth(shadowContext, positionWS, normalWS, shadowDataIndex, L);
return EvalShadow_PunctualDepth( shadowContext, positionWS, normalWS, shadowDataIndex, L, L_dist );
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L, real2 positionSS )
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L, real L_dist, real2 positionSS )
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L, L_dist );
}
#endif

return EvalShadow_CascadedDepth_Blend( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_CascadedDepth_Blend( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}
#endif

819
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl


// There are two variants provided, one takes the texture and sampler explicitly so they can be statically passed in.
// The variant without resource parameters dynamically accesses the texture when sampling.
// Helper function to offset depth based on the surface normal and light direction.
// If the light hits the surface perpendicularly there will be no offset.
real3 EvalShadow_NormalBias( real3 normalWS, real NoL, real2 texelSize, real normalBias )
float4 EvalShadow_WorldToShadow( ShadowData sd, real3 positionWS, bool perspProj )
return max( texelSize.x, texelSize.y ) * normalBias * (1.0 - NoL) * normalWS;
}
if( perspProj )
{
positionWS = positionWS - sd.pos;
float3x3 view = { sd.rot0, sd.rot1, sd.rot2 };
positionWS = mul( view, positionWS );
}
else
{
float3x4 view;
view[0] = float4( sd.rot0, sd.pos.x );
view[1] = float4( sd.rot1, sd.pos.y );
view[2] = float4( sd.rot2, sd.pos.z );
positionWS = mul( view, float4( positionWS, 1.0 ) ).xyz;
}
float4x4 proj;
proj = 0.0;
proj._m00 = sd.proj[0];
proj._m11 = sd.proj[1];
proj._m22 = sd.proj[2];
proj._m23 = sd.proj[3];
if( perspProj )
proj._m32 = -1.0;
else
proj._m33 = 1.0;
return mul( proj, float4( positionWS, 1.0 ) );
}
real3 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS, out real3 posNDC, bool clampToRect )
real3 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS, out real3 posNDC, bool perspProj )
real4 posCS = mul(real4(positionWS, 1.0), sd.worldToShadow);
posCS.z -= sd.bias * posCS.w;
posNDC = posCS.xyz / posCS.w;
real4 posCS = EvalShadow_WorldToShadow( sd, positionWS, perspProj );
posNDC = perspProj ? (posCS.xyz / posCS.w) : posCS.xyz;
real3 posTC = posNDC * 0.5 + 0.5;
posTC.xy = clampToRect ? clamp( posTC.xy, sd.texelSizeRcp.zw*0.5, 1.0.xx - sd.texelSizeRcp.zw*0.5 ) : posTC.xy;
real3 posTC = real3( posNDC.xy * 0.5 + 0.5, posNDC.z );
#if UNITY_REVERSED_Z
posTC.z = 1.0 - posTC.z;
#endif
real3 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS )
real3 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS, bool perspProj )
return EvalShadow_GetTexcoords( sd, positionWS, ndc, false );
return EvalShadow_GetTexcoords( sd, positionWS, ndc, perspProj );
uint2 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS, out real2 closestSampleNDC )
uint2 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS, out real2 closestSampleNDC, bool perspProj )
real4 posCS = mul( real4( positionWS, 1.0 ), sd.worldToShadow );
real2 posNDC = posCS.xy / posCS.w;
real4 posCS = EvalShadow_WorldToShadow( sd, positionWS, perspProj );
real2 posNDC = perspProj ? (posCS.xy / posCS.w) : posCS.xy;
// calc TCs
real2 posTC = posNDC * 0.5 + 0.5;
closestSampleNDC = (floor(posTC * sd.textureSize.zw) + 0.5) * sd.texelSizeRcp.zw * 2.0 - 1.0.xx;

int EvalShadow_GetCubeFaceID( real3 sampleToLight )
//
// Biasing functions
//
// helper function to get the world texel size
real EvalShadow_WorldTexelSize( ShadowData sd, float L_dist, bool perspProj )
real3 lightToSample = -sampleToLight; // TODO: pass the correct (flipped) direction
return perspProj ? (sd.viewBias.w * L_dist) : sd.viewBias.w;
}
// used to scale down view biases to mitigate light leaking across shadowed corners
#if SHADOW_USE_VIEW_BIAS_SCALING != 0
real EvalShadow_ReceiverBiasWeightFlag( float flag )
{
return (asint( flag ) & 2) ? 1.0 : 0.0;
}
bool EvalShadow_ReceiverBiasWeightUseNormalFlag( float flag )
{
return (asint( flag ) & 4) ? true : false;
}
#ifdef INTRINSIC_CUBEMAP_FACE_ID
return (int)CubeMapFaceID(lightToSample);
real3 EvalShadow_ReceiverBiasWeightPos( real3 positionWS, real3 normalWS, real3 L, real worldTexelSize, real tolerance, bool useNormal )
{
#if SHADOW_USE_ONLY_VIEW_BASED_BIASING != 0
return positionWS + L * worldTexelSize * tolerance;
// TODO: use CubeMapFaceID() defined in Common.hlsl for all pipelines on all platforms.
real3 dir = sampleToLight;
real3 adir = abs(dir);
return positionWS + (useNormal ? normalWS : L) * worldTexelSize * tolerance;
#endif
}
real EvalShadow_ReceiverBiasWeight( ShadowContext shadowContext, uint shadowAlgorithm, ShadowData sd, uint texIdx, uint sampIdx, real3 positionWS, real3 normalWS, real3 L, real L_dist, bool perspProj )
{
real weight = 1.0;
UNITY_BRANCH
if( shadowAlgorithm <= GPUSHADOWALGORITHM_PCF_TENT_7X7 )
{
real3 pos = EvalShadow_ReceiverBiasWeightPos( positionWS, normalWS, L, EvalShadow_WorldTexelSize( sd, L_dist, perspProj ), sd.edgeTolerance, EvalShadow_ReceiverBiasWeightUseNormalFlag( sd.normalBias.w ) );
real3 tcs = EvalShadow_GetTexcoords( sd, pos, perspProj );
weight = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, tcs, sd.slice ).x;
}
return lerp( 1.0, weight, EvalShadow_ReceiverBiasWeightFlag( sd.normalBias.w ) );
}
real EvalShadow_ReceiverBiasWeight( ShadowData sd, Texture2DArray tex, SamplerComparisonState samp, real3 positionWS, real3 normalWS, real3 L, real L_dist, bool perspProj )
{
real3 pos = EvalShadow_ReceiverBiasWeightPos( positionWS, normalWS, L, EvalShadow_WorldTexelSize( sd, L_dist, perspProj ), sd.edgeTolerance, EvalShadow_ReceiverBiasWeightUseNormalFlag( sd.normalBias.w ) );
return lerp( 1.0, SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, samp, EvalShadow_GetTexcoords( sd, pos, perspProj ), sd.slice ).x, EvalShadow_ReceiverBiasWeightFlag( sd.normalBias.w ) );
}
real EvalShadow_ReceiverBiasWeight( ShadowData sd, Texture2DArray tex, SamplerState samp, real3 positionWS, real3 normalWS, real3 L, real L_dist, bool perspProj )
{
// only used by PCF filters
return 1.0;
}
#else // SHADOW_USE_VIEW_BIAS_SCALING != 0
real EvalShadow_ReceiverBiasWeight( ShadowContext shadowContext, uint shadowAlgorithm, ShadowData sd, uint texIdx, uint sampIdx, real3 positionWS, real3 normalWS, real3 L, real L_dist, bool perspProj ) { return 1.0; }
real EvalShadow_ReceiverBiasWeight( ShadowData sd, Texture2DArray tex, SamplerComparisonState samp, real3 positionWS, real3 normalWS, real3 L, real L_dist, bool perspProj ) { return 1.0; }
real EvalShadow_ReceiverBiasWeight (ShadowData sd, Texture2DArray tex, SamplerState samp, real3 positionWS, real3 normalWS, real3 L, real L_dist, bool perspProj ) { return 1.0; }
#endif // SHADOW_USE_VIEW_BIAS_SCALING != 0
// receiver bias either using the normal to weight normal and view biases, or just light view biasing
float3 EvalShadow_ReceiverBias( ShadowData sd, float3 positionWS, float3 normalWS, float3 L, float L_dist, float lightviewBiasWeight, bool perspProj )
{
#if SHADOW_USE_ONLY_VIEW_BASED_BIASING != 0 // only light vector based biasing
float viewBiasScale = sd.viewBias.z;
return positionWS + L * viewBiasScale * lightviewBiasWeight * EvalShadow_WorldTexelSize( sd, L_dist, perspProj );
#else // biasing based on the angle between the normal and the light vector
float viewBiasMin = sd.viewBias.x;
float viewBiasMax = sd.viewBias.y;
float viewBiasScale = sd.viewBias.z;
float normalBiasMin = sd.normalBias.x;
float normalBiasMax = sd.normalBias.y;
float normalBiasScale = sd.normalBias.z;
// +Z -Z
int faceIndex = dir.z > 0.0 ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z;
float NdotL = dot( normalWS, L );
float sine = sqrt( saturate( 1.0 - NdotL * NdotL ) );
float tangent = abs( NdotL ) > 0.0 ? (sine / NdotL) : 0.0;
sine = clamp( sine * normalBiasScale, normalBiasMin, normalBiasMax );
tangent = clamp( tangent * viewBiasScale * lightviewBiasWeight, viewBiasMin, viewBiasMax );
float3 view_bias = L * tangent;
float3 normal_bias = normalWS * sine;
return positionWS + (normal_bias + view_bias) * EvalShadow_WorldTexelSize( sd, L_dist, perspProj );
#endif
}
// +X -X
if (adir.x > adir.y && adir.x > adir.z)
// sample bias used by wide PCF filters to offset individual taps
#if SHADOW_USE_SAMPLE_BIASING != 0
real EvalShadow_SampleBiasFlag( float flag )
{
return (asint( flag ) & 1) ? 1.0 : 0.0;
}
float2 EvalShadow_SampleBias_Persp( ShadowData sd, float3 positionWS, float3 normalWS, float3 tcs )
{
float3 e1, e2;
if( abs( normalWS.z ) > 0.65 )
faceIndex = dir.x > 0.0 ? CUBEMAPFACE_NEGATIVE_X : CUBEMAPFACE_POSITIVE_X;
e1 = float3( 1.0, 0.0, -normalWS.x / normalWS.z );
e2 = float3( 0.0, 1.0, -normalWS.y / normalWS.z );
// +Y -Y
else if (adir.y > adir.x && adir.y > adir.z)
else if( abs( normalWS.y ) > 0.65 )
{
e1 = float3( 1.0, -normalWS.x / normalWS.y, 0.0 );
e2 = float3( 0.0, -normalWS.z / normalWS.y, 1.0 );
}
else
faceIndex = dir.y > 0.0 ? CUBEMAPFACE_NEGATIVE_Y : CUBEMAPFACE_POSITIVE_Y;
e1 = float3( -normalWS.y / normalWS.x, 1.0, 0.0 );
e2 = float3( -normalWS.z / normalWS.x, 0.0, 1.0 );
return faceIndex;
#endif
float4 p1 = EvalShadow_WorldToShadow( sd, positionWS + e1, true );
float4 p2 = EvalShadow_WorldToShadow( sd, positionWS + e2, true );
p1.xyz /= p1.w;
p2.xyz /= p2.w;
p1.xyz = float3( p1.xy * 0.5 + 0.5, p1.z );
p2.xyz = float3( p2.xy * 0.5 + 0.5, p2.z );
p1.xy = p1.xy * sd.scaleOffset.xy + sd.scaleOffset.zw;
p2.xy = p2.xy * sd.scaleOffset.xy + sd.scaleOffset.zw;
float3 nrm = cross( p1.xyz - tcs, p2.xyz - tcs );
nrm.xy /= -nrm.z;
return isfinite( nrm.xy ) ? (EvalShadow_SampleBiasFlag( sd.normalBias.w ) * nrm.xy) : 0.0.xx;
float2 EvalShadow_SampleBias_Ortho( ShadowData sd, float3 normalWS )
{
float3x3 view = float3x3( sd.rot0, sd.rot1, sd.rot2 );
float3 nrm = mul( view, normalWS );
nrm.x /= sd.proj[0];
nrm.y /= sd.proj[1];
nrm.z /= sd.proj[2];
nrm.x *= sd.scaleOffset.y;
nrm.y *= sd.scaleOffset.x;
nrm.z *= sd.scaleOffset.x * sd.scaleOffset.y;
nrm.xy /= -nrm.z;
return isfinite( nrm.xy ) ? (EvalShadow_SampleBiasFlag( sd.normalBias.w ) * nrm.xy) : 0.0.xx;
}
#else // SHADOW_USE_SAMPLE_BIASING != 0
float2 EvalShadow_SampleBias_Persp( ShadowData sd, float3 positionWS, float3 normalWS, float3 tcs ) { return 0.0.xx; }
float2 EvalShadow_SampleBias_Ortho( ShadowData sd, float3 normalWS ) { return 0.0.xx; }
#endif // SHADOW_USE_SAMPLE_BIASING != 0
real EvalShadow_PointDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real4 L )
real EvalShadow_PointDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L, real L_dist )
ShadowData sd = shadowContext.shadowDatas[index];
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
real3 lpos = positionWS + L.xyz * L.w;
positionWS = biased_posWS;
int faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1;
// load the right shadow data for the current face
sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
ShadowData sd = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1];
// sample the texture according to the given algorithm
// get the texture
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
UnpackShadowmapId( sd.id, texIdx, sampIdx );
// bias the world position
float recvBiasWeight = EvalShadow_ReceiverBiasWeight( shadowContext, shadowAlgorithm, sd, texIdx, sampIdx, positionWS, normalWS, L, L_dist, true );
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, L_dist, recvBiasWeight, true );
// get shadowmap texcoords
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, true );
// get the per sample bias
real2 sampleBias = EvalShadow_SampleBias_Persp( sd, positionWS, normalWS, posTC );
// sample the texture according to the given algorithm
uint payloadOffset = GetPayloadOffset( sd );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, texIdx, sampIdx );
#define EvalShadow_PointDepth_( _samplerType ) \
real EvalShadow_PointDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real4 L ) \
{ \
ShadowData sd = shadowContext.shadowDatas[index]; \
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
real3 lpos = positionWS + L.xyz * L.w; \
positionWS = biased_posWS; \
int faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1; \
/* load the right shadow data for the current face */ \
sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
real slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
#define EvalShadow_PointDepth_( _samplerType ) \
real EvalShadow_PointDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L, real L_dist ) \
{ \
ShadowData sd = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1]; \
/* bias the world position */ \
real recvBiasWeight = EvalShadow_ReceiverBiasWeight( sd, tex, samp, positionWS, normalWS, L, L_dist, true ); \
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, L_dist, recvBiasWeight, true ); \
/* get shadowmap texcoords */ \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, true ); \
/* get the per sample bias */ \
real2 sampleBias = EvalShadow_SampleBias_Persp( sd, positionWS, normalWS, posTC ); \
/* sample the texture */ \
uint payloadOffset = GetPayloadOffset( sd ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, tex, samp ); \
}
EvalShadow_PointDepth_( SamplerComparisonState )
EvalShadow_PointDepth_( SamplerState )

// Spot shadows
//
real EvalShadow_SpotDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L )
real EvalShadow_SpotDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L, real L_dist )
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
UnpackShadowmapId( sd.id, texIdx, sampIdx );
// bias the world position
real recvBiasWeight = EvalShadow_ReceiverBiasWeight( shadowContext, shadowAlgorithm, sd, texIdx, sampIdx, positionWS, normalWS, L, L_dist, true );
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, L_dist, recvBiasWeight, true );
// get shadowmap texcoords
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, true );
// get the per sample bias
real2 sampleBias = EvalShadow_SampleBias_Persp( sd, positionWS, normalWS, posTC );
// sample the texture according to the given algorithm
uint payloadOffset = GetPayloadOffset( sd );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, texIdx, sampIdx );
#define EvalShadow_SpotDepth_( _samplerType ) \
real EvalShadow_SpotDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
{ \
/* load the right shadow data for the current face */ \
ShadowData sd = shadowContext.shadowDatas[index]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
real slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
#define EvalShadow_SpotDepth_( _samplerType ) \
real EvalShadow_SpotDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L, real L_dist ) \
{ \
/* load the right shadow data for the current face */ \
ShadowData sd = shadowContext.shadowDatas[index]; \
/* bias the world position */ \
real recvBiasWeight = EvalShadow_ReceiverBiasWeight( sd, tex, samp, positionWS, normalWS, L, L_dist, true ); \
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, L_dist, recvBiasWeight, true ); \
/* get shadowmap texcoords */ \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, true ); \
/* get the per sample bias */ \
real2 sampleBias = EvalShadow_SampleBias_Persp( sd, positionWS, normalWS, posTC ); \
/* sample the texture */ \
uint payloadOffset = GetPayloadOffset( sd ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, tex, samp ); \
}
EvalShadow_SpotDepth_( SamplerComparisonState )
EvalShadow_SpotDepth_( SamplerState )

// Punctual shadows for Point and Spot
//
real EvalShadow_PunctualDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real4 L )
real EvalShadow_PunctualDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L, real L_dist )
// load the right shadow data for the current face
int faceIndex = 0;
UnpackShadowType( sd.shadowType, shadowType );
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
[branch]
// load the right shadow data for the current face
UNITY_BRANCH
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
real3 lpos = positionWS + L.xyz * L.w;
positionWS = biased_posWS;
faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1;
sd.rot0 = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].rot0;
sd.rot1 = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].rot1;
sd.rot2 = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].rot2;
sd.shadowToWorld = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].shadowToWorld;
sd.scaleOffset.zw = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].scaleOffset.zw;
sd.slice = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].slice;
else
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
uint texIdx, sampIdx;
UnpackShadowmapId( sd.id, texIdx, sampIdx );
// bias the world position
float recvBiasWeight = EvalShadow_ReceiverBiasWeight( shadowContext, shadowAlgorithm, sd, texIdx, sampIdx, positionWS, normalWS, L, L_dist, true );
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, L_dist, recvBiasWeight, true );
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, true );
// get the per sample bias
real2 sampleBias = EvalShadow_SampleBias_Persp( sd, positionWS, normalWS, posTC );
uint texIdx, sampIdx;
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
uint payloadOffset = GetPayloadOffset( sd );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, texIdx, sampIdx );
#define EvalShadow_PunctualDepth_( _samplerType ) \
real EvalShadow_PunctualDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real4 L ) \
{ \
/* load the right shadow data for the current face */ \
int faceIndex = 0; \
/* get the shadow type */ \
ShadowData sd = shadowContext.shadowDatas[index]; \
uint shadowType; \
UnpackShadowType( sd.shadowType, shadowType ); \
\
[branch] \
if( shadowType == GPUSHADOWTYPE_POINT ) \
{ \
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
real3 lpos = positionWS + L.xyz * L.w; \
positionWS = biased_posWS; \
faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1; \
} \
else \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
\
sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* get shadowmap texcoords */ \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
real slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
#define EvalShadow_PunctualDepth_( _samplerType ) \
real EvalShadow_PunctualDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L, real L_dist ) \
{ \
int faceIndex = 0; \
/* get the shadow type */ \
ShadowData sd = shadowContext.shadowDatas[index]; \
uint shadowType; \
UnpackShadowType( sd.shadowType, shadowType ); \
\
/* load the right shadow data for the current face */ \
UNITY_BRANCH \
if( shadowType == GPUSHADOWTYPE_POINT ) \
{ \
sd.rot0 = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].rot0; \
sd.rot1 = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].rot1; \
sd.rot2 = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].rot2; \
sd.shadowToWorld = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].shadowToWorld; \
sd.scaleOffset.zw = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].scaleOffset.zw; \
sd.slice = shadowContext.shadowDatas[index + CubeMapFaceID( -L ) + 1].slice; \
} \
\
/* bias the world position */ \
real recvBiasWeight = EvalShadow_ReceiverBiasWeight( sd, tex, samp, positionWS, normalWS, L, L_dist, true ); \
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, L_dist, recvBiasWeight, true ); \
/* get shadowmap texcoords */ \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, true ); \
/* get the per sample bias */ \
real2 sampleBias = EvalShadow_SampleBias_Persp( sd, positionWS, normalWS, posTC ); \
/* sample the texture */ \
uint payloadOffset = GetPayloadOffset( sd ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, tex, samp ); \
//
// Directional shadows (cascaded shadow map)

#define SHADOW_REPEAT_CASCADE( _x ) _x, _x, _x, _x
int EvalShadow_GetSplitSphereIndexForDirshadows( real3 positionWS, real4 dirShadowSplitSpheres[4], out real relDistance )
void EvalShadow_LoadCascadeData( ShadowContext shadowContext, uint index, inout ShadowData sd )
real3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
real3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
real3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
real3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
real4 distances2 = real4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
sd.shadowToWorld = shadowContext.shadowDatas[index].shadowToWorld;
sd.proj = shadowContext.shadowDatas[index].proj;
sd.pos = shadowContext.shadowDatas[index].pos;
sd.scaleOffset.zw = shadowContext.shadowDatas[index].scaleOffset.zw;
sd.slice = shadowContext.shadowDatas[index].slice;
sd.viewBias.w = shadowContext.shadowDatas[index].viewBias.w;
}
real4 dirShadowSplitSphereSqRadii;
dirShadowSplitSphereSqRadii.x = dirShadowSplitSpheres[0].w;
dirShadowSplitSphereSqRadii.y = dirShadowSplitSpheres[1].w;
dirShadowSplitSphereSqRadii.z = dirShadowSplitSpheres[2].w;
dirShadowSplitSphereSqRadii.w = dirShadowSplitSpheres[3].w;
int EvalShadow_GetSplitIndex( ShadowContext shadowContext, int index, real3 positionWS, out uint payloadOffset, out real alpha )
{
payloadOffset = shadowContext.shadowDatas[index].payloadOffset;
real4 weights = real4( distances2 < dirShadowSplitSphereSqRadii );
weights.yzw = saturate( weights.yzw - weights.xyz );
int i = 0;
real relDistance = 0.0;
real3 wposDir, splitSphere;
int idx = int( 4.0 - dot( weights, real4( 4.0, 3.0, 2.0, 1.0 ) ) );
relDistance = distances2[idx] / dirShadowSplitSphereSqRadii[idx];
return idx <= 3 ? idx : -1;
}
// find the current cascade
for( ; i < kMaxShadowCascades; i++, payloadOffset++ )
{
float4 sphere = asfloat( shadowContext.payloads[payloadOffset] );
wposDir = -sphere.xyz + positionWS;
float distSq = dot( wposDir, wposDir );
relDistance = distSq / sphere.w;
if( relDistance <= 1.0 )
{
splitSphere = sphere.xyz;
wposDir /= sqrt( distSq );
break;
}
}
int shadowSplitIndex = i < kMaxShadowCascades ? i : -1;
int EvalShadow_GetSplitSphereIndexForDirshadows( real3 positionWS, real4 dirShadowSplitSpheres[4] )
{
real relDist;
return EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDist );
}
payloadOffset = shadowContext.shadowDatas[index].payloadOffset + kMaxShadowCascades;
real3 cascadeDir = asfloat( shadowContext.payloads[payloadOffset].xyz );
payloadOffset++;
real border = asfloat( shadowContext.payloads[payloadOffset][shadowSplitIndex] );
payloadOffset++;
alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
real cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
uint EvalShadow_LoadSplitSpheres( ShadowContext shadowContext, int index, out real4 splitSpheres[4] )
{
uint offset = GetPayloadOffset( shadowContext.shadowDatas[index] );
splitSpheres[0] = asfloat( shadowContext.payloads[offset + 0] );
splitSpheres[1] = asfloat( shadowContext.payloads[offset + 1] );
splitSpheres[2] = asfloat( shadowContext.payloads[offset + 2] );
splitSpheres[3] = asfloat( shadowContext.payloads[offset + 3] );
return offset + 4;
return shadowSplitIndex;
real4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
real relDistance;
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance );
uint payloadOffset;
real alpha;
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha );
real4 scales = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
real4 borders = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
real border = borders[shadowSplitIndex];
real alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
ShadowData sd = shadowContext.shadowDatas[index];
EvalShadow_LoadCascadeData( shadowContext, index + 1 + shadowSplitIndex, sd );
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
// sample the texture
uint texIdx, sampIdx;
UnpackShadowmapId( sd.id, texIdx, sampIdx );
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
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
real3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
real3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz );
real3 wposDir = normalize( -splitSphere + positionWS );
real cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
real recvBiasWeight = EvalShadow_ReceiverBiasWeight( shadowContext, shadowAlgorithm, sd, texIdx, sampIdx, positionWS, normalWS, L, 1.0, false );
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, 1.0, recvBiasWeight, false );
real3 posNDC;
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true );
// sample the texture
uint texIdx, sampIdx;
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
real shadow1 = 1.0;
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, false );
// evaluate the first cascade
real2 sampleBias = EvalShadow_SampleBias_Ortho( sd, normalWS );
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, texIdx, sampIdx );
real shadow1 = 1.0;
shadowSplitIndex++;
if( shadowSplitIndex < kMaxShadowCascades )

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 );
EvalShadow_LoadCascadeData( shadowContext, index + 1 + shadowSplitIndex, sd );
positionWS = EvalShadow_ReceiverBias( sd, orig_pos, normalWS, L, 1.0, recvBiasWeight, false );
real3 posNDC;
UnpackShadowmapId( sd.id, slice );
sampleBias = EvalShadow_SampleBias_Ortho( sd, normalWS );
[branch]
UNITY_BRANCH
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sampleBias, shadowAlgorithm, texIdx, sampIdx );
}
}
shadow = lerp( shadow, shadow1, alpha );

real EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
real EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
/* load the right shadow data for the current face */ \
real4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
real relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
uint payloadOffset; \
real alpha; \
int shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, payloadOffset, alpha ); \
\
real4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
real4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
real border = borders[shadowSplitIndex]; \
real alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
ShadowData sd = shadowContext.shadowDatas[index]; \
EvalShadow_LoadCascadeData( shadowContext, index + 1 + shadowSplitIndex, sd ); \
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
real3 orig_pos = positionWS; \
real3 orig_pos = positionWS; \
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 */ \
real3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
real3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz ); \
real3 wposDir = normalize( -splitSphere + positionWS ); \
real cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
real recvBiasWeight = EvalShadow_ReceiverBiasWeight( sd, tex, samp, positionWS, normalWS, L, 1.0, false ); \
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, 1.0, recvBiasWeight, false ); \
real3 posNDC; \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
\
/* sample the texture */ \
real slice; \
UnpackShadowmapId( sd.id, slice ); \
\
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
real shadow1 = 1.0; \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, false ); \
/* evalute the first cascade */ \
real2 sampleBias = EvalShadow_SampleBias_Ortho( sd, normalWS ); \
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
real shadow1 = 1.0; \
\
shadowSplitIndex++; \
if( shadowSplitIndex < kMaxShadowCascades ) \

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 ); \
EvalShadow_LoadCascadeData( shadowContext, index + 1 + shadowSplitIndex, sd ); \
positionWS = EvalShadow_ReceiverBias( sd, orig_pos, normalWS, L, 1.0, recvBiasWeight, false ); \
real3 posNDC; \
UnpackShadowmapId( sd.id, slice ); \
sampleBias = EvalShadow_SampleBias_Ortho( sd, normalWS ); \
[branch] \
UNITY_BRANCH \
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
shadow1 = SampleShadow_SelectAlgorithm( shadowContext, sd, orig_payloadOffset, posTC, sampleBias, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
} \
} \
shadow = lerp( shadow, shadow1, alpha ); \

real EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
real EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
{ \
uint shadowAlgorithms[kMaxShadowCascades] = { SHADOW_REPEAT_CASCADE( shadowAlgorithm ) }; \
return EvalShadow_CascadedDepth_Blend( shadowContext, shadowAlgorithms, tex, samp, positionWS, normalWS, index, L ); \

real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L )
{
// load the right shadow data for the current face
real4 dirShadowSplitSpheres[kMaxShadowCascades];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
real relDistance;
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance );
uint payloadOffset;
real alpha;
int shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, payloadOffset, alpha);
real4 scales = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
real4 borders = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
real border = borders[shadowSplitIndex];
real alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
ShadowData sd = shadowContext.shadowDatas[index];
EvalShadow_LoadCascadeData( shadowContext, index + 1 + shadowSplitIndex, sd );
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
// get texture description
uint texIdx, sampIdx;
UnpackShadowmapId( sd.id, texIdx, sampIdx );
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias );
real recvBiasWeight = EvalShadow_ReceiverBiasWeight( shadowContext, shadowAlgorithm, sd, texIdx, sampIdx, positionWS, normalWS, L, 1.0, false );
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, 1.0, recvBiasWeight, false );
real3 posNDC;
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true );
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, false );
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 );
real3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
real3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( 3, shadowSplitIndex + 1 )].xyz );
real3 wposDir = normalize( -splitSphere + positionWS );
real cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 );
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 );
EvalShadow_LoadCascadeData( shadowContext, index + 1 + nextSplit, sd );
positionWS = EvalShadow_ReceiverBias( sd, orig_pos, normalWS, L, 1.0, recvBiasWeight, false );
posTC = EvalShadow_GetTexcoords( sd, positionWS, false );
uint texIdx, sampIdx;
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
real2 sampleBias = EvalShadow_SampleBias_Ortho( sd, normalWS );
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, texIdx, sampIdx );
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
real4 dirShadowSplitSpheres[kMaxShadowCascades]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
real relDistance; \
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance ); \
uint payloadOffset; \
real alpha; \
int shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, payloadOffset, alpha ); \
\
\
real4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
real4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
payloadOffset++; \
real border = borders[shadowSplitIndex]; \
real alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
\
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
\
ShadowData sd = shadowContext.shadowDatas[index]; \
EvalShadow_LoadCascadeData( shadowContext, index + 1 + shadowSplitIndex, sd ); \
\
real3 orig_pos = positionWS; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), scales[shadowSplitIndex] * sd.texelSizeRcp.zw, sd.normalBias ); \
real3 orig_pos = positionWS; \
real recvBiasWeight = EvalShadow_ReceiverBiasWeight( sd, tex, samp, positionWS, normalWS, L, 1.0, false ); \
positionWS = EvalShadow_ReceiverBias( sd, positionWS, normalWS, L, 1.0, recvBiasWeight, false ); \
real3 posNDC; \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
\
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 ); \
real3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
real3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[nextSplit].xyz ); \
real3 wposDir = normalize( -splitSphere + positionWS ); \
real cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, false ); \
\
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 ); \
\
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 ); \
EvalShadow_LoadCascadeData( shadowContext, index + 1 + nextSplit, sd ); \
positionWS = EvalShadow_ReceiverBias( sd, orig_pos, normalWS, L, 1.0, recvBiasWeight, false ); \
posTC = EvalShadow_GetTexcoords( sd, positionWS, false ); \
real slice; \
UnpackShadowmapId( sd.id, slice ); \
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
real2 sampleBias = EvalShadow_SampleBias_Ortho( sd, normalWS ); \
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
\
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
\
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
{ \
uint shadowAlgorithms[kMaxShadowCascades] = { SHADOW_REPEAT_CASCADE( shadowAlgorithm ) }; \
return EvalShadow_CascadedDepth_Dither( shadowContext, shadowAlgorithms, tex, samp, positionWS, normalWS, index, L ); \

// get the algorithm
ShadowData sd = shadowContext.shadowDatas[index];
// load the right shadow data for the current face
int faceIndex = EvalShadow_GetCubeFaceID( L ) + 1;
int faceIndex = CubeMapFaceID( -L ) + 1;
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy, true );
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
closestNDC.z = LoadShadow_T2DA( shadowContext, texIdx, texelIdx, slice );
UnpackShadowmapId( sd.id, texIdx, sampIdx );
closestNDC.z = LoadShadow_T2DA( shadowContext, texIdx, texelIdx, sd.slice );
// reconstruct depth position
real4 closestWS = mul( closestNDC, sd.shadowToWorld );

// get the algorithm
ShadowData sd = shadowContext.shadowDatas[index];
// load the right shadow data for the current face
int faceIndex = EvalShadow_GetCubeFaceID( L ) + 1;
int faceIndex = CubeMapFaceID( -L ) + 1;
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy, true );
real slice;
UnpackShadowmapId(sd.id, slice);
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, slice, 0 ).x;
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, sd.slice, 0 ).x;
// reconstruct depth position
real4 closestWS = mul( closestNDC, sd.shadowToWorld );

ShadowData sd = shadowContext.shadowDatas[index];
real4 closestNDC = { 0,0,0,1 };
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy, true );
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
closestNDC.z = LoadShadow_T2DA( shadowContext, texIdx, texelIdx, slice );
UnpackShadowmapId( sd.id, texIdx, sampIdx );
closestNDC.z = LoadShadow_T2DA( shadowContext, texIdx, texelIdx, sd.slice );
// reconstruct depth position
real4 closestWS = mul( closestNDC, sd.shadowToWorld );

ShadowData sd = shadowContext.shadowDatas[index];
real4 closestNDC = { 0,0,0,1 };
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy, true );
real slice;
UnpackShadowmapId(sd.id, slice);
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, slice, 0 ).x;
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, sd.slice, 0 ).x;
// reconstruct depth position
real4 closestWS = mul( closestNDC, sd.shadowToWorld );

uint shadowType;
UnpackShadowType( sd.shadowType, shadowType );
// load the right shadow data for the current face
int faceIndex = shadowType == GPUSHADOWTYPE_POINT ? (EvalShadow_GetCubeFaceID( L ) + 1) : 0;
int faceIndex = shadowType == GPUSHADOWTYPE_POINT ? (CubeMapFaceID( -L ) + 1) : 0;
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy, true );
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
closestNDC.z = LoadShadow_T2DA( shadowContext, texIdx, texelIdx, slice );
UnpackShadowmapId( sd.id, texIdx, sampIdx );
closestNDC.z = LoadShadow_T2DA( shadowContext, texIdx, texelIdx, sd.slice );
// reconstruct depth position
real4 closestWS = mul( closestNDC, sd.shadowToWorld );

uint shadowType;
UnpackShadowType( sd.shadowType, shadowType );
// load the right shadow data for the current face
int faceIndex = shadowType == GPUSHADOWTYPE_POINT ? (EvalShadow_GetCubeFaceID( L ) + 1) : 0;
int faceIndex = shadowType == GPUSHADOWTYPE_POINT ? (CubeMapFaceID( -L ) + 1) : 0;
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy, true );
real slice;
UnpackShadowmapId(sd.id, slice);
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, slice, 0 ).x;
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, sd.slice, 0 ).x;
// reconstruct depth position
real4 closestWS = mul( closestNDC, sd.shadowToWorld );

real3 EvalShadow_GetClosestSample_Cascade( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real4 L )
{
// load the right shadow data for the current face
real4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
real relDistance;
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance );
uint payloadOffset;
real alpha;
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha );
real4 scales = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
real4 borders = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy, false );
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
closestNDC.z = LoadShadow_T2DA( shadowContext, texIdx, texelIdx, slice );
UnpackShadowmapId( sd.id, texIdx, sampIdx );
closestNDC.z = LoadShadow_T2DA( shadowContext, texIdx, texelIdx, sd.slice );
// reconstruct depth position
real4 closestWS = mul( closestNDC, sd.shadowToWorld );

real3 EvalShadow_GetClosestSample_Cascade( ShadowContext shadowContext, Texture2DArray tex, real3 positionWS, real3 normalWS, int index, real4 L )
{
// load the right shadow data for the current face
real4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
real relDistance;
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres, relDistance );
uint payloadOffset;
real alpha;
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha );
real4 scales = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
real4 borders = asfloat( shadowContext.payloads[payloadOffset] );
payloadOffset++;
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy );
uint2 texelIdx = EvalShadow_GetTexcoords( sd, positionWS, closestNDC.xy, false );
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, slice, 0 ).x;
UnpackShadowmapId( sd.id, texIdx, sampIdx );
closestNDC.z = LOAD_TEXTURE2D_ARRAY_LOD( tex, texelIdx, sd.slice, 0 ).x;
// reconstruct depth position
real4 closestWS = mul( closestNDC, sd.shadowToWorld );

262
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/ShadowSampling.hlsl


//
// 1 tap PCF sampling
//
real SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, real bias, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 coord, float slice, uint texIdx, uint sampIdx )
#if SHADOW_USE_DEPTH_BIAS == 1
tcs.z += depthBias;
coord.z += depthBias;
#endif
return SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, tcs, slice ).x;
return SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, coord, slice ).x;
real SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, real bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 coord, float slice, Texture2DArray tex, SamplerComparisonState compSamp )
#if SHADOW_USE_DEPTH_BIAS == 1
tcs.z += depthBias;
coord.z += depthBias;
#endif
return SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, tcs, slice );
return SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, coord, slice );
real SampleShadow_PCF_Tent_3x3( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_Tent_3x3( ShadowContext shadowContext, inout uint payloadOffset, real4 textureSize, real4 texelSizeRcp, real3 coord, real2 sampleBias, float slice, uint texIdx, uint sampIdx )
// TODO move this to shadow data to avoid the rcp?
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4( texelSizeRcp.xy, textureSize.xy );
#if SHADOW_USE_DEPTH_BIAS == 1
#endif
real shadow = 0.0;
real fetchesWeights[4];

[loop] for (int i = 0; i < 4; i++)
UNITY_LOOP
for( int i = 0; i < 4; i++ )
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z + dot( fetchesUV[i].xy - coord.xy, sampleBias ) ), slice ).x;
real SampleShadow_PCF_Tent_3x3(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_Tent_3x3(ShadowContext shadowContext, inout uint payloadOffset, real4 textureSize, real4 texelSizeRcp, real3 coord, real2 sampleBias, float slice, Texture2DArray tex, SamplerComparisonState compSamp )
// TODO move this to shadow data to avoid the rcp?
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4( texelSizeRcp.xy, textureSize.xy );
#if SHADOW_USE_DEPTH_BIAS == 1
#endif
real shadow = 0.0;
real fetchesWeights[4];

for (int i = 0; i < 4; i++)
{
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z + dot( fetchesUV[i].xy - coord.xy, sampleBias ) ), slice ).x;
}
return shadow;
}

//
real SampleShadow_PCF_Tent_5x5( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_Tent_5x5( ShadowContext shadowContext, inout uint payloadOffset, real4 textureSize, real4 texelSizeRcp, real3 coord, real2 sampleBias, float slice, uint texIdx, uint sampIdx )
// TODO move this to shadow data to avoid the rcp?
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4( texelSizeRcp.xy, textureSize.xy );
#if SHADOW_USE_DEPTH_BIAS == 1
#endif
SampleShadow_ComputeSamples_Tent_5x5(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
[loop] for (int i = 0; i < 9; i++)
SampleShadow_ComputeSamples_Tent_5x5( shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV );
UNITY_LOOP
for( int i = 0; i < 9; i++ )
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z + dot( fetchesUV[i].xy - coord.xy, sampleBias ) ), slice ).x;
real SampleShadow_PCF_Tent_5x5(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_Tent_5x5(ShadowContext shadowContext, inout uint payloadOffset, real4 textureSize, real4 texelSizeRcp, real3 coord, real2 sampleBias, float slice, Texture2DArray tex, SamplerComparisonState compSamp )
// TODO move this to shadow data to avoid the rcp
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4( texelSizeRcp.xy, textureSize.xy );
#if SHADOW_USE_DEPTH_BIAS == 1
#endif
SampleShadow_ComputeSamples_Tent_5x5(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
SampleShadow_ComputeSamples_Tent_5x5( shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV );
#if SHADOW_OPTIMIZE_REGISTER_USAGE == 1 && SHADOW_USE_SAMPLE_BIASING == 0
// the loops are only there to prevent the compiler form coalescing all 9 texture fetches which increases register usage
int i;
UNITY_LOOP
for( i = 0; i < 1; i++ )
{
shadow += fetchesWeights[ 0] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 0].xy, coord.z + dot( fetchesUV[ 0].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 1] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 1].xy, coord.z + dot( fetchesUV[ 1].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 2] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 2].xy, coord.z + dot( fetchesUV[ 2].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 3] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 3].xy, coord.z + dot( fetchesUV[ 3].xy - coord.xy, sampleBias ) ), slice ).x;
}
UNITY_LOOP
for( i = 0; i < 1; i++ )
{
shadow += fetchesWeights[ 4] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 4].xy, coord.z + dot( fetchesUV[ 4].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 5] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 5].xy, coord.z + dot( fetchesUV[ 5].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 6] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 6].xy, coord.z + dot( fetchesUV[ 6].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 7] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 7].xy, coord.z + dot( fetchesUV[ 7].xy - coord.xy, sampleBias ) ), slice ).x;
}
shadow += fetchesWeights[ 8] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 8].xy, coord.z + dot( fetchesUV[ 8].xy - coord.xy, sampleBias ) ), slice ).x;
#else
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z + dot( fetchesUV[i].xy - coord.xy, sampleBias ) ), slice ).x;
#endif
return shadow;
}

real SampleShadow_PCF_Tent_7x7( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_Tent_7x7( ShadowContext shadowContext, inout uint payloadOffset, real4 textureSize, real4 texelSizeRcp, real3 coord, real2 sampleBias, float slice, uint texIdx, uint sampIdx )
// TODO move this to shadow data to avoid the rcp
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4( texelSizeRcp.xy, textureSize.xy );
#if SHADOW_USE_DEPTH_BIAS == 1
#endif
SampleShadow_ComputeSamples_Tent_7x7(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
[loop] for (int i = 0; i < 16; i++)
SampleShadow_ComputeSamples_Tent_7x7( shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV );
UNITY_LOOP
for( int i = 0; i < 16; i++ )
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z + dot( fetchesUV[i].xy - coord.xy, sampleBias ) ), slice ).x;
real SampleShadow_PCF_Tent_7x7(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_Tent_7x7(ShadowContext shadowContext, inout uint payloadOffset, real4 textureSize, real4 texelSizeRcp, real3 coord, real2 sampleBias, float slice, Texture2DArray tex, SamplerComparisonState compSamp )
// TODO move this to shadow data to avoid the rcp
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4( texelSizeRcp.xy, textureSize.xy );
#if SHADOW_USE_DEPTH_BIAS == 1
#endif
SampleShadow_ComputeSamples_Tent_7x7(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
SampleShadow_ComputeSamples_Tent_7x7( shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV );
// the loops are only there to prevent the compiler form coalescing all 16 texture fetches which increases register usage
[loop]
UNITY_LOOP
shadow += fetchesWeights[ 0] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 0].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 1] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 1].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 2] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 2].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 3] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 3].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 0] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 0].xy, coord.z + dot( fetchesUV[ 0].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 1] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 1].xy, coord.z + dot( fetchesUV[ 1].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 2] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 2].xy, coord.z + dot( fetchesUV[ 2].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 3] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 3].xy, coord.z + dot( fetchesUV[ 3].xy - coord.xy, sampleBias ) ), slice ).x;
[loop]
UNITY_LOOP
shadow += fetchesWeights[ 4] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 4].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 5] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 5].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 6] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 6].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 7] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 7].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 4] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 4].xy, coord.z + dot( fetchesUV[ 4].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 5] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 5].xy, coord.z + dot( fetchesUV[ 5].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 6] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 6].xy, coord.z + dot( fetchesUV[ 6].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 7] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 7].xy, coord.z + dot( fetchesUV[ 7].xy - coord.xy, sampleBias ) ), slice ).x;
[loop]
UNITY_LOOP
shadow += fetchesWeights[ 8] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 8].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 9] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 9].xy, coord.z ), slice ).x;
shadow += fetchesWeights[10] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[10].xy, coord.z ), slice ).x;
shadow += fetchesWeights[11] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[11].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 8] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 8].xy, coord.z + dot( fetchesUV[ 8].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[ 9] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 9].xy, coord.z + dot( fetchesUV[ 9].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[10] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[10].xy, coord.z + dot( fetchesUV[10].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[11] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[11].xy, coord.z + dot( fetchesUV[11].xy - coord.xy, sampleBias ) ), slice ).x;
[loop]
UNITY_LOOP
shadow += fetchesWeights[12] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[12].xy, coord.z ), slice ).x;
shadow += fetchesWeights[13] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[13].xy, coord.z ), slice ).x;
shadow += fetchesWeights[14] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[14].xy, coord.z ), slice ).x;
shadow += fetchesWeights[15] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[15].xy, coord.z ), slice ).x;
shadow += fetchesWeights[12] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[12].xy, coord.z + dot( fetchesUV[12].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[13] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[13].xy, coord.z + dot( fetchesUV[13].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[14] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[14].xy, coord.z + dot( fetchesUV[14].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[15] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[15].xy, coord.z + dot( fetchesUV[15].xy - coord.xy, sampleBias ) ), slice ).x;
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z + dot( fetchesUV[i].xy - coord.xy, sampleBias ) ), slice ).x;
}
#endif
return shadow;

// 9 tap adaptive PCF sampling
//
real SampleShadow_PCF_9tap_Adaptive( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 tcs, real bias, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_9tap_Adaptive( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 tcs, real2 sampleBias, float slice, uint texIdx, uint sampIdx )
{
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;

texelSizeRcp *= filterSize;
#if SHADOW_USE_DEPTH_BIAS == 1
#endif
// Terms0 are weights for the individual samples, the other terms are offsets in texel space
real4 vShadow3x3PCFTerms0 = real4( 20.0 / 267.0, 33.0 / 267.0, 55.0 / 267.0, 0.0 );

real4 v20Taps;
v20Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
v20Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z + dot( vShadow3x3PCFTerms1.xy, sampleBias ) ), slice ).x; // 1 1
v20Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z + dot( vShadow3x3PCFTerms1.zy, sampleBias ) ), slice ).x; // -1 1
v20Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z + dot( vShadow3x3PCFTerms1.xw, sampleBias ) ), slice ).x; // 1 -1
v20Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z + dot( vShadow3x3PCFTerms1.zw, sampleBias ) ), slice ).x; // -1 -1
real flSum = dot( v20Taps.xyzw, real4( 0.25, 0.25, 0.25, 0.25 ) );
// fully in light or shadow? -> bail
if( ( flSum == 0.0 ) || ( flSum == 1.0 ) )

flSum *= vShadow3x3PCFTerms0.x * 4.0;
real4 v33Taps;
v33Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
v33Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z + dot( vShadow3x3PCFTerms2.xz, sampleBias ) ), slice ).x; // 1 0
v33Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z + dot( vShadow3x3PCFTerms3.xz, sampleBias ) ), slice ).x; // -1 0
v33Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z + dot( vShadow3x3PCFTerms3.zy, sampleBias ) ), slice ).x; // 0 -1
v33Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z + dot( vShadow3x3PCFTerms2.zy, sampleBias ) ), slice ).x; // 0 1
flSum += dot( v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy );
flSum += SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, tcs, slice ).x * vShadow3x3PCFTerms0.z;

real SampleShadow_PCF_9tap_Adaptive(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 tcs, real bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_9tap_Adaptive(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 tcs, real2 sampleBias, float slice, Texture2DArray tex, SamplerComparisonState compSamp )
{
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;

texelSizeRcp *= filterSize;
#if SHADOW_USE_DEPTH_BIAS == 1
#endif
// Terms0 are weights for the individual samples, the other terms are offsets in texel space
real4 vShadow3x3PCFTerms0 = real4(20.0 / 267.0, 33.0 / 267.0, 55.0 / 267.0, 0.0);

real4 v20Taps;
v20Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
v20Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z + dot( vShadow3x3PCFTerms1.xy, sampleBias ) ), slice ).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z + dot( vShadow3x3PCFTerms1.zy, sampleBias ) ), slice ).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z + dot( vShadow3x3PCFTerms1.xw, sampleBias ) ), slice ).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z + dot( vShadow3x3PCFTerms1.zw, sampleBias ) ), slice ).x; // -1 -1
real flSum = dot( v20Taps.xyzw, real4( 0.25, 0.25, 0.25, 0.25 ) );
// fully in light or shadow? -> bail
if( ( flSum == 0.0 ) || ( flSum == 1.0 ) )

flSum *= vShadow3x3PCFTerms0.x * 4.0;
real4 v33Taps;
v33Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
v33Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z + dot( vShadow3x3PCFTerms2.xz, sampleBias ) ), slice ).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z + dot( vShadow3x3PCFTerms3.xz, sampleBias ) ), slice ).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z + dot( vShadow3x3PCFTerms3.zy, sampleBias ) ), slice ).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z + dot( vShadow3x3PCFTerms2.zy, sampleBias ) ), slice ).x; // 0 1
flSum += dot( v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy );
flSum += SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, tcs, slice ).x * vShadow3x3PCFTerms0.z;

//
// 1 tap VSM sampling
//
real SampleShadow_VSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_VSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, float slice, uint texIdx, uint sampIdx )
{
#if UNITY_REVERSED_Z
real depth = 1.0 - tcs.z;

return ShadowMoments_ChebyshevsInequality( moments, depth, varianceBias, lightLeakBias );
}
real SampleShadow_VSM_1tap(ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, Texture2DArray tex, SamplerState samp )
real SampleShadow_VSM_1tap(ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, float slice, Texture2DArray tex, SamplerState samp )
{
#if UNITY_REVERSED_Z
real depth = 1.0 - tcs.z;

//
// 1 tap EVSM sampling
//
real SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, uint texIdx, uint sampIdx, bool fourMoments )
real SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, float slice, uint texIdx, uint sampIdx, bool fourMoments )
{
#if UNITY_REVERSED_Z
real depth = 1.0 - tcs.z;

real2 depthScale = evsmExponents * warpedDepth;
real2 minVariance = depthScale * depthScale * varianceBias;
[branch]
UNITY_BRANCH
if( fourMoments )
{
real posContrib = ShadowMoments_ChebyshevsInequality( moments.xz, warpedDepth.x, minVariance.x, lightLeakBias );

}
}
real SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool fourMoments )
real SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, float slice, Texture2DArray tex, SamplerState samp, bool fourMoments )
{
#if UNITY_REVERSED_Z
real depth = 1.0 - tcs.z;

real2 depthScale = evsmExponents * warpedDepth;
real2 minVariance = depthScale * depthScale * varianceBias;
[branch]
UNITY_BRANCH
if( fourMoments )
{
real posContrib = ShadowMoments_ChebyshevsInequality( moments.xz, warpedDepth.x, minVariance.x, lightLeakBias );

//
// 1 tap MSM sampling
//
real SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, uint texIdx, uint sampIdx, bool useHamburger )
real SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, float slice, uint texIdx, uint sampIdx, bool useHamburger )
{
real4 params = asfloat( shadowContext.payloads[payloadOffset] );
real lightLeakBias = params.x;

return (z[1] < 0.0 || z[2] > 1.0) ? ShadowMoments_SolveDelta4MSM( z, b, lightLeakBias ) : ShadowMoments_SolveDelta3MSM( z, b.xy, lightLeakBias );
}
real SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool useHamburger )
real SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, float slice, Texture2DArray tex, SamplerState samp, bool useHamburger )
{
real4 params = asfloat( shadowContext.payloads[payloadOffset] );
real lightLeakBias = params.x;

//-----------------------------------------------------------------------------------------------------
// helper function to dispatch a specific shadow algorithm
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real depthBias, uint slice, uint algorithm, uint texIdx, uint sampIdx )
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real2 sampleBias, uint algorithm, uint texIdx, uint sampIdx )
[branch]
UNITY_BRANCH
case GPUSHADOWALGORITHM_PCF_1TAP : return SampleShadow_PCF_1tap( shadowContext, payloadOffset, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_9TAP : return SampleShadow_PCF_9tap_Adaptive( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_3X3 : return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_5X5 : return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_7X7 : return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_VSM : return SampleShadow_VSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_EVSM_2 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, false );
case GPUSHADOWALGORITHM_EVSM_4 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, true );
case GPUSHADOWALGORITHM_MSM_HAM : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, true );
case GPUSHADOWALGORITHM_MSM_HAUS : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, false );
case GPUSHADOWALGORITHM_PCF_1TAP : return SampleShadow_PCF_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_9TAP : return SampleShadow_PCF_9tap_Adaptive( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_3X3 : return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_5X5 : return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_7X7 : return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_VSM : return SampleShadow_VSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_EVSM_2 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx, false );
case GPUSHADOWALGORITHM_EVSM_4 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx, true );
case GPUSHADOWALGORITHM_MSM_HAM : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx, true );
case GPUSHADOWALGORITHM_MSM_HAUS : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx, false );
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real depthBias, uint slice, uint algorithm, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real2 sampleBias, uint algorithm, Texture2DArray tex, SamplerComparisonState compSamp )
[branch]
UNITY_BRANCH
case GPUSHADOWALGORITHM_PCF_1TAP : return SampleShadow_PCF_1tap( shadowContext, payloadOffset, posTC, depthBias, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_9TAP : return SampleShadow_PCF_9tap_Adaptive( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_3X3 : return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_5X5 : return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_7X7 : return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_1TAP : return SampleShadow_PCF_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_9TAP : return SampleShadow_PCF_9tap_Adaptive( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_3X3 : return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_5X5 : return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_7X7 : return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, tex, compSamp );
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real depthBias, uint slice, uint algorithm, Texture2DArray tex, SamplerState samp )
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real2 sampleBias, uint algorithm, Texture2DArray tex, SamplerState samp )
[branch]
UNITY_BRANCH
case GPUSHADOWALGORITHM_VSM : return SampleShadow_VSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp );
case GPUSHADOWALGORITHM_EVSM_2 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp, false );
case GPUSHADOWALGORITHM_EVSM_4 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp, true );
case GPUSHADOWALGORITHM_MSM_HAM : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp, true );
case GPUSHADOWALGORITHM_MSM_HAUS : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp, false );
case GPUSHADOWALGORITHM_VSM : return SampleShadow_VSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, tex, samp );
case GPUSHADOWALGORITHM_EVSM_2 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, tex, samp, false );
case GPUSHADOWALGORITHM_EVSM_4 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, tex, samp, true );
case GPUSHADOWALGORITHM_MSM_HAM : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, tex, samp, true );
case GPUSHADOWALGORITHM_MSM_HAUS : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, tex, samp, false );
default: return 1.0;
}
}

36
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/ShadowTexFetch.hlsl


// Sampler and texture combinations are static. No shadowmap will ever be sampled with two different samplers.
// Once shadowmaps and samplers are fixed consider writing custom dispatchers directly accessing textures and samplers.
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ) \
real4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real slice ) \
real4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real slice ) \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
UNITY_UNROLL for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
UNITY_UNROLL for( uint j = 0; j < _SamplerCompSlots; j++ ) \
[branch] if( i == texIdx && j == sampIdx ) \
UNITY_BRANCH if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[i], ctxt.compSamplers[j], tcs, slice ); \
break; \

}
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ) \
real4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real2 tcs, real slice, real lod = 0.0 ) \
real4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real2 tcs, real slice, real lod = 0.0 ) \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
UNITY_UNROLL for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
UNITY_UNROLL for( uint j = 0; j < _SamplerSlots; j++ ) \
[branch] if( i == texIdx && j == sampIdx ) \
UNITY_BRANCH if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[i], ctxt.samplers[j], tcs, slice, lod ); \
break; \

# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_LOAD( _Tex2DArraySlots ) \
real LoadShadow_T2DA( ShadowContext ctxt, uint texIdx, uint2 tcs, uint slice, uint lod = 0 ) \
{ \
real res = 1.0; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
real res = 1.0; \
UNITY_UNROLL for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
[branch] if( i == texIdx ) \
UNITY_BRANCH if( i == texIdx ) \
{ \
res = LOAD_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[i], tcs, slice, lod ).x; \
break; \

real4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real4 tcs, real cubeIdx ) \
{ \
real4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
UNITY_UNROLL for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
UNITY_UNROLL for( uint j = 0; j < _SamplerCompSlots; j++ ) \
[branch] if( i == texIdx && j == sampIdx ) \
UNITY_BRANCH if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[i], ctxt.compSamplers[j], tcs, cubeIdx ); \
break; \

}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) \
real4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real cubeIdx, real lod = 0.0 ) \
real4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real cubeIdx, real lod = 0.0 ) \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
UNITY_UNROLL for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
UNITY_UNROLL for( uint j = 0; j < _SamplerSlots; j++ ) \
[branch] if( i == texIdx && j == sampIdx ) \
UNITY_BRANCH if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[i], ctxt.samplers[j], tcs, cubeIdx, lod ); \
break; \

15
ScriptableRenderPipeline/Core/CoreRP/Shadow/AdditionalShadowData.cs


public float contactShadowFadeDistance = 5.0f;
[Range(4, 64)]
public uint contactShadowSampleCount = 8;
// bias control
public float viewBiasMin = 0.5f;
public float viewBiasMax = 10.0f;
[Range(0.0F, 15.0F)]
public float viewBiasScale = 1.0f;
public float normalBiasMin = 0.2f;
public float normalBiasMax = 4.0f;
[Range(0.0F, 10.0F)]
public float normalBiasScale = 1.0f;
public bool sampleBiasScale = true;
public bool edgeLeakFixup = true;
public bool edgeToleranceNormal = true;
[Range(0.0F, 1.0F)]
public float edgeTolerance = 1.0f;
// shadow related parameters
[System.Serializable]

168
ScriptableRenderPipeline/Core/CoreRP/Shadow/Shadow.cs


protected uint[] m_TmpWidths = new uint[ShadowmapBase.ShadowRequest.k_MaxFaceCount];
protected uint[] m_TmpHeights = new uint[ShadowmapBase.ShadowRequest.k_MaxFaceCount];
protected Vector4[] m_TmpSplits = new Vector4[k_MaxCascadesInShader];
protected float[] m_TmpScales = new float[((k_MaxCascadesInShader+3)/4)*4];
protected Material m_DebugMaterial = null;
private Material m_ClearMat;
private readonly VectorArray<CachedEntry>.Cleanup m_Cleanup;
private readonly VectorArray<CachedEntry>.Comparator<Key> m_Comparator;
public bool captureFrame { get; set; }

public struct AtlasInit
{
public BaseInit baseInit; // the base class's initializer
public string shaderKeyword; // the global shader keyword to use when rendering the shadowmap
public BaseInit baseInit; // the base class's initializer
public string shaderKeyword; // the global shader keyword to use when rendering the shadowmap
public Shader shadowClearShader;
public ComputeShader shadowBlurMoments;
}
// UI stuff

#endif
public int Default() { return ShadowUtils.Asint( ValScale * ValDef ); }
}
readonly ValRange m_DefPCF_DepthBias = new ValRange( "Depth Bias", 0.0f, 0.05f, 1.0f, 000.1f );
readonly ValRange m_DefPCF_DepthBias = new ValRange( "Depth Bias", 0.0f, 0.0f, 1.0f, 000.1f );
m_ClearMat = CoreUtils.CreateEngineMaterial(init.shadowClearShader);
m_Cleanup = (CachedEntry entry) => { Free( entry ); };
m_Comparator = (ref Key k, ref CachedEntry entry) => { return k.id == entry.key.id && k.faceIdx == entry.key.faceIdx; };

m_Shadowmap = new RenderTexture( (int) m_Width, (int) m_Height, (int) m_ShadowmapBits, m_ShadowmapFormat, RenderTextureReadWrite.Linear );
CreateShadowmap( m_Shadowmap );
m_Shadowmap.Create();
#if false && UNITY_PS4 && !UNITY_EDITOR
if( m_Shadowmap != null )
UnityEngine.PS4.RenderSettings.DisableDepthBufferCompression( m_Shadowmap );
#endif
}
virtual protected void CreateShadowmap( RenderTexture shadowmap )

public void Initialize( AtlasInit init )
{
m_ShaderKeyword = init.shaderKeyword;
m_DebugMaterial = new Material(Shader.Find("Hidden/ScriptableRenderPipeline/DebugDisplayShadowMap")) { hideFlags = HideFlags.HideAndDontSave };
}
override public void ReserveSlots( ShadowContextStorage sc )

if( m_Shadowmap != null )
m_Shadowmap.Release();
Object.DestroyImmediate(m_DebugMaterial);
CoreUtils.Destroy(m_ClearMat);
}
override public bool Reserve( FrameId frameId, Camera camera, bool cameraRelativeRendering, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, List<VisibleLight> lights)

float nearPlaneOffset = QualitySettings.shadowNearPlaneOffset;
GPUShadowAlgorithm sanitizedAlgo = ShadowUtils.ClearPrecision( sr.shadowAlgorithm );
AdditionalShadowData asd = lights[sr.index].light.GetComponent<AdditionalShadowData>();
if( !asd )
return false;
int cascadeCnt = 0;
int cascadeCnt = 0;
AdditionalShadowData asd = lights[sr.index].light.GetComponent<AdditionalShadowData>();
if( !asd )
return false;
uint multiFaceIdx = key.shadowDataIdx;
// For lights with multiple faces, the first shadow data contains
// per light information, so not all fields contain valid data.
// Shader code must make sure to read per face data from per face entries.
sd.texelSizeRcp = new Vector4( m_WidthRcp, m_HeightRcp, 1.0f / widths[0], 1.0f / heights[0] );
sd.PackShadowType( sr.shadowType, sanitizedAlgo );
sd.payloadOffset = payload.Count();
entries.AddUnchecked( sd );
key.shadowDataIdx++;
}

ce.zclip = sr.shadowType != GPUShadowType.Directional;
// modify
Matrix4x4 vp, invvp;
Matrix4x4 vp, invvp, devproj;
vp = ShadowUtils.ExtractPointLightMatrix( lights[sr.index], key.faceIdx, 2.0f, out ce.current.view, out ce.current.proj, out invvp, out ce.current.lightDir, out ce.current.splitData );
{
// calculate the fov bias
float guardAngle = ShadowUtils.CalcGuardAnglePerspective( 90.0f, ce.current.viewport.width, GetFilterWidthInTexels( sr, asd ), asd.normalBiasMax, 79.0f );
vp = ShadowUtils.ExtractPointLightMatrix( lights[sr.index], key.faceIdx, guardAngle, out ce.current.view, out ce.current.proj, out devproj, out invvp, out ce.current.lightDir, out ce.current.splitData );
}
vp = ShadowUtils.ExtractSpotLightMatrix( lights[sr.index], out ce.current.view, out ce.current.proj, out invvp, out ce.current.lightDir, out ce.current.splitData );
{
float spotAngle = lights[sr.index].spotAngle;
float guardAngle = ShadowUtils.CalcGuardAnglePerspective( spotAngle, ce.current.viewport.width, GetFilterWidthInTexels( sr, asd ), asd.normalBiasMax, 180.0f - spotAngle );
vp = ShadowUtils.ExtractSpotLightMatrix( lights[sr.index], guardAngle, out ce.current.view, out ce.current.proj, out devproj, out invvp, out ce.current.lightDir, out ce.current.splitData );
}
vp = ShadowUtils.ExtractDirectionalLightMatrix( lights[sr.index], key.faceIdx, cascadeCnt, cascadeRatios, nearPlaneOffset, width, height, out ce.current.view, out ce.current.proj, out invvp, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int) sr.index );
vp = ShadowUtils.ExtractDirectionalLightMatrix( lights[sr.index], key.faceIdx, cascadeCnt, cascadeRatios, nearPlaneOffset, width, height, out ce.current.view, out ce.current.proj, out devproj, out invvp, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int) sr.index );
m_TmpSplits[key.faceIdx] = ce.current.splitData.cullingSphere;
if( ce.current.splitData.cullingSphere.w != float.NegativeInfinity )
{

m_TmpScales[face] = Mathf.Max( texelSizeX, texelSizeY );
vp = invvp = Matrix4x4.identity; // should never happen, though
vp = invvp = devproj = Matrix4x4.identity; // should never happen, though
if (cameraRelativeRendering)
{

vp *= translation;
translation.SetColumn( 3, -camPosWS );
translation[15] = 1.0f;
invvp = translation * invvp;
if (sr.shadowType == GPUShadowType.Directional)
{
m_TmpSplits[key.faceIdx].x -= camPosWS.x;

}
// extract texel size in world space
int flags = 0;
flags |= asd.sampleBiasScale ? (1 << 0) : 0;
flags |= asd.edgeLeakFixup ? (1 << 1) : 0;
flags |= asd.edgeToleranceNormal ? (1 << 2) : 0;
sd.edgeTolerance = asd.edgeTolerance;
sd.viewBias = new Vector4( asd.viewBiasMin, asd.viewBiasMax, asd.viewBiasScale, 2.0f / ce.current.proj.m00 / ce.current.viewport.width * 1.4142135623730950488016887242097f );
sd.normalBias = new Vector4( asd.normalBiasMin, asd.normalBiasMax, asd.normalBiasScale, ShadowUtils.Asfloat( flags ) );
sd.worldToShadow = vp.transpose; // apparently we need to transpose matrices that are sent to HLSL
if (sr.shadowType == GPUShadowType.Directional)
sd.pos = new Vector3( ce.current.view.m03, ce.current.view.m13, ce.current.view.m23 );
else
sd.pos = cameraRelativeRendering ? (lights[sr.index].light.transform.position - camera.transform.position) : lights[sr.index].light.transform.position;
sd.proj = new Vector4( devproj.m00, devproj.m11, devproj.m22, devproj.m23 );
sd.rot0 = new Vector3( ce.current.view.m00, ce.current.view.m01, ce.current.view.m02 );
sd.rot1 = new Vector3( ce.current.view.m10, ce.current.view.m11, ce.current.view.m12 );
sd.rot2 = new Vector3( ce.current.view.m20, ce.current.view.m21, ce.current.view.m22 );
sd.PackShadowmapId( m_TexSlot, m_SampSlot, ce.current.slice );
sd.PackShadowmapId( m_TexSlot, m_SampSlot );
sd.slice = ce.current.slice;
if( multiFace )
{
entries[multiFaceIdx] = sd;
multiFace = false;
}
resIdx++;
facecnt--;
key.shadowDataIdx++;

// Returns how many entries will be written into the payload buffer per light.
virtual protected uint ReservePayload( ShadowRequest sr )
{
uint payloadSize = sr.shadowType == GPUShadowType.Directional ? (k_MaxCascadesInShader + ((uint)m_TmpScales.Length / 4) + ((uint)m_TmpBorders.Length / 4)) : 0;
uint payloadSize = sr.shadowType == GPUShadowType.Directional ? (1 + k_MaxCascadesInShader + ((uint)m_TmpBorders.Length / 4)) : 0;
virtual protected float GetFilterWidthInTexels( ShadowRequest sr, AdditionalShadowData asd )
{
ShadowAlgorithm algo;
ShadowVariant vari;
ShadowPrecision prec;
ShadowUtils.Unpack( sr.shadowAlgorithm, out algo, out vari, out prec );
if( algo != ShadowAlgorithm.PCF )
return 1.0f;
switch( vari )
{
case ShadowVariant.V0: return 1;
case ShadowVariant.V1:
{
int shadowDataFormat;
int[] shadowData = asd.GetShadowData( out shadowDataFormat );
return ShadowUtils.Asfloat( shadowData[1] );
}
case ShadowVariant.V2: return 3;
case ShadowVariant.V3: return 5;
case ShadowVariant.V4: return 7;
default: return 1.0f;
}
}
// Writes additional per light data into the payload vector. Make sure to call base.WritePerLightPayload first.
virtual protected void WritePerLightPayload(List<VisibleLight> lights, ShadowRequest sr, ref ShadowData sd, ref ShadowPayloadVector payload, ref uint payloadOffset )
{

uint first = k_MaxCascadesInShader, second = k_MaxCascadesInShader;
first = (first == k_MaxCascadesInShader && m_TmpSplits[i].w > 0.0f) ? i : first;
second = (second == k_MaxCascadesInShader && m_TmpSplits[i].w > 0.0f) ? i : second;
for( int i = 0; i < m_TmpScales.Length; i += 4 )
{
sp.Set( m_TmpScales[i+0], m_TmpScales[i+1], m_TmpScales[i+2], m_TmpScales[i+3] );
payload[payloadOffset] = sp;
payloadOffset++;
}
if( second != k_MaxCascadesInShader )
sp.Set( (m_TmpSplits[second] - m_TmpSplits[first]).normalized );
else
sp.Set( 0.0f, 0.0f, 0.0f, 0.0f );
payload[payloadOffset] = sp;
payloadOffset++;
for( int i = 0; i < m_TmpBorders.Length; i += 4 )
{

ShadowData sd = entries[ce.key.shadowDataIdx];
// update the shadow data with the actual result of the layouting step
sd.scaleOffset = new Vector4( ce.current.viewport.width * m_WidthRcp, ce.current.viewport.height * m_HeightRcp, ce.current.viewport.x * m_WidthRcp, ce.current.viewport.y * m_HeightRcp );
sd.PackShadowmapId( m_TexSlot, m_SampSlot, ce.current.slice );
sd.PackShadowmapId( m_TexSlot, m_SampSlot );
sd.slice = ce.current.slice;
// write back the correct results
entries[ce.key.shadowDataIdx] = sd;
}

cb.GetTemporaryRT(m_TempDepthId, (int)m_Width, (int)m_Height, (int)m_ShadowmapBits, FilterMode.Bilinear, RenderTextureFormat.Shadowmap, RenderTextureReadWrite.Default);
cb.SetRenderTarget( new RenderTargetIdentifier( m_TempDepthId ) );
}
cb.ClearRenderTarget( true, !IsNativeDepth(), m_ClearColor );
}
override public void Update( FrameId frameId, ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults, List<VisibleLight> lights)

}
cmd.SetViewport( m_EntryCache[i].current.viewport );
cbName = "Shadowmap.ClearRect";
cmd.BeginSample( cbName );
CoreUtils.DrawFullScreen( cmd, m_ClearMat, null, 0 );
cmd.EndSample( cbName );
cmd.SetViewProjectionMatrices( m_EntryCache[i].current.view, m_EntryCache[i].current.proj );
cmd.SetGlobalVector( "g_vLightDirWs", m_EntryCache[i].current.lightDir );
cmd.SetGlobalFloat( m_ZClipId, m_EntryCache[i].zclip ? 1.0f : 0.0f );

m_EntryPool.Add( ce );
}
override public void DisplayShadowMap(CommandBuffer debugCB, Vector4 scaleBias, uint slice, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
override public void DisplayShadowMap(CommandBuffer debugCB, Material debugMaterial, Vector4 scaleBias, uint slice, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
{
Vector4 validRange = new Vector4(minValue, 1.0f / (maxValue - minValue));

propertyBlock.SetFloat("_TextureSlice", (float)slice);
propertyBlock.SetVector("_ValidRange", validRange);
debugCB.SetViewport(new Rect(screenX, screenY, screenSizeX, screenSizeY));
debugCB.DrawProcedural(Matrix4x4.identity, m_DebugMaterial, m_DebugMaterial.FindPass("REGULARSHADOW"), MeshTopology.Triangles, 3, 1, propertyBlock);
debugCB.DrawProcedural(Matrix4x4.identity, debugMaterial, debugMaterial.FindPass("REGULARSHADOW"), MeshTopology.Triangles, 3, 1, propertyBlock);
}
}

m_Flags |= SystemInfo.usesReversedZBuffer ? Flags.reversed_z : 0;
m_SampleCount = sampleCount <= 0 ? 1 : (sampleCount > k_MaxSampleCount ? k_MaxSampleCount : sampleCount);
m_MomentBlurCS = Resources.Load<ComputeShader>( "ShadowBlurMoments" );
m_MomentBlurCS = init.shadowBlurMoments;
if( m_MomentBlurCS )
{

}
}
override protected float GetFilterWidthInTexels( ShadowRequest sr, AdditionalShadowData asd )
{
return 1.0f;
}
// Writes additional per light data into the payload vector. Make sure to call base.WritePerLightPayload first.
override protected void WritePerLightPayload(List<VisibleLight> lights, ShadowRequest sr, ref ShadowData sd, ref ShadowPayloadVector payload, ref uint payloadOffset )
{

cb.EndSample("VSM conversion");
}
override public void DisplayShadowMap(CommandBuffer debugCB, Vector4 scaleBias, uint slice, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
override public void DisplayShadowMap(CommandBuffer debugCB, Material debugMaterial, Vector4 scaleBias, uint slice, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
{
Vector4 validRange = new Vector4(minValue, 1.0f / (maxValue - minValue));

propertyBlock.SetFloat("_TextureSlice", (float)slice);
propertyBlock.SetVector("_ValidRange", validRange);
debugCB.SetViewport(new Rect(screenX, screenY, screenSizeX, screenSizeY));
debugCB.DrawProcedural(Matrix4x4.identity, m_DebugMaterial, m_DebugMaterial.FindPass("VARIANCESHADOW"), MeshTopology.Triangles, 3, 1, propertyBlock);
debugCB.DrawProcedural(Matrix4x4.identity, debugMaterial, debugMaterial.FindPass("VARIANCESHADOW"), MeshTopology.Triangles, 3, 1, propertyBlock);
}
}
// -------------------------------------------------------------------------------------------------------------------------------------------------

// set light specific values that are not related to the shadowmap
GPUShadowType shadowtype = GetShadowLightType(l);
// current bias value range is way too large, so scale by 0.01 for now until we've decided whether to actually keep this value or not.
sd.bias = 0.01f * (SystemInfo.usesReversedZBuffer ? l.shadowBias : -l.shadowBias);
sd.normalBias = 2.0f * l.shadowNormalBias;
shadowIndices.AddUnchecked( (int) shadowDatas.Count() );

}
}
public override void DisplayShadow(CommandBuffer cmd, int shadowRequestIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
public override void DisplayShadow(CommandBuffer cmd, Material debugMaterial, int shadowRequestIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
{
if (m_ShadowIndices.Count() == 0)
return;

VectorArray<ShadowData> shadowDatas = m_ShadowCtxt.shadowDatas;
ShadowData faceData = shadowDatas[(uint)(m_ShadowIndices[index] + offset + faceIndex)];
uint texID, samplerID, slice;
faceData.UnpackShadowmapId(out texID, out samplerID, out slice);
m_Shadowmaps[texID].DisplayShadowMap(cmd, faceData.scaleOffset, slice, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue);
uint texID, samplerID;
faceData.UnpackShadowmapId(out texID, out samplerID);
m_Shadowmaps[texID].DisplayShadowMap(cmd, debugMaterial, faceData.scaleOffset, (uint) faceData.slice, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue);
public override void DisplayShadowMap(CommandBuffer cmd, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
public override void DisplayShadowMap(CommandBuffer cmd, Material debugMaterial, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
m_Shadowmaps[index].DisplayShadowMap(cmd, new Vector4(1.0f, 1.0f, 0.0f, 0.0f), sliceIndex, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue);
m_Shadowmaps[index].DisplayShadowMap(cmd, debugMaterial, new Vector4(1.0f, 1.0f, 0.0f, 0.0f), sliceIndex, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue);
}
public override void SyncData()

35
ScriptableRenderPipeline/Core/CoreRP/Shadow/ShadowBase.cs


public struct ShadowData
{
// shadow texture related params (need to be set by ShadowmapBase and derivatives)
public Matrix4x4 worldToShadow; // to light space matrix
public Matrix4x4 shadowToWorld; // from light space matrix
public Vector4 proj; // projection matrix value _00, _11, _22, _23
public Vector3 pos; // view matrix light position
public Vector3 rot0; // first column of view matrix rotation
public Vector3 rot1; // second column of view matrix rotation
public Vector3 rot2; // third column of view matrix rotation
public Vector4 scaleOffset; // scale and offset of shadowmap in atlas
public Vector4 textureSize; // the shadowmap's size in x and y. xy is texture relative, zw is viewport relative.
public Vector4 texelSizeRcp; // reciprocal of the shadowmap's texel size in x and y. xy is texture relative, zw is viewport relative.

public float slice; // shadowmap slice
public Vector4 viewBias; // x = min, y = max, z = scale, w = shadowmap texel size in world space at distance 1 from light
public Vector4 normalBias; // x = min, y = max, z = scale, w = enable/disable sample biasing
public float edgeTolerance; // specifies the offset along either the normal or view vector used for calculating the edge leak fixup
public Vector3 _pad; // 16 byte padding
public Matrix4x4 shadowToWorld; // from light space matrix
// light related params (need to be set via ShadowMgr and derivatives)
public float bias; // bias setting
public float normalBias; // bias based on the normal
public void PackShadowmapId( uint texIdx, uint sampIdx, uint slice )
public void PackShadowmapId( uint texIdx, uint sampIdx )
Debug.Assert( slice <= 0xffff );
id = texIdx << 24 | sampIdx << 16 | slice;
id = texIdx << 24 | sampIdx << 16;
public void UnpackShadowmapId(out uint texIdx, out uint sampIdx, out uint slice)
public void UnpackShadowmapId( out uint texIdx, out uint sampIdx )
slice = (id & 0xffff);
}
public void PackShadowType( GPUShadowType type, GPUShadowAlgorithm algorithm )

abstract public void Fill( ShadowContextStorage cs );
abstract public void CreateShadowmap();
abstract protected void Register( GPUShadowType type, ShadowRegistry registry );
abstract public void DisplayShadowMap(CommandBuffer cmd, Vector4 scaleBias, uint slice, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
abstract public void DisplayShadowMap(CommandBuffer cmd, Material debugMaterial, Vector4 scaleBias, uint slice, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
}
public interface IShadowManager

// Renders all shadows for lights the were deemed shadow casters after the last call to ProcessShadowRequests
void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults, List<VisibleLight> lights);
// Debug function to display a shadow at the screen coordinate
void DisplayShadow(CommandBuffer cmd, int shadowIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
void DisplayShadowMap(CommandBuffer cmd, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
void DisplayShadow(CommandBuffer cmd, Material debugMaterial, int shadowIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
void DisplayShadowMap(CommandBuffer cmd, Material debugMaterial, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
// Synchronize data with GPU buffers
void SyncData();
// Binds resources to shader stages just before rendering the lighting pass

{
public abstract void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
public abstract void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults, List<VisibleLight> lights);
public abstract void DisplayShadow(CommandBuffer cmd, int shadowIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
public abstract void DisplayShadowMap(CommandBuffer cmd, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
public abstract void DisplayShadow(CommandBuffer cmd, Material debugMaterial, int shadowIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
public abstract void DisplayShadowMap(CommandBuffer cmd, Material debugMaterial, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
public abstract void SyncData();
public abstract void BindResources( CommandBuffer cmd, ComputeShader computeShader, int computeKernel);
public abstract void UpdateCullingParameters( ref ScriptableCullingParameters cullingParams );

57
ScriptableRenderPipeline/Core/CoreRP/Shadow/ShadowBase.cs.hlsl


// PackingRules = Exact
struct ShadowData
{
float4x4 worldToShadow;
float4x4 shadowToWorld;
float4 proj;
float3 pos;
float3 rot0;
float3 rot1;
float3 rot2;
float4 scaleOffset;
float4 textureSize;
float4 texelSizeRcp;

float bias;
float normalBias;
float slice;
float4 viewBias;
float4 normalBias;
float edgeTolerance;
float3 _pad;
float4x4 shadowToWorld;
float4x4 GetWorldToShadow(ShadowData value)
float4 GetProj(ShadowData value)
{
return value.proj;
}
float3 GetPos(ShadowData value)
{
return value.pos;
}
float3 GetRot0(ShadowData value)
{
return value.rot0;
}
float3 GetRot1(ShadowData value)
return value.worldToShadow;
return value.rot1;
float4x4 GetShadowToWorld(ShadowData value)
float3 GetRot2(ShadowData value)
return value.shadowToWorld;
return value.rot2;
}
float4 GetScaleOffset(ShadowData value)
{

{
return value.payloadOffset;
}
float GetBias(ShadowData value)
float GetSlice(ShadowData value)
return value.bias;
return value.slice;
float GetNormalBias(ShadowData value)
float4 GetViewBias(ShadowData value)
{
return value.viewBias;
}
float4 GetNormalBias(ShadowData value)
}
float GetEdgeTolerance(ShadowData value)
{
return value.edgeTolerance;
}
float3 Get_pad(ShadowData value)
{
return value._pad;
}
float4x4 GetShadowToWorld(ShadowData value)
{
return value.shadowToWorld;
}

45
ScriptableRenderPipeline/Core/CoreRP/Shadow/ShadowUtilities.cs


vpinv = invview * invproj;
}
public static Matrix4x4 ExtractSpotLightMatrix( VisibleLight vl, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData )
public static Matrix4x4 ExtractSpotLightMatrix( VisibleLight vl, float guardAngle, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 deviceProj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData )
{
splitData = new ShadowSplitData();
splitData.cullingSphere.Set( 0.0f, 0.0f, 0.0f, float.NegativeInfinity );

// calculate projection
float zfar = vl.range;
float znear = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
float fov = vl.spotAngle;
float fov = vl.spotAngle + guardAngle;
// and the compound
InvertPerspective( ref proj, ref view, out vpinverse );
return proj * view;
// and the compound (deviceProj will potentially inverse-Z)
deviceProj = GL.GetGPUProjectionMatrix( proj, false );
InvertPerspective( ref deviceProj, ref view, out vpinverse );
return deviceProj * view;
public static Matrix4x4 ExtractPointLightMatrix( VisibleLight vl, uint faceIdx, float fovBias, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData )
public static Matrix4x4 ExtractPointLightMatrix( VisibleLight vl, uint faceIdx, float guardAngle, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 deviceProj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData )
{
if( faceIdx > (uint) CubemapFace.NegativeZ )
Debug.LogError( "Tried to extract cubemap face " + faceIdx + "." );

// calculate projection
float farPlane = vl.range;
float nearPlane = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
proj = Matrix4x4.Perspective( 90.0f + fovBias, 1.0f, nearPlane, farPlane );
// and the compound
InvertPerspective( ref proj, ref view, out vpinverse );
return proj * view;
proj = Matrix4x4.Perspective( 90.0f + guardAngle, 1.0f, nearPlane, farPlane );
// and the compound (deviceProj will potentially inverse-Z)
deviceProj = GL.GetGPUProjectionMatrix( proj, false );
InvertPerspective( ref deviceProj, ref view, out vpinverse );
return deviceProj * view;
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, float[] splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, float[] splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Matrix4x4 deviceProj, out Matrix4x4 vpinverse, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
{
Debug.Assert( width == height, "Currently the cascaded shadow mapping code requires square cascades." );
splitData = new ShadowSplitData();

for( int i = 0, cnt = splitRatio.Length < 3 ? splitRatio.Length : 3; i < cnt; i++ )
ratios[i] = splitRatio[i];
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( lightIndex, (int) cascadeIdx, cascadeCount, ratios, (int) width, nearPlaneOffset, out view, out proj, out splitData );
// and the compound
InvertOrthographic( ref proj, ref view, out vpinverse );
return proj * view;
// and the compound (deviceProj will potentially inverse-Z)
deviceProj = GL.GetGPUProjectionMatrix( proj, false );
InvertOrthographic( ref deviceProj, ref view, out vpinverse );
return deviceProj * view;
}
public static float CalcGuardAnglePerspective( float angleInDeg, float resolution, float filterWidth, float normalBiasMax, float guardAngleMaxInDeg )
{
float angleInRad = angleInDeg * 0.5f * Mathf.Deg2Rad;
float res = 2.0f / resolution;
float texelSize = Mathf.Cos( angleInRad ) * res;
float beta = normalBiasMax * texelSize * 1.4142135623730950488016887242097f;
float guardAngle = Mathf.Atan( beta );
texelSize = Mathf.Tan( angleInRad + guardAngle ) * res;
guardAngle = Mathf.Atan( (resolution + Mathf.Ceil( filterWidth )) * texelSize * 0.5f ) * 2.0f * Mathf.Rad2Deg - angleInDeg;
guardAngle *= 2.0f;
return guardAngle < guardAngleMaxInDeg ? guardAngle : guardAngleMaxInDeg;
}
public static GPUShadowAlgorithm Pack( ShadowAlgorithm algo, ShadowVariant vari, ShadowPrecision prec )

8
ScriptableRenderPipeline/Core/CoreRP/TextureCache.cs


return !TextureCache.supportsCubemapArrayTextures ? (Texture)m_CacheNoCubeArray : m_Cache;
}
public bool AllocTextureArray(int numCubeMaps, int width, TextureFormat format, bool isMipMapped)
public bool AllocTextureArray(int numCubeMaps, int width, TextureFormat format, bool isMipMapped, Material cubeBlitMaterial)
{
var res = AllocTextureArray(numCubeMaps);
m_NumMipLevels = GetNumMips(width, width); // will calculate same way whether we have cube array or not

if (!m_CubeBlitMaterial) m_CubeBlitMaterial = new Material(Shader.Find("Hidden/CubeToPano")) { hideFlags = HideFlags.HideAndDontSave };
m_CubeBlitMaterial = cubeBlitMaterial;
int panoWidthTop = 4 * width;
int panoHeightTop = 2 * width;

// In case the texture content with which we update the cache is not the input texture, we need to provide the right update count.
public void UpdateSlice(CommandBuffer cmd, int sliceIndex, Texture content, uint textureHash)
{
{
// transfer new slice to sliceIndex from source texture
SetSliceHash(sliceIndex, textureHash);
TransferToSlice(cmd, sliceIndex, content);

public void UpdateSlice(CommandBuffer cmd, int sliceIndex, Texture content)
{
UpdateSlice(cmd, sliceIndex, content, GetTextureHash(content));
}
}
public int FetchSlice(CommandBuffer cmd, Texture texture, bool forceReinject=false)
{

2
ScriptableRenderPipeline/Core/package.json


{
"name": "com.unity.render-pipelines.core",
"description": "Core library for Unity render pipelines.",
"version": "0.1.29",
"version": "0.1.32",
"unity": "2018.1",
"dependencies": {
"com.unity.postprocessing": "0.1.8"

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDAdditionalCameraData.cs


Unlit // Hard coded path
};
public enum ClearColorMode
{
Sky,
BackgroundColor,
None
};
public ClearColorMode clearColorMode = ClearColorMode.Sky;
[ColorUsage(true, true)]
public Color backgroundColorHDR = new Color(0.025f, 0.07f, 0.19f, 0.0f);
public bool clearDepth = true;
public RenderingPath renderingPath;
[Tooltip("Layer Mask used for the volume interpolation for this camera.")]
public LayerMask volumeLayerMask = -1;

44
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs


// happen, but you never know...
int m_LastFrameActive;
public bool clearDepth
{
get { return m_AdditionalCameraData != null ? m_AdditionalCameraData.clearDepth : camera.clearFlags != CameraClearFlags.Nothing; }
}
public HDAdditionalCameraData.ClearColorMode clearColorMode
{
get
{
if (m_AdditionalCameraData != null)
{
return m_AdditionalCameraData.clearColorMode;
}
if (camera.clearFlags == CameraClearFlags.Skybox)
return HDAdditionalCameraData.ClearColorMode.Sky;
else if (camera.clearFlags == CameraClearFlags.SolidColor)
return HDAdditionalCameraData.ClearColorMode.BackgroundColor;
else // None
return HDAdditionalCameraData.ClearColorMode.None;
}
}
public Color backgroundColorHDR
{
get
{
if (m_AdditionalCameraData != null)
{
return m_AdditionalCameraData.backgroundColorHDR;
}
// The scene view has no additional data so this will correctly pick the editor preference backround color here.
return camera.backgroundColor.linear;
}
}
static Dictionary<Camera, HDCamera> s_Cameras = new Dictionary<Camera, HDCamera>();
static List<Camera> s_Cleanup = new List<Camera>(); // Recycled to reduce GC pressure

isFirstFrame = false;
}
taaFrameIndex = taaEnabled ? (uint)postProcessLayer.temporalAntialiasing.sampleIndex : 0;
// TEMP: Re-enable this code once we bump the postprocessing package to 0.1.19 (or above)
// current package 0.1.8 don't have the .sampleIndex and it fail with template...
// taaFrameIndex = taaEnabled ? (uint)postProcessLayer.temporalAntialiasing.sampleIndex : 0;
const uint taaFrameCount = 8;
taaFrameIndex = taaEnabled ? (uint)Time.renderedFrameCount % taaFrameCount : 0;
// END TEMP
taaFrameRotation = new Vector2(Mathf.Sin(taaFrameIndex * (0.5f * Mathf.PI)),
Mathf.Cos(taaFrameIndex * (0.5f * Mathf.PI)));

18
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraUI.cs


public static readonly CED.IDrawer[] Inspector = null;
public static readonly CED.IDrawer SectionPrimarySettings = CED.Group(
CED.Action(Drawer_FieldBackgroundColor),
CED.Action(Drawer_FieldClearColorMode),
CED.Action(Drawer_FieldBackgroundColorHDR),
CED.Action(Drawer_FieldClearDepth),
CED.Action(Drawer_FieldCullingMask),
CED.Action(Drawer_FieldVolumeLayerMask),
CED.space,

frameSettingsUI.Update();
}
static void Drawer_FieldBackgroundColor(HDCameraUI s, SerializedHDCamera p, Editor owner)
static void Drawer_FieldBackgroundColorHDR(HDCameraUI s, SerializedHDCamera p, Editor owner)
EditorGUILayout.PropertyField(p.backgroundColor, _.GetContent("Background Color|The Camera clears the screen to this color before rendering."));
EditorGUILayout.PropertyField(p.backgroundColorHDR, _.GetContent("Background Color|The BackgroundColor used to clear the screen when selecting BackgrounColor before rendering."));
}
static void Drawer_FieldVolumeLayerMask(HDCameraUI s, SerializedHDCamera p, Editor owner)

EditorGUILayout.PropertyField(p.depth, _.GetContent("Depth"));
}
static void Drawer_FieldClearColorMode(HDCameraUI s, SerializedHDCamera p, Editor owner)
{
EditorGUILayout.PropertyField(p.clearColorMode, _.GetContent("Clear Mode|The Camera clears the screen to selected mode."));
}
}
static void Drawer_FieldClearDepth(HDCameraUI s, SerializedHDCamera p, Editor owner)
{
EditorGUILayout.PropertyField(p.clearDepth, _.GetContent("ClearDepth|The Camera clears the depth buffer before rendering."));
}
static void Drawer_FieldRenderTarget(HDCameraUI s, SerializedHDCamera p, Editor owner)

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/SerializedHDCamera.cs


public SerializedObject serializedObject;
public SerializedObject serializedAdditionalDataObject;
public SerializedProperty backgroundColor;
//public SerializedProperty backgroundColor;
public SerializedProperty normalizedViewPortRect;
public SerializedProperty fieldOfView;
public SerializedProperty orthographic;

public SerializedProperty targetDisplay;
#endif
public SerializedProperty clearColorMode;
public SerializedProperty backgroundColorHDR;
public SerializedProperty clearDepth;
public SerializedProperty volumeLayerMask;
public SerializedFrameSettings frameSettings;

hideFlags.intValue = (int)HideFlags.HideInInspector;
serializedAdditionalDataObject.ApplyModifiedProperties();
backgroundColor = serializedObject.FindProperty("m_BackGroundColor");
//backgroundColor = serializedObject.FindProperty("m_BackGroundColor");
normalizedViewPortRect = serializedObject.FindProperty("m_NormalizedViewPortRect");
nearClippingPlane = serializedObject.FindProperty("near clip plane");
farClippingPlane = serializedObject.FindProperty("far clip plane");

targetEye = serializedObject.FindProperty("m_TargetEye");
clearColorMode = serializedAdditionalDataObject.Find((HDAdditionalCameraData d) => d.clearColorMode);
backgroundColorHDR = serializedAdditionalDataObject.Find((HDAdditionalCameraData d) => d.backgroundColorHDR);
clearDepth = serializedAdditionalDataObject.Find((HDAdditionalCameraData d) => d.clearDepth);
volumeLayerMask = serializedAdditionalDataObject.Find((HDAdditionalCameraData d) => d.volumeLayerMask);
frameSettings = new SerializedFrameSettings(serializedAdditionalDataObject.FindProperty("m_FrameSettings"));
}

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDAssetFactory.cs


newAsset.deferredShader = Load<Shader>(HDRenderPipelinePath + "Lighting/Deferred.Shader");
newAsset.gaussianPyramidCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ColorPyramid.compute");
newAsset.depthPyramidCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/DepthPyramid.compute");
newAsset.copyChannelCS = Load<ComputeShader>(CorePath + "Resources/GPUCopy.compute");
newAsset.copyChannelCS = Load<ComputeShader>(CorePath + "CoreResources/GPUCopy.compute");
newAsset.applyDistortionCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ApplyDistorsion.compute");
newAsset.clearDispatchIndirectShader = Load<ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/cleardispatchindirect.compute");

newAsset.GGXConvolve = Load<Shader>(HDRenderPipelinePath + "Material/GGXConvolution/GGXConvolve.shader");
newAsset.opaqueAtmosphericScattering = Load<Shader>(HDRenderPipelinePath + "Sky/OpaqueAtmosphericScattering.shader");
newAsset.encodeBC6HCS = Load<ComputeShader>(CorePath + "Resources/EncodeBC6H.compute");
// Utilities / Core
newAsset.encodeBC6HCS = Load<ComputeShader>(CorePath + "CoreResources/EncodeBC6H.compute");
newAsset.cubeToPanoShader = Load<Shader>(CorePath + "CoreResources/CubeToPano.shader");
newAsset.blitCubeTextureFace = Load<Shader>(CorePath + "CoreResources/BlitCubeTextureFace.shader");
// Shadow
newAsset.shadowClearShader = Load<Shader>(CorePath + "Shadow/ShadowClear.shader");
newAsset.shadowBlurMoments = Load<ComputeShader>(CorePath + "Shadow/ShadowBlurMoments.compute");
newAsset.debugShadowMapShader = Load<Shader>(CorePath + "Shadow/DebugDisplayShadowMap.shader");
AssetDatabase.CreateAsset(newAsset, pathName);
ProjectWindowUtil.ShowCreatedAsset(newAsset);

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRenderPipelineMenuItems.cs


light.gameObject.AddComponent<HDAdditionalLightData>();
if (light.GetComponent<AdditionalShadowData>() == null)
light.gameObject.AddComponent<AdditionalShadowData>();
{
AdditionalShadowData shadowData = light.gameObject.AddComponent<AdditionalShadowData>();
HDAdditionalShadowData.InitDefaultHDAdditionalShadowData(shadowData);
}
}
}

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.Styles.cs


public readonly GUIContent contactShadowFadeDistance = new GUIContent("Fade Distance", "Distance in world units over which the contact shadows are faded out (see Max Distance).");
public readonly GUIContent contactShadowSampleCount = new GUIContent("Sample Count", "Number of samples when ray casting.");
// Bias control
public readonly GUIContent viewBiasMin = new GUIContent("View Bias");
public readonly GUIContent viewBiasMax = new GUIContent("View Bias Max");
public readonly GUIContent viewBiasScale = new GUIContent("View Bias Scale");
public readonly GUIContent normalBiasMin = new GUIContent("Normal Bias");
public readonly GUIContent normalBiasMax = new GUIContent("Normal Bias Max");
public readonly GUIContent normalBiasScale = new GUIContent("Normal Bias Scale");
public readonly GUIContent sampleBiasScale = new GUIContent("Sample Bias Scale");
public readonly GUIContent edgeLeakFixup = new GUIContent("Edge Leak Fixup");
public readonly GUIContent edgeToleranceNormal = new GUIContent("Edge Tolerance Normal");
public readonly GUIContent edgeTolerance = new GUIContent("Edge Tolerance");
public Styles()
{
shapeNames = Enum.GetNames(typeof(LightShape))

58
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.cs


public SerializedProperty contactShadowMaxDistance;
public SerializedProperty contactShadowFadeDistance;
public SerializedProperty contactShadowSampleCount;
// Bias control
public SerializedProperty viewBiasMin;
public SerializedProperty viewBiasMax;
public SerializedProperty viewBiasScale;
public SerializedProperty normalBiasMin;
public SerializedProperty normalBiasMax;
public SerializedProperty normalBiasScale;
public SerializedProperty sampleBiasScale;
public SerializedProperty edgeLeakFixup;
public SerializedProperty edgeToleranceNormal;
public SerializedProperty edgeTolerance;
}
SerializedObject m_SerializedAdditionalLightData;

// Get & automatically add additional HD data if not present
var lightData = CoreEditorUtils.GetAdditionalData<HDAdditionalLightData>(targets);
var shadowData = CoreEditorUtils.GetAdditionalData<AdditionalShadowData>(targets);
var shadowData = CoreEditorUtils.GetAdditionalData<AdditionalShadowData>(targets, HDAdditionalShadowData.InitDefaultHDAdditionalShadowData);
m_SerializedAdditionalLightData = new SerializedObject(lightData);
m_SerializedAdditionalShadowData = new SerializedObject(shadowData);

contactShadowMaxDistance = o.Find(x => x.contactShadowMaxDistance),
contactShadowFadeDistance = o.Find(x => x.contactShadowFadeDistance),
contactShadowSampleCount = o.Find(x => x.contactShadowSampleCount),
viewBiasMin = o.Find(x => x.viewBiasMin),
viewBiasMax = o.Find(x => x.viewBiasMax),
viewBiasScale = o.Find(x => x.viewBiasScale),
normalBiasMin = o.Find(x => x.normalBiasMin),
normalBiasMax = o.Find(x => x.normalBiasMax),
normalBiasScale = o.Find(x => x.normalBiasScale),
sampleBiasScale = o.Find(x => x.sampleBiasScale),
edgeLeakFixup = o.Find(x => x.edgeLeakFixup),
edgeToleranceNormal = o.Find(x => x.edgeToleranceNormal),
edgeTolerance = o.Find(x => x.edgeTolerance)
};
}

}
EditorGUILayout.PropertyField(m_AdditionalShadowData.resolution, s_Styles.shadowResolution);
EditorGUILayout.Slider(settings.shadowsBias, 0.001f, 1f, s_Styles.shadowBias);
EditorGUILayout.Slider(settings.shadowsNormalBias, 0.001f, 1f, s_Styles.shadowNormalBias);
//EditorGUILayout.Slider(settings.shadowsBias, 0.001f, 1f, s_Styles.shadowBias);
//EditorGUILayout.Slider(settings.shadowsNormalBias, 0.001f, 1f, s_Styles.shadowNormalBias);
EditorGUILayout.Slider(m_AdditionalShadowData.viewBiasScale, 0.0f, 15.0f, s_Styles.viewBiasScale);
EditorGUILayout.Slider(settings.shadowsNearPlane, 0.01f, 10f, s_Styles.shadowNearPlane);
if (settings.lightType.enumValueIndex == (int)LightType.Directional)

DrawBakedShadowParameters();
// There is currently no additional settings for shadow on directional light
if (m_AdditionalLightData.showAdditionalSettings.boolValue && settings.lightType.enumValueIndex != (int)LightType.Directional)
if (m_AdditionalLightData.showAdditionalSettings.boolValue)
if (settings.lightType.enumValueIndex == (int)LightType.Point || settings.lightType.enumValueIndex == (int)LightType.Spot)
if (settings.lightType.enumValueIndex != (int)LightType.Directional)
{
EditorGUILayout.PropertyField(m_AdditionalShadowData.dimmer, s_Styles.shadowDimmer);
}
EditorGUILayout.PropertyField(m_AdditionalShadowData.dimmer, s_Styles.shadowDimmer);
EditorGUILayout.Slider(m_AdditionalShadowData.viewBiasMin, 0.0f, 5.0f, s_Styles.viewBiasMin);
//EditorGUILayout.PropertyField(m_AdditionalShadowData.viewBiasMax, s_Styles.viewBiasMax);
EditorGUI.BeginChangeCheck();
EditorGUILayout.Slider(m_AdditionalShadowData.normalBiasMin, 0.0f, 5.0f, s_Styles.normalBiasMin);
if (EditorGUI.EndChangeCheck())
{
// Link min to max and don't expose normalBiasScale (useless when min == max)
m_AdditionalShadowData.normalBiasMax = m_AdditionalShadowData.normalBiasMin;
}
//EditorGUILayout.PropertyField(m_AdditionalShadowData.normalBiasMax, s_Styles.normalBiasMax);
//EditorGUILayout.PropertyField(m_AdditionalShadowData.normalBiasScale, s_Styles.normalBiasScale);
//EditorGUILayout.PropertyField(m_AdditionalShadowData.sampleBiasScale, s_Styles.sampleBiasScale);
EditorGUILayout.PropertyField(m_AdditionalShadowData.edgeLeakFixup, s_Styles.edgeLeakFixup);
if (m_AdditionalShadowData.edgeLeakFixup.boolValue)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_AdditionalShadowData.edgeToleranceNormal, s_Styles.edgeToleranceNormal);
EditorGUILayout.Slider(m_AdditionalShadowData.edgeTolerance, 0.0f, 1.0f, s_Styles.edgeTolerance);
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
}
}

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditorUtility.cs


[InitializeOnLoadMethod]
static void Initialize()
{
s_PreviewMaterial = new Material(Shader.Find("Debug/ReflectionProbePreview"))
{
hideFlags = HideFlags.HideAndDontSave
};
s_SphereMesh = Resources.GetBuiltinResource(typeof(Mesh), "New-Sphere.fbx") as Mesh;
}

var meshRenderer = p.GetComponent<MeshRenderer>() ?? p.gameObject.AddComponent<MeshRenderer>();
meshFilter.sharedMesh = s_SphereMesh;
// Lazy evaluation attempt to avoid shader compil error issue in Editor (The shader is not found the first time
// we load after deleting Library folder)
if (s_PreviewMaterial == null)
{
s_PreviewMaterial = new Material(Shader.Find("Debug/ReflectionProbePreview"))
{
hideFlags = HideFlags.HideAndDontSave
};
}
var material = meshRenderer.sharedMaterial;
if (material == null

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/LayeredLit/LayeredLitUI.cs


MaterialProperty[] showLayer = new MaterialProperty[kMaxLayerCount];
const string kShowLayer = "_ShowLayer";
bool m_UseHeightBasedBlend;
protected override void FindMaterialProperties(MaterialProperty[] props)
{
base.FindMaterialLayerProperties(props);

EditorGUILayout.Space();
}
DoLayerGUI(material, layerIndex, true);
DoLayerGUI(material, layerIndex, true, m_UseHeightBasedBlend);
if (layerIndex == 0)
EditorGUILayout.Space();

EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = useHeightBasedBlend.hasMixedValue;
bool enabled = EditorGUILayout.Toggle(styles.useHeightBasedBlendText, useHeightBasedBlend.floatValue > 0.0f);
m_UseHeightBasedBlend = EditorGUILayout.Toggle(styles.useHeightBasedBlendText, useHeightBasedBlend.floatValue > 0.0f);
useHeightBasedBlend.floatValue = enabled ? 1.0f : 0.0f;
useHeightBasedBlend.floatValue = m_UseHeightBasedBlend ? 1.0f : 0.0f;
if (enabled)
if (m_UseHeightBasedBlend)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(heightTransition, styles.heightTransition);

44
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/LitUI.cs


// Iridescence
public static GUIContent iridescenceMaskText = new GUIContent("Iridescence Mask", "Control intensity of the iridescence");
public static GUIContent thicknessIridescenceText = new GUIContent("Iridescence Thickness");
public static GUIContent thicknessMapIridescenceText = new GUIContent("Iridescence Thickness map");
public static GUIContent thicknessRemapIridescenceText = new GUIContent("Iridescence Thickness remap");
public static GUIContent iridescenceThicknessText = new GUIContent("Iridescence Layer Thickness");
public static GUIContent iridescenceThicknessMapText = new GUIContent("Iridescence Layer Thickness map");
public static GUIContent iridescenceThicknessRemapText = new GUIContent("Iridescence Layer Thickness remap");
// Clear Coat
public static GUIContent coatMaskText = new GUIContent("Coat Mask", "Attenuate the coating effect (similar to change to IOR of 1");

protected const string kIridescenceMask = "_IridescenceMask";
protected MaterialProperty iridescenceMaskMap = null;
protected const string kIridescenceMaskMap = "_IridescenceMaskMap";
protected MaterialProperty thicknessIridescence = null;
protected const string kThicknessIridescence = "_ThicknessIridescence";
protected MaterialProperty thicknessMapIridescence = null;
protected const string kThicknessMapIridescence = "_ThicknessMapIridescence";
protected MaterialProperty thicknessRemapIridescence = null;
protected const string kThicknessRemapIridescence = "_ThicknessRemapIridescence";
protected MaterialProperty iridescenceThickness = null;
protected const string kIridescenceThickness = "_IridescenceThickness";
protected MaterialProperty iridescenceThicknessMap = null;
protected const string kIridescenceThicknessMap = "_IridescenceThicknessMap";
protected MaterialProperty iridescenceThicknessRemap = null;
protected const string kIridescenceThicknessRemap = "_IridescenceThicknessRemap";
protected MaterialProperty coatMask = null;
protected const string kCoatMask = "_CoatMask";

// Iridescence
iridescenceMask = FindProperty(kIridescenceMask, props);
iridescenceMaskMap = FindProperty(kIridescenceMaskMap, props);
thicknessIridescence = FindProperty(kThicknessIridescence, props);
thicknessMapIridescence = FindProperty(kThicknessMapIridescence, props);
thicknessRemapIridescence = FindProperty(kThicknessRemapIridescence, props);
iridescenceThickness = FindProperty(kIridescenceThickness, props);
iridescenceThicknessMap = FindProperty(kIridescenceThicknessMap, props);
iridescenceThicknessRemap = FindProperty(kIridescenceThicknessRemap, props);
// clear coat
coatMask = FindProperty(kCoatMask, props);

{
m_MaterialEditor.TexturePropertySingleLine(Styles.iridescenceMaskText, iridescenceMaskMap, iridescenceMask);
m_MaterialEditor.TexturePropertySingleLine(Styles.thicknessMapIridescenceText, thicknessMapIridescence);
if (thicknessMapIridescence.textureValue != null)
m_MaterialEditor.TexturePropertySingleLine(Styles.iridescenceThicknessMapText, iridescenceThicknessMap);
if (iridescenceThicknessMap.textureValue != null)
Vector2 remap = thicknessRemapIridescence.vectorValue;
Vector2 remap = iridescenceThicknessRemap.vectorValue;
EditorGUILayout.MinMaxSlider(Styles.thicknessRemapIridescenceText, ref remap.x, ref remap.y, 0.0f, 1.0f);
EditorGUILayout.MinMaxSlider(Styles.iridescenceThicknessRemapText, ref remap.x, ref remap.y, 0.0f, 1.0f);
thicknessRemapIridescence.vectorValue = remap;
iridescenceThicknessRemap.vectorValue = remap;
m_MaterialEditor.ShaderProperty(thicknessIridescence, Styles.thicknessIridescenceText);
m_MaterialEditor.ShaderProperty(iridescenceThickness, Styles.iridescenceThicknessText);
}
}

}
}
protected void DoLayerGUI(Material material, int layerIndex, bool isLayeredLit)
protected void DoLayerGUI(Material material, int layerIndex, bool isLayeredLit, bool showHeightMap)
{
EditorGUILayout.LabelField(Styles.InputsText, EditorStyles.boldLabel);

}
DisplacementMode displaceMode = (DisplacementMode)displacementMode.floatValue;
if(displaceMode != DisplacementMode.None)
if(displaceMode != DisplacementMode.None || showHeightMap)
{
EditorGUI.BeginChangeCheck();
m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap[layerIndex]);

protected override void MaterialPropertiesGUI(Material material)
{
DoLayerGUI(material, 0, false);
DoLayerGUI(material, 0, false, false);
DoEmissiveGUI(material);
// The parent Base.ShaderPropertiesGUI will call DoEmissionArea
}

CoreUtils.SetKeyword(material, "_DETAIL_MAP", material.GetTexture(kDetailMap));
CoreUtils.SetKeyword(material, "_SUBSURFACE_MASK_MAP", material.GetTexture(kSubsurfaceMaskMap));
CoreUtils.SetKeyword(material, "_THICKNESSMAP", material.GetTexture(kThicknessMap));
CoreUtils.SetKeyword(material, "_THICKNESSMAP_IRIDESCENCE", material.GetTexture(kThicknessMapIridescence));
CoreUtils.SetKeyword(material, "_IRIDESCENCE_THICKNESSMAP", material.GetTexture(kIridescenceThicknessMap));
CoreUtils.SetKeyword(material, "_SPECULARCOLORMAP", material.GetTexture(kSpecularColorMap));
bool needUV2 = (UVDetailMapping)material.GetFloat(kUVDetail) == UVDetailMapping.UV2 || (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV2;

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/GlobalLightLoopSettingsUI.cs


{
EditorGUILayout.LabelField(_.GetContent("Cookies"), EditorStyles.boldLabel);
++EditorGUI.indentLevel;
EditorGUILayout.PropertyField(d.cookieSize, _.GetContent("Cookie Size"));
EditorGUILayout.PropertyField(d.cubeCookieTexArraySize, _.GetContent("Cubemap Array Size"));
EditorGUILayout.PropertyField(d.spotCookieSize, _.GetContent("Spot Cookie Size"));
EditorGUILayout.PropertyField(d.cubeCookieTexArraySize, _.GetContent("Cubemap Array Size"));
--EditorGUI.indentLevel;
}

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedGlobalLightLoopSettings.cs


{
public SerializedProperty root;
public SerializedProperty spotCookieSize;
public SerializedProperty cookieSize;
public SerializedProperty cookieTexArraySize;
public SerializedProperty pointCookieSize;
public SerializedProperty cubeCookieTexArraySize;

{
this.root = root;
spotCookieSize = root.Find((GlobalLightLoopSettings s) => s.spotCookieSize);
cookieSize = root.Find((GlobalLightLoopSettings s) => s.cookieSize);
cookieTexArraySize = root.Find((GlobalLightLoopSettings s) => s.cookieTexArraySize);
pointCookieSize = root.Find((GlobalLightLoopSettings s) => s.pointCookieSize);
cubeCookieTexArraySize = root.Find((GlobalLightLoopSettings s) => s.cubeCookieTexArraySize);

48
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


{
// 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)
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthOnlyAndDepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque, m_DepthStateOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthOnlyAndDepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque, m_DepthStateOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthOnlyPassNames, 0, renderQueueRange, m_DepthStateOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthOnlyPassNames, 0, renderQueueRange);
}
}
}

}
else
{
// When rendering debug material we shouldn't rely on a depth prepass for optimizing the alpha clip test. As it is control on the material inspector side
// we must override the state here.
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, m_AllForwardOpaquePassNames, m_currentRendererConfigurationBakedLighting);
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, m_AllForwardOpaquePassNames, m_currentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque);
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, cmd, m_AllTransparentPassNames, m_currentRendererConfigurationBakedLighting);
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, cmd, m_AllTransparentPassNames, m_currentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque);
}
}

cmd.GetTemporaryRT(HDShaderIDs._CameraDepthTexture, hdcamera.actualWidth, hdcamera.actualHeight, m_CameraDepthStencilBuffer.rt.depth, FilterMode.Point, m_CameraDepthStencilBuffer.rt.format);
m_CopyDepth.SetTexture(HDShaderIDs._InputDepth, m_CameraDepthStencilBuffer);
cmd.Blit(null, HDShaderIDs._CameraDepthTexture, m_CopyDepth);
cmd.GetTemporaryRT(HDShaderIDs._CameraMotionVectorsTexture, hdcamera.actualWidth, hdcamera.actualHeight, 0, FilterMode.Point, m_VelocityBuffer.rt.format);
HDUtils.BlitCameraTexture(cmd, hdcamera, m_VelocityBuffer, HDShaderIDs._CameraMotionVectorsTexture);
if (m_VelocityBuffer != null)
{
cmd.GetTemporaryRT(HDShaderIDs._CameraMotionVectorsTexture, hdcamera.actualWidth, hdcamera.actualHeight, 0, FilterMode.Point, m_VelocityBuffer.rt.format);
HDUtils.BlitCameraTexture(cmd, hdcamera, m_VelocityBuffer, HDShaderIDs._CameraMotionVectorsTexture);
}
cmd.GetTemporaryRT(HDShaderIDs._CameraColorTexture, hdcamera.actualWidth, hdcamera.actualHeight, 0, FilterMode.Point, m_CameraColorBuffer.rt.format);
HDUtils.BlitCameraTexture(cmd, hdcamera, m_CameraColorBuffer, HDShaderIDs._CameraColorTexture);
source = HDShaderIDs._CameraColorTexture;

// Clear depth/stencil and init buffers
using (new ProfilingSample(cmd, "Clear Depth/Stencil", CustomSamplerId.ClearDepthStencil.GetSampler()))
{
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraColorBuffer, m_CameraDepthStencilBuffer, ClearFlag.Depth);
if (hdCamera.clearDepth)
{
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraColorBuffer, m_CameraDepthStencilBuffer, ClearFlag.Depth);
}
}
// Clear the HDR target
using (new ProfilingSample(cmd, "Clear HDR target", CustomSamplerId.ClearHDRTarget.GetSampler()))
{
if (hdCamera.clearColorMode == HDAdditionalCameraData.ClearColorMode.BackgroundColor ||
// If we want the sky but the sky don't exist, still clear with background color
(hdCamera.clearColorMode == HDAdditionalCameraData.ClearColorMode.Sky && !m_SkyManager.IsSkyValid()) ||
// Special handling for Preview we force to clear with background color (i.e black)
// Note that the sky use in this case is the last one setup. If there is no scene or game, there is no sky use as reflection in the preview
hdCamera.camera.cameraType == CameraType.Preview
)
{
Color clearColor = hdCamera.backgroundColorHDR;
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraColorBuffer, m_CameraDepthStencilBuffer, ClearFlag.Color, clearColor);
}
}
// Clear the diffuse SSS lighting target

}
// TODO: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.
// Clear the HDR target
using (new ProfilingSample(cmd, "Clear HDR target", CustomSamplerId.ClearHDRTarget.GetSampler()))
{
Color clearColor = hdCamera.camera.backgroundColor.linear; // Need it in linear because we clear a linear fp16 texture.
HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraColorBuffer, m_CameraDepthStencilBuffer, ClearFlag.Color, clearColor);
}
// Clear GBuffers
if (!m_FrameSettings.enableForwardRenderingOnly)

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.asset


--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1

supportSSR: 1
supportSSAO: 1
supportSubsurfaceScattering: 1
supportsForwardOnly: 0
supportForwardOnly: 0
supportMSAAAntiAliasing: 0
supportMSAA: 0
supportsMotionVectors: 1
supportsStereo: 0
supportMotionVectors: 1
supportStereo: 0
spotCookieSize: 128
cookieSize: 128
cookieTexArraySize: 16
pointCookieSize: 512
cubeCookieTexArraySize: 16

38
ScriptableRenderPipeline/HDRenderPipeline/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 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
#endif
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "../ShaderVariables.hlsl"

RWTexture2D<float4> _DeferredShadowTextureUAV;
CBUFFER_START(DeferredShadowParameters)
float _DirectionalShadowIndex;
uint _DirectionalShadowIndex;
float3 _LightDirection;
float4 _ScreenSpaceShadowsParameters;
int _SampleCount;

uint2 pixelCoord = groupId * DEFERRED_SHADOW_TILE_SIZE + groupThreadId;
uint2 tileCoord = groupId;
float depth = LOAD_TEXTURE2D(_MainDepthTexture, pixelCoord.xy).x;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP, tileCoord);
float depth = LOAD_TEXTURE2D(_MainDepthTexture, pixelCoord.xy).x;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP, 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
float shadow = GetDirectionalShadowAttenuation(shadowContext, posInput.positionWS, float3(0.0, 0.0, 0.0), (uint)_DirectionalShadowIndex, float3(0.0, 0.0, 0.0));
float shadow = GetDirectionalShadowAttenuation(shadowContext, posInput.positionWS, nrm, _DirectionalShadowIndex, _LightDirection);
#ifdef ENABLE_CONTACT_SHADOWS
float contactShadow = 1.0f;

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl


color = lightData.color;
attenuation = 1.0; // Note: no volumetric attenuation along shadow rays for directional lights
[branch] if (lightData.cookieIndex >= 0)
UNITY_BRANCH if (lightData.cookieIndex >= 0)
{
float3 lightToSample = positionWS - lightData.positionWS;
float3 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, lightToSample);

shadow = shadowMask = (lightData.shadowMaskSelector.x >= 0.0) ? dot(bakeLightingData.bakeShadowMask, lightData.shadowMaskSelector) : 1.0;
#endif
[branch] if (lightData.shadowIndex >= 0)
UNITY_BRANCH if (lightData.shadowIndex >= 0)
{
#ifdef USE_DEFERRED_DIRECTIONAL_SHADOWS
shadow = LOAD_TEXTURE2D(_DeferredShadowTexture, posInput.positionSS).x;

float4 cookie;
[branch] if (lightType == GPULIGHTTYPE_POINT)
UNITY_BRANCH if (lightType == GPULIGHTTYPE_POINT)
{
cookie.rgb = SampleCookieCube(lightLoopContext, positionLS, lightData.cookieIndex);
cookie.a = 1;

#endif
// Projector lights always have cookies, so we can perform clipping inside the if().
[branch] if (lightData.cookieIndex >= 0)
UNITY_BRANCH if (lightData.cookieIndex >= 0)
{
float4 cookie = EvaluateCookie_Punctual(lightLoopContext, lightData, lightToSample);

shadow = shadowMask = (lightData.shadowMaskSelector.x >= 0.0) ? dot(bakeLightingData.bakeShadowMask, lightData.shadowMaskSelector) : 1.0;
#endif
[branch] if (lightData.shadowIndex >= 0)
UNITY_BRANCH if (lightData.shadowIndex >= 0)
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
float4 L_dist = float4(L, distances.x);
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, N, lightData.shadowIndex, L_dist, posInput.positionSS);
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS, N, lightData.shadowIndex, L, distances.x, posInput.positionSS);
#ifdef SHADOWS_SHADOWMASK
// Note: Legacy Unity have two shadow mask mode. ShadowMask (ShadowMask contain static objects shadow and ShadowMap contain only dynamic objects shadow, final result is the minimun of both value)
// and ShadowMask_Distance (ShadowMask contain static objects shadow and ShadowMap contain everything and is blend with ShadowMask based on distance (Global distance setup in QualitySettigns)).

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/GlobalLightLoopSettings.cs


[Serializable]
public class GlobalLightLoopSettings
{
public int spotCookieSize = 128;
public int cookieSize = 128;
public int pointCookieSize = 512;
public int pointCookieSize = 128;
public int cubeCookieTexArraySize = 16;
public int reflectionProbeCacheSize = 4;

48
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


return shadowType;
}
public ShadowSetup(ShadowInitParameters shadowInit, ShadowSettings shadowSettings, out IShadowManager shadowManager)
public ShadowSetup(RenderPipelineResources resources, ShadowInitParameters shadowInit, ShadowSettings shadowSettings, out IShadowManager shadowManager)
{
s_ShadowDataBuffer = new ComputeBuffer( k_MaxShadowDataSlots, System.Runtime.InteropServices.Marshal.SizeOf( typeof( ShadowData ) ) );
s_ShadowPayloadBuffer = new ComputeBuffer( k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData, System.Runtime.InteropServices.Marshal.SizeOf( typeof( ShadowPayload ) ) );

atlasInit.baseInit.maxPayloadCount = 0;
atlasInit.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Directional | ShadowmapBase.ShadowSupport.Point | ShadowmapBase.ShadowSupport.Spot;
atlasInit.shaderKeyword = null;
atlasInit.shadowClearShader = resources.shadowClearShader;
atlasInit.shadowBlurMoments = resources.shadowBlurMoments;
var varianceInit = atlasInit;
varianceInit.baseInit.shadowmapFormat = ShadowVariance.GetFormat( false, false, true );

m_ShadowMgr = new ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
// set global overrides - these need to match the override specified in LightLoop/Shadow.hlsl
bool useGlobalOverrides = true;
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Spot , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point , ShadowAlgorithm.PCF, ShadowVariant.V2, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Spot , ShadowAlgorithm.PCF, ShadowVariant.V2, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Directional , ShadowAlgorithm.PCF, ShadowVariant.V3, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetShadowLightTypeDelegate(HDShadowLightType);

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;

// Following is an array of material of size eight for all combination of keyword: OUTPUT_SPLIT_LIGHTING - LIGHTLOOP_TILE_PASS - SHADOWS_SHADOWMASK - USE_FPTL_LIGHTLIST/USE_CLUSTERED_LIGHTLIST - DEBUG_DISPLAY
Material[] m_deferredLightingMaterial;
Material m_DebugViewTilesMaterial;
Material m_DebugShadowMapMaterial;
Material m_CubeToPanoMaterial;
Light m_CurrentSunLight;
int m_CurrentSunLightShadowIndex = -1;

List<int> m_ShadowRequests = new List<int>();
Dictionary<int, int> m_ShadowIndices = new Dictionary<int, int>();
void InitShadowSystem(ShadowInitParameters initParam, ShadowSettings shadowSettings)
void InitShadowSystem(HDRenderPipelineAsset hdAsset, ShadowSettings shadowSettings)
m_ShadowSetup = new ShadowSetup(initParam, shadowSettings, out m_ShadowMgr);
m_ShadowSetup = new ShadowSetup(hdAsset.renderPipelineResources, hdAsset.GetRenderPipelineSettings().shadowInitParams, shadowSettings, out m_ShadowMgr);
}
void DeinitShadowSystem()

{
m_Resources = hdAsset.renderPipelineResources;
m_DebugViewTilesMaterial = CoreUtils.CreateEngineMaterial(m_Resources.debugViewTilesShader);
m_DebugShadowMapMaterial = CoreUtils.CreateEngineMaterial(m_Resources.debugShadowMapShader);
m_CubeToPanoMaterial = CoreUtils.CreateEngineMaterial(m_Resources.cubeToPanoShader);
m_lightList = new LightList();
m_lightList.Allocate();
m_Env2DCaptureVP.Clear();

GlobalLightLoopSettings gLightLoopSettings = hdAsset.GetRenderPipelineSettings().lightLoopSettings;
m_CookieTexArray = new TextureCache2D();
m_CookieTexArray.AllocTextureArray(gLightLoopSettings.cookieTexArraySize, gLightLoopSettings.spotCookieSize, gLightLoopSettings.spotCookieSize, TextureFormat.RGBA32, true);
m_CookieTexArray.AllocTextureArray(gLightLoopSettings.cookieTexArraySize, gLightLoopSettings.cookieSize, gLightLoopSettings.cookieSize, TextureFormat.RGBA32, true);
m_CubeCookieTexArray.AllocTextureArray(gLightLoopSettings.cubeCookieTexArraySize, gLightLoopSettings.pointCookieSize, TextureFormat.RGBA32, true);
m_CubeCookieTexArray.AllocTextureArray(gLightLoopSettings.cubeCookieTexArraySize, gLightLoopSettings.pointCookieSize, TextureFormat.RGBA32, true, m_CubeToPanoMaterial);
m_ReflectionProbeCache = new ReflectionProbeCache(iblFilterGGX, gLightLoopSettings.reflectionProbeCacheSize, gLightLoopSettings.reflectionCubemapSize, probeCacheFormat, true);
m_ReflectionProbeCache = new ReflectionProbeCache(hdAsset, iblFilterGGX, gLightLoopSettings.reflectionProbeCacheSize, gLightLoopSettings.reflectionCubemapSize, probeCacheFormat, true);
m_ReflectionPlanarProbeCache = new PlanarReflectionProbeCache(iblFilterGGX, gLightLoopSettings.planarReflectionProbeCacheSize, gLightLoopSettings.planarReflectionTextureSize, planarProbeCacheFormat, true);
m_ReflectionPlanarProbeCache = new PlanarReflectionProbeCache(hdAsset, iblFilterGGX, gLightLoopSettings.planarReflectionProbeCacheSize, gLightLoopSettings.planarReflectionTextureSize, planarProbeCacheFormat, true);
s_GenAABBKernel = buildScreenAABBShader.FindKernel("ScreenBoundsAABB");

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++)
{

}
}
}
m_DebugViewTilesMaterial = CoreUtils.CreateEngineMaterial(m_Resources.debugViewTilesShader);
s_DefaultTexture2DArray = new Texture2DArray(1, 1, 1, TextureFormat.ARGB32, false);
s_DefaultTexture2DArray.SetPixels32(new Color32[1] { new Color32(128, 128, 128, 128) }, 0);

s_DefaultTextureCube.Apply();
InitShadowSystem(hdAsset.GetRenderPipelineSettings().shadowInitParams, shadowSettings);
InitShadowSystem(hdAsset, shadowSettings);
}
public void Cleanup()

}
CoreUtils.Destroy(m_DebugViewTilesMaterial);
CoreUtils.Destroy(m_DebugShadowMapMaterial);
CoreUtils.Destroy(m_CubeToPanoMaterial);
}
public void NewFrame(FrameSettings frameSettings)

AdditionalShadowData asd = m_CurrentSunLight.GetComponent<AdditionalShadowData>();
bool enableContactShadows = m_FrameSettings.enableContactShadows && asd.enableContactShadows && asd.contactShadowLength > 0.0f;
int kernel = enableContactShadows ? s_deferredDirectionalShadow_Contact_Kernel : s_deferredDirectionalShadowKernel;
int kernel;
if (enableContactShadows)
kernel = m_FrameSettings.enableForwardRenderingOnly ? s_deferredDirectionalShadow_Contact_Kernel : s_deferredDirectionalShadow_Contact_Normals_Kernel;
else
kernel = m_FrameSettings.enableForwardRenderingOnly ? s_deferredDirectionalShadowKernel : s_deferredDirectionalShadow_Normals_Kernel;
m_ShadowMgr.BindResources(cmd, deferredDirectionalShadowComputeShader, kernel);

cmd.SetComputeIntParam(deferredDirectionalShadowComputeShader, HDShaderIDs._DirectionalContactShadowSampleCount, (int)asd.contactShadowSampleCount);
}
cmd.SetComputeFloatParam(deferredDirectionalShadowComputeShader, HDShaderIDs._DirectionalShadowIndex, (float)m_CurrentSunLightShadowIndex);
cmd.SetComputeIntParam(deferredDirectionalShadowComputeShader, HDShaderIDs._DirectionalShadowIndex, m_CurrentSunLightShadowIndex);
cmd.SetComputeVectorParam(deferredDirectionalShadowComputeShader, HDShaderIDs._DirectionalLightDirection, -m_CurrentSunLight.transform.forward);
cmd.SetComputeTextureParam(deferredDirectionalShadowComputeShader, kernel, HDShaderIDs._DeferredShadowTextureUAV, deferredShadowRT);
cmd.SetComputeTextureParam(deferredDirectionalShadowComputeShader, kernel, HDShaderIDs._MainDepthTexture, depthTexture);

uint faceCount = m_ShadowMgr.GetShadowRequestFaceCount((uint)index);
for (uint i = 0; i < faceCount; ++i)
{
m_ShadowMgr.DisplayShadow(cmd, index, i, x, y, overlaySize, overlaySize, lightingDebug.shadowMinValue, lightingDebug.shadowMaxValue);
m_ShadowMgr.DisplayShadow(cmd, m_DebugShadowMapMaterial, index, i, x, y, overlaySize, overlaySize, lightingDebug.shadowMinValue, lightingDebug.shadowMaxValue);
HDUtils.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, hdCamera.actualWidth);
}
}

m_ShadowMgr.DisplayShadowMap(cmd, lightingDebug.shadowAtlasIndex, 0, x, y, overlaySize, overlaySize, lightingDebug.shadowMinValue, lightingDebug.shadowMaxValue);
m_ShadowMgr.DisplayShadowMap(cmd, m_DebugShadowMapMaterial, lightingDebug.shadowAtlasIndex, 0, x, y, overlaySize, overlaySize, lightingDebug.shadowMinValue, lightingDebug.shadowMaxValue);
HDUtils.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, hdCamera.actualWidth);
}
}

26
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.hlsl


float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
float3(1.0, 1.0, 0.0)
float3(1.0, 1.0, 0.0),
float3(1.0, 1.0, 1.0)
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, float3(0.0, 1.0, 0.0 ), 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
float4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres(lightLoopContext.shadowContext, 0, dirShadowSplitSpheres);
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows(positionWS, dirShadowSplitSpheres);
if (shadowSplitIndex == -1)
{
diffuseLighting = float3(0.0, 0.0, 0.0);
}
else
diffuseLighting = float3(0.0, 0.0, 0.0);
if (_DirectionalLightCount > 0)
diffuseLighting = s_CascadeColors[shadowSplitIndex] * shadow;
int shadowIdx = _DirectionalLightDatas[0].shadowIndex;
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, float3(0.0, 1.0, 0.0 ), shadowIdx, -_DirectionalLightDatas[0].forward, float2(0.0, 0.0));
uint payloadOffset;
real alpha;
int shadowSplitIndex = EvalShadow_GetSplitIndex(lightLoopContext.shadowContext, shadowIdx, positionWS, payloadOffset, alpha);
if (shadowSplitIndex >= 0)
{
diffuseLighting = lerp(s_CascadeColors[shadowSplitIndex], s_CascadeColors[shadowSplitIndex+1], alpha) * shadow;
}
}
}
#endif

29
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Shadow.hlsl


#define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL
#define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
#define SHADOW_USE_VIEW_BIAS_SCALING 1 // Enable view bias scaling to mitigate light leaking across edges. Uses the light vector if SHADOW_USE_ONLY_VIEW_BASED_BIASING is defined, otherwise uses the normal.
// Note: Sample biasing work well but is very costly in term of VGPR, disable it for now
#define SHADOW_USE_SAMPLE_BIASING 0 // Enable per sample biasing for wide multi-tap PCF filters. Incompatible with SHADOW_USE_ONLY_VIEW_BASED_BIASING.
#define SHADOW_USE_DEPTH_BIAS 0 // Enable clip space z biasing
#include "ShadowContext.hlsl"
// This is an example of how to override the default dynamic resource dispatcher

// Caution: When updating algorithm here, think to update Lightloop.ShadowSetup() function
// (the various m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point, ShadowAlgorithm.PCF, ShadowVariant.V1, ShadowPrecision.High, useGlobalOverrides ));
// The enum value for the variant is in GPUShadowAlgorithm and is express like: PCF_tent_3x3 = ShadowAlgorithm.PCF << 3 | ShadowVariant.V2
//#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

// point
#define SHADOW_DISPATCH_POINT_TEX 3
#define SHADOW_DISPATCH_POINT_SMP 0
#define SHADOW_DISPATCH_POINT_ALG GPUSHADOWALGORITHM_PCF_1TAP
#define SHADOW_DISPATCH_POINT_ALG GPUSHADOWALGORITHM_PCF_TENT_3X3
#define SHADOW_DISPATCH_SPOT_ALG GPUSHADOWALGORITHM_PCF_9TAP
#define SHADOW_DISPATCH_SPOT_ALG GPUSHADOWALGORITHM_PCF_TENT_3X3
#define SHADOW_DISPATCH_PUNC_ALG GPUSHADOWALGORITHM_PCF_9TAP
#define SHADOW_DISPATCH_PUNC_ALG GPUSHADOWALGORITHM_PCF_TENT_3X3
// example of overriding directional lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL

// example of overriding punctual lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float4 L )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float L_dist )
{
#ifdef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
// example for choosing different algos for point and spot lights

[branch]
UNITY_BRANCH
return EvalShadow_PointDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_PointDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L, L_dist );
}
else
{

return EvalShadow_SpotDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_SpotDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L, L_dist );
}
#else
// example for choosing the same algo

return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L, L_dist );
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float4 L, float2 positionSS )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float L_dist, float2 positionSS )
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L, L_dist );
}
#endif

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-bigtile.compute


bool canEnter = idxCoarse<(uint) g_iNrVisibLights;
if(canEnter) canEnter = _LightVolumeData[idxCoarse].lightVolume != LIGHTVOLUMETYPE_SPHERE; // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
[branch]if(canEnter)
UNITY_BRANCH if(canEnter)
{
SFiniteLightBound lgtDat = g_data[idxCoarse];

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-clustered.compute


GroupMemoryBarrierWithGroupSync();
#endif
const int idxCoarse = coarseList[l];
[branch]if (_LightVolumeData[idxCoarse].lightVolume != LIGHTVOLUMETYPE_SPHERE) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
UNITY_BRANCH if (_LightVolumeData[idxCoarse].lightVolume != LIGHTVOLUMETYPE_SPHERE) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
{
SFiniteLightBound lgtDat = g_data[idxCoarse];

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild.compute


float4 vLinDepths;
{
// Fetch depths and calculate min/max
[unroll]
UNITY_UNROLL
for(int i = 0; i < 4; i++)
{
int idx = i * NR_THREADS + t;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/materialflags.compute


GroupMemoryBarrierWithGroupSync();
uint materialFeatureFlags = g_BaseFeatureFlags; // Contain all lightFeatures or 0 (depends if we enable light classification or not)
[unroll]
UNITY_UNROLL
for(int i = 0; i < 4; i++)
{
int idx = i * NR_THREADS + threadID;

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/PlanarReflectionProbeCache.cs


MaterialPropertyBlock m_ConvertTextureMPB;
bool m_PerformBC6HCompression;
public PlanarReflectionProbeCache(IBLFilterGGX iblFilter, int cacheSize, int probeSize, TextureFormat probeFormat, bool isMipmaped)
public PlanarReflectionProbeCache(HDRenderPipelineAsset hdAsset, IBLFilterGGX iblFilter, int cacheSize, int probeSize, TextureFormat probeFormat, bool isMipmaped)
m_ConvertTextureMaterial = CoreUtils.CreateEngineMaterial(hdAsset.renderPipelineResources.blitCubeTextureFace);
m_ConvertTextureMPB = new MaterialPropertyBlock();
// BC6H requires CPP feature not yet available
probeFormat = TextureFormat.RGBAHalf;

m_ConvolutionTargetTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "PlanarReflectionConvolution", mips: true);
m_ConvolutionTargetTexture.Create();
m_ConvertTextureMaterial = CoreUtils.CreateEngineMaterial("Hidden/SRP/BlitCubeTextureFace");
m_ConvertTextureMPB = new MaterialPropertyBlock();
InitializeProbeBakingStates();
}
}

m_ConvolutionTargetTexture = null;
}
m_ProbeBakingState = null;
CoreUtils.Destroy(m_ConvertTextureMaterial);
}
public void NewFrame()

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionProbeCache.cs


RenderTexture m_ConvolutionTargetTexture;
ProbeFilteringState[] m_ProbeBakingState;
Material m_ConvertTextureMaterial;
Material m_CubeToPano;
public ReflectionProbeCache(IBLFilterGGX iblFilter, int cacheSize, int probeSize, TextureFormat probeFormat, bool isMipmaped)
public ReflectionProbeCache(HDRenderPipelineAsset hdAsset, IBLFilterGGX iblFilter, int cacheSize, int probeSize, TextureFormat probeFormat, bool isMipmaped)
m_ConvertTextureMaterial = CoreUtils.CreateEngineMaterial(hdAsset.renderPipelineResources.blitCubeTextureFace);
m_ConvertTextureMPB = new MaterialPropertyBlock();
m_CubeToPano = CoreUtils.CreateEngineMaterial(hdAsset.renderPipelineResources.cubeToPanoShader);
// BC6H requires CPP feature not yet available
probeFormat = TextureFormat.RGBAHalf;

m_CacheSize = cacheSize;
m_TextureCache = new TextureCacheCubemap();
m_TextureCache.AllocTextureArray(cacheSize, probeSize, probeFormat, isMipmaped);
m_TextureCache.AllocTextureArray(cacheSize, probeSize, probeFormat, isMipmaped, m_CubeToPano);
m_IBLFilterGGX = iblFilter;
m_PerformBC6HCompression = probeFormat == TextureFormat.BC6H;

void Initialize()
{
if(m_TempRenderTexture == null)
if (m_TempRenderTexture == null)
{
// Temporary RT used for convolution and compression
m_TempRenderTexture = new RenderTexture(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf);

m_ConvolutionTargetTexture.autoGenerateMips = false;
m_ConvolutionTargetTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "PlanarReflection", mips : true);
m_ConvolutionTargetTexture.Create();
m_ConvertTextureMaterial = CoreUtils.CreateEngineMaterial("Hidden/SRP/BlitCubeTextureFace");
m_ConvertTextureMPB = new MaterialPropertyBlock();
InitializeProbeBakingStates();
}

m_ConvolutionTargetTexture = null;
}
m_ProbeBakingState = null;
CoreUtils.Destroy(m_ConvertTextureMaterial);
CoreUtils.Destroy(m_CubeToPano);
}
public void NewFrame()

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/Resources/VolumetricLighting.compute


tileCoord = WaveReadFirstLane(tileCoord);
}
[branch] if (voxelCoord.x >= (uint)_VBufferResolution.x ||
UNITY_BRANCH if (voxelCoord.x >= (uint)_VBufferResolution.x ||
voxelCoord.y >= (uint)_VBufferResolution.y)
{
return;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VBuffer.hlsl


// TODO: add the proper sampler support.
bool isInBounds = Min3(uv.x, uv.y, d) > 0 && Max3(uv.x, uv.y, d) < 1;
[branch] if (clampToEdge || isInBounds)
UNITY_BRANCH if (clampToEdge || isInBounds)
{
#if 1
// Ignore non-linearity (for performance reasons) at the cost of accuracy.

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLit.shader


SubShader
{
// This tags allow to use the shader replacement features
Tags{ "RenderType" = "HDLitShader" }
// Caution: The outline selection in the editor use the vertex shader/hull/domain shader of the first pass declare. So it should not bethe meta pass.
Pass
{

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl


// If a top layer doesn't use the full weight, the remaining can be use by the following layer.
float weightsSum = 0.0;
[unroll]
UNITY_UNROLL
for (int i = _LAYER_COUNT - 1; i >= 0; --i)
{
outWeights[i] = min(masks[i], (1.0 - weightsSum));

surfaceData.anisotropy = 0.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
surfaceData.coatMask = 0.0;
surfaceData.thicknessIridescence = 0.0;
surfaceData.iridescenceThickness = 0.0;
surfaceData.iridescenceMask = 0.0;
// Transparency parameters

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitTessellation.shader


SubShader
{
// This tags allow to use the shader replacement features
Tags{ "RenderType" = "HDLitShader" }
// Caution: The outline selection in the editor use the vertex shader/hull/domain shader of the first pass declare. So it should not bethe meta pass.
Pass
{

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs


public float anisotropy; // anisotropic ratio(0->no isotropic; 1->full anisotropy in tangent direction, -1->full anisotropy in bitangent direction)
// Iridescence
[SurfaceDataAttributes("Thickness of Iridescence")]
public float thicknessIridescence;
[SurfaceDataAttributes("Iridescence Layer Thickness")]
public float iridescenceThickness;
[SurfaceDataAttributes("Iridescence Mask")]
public float iridescenceMask;

public float anisotropy;
// Iridescence
public float thicknessIridescence;
public float iridescenceThickness;
public float iridescenceMask;
// ClearCoat

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl


#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS (1012)
#define DEBUGVIEW_LIT_SURFACEDATA_TANGENT (1013)
#define DEBUGVIEW_LIT_SURFACEDATA_ANISOTROPY (1014)
#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS_OF_IRIDESCENCE (1015)
#define DEBUGVIEW_LIT_SURFACEDATA_IRIDESCENCE_LAYER_THICKNESS (1015)
#define DEBUGVIEW_LIT_SURFACEDATA_IRIDESCENCE_MASK (1016)
#define DEBUGVIEW_LIT_SURFACEDATA_INDEX_OF_REFRACTION (1017)
#define DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_COLOR (1018)

#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_T (1045)
#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_B (1046)
#define DEBUGVIEW_LIT_BSDFDATA_ANISOTROPY (1047)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS_IRIDESCENCE (1048)
#define DEBUGVIEW_LIT_BSDFDATA_IRIDESCENCE_THICKNESS (1048)
#define DEBUGVIEW_LIT_BSDFDATA_IRIDESCENCE_MASK (1049)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_ROUGHNESS (1050)
#define DEBUGVIEW_LIT_BSDFDATA_IOR (1051)

float thickness;
float3 tangentWS;
float anisotropy;
float thicknessIridescence;
float iridescenceThickness;
float iridescenceMask;
float ior;
float3 transmittanceColor;

float roughnessT;
float roughnessB;
float anisotropy;
float thicknessIridescence;
float iridescenceThickness;
float iridescenceMask;
float coatRoughness;
float ior;

case DEBUGVIEW_LIT_SURFACEDATA_ANISOTROPY:
result = surfacedata.anisotropy.xxx;
break;
case DEBUGVIEW_LIT_SURFACEDATA_THICKNESS_OF_IRIDESCENCE:
result = surfacedata.thicknessIridescence.xxx;
case DEBUGVIEW_LIT_SURFACEDATA_IRIDESCENCE_LAYER_THICKNESS:
result = surfacedata.iridescenceThickness.xxx;
break;
case DEBUGVIEW_LIT_SURFACEDATA_IRIDESCENCE_MASK:
result = surfacedata.iridescenceMask.xxx;

case DEBUGVIEW_LIT_BSDFDATA_ANISOTROPY:
result = bsdfdata.anisotropy.xxx;
break;
case DEBUGVIEW_LIT_BSDFDATA_THICKNESS_IRIDESCENCE:
result = bsdfdata.thicknessIridescence.xxx;
case DEBUGVIEW_LIT_BSDFDATA_IRIDESCENCE_THICKNESS:
result = bsdfdata.iridescenceThickness.xxx;
break;
case DEBUGVIEW_LIT_BSDFDATA_IRIDESCENCE_MASK:
result = bsdfdata.iridescenceMask.xxx;

125
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


// Helper functions/variable specific to this material
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Iridescence
//-----------------------------------------------------------------------------
// Ref: https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html
// Evaluation XYZ sensitivity curves in Fourier space
float3 EvalSensitivity(float opd, float shift)
{
// Use Gaussian fits, given by 3 parameters: val, pos and var
float phase = 2.0 * PI * opd * 1e-6;
float3 val = float3(5.4856e-13, 4.4201e-13, 5.2481e-13);
float3 pos = float3(1.6810e+06, 1.7953e+06, 2.2084e+06);
float3 var = float3(4.3278e+09, 9.3046e+09, 6.6121e+09);
float3 xyz = val * sqrt(2.0 * PI * var) * cos(pos * phase + shift) * exp(-var * phase * phase);
xyz.x += 9.7470e-14 * sqrt(2.0 * PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift) * exp(-4.5282e+09 * phase * phase);
return xyz / 1.0685e-7;
}
// Evaluate the reflectance for a thin-film layer on top of a dielectric medum.
float3 EvalIridescence(float eta_1, float cosTheta1, BSDFData bsdfData)
{
// thicknessIridescence unit is micrometer for this equation here. Mean 0.5 is 500nm.
float Dinc = 3.0 * bsdfData.thicknessIridescence;
// Note: Unlike the code provide with the paper, here we use schlick approximation
// Schlick is a very poor approximation when dealing with iridescence to the Fresnel
// term and there is no "neutral" value in this unlike in the original paper.
// We use Iridescence mask here to allow to have neutral value
// Hack: In order to use only one parameter (DInc), we deduced the ior of iridescence from current Dinc thicknessIridescence
// and we use mask instead to fade out the effect
float eta_2 = lerp(2.0, 1.0, bsdfData.thicknessIridescence);
// Following line from original code is not needed for us, it create a discontinuity
// Force eta_2 -> eta_1 when Dinc -> 0.0
// float eta_2 = lerp(eta_1, eta_2, smoothstep(0.0, 0.03, Dinc));
// Evaluate the cosTheta on the base layer (Snell law)
float cosTheta2 = sqrt(1.0 - Sq(eta_1 / eta_2) * (1.0 - Sq(cosTheta1)));
// First interface
float R0 = IorToFresnel0(eta_2, eta_1);
float R12 = F_Schlick(R0, cosTheta1);
float R21 = R12;
float T121 = 1.0 - R12;
float phi12 = 0.0;
float phi21 = PI - phi12;
// Second interface
float3 R23 = F_Schlick(bsdfData.fresnel0, cosTheta2);
float phi23 = 0.0;
// Phase shift
float OPD = Dinc * cosTheta2;
float phi = phi21 + phi23;
// Compound terms
float3 R123 = R12 * R23;
float3 r123 = sqrt(R123);
float3 Rs = Sq(T121) * R23 / (float3(1.0, 1.0, 1.0) - R123);
// Reflectance term for m = 0 (DC term amplitude)
float3 C0 = R12 + Rs;
float3 I = C0;
// Reflectance term for m > 0 (pairs of diracs)
float3 Cm = Rs - T121;
for (int m = 1; m <= 2; ++m)
{
Cm *= r123;
float3 Sm = 2.0 * EvalSensitivity(m * OPD, m * phi);
//vec3 SmP = 2.0 * evalSensitivity(m*OPD, m*phi2.y);
I += Cm * Sm;
}
// Convert back to RGB reflectance
//I = clamp(mul(I, XYZ_TO_RGB), float3(0.0, 0.0, 0.0), float3(1.0, 1.0, 1.0));
//I = mul(XYZ_TO_RGB, I);
return I;
}
#if HAS_REFRACTION
# include "CoreRP/ShaderLibrary/Refraction.hlsl"

void FillMaterialIridescence(float mask, float thickness, inout BSDFData bsdfData)
{
bsdfData.iridescenceMask = mask;
bsdfData.thicknessIridescence = thickness;
bsdfData.iridescenceThickness = thickness;
}
// Note: this modify the parameter perceptualRoughness and fresnel0, so they need to be setup

bsdfData.absorptionCoefficient = TransmittanceColorAtDistanceToAbsorption(transmittanceColor, atDistance);
bsdfData.transmittanceMask = transmittanceMask;
bsdfData.thickness = max(thickness, 0.0001);
}
// Remap IOR in range 1..2.5 to 0..1
float RemapIor25to01(float ior)
{
return saturate((ior - 1.0) / 1.5);
}
float RemapIor01to25(float ior)
{
return ior * 1.5 + 1.0;
}
// For image based lighting, a part of the BSDF is pre-integrated.

if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
{
FillMaterialIridescence(surfaceData.iridescenceMask, surfaceData.thicknessIridescence, bsdfData);
FillMaterialIridescence(surfaceData.iridescenceMask, surfaceData.iridescenceThickness, bsdfData);
}
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))

{
materialFeatureId = GBUFFER_LIT_IRIDESCENCE;
outGBuffer2.rgb = float3(surfaceData.iridescenceMask, surfaceData.thicknessIridescence,
outGBuffer2.rgb = float3(surfaceData.iridescenceMask, surfaceData.iridescenceThickness,
PackFloatInt8bit(surfaceData.metallic, 0, 8));
}
else // Standard

result = (surfaceData.materialFeatures.xxx) / 255.0; // Aloow to read with color picker debug mode
break;
case DEBUGVIEW_LIT_SURFACEDATA_INDEX_OF_REFRACTION:
result = RemapIor25to01(surfaceData.ior).xxx;
result = saturate((surfaceData.ior - 1.0) / 1.5).xxx;
break;
}
}

result = (bsdfData.materialFeatures.xxx) / 255.0; // Aloow to read with color picker debug mode
break;
case DEBUGVIEW_LIT_BSDFDATA_IOR:
result = RemapIor25to01(bsdfData.ior).xxx;
result = saturate((bsdfData.ior - 1.0) / 1.5).xxx;
break;
}
}

if (bsdfData.iridescenceMask > 0.0)
{
bsdfData.fresnel0 = lerp(bsdfData.fresnel0, EvalIridescence(topIor, viewAngle, bsdfData), bsdfData.iridescenceMask);
bsdfData.fresnel0 = lerp(bsdfData.fresnel0, EvalIridescence(topIor, viewAngle, bsdfData.iridescenceThickness, bsdfData.fresnel0), bsdfData.iridescenceMask);
}
}

float NdotV = ClampNdotV(preLightData.NdotV);
float3 F = F_Schlick(bsdfData.fresnel0, LdotH);
// Note: Here we are suppose to call EvalIridescence with LdotH
// This is to expensive for our need, so instead we use the NdotV
// Moreover, the bsdfData.fresnel0 here already contain the evaluation of F_Schlick
// in the context of iridescence, so if iridescence is enabled, don't apply schlick a second time
// Remark: Fresnel must be use with LdotH angle. But Fresnel for iridescence is expensive to compute at each light.
// Instead we use the incorrect angle NdotV as an approximation for LdotH for Fresnel evaluation.
// The Fresnel with iridescence and NDotV angle is precomputed ahead and here we jsut reuse the result.
// Thus why we shouldn't apply a second time Fresnel on the value if iridescence is enabled.
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
{
F = lerp(F, bsdfData.fresnel0, bsdfData.iridescenceMask);

float intensity = max(0, attenuation * NdotL); // Warning: attenuation can be greater than 1 due to the inverse square attenuation (when position is close to light)
// Note: We use NdotL here to early out, but in case of clear coat this is not correct. But we are ok with this
[branch] if (intensity > 0.0)
UNITY_BRANCH if (intensity > 0.0)
{
BSDF(V, L, NdotL, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);

[branch] if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
UNITY_BRANCH if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, NdotL, ClampNdotV(preLightData.NdotV), attenuation * lightData.diffuseScale);

float intensity = max(0, attenuation * NdotL); // Warning: attenuation can be greater than 1 due to the inverse square attenuation (when position is close to light)
// Note: We use NdotL here to early out, but in case of clear coat this is not correct. But we are ok with this
[branch] if (intensity > 0.0)
UNITY_BRANCH if (intensity > 0.0)
{
// Simulate a sphere light with this hack
// Note that it is not correct with our pre-computation of PartLambdaV (mean if we disable the optimization we will not have the

lighting.specular *= intensity * lightData.specularScale;
}
[branch] if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
UNITY_BRANCH if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, NdotL, ClampNdotV(preLightData.NdotV), attenuation * lightData.diffuseScale);

// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
[branch] if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
UNITY_BRANCH if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,

// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
[branch] if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
UNITY_BRANCH if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,

13
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.shader


_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessIridescence("Thickness sridescence", Range(0.0, 1.0)) = 1.0
_ThicknessMapIridescence("Thickness Map Iridescence", 2D) = "white" {}
_ThicknessRemapIridescence("Thickness Remap Iridescence", Vector) = (0, 1, 0, 0)
_IridescenceThickness("Iridescence Thickness", Range(0.0, 1.0)) = 1.0
_IridescenceThicknessMap("Iridescence Thickness Map", 2D) = "white" {}
_IridescenceThicknessRemap("Iridescence Thickness Remap", Vector) = (0, 1, 0, 0)
_IridescenceMask("Iridescence Mask", Range(0.0, 1.0)) = 1.0
_IridescenceMaskMap("Iridescence Mask Map", 2D) = "white" {}

// Transparency
[Enum(None, 0, Plane, 1, Sphere, 2)]_RefractionMode("Refraction Mode", Int) = 0
_Ior("Indice Of Refraction", Range(1.0, 2.5)) = 1.0
_Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)
_TransmittanceColorMap("TransmittanceColorMap", 2D) = "white" {}

#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _SUBSURFACE_MASK_MAP
#pragma shader_feature _THICKNESSMAP
#pragma shader_feature _THICKNESSMAP_IRIDESCENCE
#pragma shader_feature _IRIDESCENCE_THICKNESSMAP
#pragma shader_feature _SPECULARCOLORMAP
#pragma shader_feature _TRANSMITTANCECOLORMAP

SubShader
{
// This tags allow to use the shader replacement features
Tags{ "RenderType" = "HDLitShader" }
// Caution: The outline selection in the editor use the vertex shader/hull/domain shader of the first pass declare. So it should not bethe meta pass.
Pass
{

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataDisplacement.hlsl


float planeHeight;
// Perform a POM in each direction and modify appropriate texture coordinate
[branch] if (layerTexCoord.triplanarWeights.x >= 0.001)
UNITY_BRANCH if (layerTexCoord.triplanarWeights.x >= 0.001)
{
ppdParam.uv = layerTexCoord.base.uvZY;
float3 viewDirTS = float3(uvZY, abs(V.x));

NdotV += layerTexCoord.triplanarWeights.x * viewDirTS.z;
}
[branch] if (layerTexCoord.triplanarWeights.y >= 0.001)
UNITY_BRANCH if (layerTexCoord.triplanarWeights.y >= 0.001)
{
ppdParam.uv = layerTexCoord.base.uvXZ;
float3 viewDirTS = float3(uvXZ, abs(V.y));

NdotV += layerTexCoord.triplanarWeights.y * viewDirTS.z;
}
[branch] if (layerTexCoord.triplanarWeights.z >= 0.001)
UNITY_BRANCH if (layerTexCoord.triplanarWeights.z >= 0.001)
{
ppdParam.uv = layerTexCoord.base.uvXY;
float3 viewDirTS = float3(uvXY, abs(V.z));

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataIndividualLayer.hlsl


#endif
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
#ifdef _THICKNESSMAP_IRIDESCENCE
surfaceData.thicknessIridescence = SAMPLE_UVMAPPING_TEXTURE2D(_ThicknessMapIridescence, sampler_ThicknessMapIridescence, layerTexCoord.base).r;
surfaceData.thicknessIridescence = _ThicknessRemapIridescence.x + _ThicknessRemapIridescence.y * surfaceData.thicknessIridescence;
#ifdef _IRIDESCENCE_THICKNESSMAP
surfaceData.iridescenceThickness = SAMPLE_UVMAPPING_TEXTURE2D(_IridescenceThicknessMap, sampler_IridescenceThicknessMap, layerTexCoord.base).r;
surfaceData.iridescenceThickness = _IridescenceThicknessRemap.x + _IridescenceThicknessRemap.y * surfaceData.iridescenceThickness;
surfaceData.thicknessIridescence = _ThicknessIridescence;
surfaceData.iridescenceThickness = _IridescenceThickness;
surfaceData.thicknessIridescence = 0.0;
surfaceData.iridescenceThickness = 0.0;
surfaceData.iridescenceMask = 0.0;
#endif

surfaceData.tangentWS = float3(0.0, 0.0, 0.0);
surfaceData.anisotropy = 0.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
surfaceData.thicknessIridescence = 0.0;
surfaceData.iridescenceThickness = 0.0;
surfaceData.iridescenceMask = 0.0;
surfaceData.coatMask = 0.0;

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitProperties.hlsl


TEXTURE2D(_ThicknessMap);
SAMPLER(sampler_ThicknessMap);
TEXTURE2D(_ThicknessMapIridescence);
SAMPLER(sampler_ThicknessMapIridescence);
TEXTURE2D(_IridescenceThicknessMap);
SAMPLER(sampler_IridescenceThicknessMap);
TEXTURE2D(_IridescenceMaskMap);
SAMPLER(sampler_IridescenceMaskMap);

float4 _ThicknessRemap;
float _ThicknessIridescence;
float4 _ThicknessRemapIridescence;
float _IridescenceThickness;
float4 _IridescenceThicknessRemap;
float _IridescenceMask;
float _CoatMask;

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitTessellation.shader


_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessIridescence("Thickness sridescence", Range(0.0, 1.0)) = 1.0
_ThicknessMapIridescence("Thickness Map Iridescence", 2D) = "white" {}
_ThicknessRemapIridescence("Thickness Remap Iridescence", Vector) = (0, 1, 0, 0)
_IridescenceThickness("Iridescence Thickness", Range(0.0, 1.0)) = 1.0
_IridescenceThicknessMap("Iridescence Thickness Map", 2D) = "white" {}
_IridescenceThicknessRemap("Iridescence Thickness Remap", Vector) = (0, 1, 0, 0)
_CoatMask("Coat Mask", Range(0.0, 1.0)) = 0.0
_CoatMaskMap("CoatMaskMap", 2D) = "white" {}

// Transparency
[Enum(None, 0, Plane, 1, Sphere, 2)]_RefractionMode("Refraction Mode", Int) = 0
_Ior("Indice Of Refraction", Range(1.0, 2.5)) = 1.0
_Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)
_TransmittanceColorMap("TransmittanceColorMap", 2D) = "white" {}

#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _SUBSURFACE_MASK_MAP
#pragma shader_feature _THICKNESSMAP
#pragma shader_feature _THICKNESSMAP_IRIDESCENCE
#pragma shader_feature _IRIDESCENCE_THICKNESSMAP
#pragma shader_feature _SPECULARCOLORMAP
#pragma shader_feature _TRANSMITTANCECOLORMAP

SubShader
{
// This tags allow to use the shader replacement features
Tags{ "RenderType" = "HDLitShader" }
// Caution: The outline selection in the editor use the vertex shader/hull/domain shader of the first pass declare. So it should not bethe meta pass.
Pass
{

22
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.compute


int2 cacheCoord = pixelCoord - cacheOffset;
bool isInCache = max((uint)cacheCoord.x, (uint)cacheCoord.y) < TEXTURE_CACHE_SIZE_1D;
[branch] if (isInCache)
UNITY_BRANCH if (isInCache)
{
return LoadSampleFromCacheMemory(cacheCoord);
}

uint2 pixelCoord = groupOffset + groupCoord;
int2 cacheOffset = (int2)groupOffset - TEXTURE_CACHE_BORDER;
[branch] if (groupThreadId == 0)
UNITY_BRANCH if (groupThreadId == 0)
{
float stencilRef = STENCILLIGHTINGUSAGE_SPLIT_LIGHTING;

// Wait for the LDS.
GroupMemoryBarrierWithGroupSync();
[branch] if (!processGroup) { return; }
UNITY_BRANCH if (!processGroup) { return; }
float3 centerIrradiance = LOAD_TEXTURE2D(_IrradianceSource, pixelCoord).rgb;
float centerDepth = 0;

// Save some bandwidth by only loading depth values for SSS pixels.
[branch] if (passedStencilTest)
UNITY_BRANCH if (passedStencilTest)
{
centerDepth = LOAD_TEXTURE2D(_DepthTexture, pixelCoord).r;
centerViewZ = LinearEyeDepth(centerDepth, _ZBufferParams);

uint numBorderQuadsPerWave = TEXTURE_CACHE_SIZE_1D / 2 - 1;
uint halfCacheWidthInQuads = TEXTURE_CACHE_SIZE_1D / 4;
[branch] if (quadIndex < numBorderQuadsPerWave)
UNITY_BRANCH if (quadIndex < numBorderQuadsPerWave)
{
// Fetch another texel into the LDS.
uint2 startQuad = halfCacheWidthInQuads * DeinterleaveQuad(waveIndex);

float viewZ2 = 0;
// Save some bandwidth by only loading depth values for SSS pixels.
[branch] if (TestLightingForSSS(irradiance2))
UNITY_BRANCH if (TestLightingForSSS(irradiance2))
{
viewZ2 = LinearEyeDepth(LOAD_TEXTURE2D(_DepthTexture, pixelCoord2).r, _ZBufferParams);
}

GroupMemoryBarrierWithGroupSync();
#endif
[branch] if (!passedStencilTest) { return; }
UNITY_BRANCH if (!passedStencilTest) { return; }
PositionInputs posInput = GetPositionInput(pixelCoord, _ScreenSize.zw);

uint texturingMode = GetSubsurfaceScatteringTexturingMode(profileID);
float3 albedo = ApplySubsurfaceScatteringTexturingMode(texturingMode, sssData.diffuseColor);
[branch] if (distScale == 0 || maxDistInPixels < 1)
UNITY_BRANCH if (distScale == 0 || maxDistInPixels < 1)
{
#if SSS_DEBUG_LOD
StoreResult(pixelCoord, float3(0, 0, 1));

int i, n; // Declare once to avoid the warning from the Unity shader compiler.
[unroll]
UNITY_UNROLL
for (i = 1, n = SSS_N_SAMPLES_FAR_FIELD; i < n; i++)
{
// Integrate over the image or tangent plane in the view space.

totalIrradiance, totalWeight);
}
[branch] if (!useNearFieldKernel)
UNITY_BRANCH if (!useNearFieldKernel)
[unroll]
UNITY_UNROLL
for (i = SSS_N_SAMPLES_FAR_FIELD, n = SSS_N_SAMPLES_NEAR_FIELD; i < n; i++)
{
// Integrate over the image or tangent plane in the view space.

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.shader


// We use the value of 1 instead of 0.5 as an optimization.
float maxDistInPixels = maxDistance * max(pixelsPerCm.x, pixelsPerCm.y);
[branch]
UNITY_BRANCH
if (distScale == 0 || maxDistInPixels < 1)
{
#if SSS_DEBUG_LOD

float3 totalIrradiance = sampleWeight * sampleIrradiance;
float3 totalWeight = sampleWeight;
[unroll]
UNITY_UNROLL
for (int i = 1; i < SSS_BASIC_N_SAMPLES; i++)
{
samplePosition = posInput.positionSS + rotatedDirection * _FilterKernelsBasic[profileID][i].a;

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Unlit/Unlit.shader


SubShader
{
// This tags allow to use the shader replacement features
Tags{ "RenderType" = "HDUnlitShader" }
// Caution: The outline selection in the editor use the vertex shader/hull/domain shader of the first pass declare. So it should not be the meta pass.
Pass

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset


type: 3}
skyboxCubemap: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
encodeBC6HCS: {fileID: 7200000, guid: aa922d239de60304f964e24488559eeb, type: 3}
cubeToPanoShader: {fileID: 4800000, guid: 595434cc3b6405246b6cd3086d0b6f7d, type: 3}
blitCubeTextureFace: {fileID: 4800000, guid: d850d0a2481878d4bbf17e5126b04163, type: 3}
shadowClearShader: {fileID: 4800000, guid: e3cab24f27741f44d8af1e94d006267c, type: 3}
shadowBlurMoments: {fileID: 7200000, guid: fb36979473602464fa32deacb9630c08, type: 3}
debugShadowMapShader: {fileID: 4800000, guid: ee25e539f5594f44085e0a9000c15d9b,
type: 3}

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipelineResources/RenderPipelineResources.cs


public Shader skyboxCubemap;
// Utilities
// Utilities / Core
public Shader cubeToPanoShader;
public Shader blitCubeTextureFace;
// Shadow
public Shader shadowClearShader;
public ComputeShader shadowBlurMoments;
public Shader debugShadowMapShader;
}
}

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyManager.cs


bool m_NeedUpdateRealtimeEnv = false;
bool m_NeedUpdateBakingSky = true;
#if UNITY_EDITOR
// For Preview windows we want to have a 'fixed' sky, so we can display chrome metal and have always the same look
ProceduralSky m_DefaultPreviewSky;
#endif
// This is the sky used for rendering in the main view. It will also be used for lighting if no lighting override sky is setup.
// Ambient Probe: Only for real time GI (otherwise we use the baked one)
// Reflection Probe : Always used and updated depending on the OnChanged/Realtime flags.

void UpdateCurrentSkySettings(HDCamera camera)
{
m_VisualSky.skySettings = GetSkySetting(VolumeManager.instance.stack);
#if UNITY_EDITOR
if (camera.camera.cameraType == CameraType.Preview)
{
m_VisualSky.skySettings = m_DefaultPreviewSky;
}
#endif
m_BakingSky.skySettings = SkyManager.GetBakingSkySettings();
// Update needs to happen before testing if the component is active other internal data structure are not properly updated yet.

m_LightingOverrideVolumeStack = VolumeManager.instance.CreateStack();
m_LightingOverrideLayerMask = hdAsset.renderPipelineSettings.lightLoopSettings.skyLightingOverrideLayerMask;
#if UNITY_EDITOR
m_DefaultPreviewSky = ScriptableObject.CreateInstance<ProceduralSky>();
#endif
}
public void Cleanup()

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyRenderingContext.cs


return result;
}
public void RenderSky(SkyUpdateContext skyContext, HDCamera camera, Light sunLight, RTHandle colorBuffer, RTHandle depthBuffer, CommandBuffer cmd)
public void RenderSky(SkyUpdateContext skyContext, HDCamera hdCamera, Light sunLight, RTHandle colorBuffer, RTHandle depthBuffer, CommandBuffer cmd)
if (skyContext.IsValid())
if (skyContext.IsValid() && hdCamera.clearColorMode == HDAdditionalCameraData.ClearColorMode.Sky)
m_BuiltinParameters.pixelCoordToViewDirMatrix = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(camera.camera.fieldOfView * Mathf.Deg2Rad, camera.screenSize, camera.viewMatrix, false);
m_BuiltinParameters.invViewProjMatrix = camera.viewProjMatrix.inverse;
m_BuiltinParameters.screenSize = camera.screenSize;
m_BuiltinParameters.cameraPosWS = camera.camera.transform.position;
m_BuiltinParameters.pixelCoordToViewDirMatrix = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(hdCamera.camera.fieldOfView * Mathf.Deg2Rad, hdCamera.screenSize, hdCamera.viewMatrix, false);
m_BuiltinParameters.invViewProjMatrix = hdCamera.viewProjMatrix.inverse;
m_BuiltinParameters.screenSize = hdCamera.screenSize;
m_BuiltinParameters.cameraPosWS = hdCamera.camera.transform.position;
m_BuiltinParameters.hdCamera = camera;
m_BuiltinParameters.hdCamera = hdCamera;
skyContext.renderer.SetRenderTargets(m_BuiltinParameters);
skyContext.renderer.RenderSky(m_BuiltinParameters, false);

4
ScriptableRenderPipeline/HDRenderPipeline/package.json


{
"name": "com.unity.render-pipelines.high-definition",
"description": "HD Render Pipeline for Unity.",
"version": "0.1.29",
"version": "0.1.32",
"com.unity.render-pipelines.core": "0.1.29"
"com.unity.render-pipelines.core": "0.1.32"
}
}

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/LightweightLightEditor.cs


ShadowsGUI();
/* Tim: Disable cookie for v1 to save on shader combinations
using (var group = new EditorGUILayout.FadeGroupScope(animShowRuntimeOptions.faded))
if (group.visible)
DrawCookie();

if (group.visible)
DrawCookieSize();
*/
settings.DrawRenderMode();
settings.DrawCullingMask();

4
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGUI/LightweightShaderGUI.cs


material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = -1;
material.SetShaderPassEnabled("ShadowCaster", true);
break;
case BlendMode.Cutout:
material.SetOverrideTag("RenderType", "TransparentCutout");

material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
material.SetShaderPassEnabled("ShadowCaster", true);
break;
case BlendMode.Fade:
material.SetOverrideTag("RenderType", "Transparent");

material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
case BlendMode.Transparent:
material.SetOverrideTag("RenderType", "Transparent");

material.DisableKeyword("_ALPHABLEND_ON");
material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetShaderPassEnabled("ShadowCaster", false);
break;
}
}

34
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


bool shadows = ShadowPass(visibleLights, ref context, ref lightData);
FrameRenderingConfiguration frameRenderingConfiguration;
SetupFrameRenderingConfiguration(out frameRenderingConfiguration, shadows, stereoEnabled);
SetupFrameRenderingConfiguration(out frameRenderingConfiguration, shadows, stereoEnabled, sceneViewCamera);
SetupIntermediateResources(frameRenderingConfiguration, ref context);
// SetupCameraProperties does the following:

ShadowCollectPass(visibleLights, ref context, ref lightData);
}
if (!shadows)
{
var setRT = CommandBufferPool.Get("Generate Small Shadow Buffer");
setRT.GetTemporaryRT(m_ScreenSpaceShadowMapRTID, 4, 4, 0, FilterMode.Bilinear, RenderTextureFormat.R8);
setRT.Blit(Texture2D.whiteTexture, m_ScreenSpaceShadowMapRT);
context.ExecuteCommandBuffer(setRT);
}
#if UNITY_EDITOR
if (sceneViewCamera)
CopyTexture(cmd, CameraRenderTargetID.depth, BuiltinRenderTextureType.CameraTarget, m_CopyDepthMaterial, true);
#endif
cmd.ReleaseTemporaryRT(m_ShadowMapRTID);
cmd.ReleaseTemporaryRT(m_ScreenSpaceShadowMapRTID);
cmd.ReleaseTemporaryRT(CameraRenderTargetID.depthCopy);

// There's no way to map shadow light indices. We need to pass in the original unsorted index.
// If no additional lights then no light sorting is performed and the indices match.
int shadowOriginalIndex = (lightData.totalAdditionalLightsCount > 0) ? GetLightUnsortedIndex(lightData.mainLightIndex) : lightData.mainLightIndex;
bool shadowsRendered = RenderShadows(ref m_CullResults, ref mainLight,
shadowOriginalIndex, ref context);
bool shadowsRendered = RenderShadows(ref m_CullResults, ref mainLight, shadowOriginalIndex, ref context);
if (shadowsRendered)
{
lightData.shadowMapSampleType = (m_Asset.ShadowSetting != ShadowType.SOFT_SHADOWS)

}
}
private void SetupFrameRenderingConfiguration(out FrameRenderingConfiguration configuration, bool shadows, bool stereoEnabled)
private void SetupFrameRenderingConfiguration(out FrameRenderingConfiguration configuration, bool shadows, bool stereoEnabled, bool sceneViewCamera)
{
configuration = (stereoEnabled) ? FrameRenderingConfiguration.Stereo : FrameRenderingConfiguration.None;
if (stereoEnabled && XRSettings.eyeTextureDesc.dimension == TextureDimension.Tex2DArray)

m_RequireCopyColor = true;
}
}
if (sceneViewCamera)
m_RequireDepthTexture = true;
if (shadows)
{

int vertexLightsCount = lightData.totalAdditionalLightsCount - lightData.pixelAdditionalLightsCount;
int mainLightIndex = lightData.mainLightIndex;
//TIM: Not used in shader for V1 to reduce keywords
//TIM: Not used in shader for V1 to reduce keywords
//TIM: Not used in shader for V1 to reduce keywords
//TIM: Not used in shader for V1 to reduce keywords
CoreUtils.SetKeyword(cmd, "_ADDITIONAL_LIGHTS", lightData.totalAdditionalLightsCount > 0);
CoreUtils.SetKeyword(cmd, "_MIXED_LIGHTING_SUBTRACTIVE", m_MixedLightingSetup == MixedLightingSetup.Subtractive);
CoreUtils.SetKeyword(cmd, "_VERTEX_LIGHTS", vertexLightsCount > 0);

}
}
private void CopyTexture(CommandBuffer cmd, RenderTargetIdentifier sourceRT, RenderTargetIdentifier destRT, Material copyMaterial)
private void CopyTexture(CommandBuffer cmd, RenderTargetIdentifier sourceRT, RenderTargetIdentifier destRT, Material copyMaterial, bool forceBlit = false)
if (m_CopyTextureSupport != CopyTextureSupport.None)
if (m_CopyTextureSupport != CopyTextureSupport.None && !forceBlit)
cmd.CopyTexture(sourceRT, destRT);
else
cmd.Blit(sourceRT, destRT, copyMaterial);

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineUtils.cs


DepthPrePass = (1 << 4),
DepthCopy = (1 << 5),
DefaultViewport = (1 << 6),
IntermediateTexture = (1 << 7),
IntermediateTexture = (1 << 7)
}
public static class LightweightUtils

16
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl


half4 GetMainLightDirectionAndAttenuation(LightInput lightInput, float3 positionWS)
{
half4 directionAndAttenuation;
#if defined(_MAIN_LIGHT_DIRECTIONAL)
directionAndAttenuation = half4(lightInput.position.xyz, 1.0);
#else
directionAndAttenuation = GetLightDirectionAndAttenuation(lightInput, positionWS);
#endif
half4 directionAndAttenuation = lerp(half4(lightInput.position.xyz, 1.0), GetLightDirectionAndAttenuation(lightInput, positionWS), lightInput.position.w);
// Cookies are only computed for main light
directionAndAttenuation.w *= CookieAttenuation(positionWS);

void MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout half3 bakedGI, half4 shadowMask)
{
#if defined(_MAIN_LIGHT_DIRECTIONAL) && defined(_MIXED_LIGHTING_SUBTRACTIVE) && defined(LIGHTMAP_ON) && defined(_SHADOWS_ENABLED)
bakedGI = SubtractDirectMainLightFromLightmap(light, normalWS, bakedGI);
#if defined(_MIXED_LIGHTING_SUBTRACTIVE) && defined(LIGHTMAP_ON) && defined(_SHADOWS_ENABLED)
bakedGI = lerp(SubtractDirectMainLightFromLightmap(light, normalWS, bakedGI), bakedGI, _MainLightPosition.w);
#endif
#if defined(LIGHTMAP_ON)

Light mainLight = GetMainLight(inputData.positionWS);
#ifdef _SHADOWS_ENABLED
#endif
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);

half4 LightweightFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half shininess, half3 emission, half alpha)
{
Light mainLight = GetMainLight(inputData.positionWS);
#ifdef _SHADOWS_ENABLED
#endif
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 attenuatedLightColor = mainLight.color * mainLight.attenuation;

31
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl


half3 viewDir : TEXCOORD6;
half4 fogFactorAndVertexLight : TEXCOORD7; // x: fogFactor, yzw: vertex light
#ifdef _SHADOWS_ENABLED
#endif
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID

inputData.viewDirectionWS = normalize(IN.viewDir);
#endif
#ifdef _SHADOWS_ENABLED
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = IN.fogFactorAndVertexLight.x;
inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;

half3 vertexLight = VertexLighting(o.posWS, o.normal);
half fogFactor = ComputeFogFactor(o.clipPos.z);
o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#ifdef _SHADOWS_ENABLED
o.shadowCoord = ComputeScreenPos(o.clipPos);
#endif
o.shadowCoord = ComputeShadowCoord(o.clipPos);
return o;
}

return color;
}
// Used for Standard shader
half4 LitPassFragmentNull(LightweightVertexOutput IN) : SV_Target
{
LitPassFragment(IN);
return 0;
}
// Used for StandardSimpleLighting shader
half4 LitPassFragmentSimple(LightweightVertexOutput IN) : SV_Target
{

half4 diffuseAlpha = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
half3 diffuse = diffuseAlpha.rgb * _Color.rgb;
#ifdef _GLOSSINESS_FROM_BASE_ALPHA
half alpha = _Color.a;
#else
#endif
AlphaDiscard(alpha, _Cutoff);
#ifdef _NORMALMAP

return LightweightFragmentBlinnPhong(inputData, diffuse, specularGloss, shininess, emission, alpha);
};
// Used for StandardSimpleLighting shader
half4 LitPassFragmentSimpleNull(LightweightVertexOutput IN) : SV_Target
{
half4 result = LitPassFragmentSimple(IN);
return result.a;
}
#endif

31
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassShadow.hlsl


#ifndef LIGHTWEIGHT_PASS_SHADOW_INCLUDED
#define LIGHTWEIGHT_PASS_SHADOW_INCLUDED
#include "LWRP/ShaderLibrary/Core.hlsl"
#include "LWRP/ShaderLibrary/LightweightPassLit.hlsl"
struct VertexInput
{
float4 position : POSITION;
float3 normal : NORMAL;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
float4 ShadowPassVertex(VertexInput v) : SV_POSITION
LightweightVertexOutput ShadowPassVertex(LightweightVertexInput v)
UNITY_SETUP_INSTANCE_ID(v);
LightweightVertexOutput o = LitPassVertex(v);
float3 positionWS = TransformObjectToWorld(v.position.xyz);
float3 normalWS = TransformObjectToWorldDir(v.normal);
float invNdotL = 1.0 - saturate(dot(_LightDirection, normalWS));
float invNdotL = 1.0 - saturate(dot(_LightDirection, o.normal));
positionWS = normalWS * scale.xxx + positionWS;
float4 clipPos = TransformWorldToHClip(positionWS);
o.posWS = o.normal * scale.xxx + o.posWS;
float4 clipPos = TransformWorldToHClip(o.posWS);
// _ShadowBias.x sign depens on if platform has reversed z buffer
clipPos.z += _ShadowBias.x;

#else
clipPos.z = max(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
#endif
return clipPos;
}
half4 ShadowPassFragment() : SV_TARGET
{
return 0;
o.clipPos = clipPos;
return o;
#endif

15
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl


inline half SampleScreenSpaceShadowMap(float4 shadowCoord)
{
shadowCoord.xy = shadowCoord.xy / shadowCoord.w;
shadowCoord.xy /= shadowCoord.w;
half attenuation = SAMPLE_TEXTURE2D(_ScreenSpaceShadowMap, sampler_ScreenSpaceShadowMap, shadowCoord.xy).x;
// Apply shadow strength

inline real SampleShadowmap(float4 shadowCoord)
{
shadowCoord.xyz = shadowCoord.xyz /= shadowCoord.w;
shadowCoord.xyz /= shadowCoord.w;
real attenuation;

return 4 - dot(weights, half4(4, 3, 2, 1));
}
float4 ComputeShadowCoord(float3 positionWS)
float4 ComputeScreenSpaceShadowCoords(float3 positionWS)
#ifdef _SHADOWS_CASCADE
#ifdef _SHADOWS_CASCADE
#else
return mul(_WorldToShadow[0], float4(positionWS, 1.0));
}
return mul(_WorldToShadow[0], float4(positionWS, 1.0));
float4 ComputeShadowCoord(float4 clipPos)
{
return ComputeScreenPos(clipPos);
}
half RealtimeShadowAttenuation(float4 shadowCoord)

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightCopyDepth.shader


Pass
{
ZTest Always ZWrite Off ColorMask 0
ZTest Always ZWrite On ColorMask 0
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library

8
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader


float3 wpos = mul(unity_CameraToWorld, float4(vpos, 1)).xyz;
//Fetch shadow coordinates for cascade.
float4 coords = ComputeShadowCoord(wpos);
float4 coords = ComputeScreenSpaceShadowCoords(wpos);
return SampleShadowmap(coords);
}

Pass
{
ZTest Always ZWrite Off
{
ZTest Always
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma multi_compile _ _SHADOWS_SOFT

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存