Evgenii Golubev 6 年前
当前提交
1f059c6b
共有 1622 个文件被更改,包括 1837 次插入768 次删除
  1. 7
      .gitignore
  2. 3
      .gitmodules
  3. 4
      ImageTemplates/FailStamp.png.meta
  4. 4
      ImageTemplates/LightweightPipeline/Scenes/001_SimpleCube.unity.png.meta
  5. 4
      ImageTemplates/LightweightPipeline/Scenes/002_Camera_Clip.unity.png.meta
  6. 4
      ImageTemplates/LightweightPipeline/Scenes/003_Camera_Ortho.unity.png.meta
  7. 4
      ImageTemplates/LightweightPipeline/Scenes/004_Camera_TargetTexture.unity.png.meta
  8. 4
      ImageTemplates/LightweightPipeline/Scenes/005_LitBakedEmission.unity.png.meta
  9. 4
      ImageTemplates/LightweightPipeline/Scenes/006_LitShaderLightProbes.unity.png.meta
  10. 4
      ImageTemplates/LightweightPipeline/Scenes/007_LitShaderMaps.unity.png.meta
  11. 4
      ImageTemplates/LightweightPipeline/Scenes/008_LitShaderReflection.unity.png.meta
  12. 4
      ImageTemplates/LightweightPipeline/Scenes/009_LightweightShading.unity.png.meta
  13. 4
      ImageTemplates/LightweightPipeline/Scenes/010_MultiplePointLights.unity.png.meta
  14. 4
      ImageTemplates/LightweightPipeline/Scenes/011_UnlitSprites.unity.png.meta
  15. 4
      ImageTemplates/LightweightPipeline/Scenes/012_PBS_EnvironmentBRDF_Spheres.unity.png.meta
  16. 4
      ImageTemplates/LightweightPipeline/Scenes/016_Lighting_Scene_Directional.unity.png.meta
  17. 4
      ImageTemplates/LightweightPipeline/Scenes/017_Lighting_Scene_DirectionalBaked.unity.png.meta
  18. 4
      ImageTemplates/LightweightPipeline/Scenes/018_Lighting_Scene_DirectionalBakedIndirect.unity.png.meta
  19. 4
      ImageTemplates/LightweightPipeline/Scenes/019_Lighting_Scene_PointLights.unity.png.meta
  20. 4
      ImageTemplates/LightweightPipeline/Scenes/020_Lighting_BasicDirectional.unity.png.meta
  21. 4
      ImageTemplates/LightweightPipeline/Scenes/021_Lighting_BasicPoint.unity.png.meta
  22. 4
      ImageTemplates/LightweightPipeline/Scenes/022_Lighting_BasicSpot.unity.png.meta
  23. 4
      ImageTemplates/LightweightPipeline/Scenes/023_Lighting_Mixed.unity.png.meta
  24. 4
      ImageTemplates/LightweightPipeline/Scenes/024_Shader_PBRvalidation_Specular.unity.png.meta
  25. 4
      ImageTemplates/LightweightPipeline/Scenes/025_Shader_PBRvalidation_Metallic.unity.png.meta
  26. 4
      ImageTemplates/LightweightPipeline/Scenes/026_Shader_PBRscene.unity.png.meta
  27. 4
      ImageTemplates/LightweightPipeline/Scenes/027_PostProcessing.unity.png.meta
  28. 4
      ImageTemplates/LightweightPipeline/Scenes/028_PostProcessing_Custom.unity.png.meta
  29. 4
      ImageTemplates/LightweightPipeline/Scenes/029_Particles.unity.png.meta
  30. 4
      ImageTemplates/LightweightPipeline/Scenes/031_Shader_GlossyEnvironmentSky.unity.png.meta
  31. 4
      ImageTemplates/LightweightPipeline/Scenes/032_Shader_GlossyEnvironmentColor.unity.png.meta
  32. 4
      ImageTemplates/LightweightPipeline/Scenes/033_Shader_HighlightsEnvironmentGradientSH.unity.png.meta
  33. 4
      ImageTemplates/LightweightPipeline/Scenes/034_Shader_HighlightsEnvironmentGradientBaked.unity.png.meta
  34. 4
      ImageTemplates/LightweightPipeline/Scenes/035_Shader_TerrainShaders.unity.png.meta
  35. 4
      ImageTemplates/LightweightPipeline/Scenes/036_Lighting_Scene_DirectionalBakedDirectional.unity.png.meta
  36. 4
      ImageTemplates/LightweightPipeline/Scenes/037_Particles.unity.png.meta
  37. 4
      ImageTemplates/LightweightPipeline/Scenes/038_Lighting_DirectionalCookie.unity.png.meta
  38. 4
      ImageTemplates/LightweightPipeline/Scenes/039_Lighting_SpotCookie.unity.png.meta
  39. 4
      ImageTemplates/LightweightPipeline/Scenes/040_UpgradeScene.unity.png.meta
  40. 4
      ImageTemplates/LightweightPipeline/Scenes/041_Lighting_BasicArea.unity.png.meta
  41. 4
      ImageTemplates/LightweightPipeline/Scenes/042_Lighting_Scene_VertexLighting.unity.png.meta
  42. 4
      ImageTemplates/LightweightPipeline/Scenes/043_Lighting_Mixed_ShadowMask.unity.png.meta
  43. 4
      ImageTemplates/LightweightPipeline/Scenes/044_ReflectionProbe.unity.png.meta
  44. 5
      ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugManager.cs
  45. 1
      ScriptableRenderPipeline/Core/CoreRP/Editor/CoreEditorDrawers.cs
  46. 17
      ScriptableRenderPipeline/Core/CoreRP/Editor/Debugging/DebugWindow.cs
  47. 2
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/GeometricTools.hlsl
  48. 35
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/UnityInstancing.hlsl
  49. 7
      ScriptableRenderPipeline/Core/CoreRP/Shadow/Shadow.cs
  50. 2
      ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandleSystem.RTHandle.cs
  51. 14
      ScriptableRenderPipeline/HDRenderPipeline/CHANGELOG.md
  52. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDAdditionalCameraData.cs
  53. 21
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  54. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs
  55. 21
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs
  56. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/BuildPlayer/HDRPVariantStripper.cs
  57. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraEditor.Handlers.cs
  58. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraEditor.cs
  59. 13
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDLightEditor.cs
  60. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDReflectionProbeUI.Drawers.cs
  61. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Decal/DecalProjectorComponentEditor.cs
  62. 44
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/StackLit/StackLitUI.cs
  63. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/FrameSettingsUI.cs
  64. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/RenderPipelineSettingsUI.cs
  65. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedFrameSettings.cs
  66. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedRenderPipelineSettings.cs
  67. 237
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  68. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.cs
  69. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDUtils.cs
  70. 35
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/GlobalIlluminationUtils.cs
  71. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs
  72. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs.hlsl
  73. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl
  74. 59
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/GlobalLightLoopSettings.cs
  75. 27
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  76. 64
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystemInternal.cs
  77. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/DensityVolumeManager.cs
  78. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.compute
  79. 118
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  80. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DBufferManager.cs
  81. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalData.hlsl
  82. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalUtilities.hlsl
  83. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  84. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs
  85. 111
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs.hlsl
  86. 713
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl
  87. 23
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.shader
  88. 13
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitData.hlsl
  89. 21
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitProperties.hlsl
  90. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs
  91. 30
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/FrameSettings.cs
  92. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/RenderPipelineSettings.cs
  93. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassLightTransport.hlsl
  94. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.cs
  95. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/ExponentialFog.cs
  96. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/LinearFog.cs
  97. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/VolumetricFog.cs
  98. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/SkyManager.cs
  99. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/VisualEnvironment.cs
  100. 573
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs

7
.gitignore


Library/*
obj/*
Temp/*
.vs
.vscode
.idea
.DS_Store
*.aspx
*.browser

*.sublime-workspace
*.suo
*.userprefs
.npmrc
ShaderGraph/DebugOutput.meta
ShaderGraph/DebugOutput/**
ShaderGraph/Testing/IntegrationTests/.Failed

3
.gitmodules


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

4
ImageTemplates/FailStamp.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/001_SimpleCube.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/002_Camera_Clip.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/003_Camera_Ortho.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/004_Camera_TargetTexture.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/005_LitBakedEmission.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/006_LitShaderLightProbes.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/007_LitShaderMaps.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/008_LitShaderReflection.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/009_LightweightShading.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/010_MultiplePointLights.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/011_UnlitSprites.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/012_PBS_EnvironmentBRDF_Spheres.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/016_Lighting_Scene_Directional.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/017_Lighting_Scene_DirectionalBaked.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/018_Lighting_Scene_DirectionalBakedIndirect.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/019_Lighting_Scene_PointLights.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/020_Lighting_BasicDirectional.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/021_Lighting_BasicPoint.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/022_Lighting_BasicSpot.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/023_Lighting_Mixed.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/024_Shader_PBRvalidation_Specular.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/025_Shader_PBRvalidation_Metallic.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/026_Shader_PBRscene.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/027_PostProcessing.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/028_PostProcessing_Custom.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/029_Particles.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/031_Shader_GlossyEnvironmentSky.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/032_Shader_GlossyEnvironmentColor.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/033_Shader_HighlightsEnvironmentGradientSH.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/034_Shader_HighlightsEnvironmentGradientBaked.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/035_Shader_TerrainShaders.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/036_Lighting_Scene_DirectionalBakedDirectional.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/037_Particles.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/038_Lighting_DirectionalCookie.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/039_Lighting_SpotCookie.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/040_UpgradeScene.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/041_Lighting_BasicArea.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/042_Lighting_Scene_VertexLighting.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/043_Lighting_Mixed_ShadowMask.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

4
ImageTemplates/LightweightPipeline/Scenes/044_ReflectionProbe.unity.png.meta


TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 5
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1

heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0

5
ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugManager.cs


public sealed partial class DebugManager
{
#if UNITY_EDITOR
// HACK: Make debug windows work correctly with FrameSettings in Editor
public static bool renderPipelineIsRecreated = false;
#endif
static readonly DebugManager s_Instance = new DebugManager();
public static DebugManager instance { get { return s_Instance; } }

1
ScriptableRenderPipeline/Core/CoreRP/Editor/CoreEditorDrawers.cs


AnimBoolGetter m_IsExpanded;
string m_Title;
FoldoutOption m_Options;
bool m_Animate;
bool animate { get { return (m_Options & FoldoutOption.Animate) != 0; } }
bool indent { get { return (m_Options & FoldoutOption.Indent) != 0; } }

17
ScriptableRenderPipeline/Core/CoreRP/Editor/Debugging/DebugWindow.cs


DebugManager.instance.onSetDirty -= MarkDirty;
Undo.ClearUndo(m_Settings);
DestroyWidgetStates();
}
public void DestroyWidgetStates()
{
if (m_WidgetStates != null)
{
// Clear all the states from memory

void Update()
{
// HACK: Make debug windows work correctly with FrameSettings in Editor
// When we manipulate the framesettings on HDRenderPipelineAsset, the debug windows is not
// refresh, it keep the old state of the runtime framesettings in memory and thus overwrite
// our freshly edited value. To ensure debug windows is aware of framesettings change we need to
// destroy its internal widget state.
if (DebugManager.renderPipelineIsRecreated)
{
DestroyWidgetStates();
DebugManager.renderPipelineIsRecreated = false;
}
// END HACK
int treeState = DebugManager.instance.GetState();
if (m_DebugTreeState != treeState || m_IsDirty)

2
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/GeometricTools.hlsl


// This simplified version assume that we care about the result only when we are inside the box
float IntersectRayAABBSimple(float3 start, float3 dir, float3 boxMin, float3 boxMax)
{
float3 invDir = 1.0 / dir;
float3 invDir = rcp(dir);
// Find the ray intersection with box plane
float3 rbmin = (boxMin - start) * invDir;

35
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/UnityInstancing.hlsl


#define UNITY_SUPPORT_INSTANCING
#endif
#if defined(SHADER_API_D3D11)
#if defined(SHADER_API_D3D11) || defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES3)
#define UNITY_SUPPORT_STEREO_INSTANCING
#endif

// - UNITY_TRANSFER_VERTEX_OUTPUT_STEREO Copy stero target from input struct to output struct. Used in vertex shader.
// - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX
#ifdef UNITY_STEREO_INSTANCING_ENABLED
#if defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)
#define DEFAULT_UNITY_VERTEX_OUTPUT_STEREO uint stereoTargetEyeIndexSV : SV_RenderTargetArrayIndex; uint stereoTargetEyeIndex : BLENDINDICES0;
#define DEFAULT_UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output) output.stereoTargetEyeIndexSV = unity_StereoEyeIndex; output.stereoTargetEyeIndex = unity_StereoEyeIndex;
#else
#endif
#define DEFAULT_UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(input, output) output.stereoTargetEyeIndex = input.stereoTargetEyeIndex;
#define DEFAULT_UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input) unity_StereoEyeIndex = input.stereoTargetEyeIndex;
#elif defined(UNITY_STEREO_MULTIVIEW_ENABLED)

void UnitySetupInstanceID(uint inputInstanceID)
{
#ifdef UNITY_STEREO_INSTANCING_ENABLED
// stereo eye index is automatically figured out from the instance ID
unity_StereoEyeIndex = inputInstanceID & 0x01;
unity_InstanceID = unity_BaseInstanceID + (inputInstanceID >> 1);
#if defined(SHADER_API_GLES3)
// We must calculate the stereo eye index differently for GLES3
// because otherwise, the unity shader compiler will emit a bitfieldInsert function.
// bitfieldInsert requires support for glsl version 400 or later. Therefore the
// generated glsl code will fail to compile on lower end devices. By changing the
// way we calculate the stereo eye index, we can help the shader compiler to avoid
// emitting the bitfieldInsert function and thereby increase the number of devices we
// can run stereo instancing on.
unity_StereoEyeIndex = round(fmod(inputInstanceID, 2.0));
unity_InstanceID = unity_BaseInstanceID + (inputInstanceID >> 1);
#else
// stereo eye index is automatically figured out from the instance ID
unity_StereoEyeIndex = inputInstanceID & 0x01;
unity_InstanceID = unity_BaseInstanceID + (inputInstanceID >> 1);
#endif
#else
unity_InstanceID = inputInstanceID + unity_BaseInstanceID;
#endif

UNITY_DEFINE_INSTANCED_PROP(float4x4, unity_WorldToObjectArray)
#endif
#if defined(UNITY_USE_LODFADE_ARRAY) && defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE)
UNITY_DEFINE_INSTANCED_PROP(float, unity_LODFadeArray)
// the quantized fade value (unity_LODFade.y) is automatically used for cross-fading instances
#define unity_LODFade UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_LODFadeArray).xxxx
UNITY_DEFINE_INSTANCED_PROP(float2, unity_LODFadeArray)
#define unity_LODFade UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, unity_LODFadeArray).xyxx
#endif
UNITY_INSTANCING_BUFFER_END(unity_Builtins0)

#endif
#if defined(UNITY_USE_LODFADE_ARRAY) && !defined(UNITY_INSTANCING_SUPPORT_FLEXIBLE_ARRAY_SIZE)
UNITY_DEFINE_INSTANCED_PROP(float, unity_LODFadeArray)
// the quantized fade value (unity_LODFade.y) is automatically used for cross-fading instances
#define unity_LODFade UNITY_ACCESS_INSTANCED_PROP(unity_Builtins1, unity_LODFadeArray).xxxx
UNITY_DEFINE_INSTANCED_PROP(float2, unity_LODFadeArray)
#define unity_LODFade UNITY_ACCESS_INSTANCED_PROP(unity_Builtins1, unity_LODFadeArray).xyxx
#endif
UNITY_INSTANCING_BUFFER_END(unity_Builtins1)

7
ScriptableRenderPipeline/Core/CoreRP/Shadow/Shadow.cs


int requestIdx = shadowRequests[i];
VisibleLight vl = lights[requestIdx];
int facecount = 0;
GPUShadowType shadowType = GPUShadowType.Point;
GPUShadowType shadowType = GetShadowLightType( vl.light );
bool add = (distToCam < asd.shadowFadeDistance || vl.lightType == LightType.Directional) && m_ShadowSettings.enabled;
bool add = shadowType != GPUShadowType.Unknown && (distToCam < asd.shadowFadeDistance || vl.lightType == LightType.Directional) && m_ShadowSettings.enabled;
if( add )
{

add = --m_MaxShadows[(int)GPUShadowType.Directional, 0] >= 0;
shadowType = GPUShadowType.Directional;
shadowType = GPUShadowType.Point;
shadowType = GPUShadowType.Spot;
facecount = 1;
break;
}

2
ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandleSystem.RTHandle.cs


{
get
{
if(!useScaling)
if (!useScaling)
{
return m_EnableMSAA ? m_RTs[(int)RTCategory.MSAA] : m_RTs[(int)RTCategory.Regular];
}

14
ScriptableRenderPipeline/HDRenderPipeline/CHANGELOG.md


# Changelog
## [2018.2 undecided]
- Fix issue with LOD transition and instancing
### Improvements
- Add stripper of shader variant when building a player. Save shader compile time.

- Add a better mapping of roughness to mipmap for planar reflection
- The VolumetricLightingSystem now uses RTHandles, which allows to save memory by sharing buffers between different cameras (history buffers are not shared), and reduce reallocation frequency by reallocating buffers only if the rendering resolution increases (and suballocating within existing buffers if the rendering resolution decreases)
- Add a Volumetric Dimmer slider to lights to control the intensity of the scattered volumetric lighting
- Add UV tiling and offset support for decals.
### Changed, Removals and deprecations
- Remove Resource folder of PreIntegratedFGD and add the resource to RenderPipeline Asset

- Update of UI of cookie, CubeCookie, Reflection probe and planar reflection probe to combo box
- Allow enabling/disabling shadows for area lights when they are set to baked.
- Hide applyRangeAttenuation and FadeDistance for directional shadow as they are not used
### Bug fixes
- Fix ConvertPhysicalLightIntensityToLightIntensity() function used when creating light from script to match HDLightEditor behavior

- Fix meta pass with triplanar (was not handling correctly the normal)
- Fix preview when a planar reflection is present
- Fix Camera preview, it is now a Preview cameraType (was a SceneView)
- Fix handling unknown GPUShadowTypes in the shadow manager.
- Fix area light shapes sent as point lights to the baking backends when they are set to baked.
- Fix unnecessary division by PI for baked area lights.
- Fix line lights sent to the lightmappers. The backends don't support this light type.
- Fix issue with shadow mask framesettings not correctly taken into account when shadow mask is enabled for lighting.
- Fix directional light and shadow mask transition, they are now matching making smooth transition
## [2018.1.0f2]

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


public Color backgroundColorHDR = new Color(0.025f, 0.07f, 0.19f, 0.0f);
public bool clearDepth = true;
public RenderingPath renderingPath;
public RenderingPath renderingPath;
public LayerMask volumeLayerMask = -1;
public LayerMask volumeLayerMask = -1;
// Physical parameters
public float aperture = 8f;

// we create a runtime copy (m_ActiveFrameSettings that is used, and any parametrization is done on serialized frameSettings)
[SerializeField]
[FormerlySerializedAs("serializedFrameSettings")]
FrameSettings m_FrameSettings = new FrameSettings(); // Serialize frameSettings
FrameSettings m_FrameSettings = new FrameSettings(); // Serialize frameSettings
// Not serialized, visible only in the debug windows
FrameSettings m_FrameSettingsRuntime = new FrameSettings();

// Use for debug windows
// When camera name change we need to update the name in DebugWindows.
// This is the purpose of this class
bool m_IsDebugRegistered = false;
string m_CameraRegisterName;
bool m_IsDebugRegistered = false;
string m_CameraRegisterName;
// When we are a preview, there is no way inside Unity to make a disctinctoin between camera preview and material preview.
// This property allow to say that we are an editor camera preview when the type is preview.
public bool isEditorCameraPreview { get; set; }
// This is the function use outside to access FrameSettings. It return the current state of FrameSettings for the camera
// taking into account the customization via the debug menu

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


Vector2 m_ViewportScalePreviousFrame;
// Current mssa sample
MSAASamples m_msaaSamples;
FrameSettings m_frameSettings;
public int actualWidth { get { return m_ActualWidth; } }
public int actualHeight { get { return m_ActualHeight; } }

public FrameSettings frameSettings { get { return m_frameSettings; } }
public Matrix4x4 viewProjMatrix
{

// Pass all the systems that may want to update per-camera data here.
// That way you will never update an HDCamera and forget to update the dependent system.
public void Update(PostProcessLayer postProcessLayer, FrameSettings frameSettings, VolumetricLightingSystem vlSys)
public void Update(FrameSettings currentFrameSettings, PostProcessLayer postProcessLayer, VolumetricLightingSystem vlSys)
m_frameSettings = currentFrameSettings;
frameSettings.enablePostprocess;
m_frameSettings.enablePostprocess;
var nonJitteredCameraProj = camera.projectionMatrix;
var cameraProj = taaEnabled

var screenWidth = m_ActualWidth;
var screenHeight = m_ActualHeight;
#if !UNITY_SWITCH
if (frameSettings.enableStereo)
if (m_frameSettings.enableStereo)
{
screenWidth = XRSettings.eyeTextureWidth;
screenHeight = XRSettings.eyeTextureHeight;

// Unfortunately sometime (like in the HDCameraEditor) HDUtils.hdrpSettings can be null because of scripts that change the current pipeline...
m_msaaSamples = HDUtils.hdrpSettings != null ? HDUtils.hdrpSettings.msaaSampleCount : MSAASamples.None;
RTHandles.SetReferenceSize(m_ActualWidth, m_ActualHeight, frameSettings.enableMSAA, m_msaaSamples);
m_HistoryRTSystem.SetReferenceSize(m_ActualWidth, m_ActualHeight, frameSettings.enableMSAA, m_msaaSamples);
RTHandles.SetReferenceSize(m_ActualWidth, m_ActualHeight, m_frameSettings.enableMSAA, m_msaaSamples);
m_HistoryRTSystem.SetReferenceSize(m_ActualWidth, m_ActualHeight, m_frameSettings.enableMSAA, m_msaaSamples);
m_HistoryRTSystem.Swap();
int maxWidth = RTHandles.maxWidth;

}
// Stopgap method used to extract stereo combined matrix state.
public void UpdateStereoDependentState(FrameSettings frameSettings, ref ScriptableCullingParameters cullingParams)
public void UpdateStereoDependentState(ref ScriptableCullingParameters cullingParams)
if (!frameSettings.enableStereo)
if (!m_frameSettings.enableStereo)
return;
// What constants in UnityPerPass need updating for stereo considerations?

s_Cleanup.Clear();
}
// Look for any camera that hasn't been used in the last frame and remove them for the pool.
// Look for any camera that hasn't been used in the last frame and remove them from the pool.
public static void CleanUnused()
{
int frameCheck = Time.frameCount - 1;

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs


public Material m_Material = null;
public float m_DrawDistance = 1000.0f;
public float m_FadeScale = 0.9f;
public Vector2 m_UVScale = new Vector2(1,1);
public Vector2 m_UVBias = new Vector2(0,0);
private Material m_OldMaterial = null;
private DecalSystem.DecalHandle m_Handle = null;

if(m_Handle != null)
DecalSystem.instance.RemoveDecal(m_Handle);
m_Handle = DecalSystem.instance.AddDecal(transform, m_DrawDistance, m_FadeScale, m_Material);
Vector4 uvScaleBias = new Vector4(m_UVScale.x, m_UVScale.y, m_UVBias.x, m_UVBias.y);
m_Handle = DecalSystem.instance.AddDecal(transform, m_DrawDistance, m_FadeScale, uvScaleBias, m_Material);
}
public void OnDisable()

{
if( m_Handle != null)
DecalSystem.instance.RemoveDecal(m_Handle);
m_Handle = DecalSystem.instance.AddDecal(transform, m_DrawDistance, m_FadeScale, m_Material);
Vector4 uvScaleBias = new Vector4(m_UVScale.x, m_UVScale.y, m_UVBias.x, m_UVBias.y);
m_Handle = DecalSystem.instance.AddDecal(transform, m_DrawDistance, m_FadeScale, uvScaleBias, m_Material);
m_OldMaterial = m_Material;
// notify the editor that material has changed so it can update the shader foldout

{
if (transform.hasChanged == true)
{
DecalSystem.instance.UpdateCachedData(transform, m_DrawDistance, m_FadeScale, m_Handle);
Vector4 uvScaleBias = new Vector4(m_UVScale.x, m_UVScale.y, m_UVBias.x, m_UVBias.y);
DecalSystem.instance.UpdateCachedData(transform, m_DrawDistance, m_FadeScale, uvScaleBias, m_Handle);
transform.hasChanged = false;
}
}

{
DrawGizmo(true);
// if this object is selected there is a chance the transform was changed so update culling info
DecalSystem.instance.UpdateCachedData(transform, m_DrawDistance, m_FadeScale, m_Handle);
Vector4 uvScaleBias = new Vector4(m_UVScale.x, m_UVScale.y, m_UVBias.x, m_UVBias.y);
DecalSystem.instance.UpdateCachedData(transform, m_DrawDistance, m_FadeScale, uvScaleBias, m_Handle);
}
public void OnDrawGizmos()

21
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs


return res;
}
public void UpdateCachedData(Transform transform, float drawDistance, float fadeScale, DecalHandle handle)
public void UpdateCachedData(Transform transform, float drawDistance, float fadeScale, Vector4 uvScaleBias, DecalHandle handle)
{
int index = handle.m_Index;
m_CachedDecalToWorld[index] = transform.localToWorldMatrix;

? drawDistance
: instance.DrawDistance;
m_CachedDrawDistances[index].y = fadeScale;
m_CachedUVScaleBias[index] = uvScaleBias;
public DecalHandle AddDecal(Transform transform, float drawDistance, float fadeScale, int materialID)
public DecalHandle AddDecal(Transform transform, float drawDistance, float fadeScale, Vector4 uvScaleBias, int materialID)
{
// increase array size if no space left
if (m_DecalsCount == m_Handles.Length)

Matrix4x4[] newCachedTransforms = new Matrix4x4[m_DecalsCount + kDecalBlockSize];
Matrix4x4[] newCachedNormalToWorld = new Matrix4x4[m_DecalsCount + kDecalBlockSize];
Vector2[] newCachedDrawDistances = new Vector2[m_DecalsCount + kDecalBlockSize];
Vector4[] newCachedUVScaleBias = new Vector4[m_DecalsCount + kDecalBlockSize];
m_ResultIndices = new int[m_DecalsCount + kDecalBlockSize];
m_Handles.CopyTo(newHandles, 0);

m_CachedDrawDistances.CopyTo(newCachedDrawDistances, 0);
m_CachedUVScaleBias.CopyTo(newCachedUVScaleBias, 0);
m_Handles = newHandles;
m_BoundingSpheres = newSpheres;

m_CachedUVScaleBias = newCachedUVScaleBias;
UpdateCachedData(transform, drawDistance, fadeScale, decalHandle);
UpdateCachedData(transform, drawDistance, fadeScale, uvScaleBias, decalHandle);
m_DecalsCount++;
return decalHandle;
}

m_CachedDecalToWorld[removeAtIndex] = m_CachedDecalToWorld[m_DecalsCount - 1];
m_CachedNormalToWorld[removeAtIndex] = m_CachedNormalToWorld[m_DecalsCount - 1];
m_CachedDrawDistances[removeAtIndex] = m_CachedDrawDistances[m_DecalsCount - 1];
m_CachedUVScaleBias[removeAtIndex] = m_CachedUVScaleBias[m_DecalsCount - 1];
m_DecalsCount--;
handle.m_Index = kInvalidIndex;
}

normalToWorldBatch[instanceCount] = m_CachedNormalToWorld[decalIndex];
float fadeFactor = Mathf.Clamp((cullDistance - distanceToDecal) / (cullDistance * (1.0f - m_CachedDrawDistances[decalIndex].y)), 0.0f, 1.0f);
normalToWorldBatch[instanceCount].m03 = fadeFactor * m_Blend; // vector3 rotation matrix so bottom row and last column can be used for other data to save space
normalToWorldBatch[instanceCount].SetRow(3, m_CachedUVScaleBias[decalIndex]);
// clustered forward data
m_DecalDatas[m_DecalDatasCount].worldToDecal = decalToWorldBatch[instanceCount].inverse;

private Matrix4x4[] m_CachedDecalToWorld = new Matrix4x4[kDecalBlockSize];
private Matrix4x4[] m_CachedNormalToWorld = new Matrix4x4[kDecalBlockSize];
private Vector2[] m_CachedDrawDistances = new Vector2[kDecalBlockSize]; // x - draw distance, y - fade scale
private Vector4[] m_CachedUVScaleBias = new Vector4[kDecalBlockSize]; // xy - scale, zw bias
private Material m_Material;
private float m_Blend = 0;

}
public DecalHandle AddDecal(Transform transform, float drawDistance, float fadeScale, Material material)
public DecalHandle AddDecal(Transform transform, float drawDistance, float fadeScale, Vector4 uvScaleBias, Material material)
{
DecalSet decalSet = null;
int key = material.GetInstanceID();

m_DecalSets.Add(key, decalSet);
}
return decalSet.AddDecal(transform, drawDistance, fadeScale, key);
return decalSet.AddDecal(transform, drawDistance, fadeScale, uvScaleBias, key);
}
public void RemoveDecal(DecalHandle handle)

}
}
public void UpdateCachedData(Transform transform, float drawDistance, float fadeScale, DecalHandle handle)
public void UpdateCachedData(Transform transform, float drawDistance, float fadeScale, Vector4 uvScaleBias, DecalHandle handle)
{
if(!DecalHandle.IsValid(handle))
return;

if (m_DecalSets.TryGetValue(key, out decalSet))
{
decalSet.UpdateCachedData(transform, drawDistance, fadeScale, handle);
decalSet.UpdateCachedData(transform, drawDistance, fadeScale, uvScaleBias, handle);
}
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/BuildPlayer/HDRPVariantStripper.cs


using System.Collections;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build;
using UnityEditor.Rendering;

ShaderKeyword m_TileLighting;
ShaderKeyword m_ClusterLighting;
ShaderKeyword m_FeatureSSS;
//ShaderKeyword m_FeatureSSS;
public HDRPVariantStripper()
{

m_TileLighting = new ShaderKeyword("USE_FPTL_LIGHTLIST");
m_ClusterLighting = new ShaderKeyword("USE_CLUSTERED_LIGHTLIST");
m_FeatureSSS = new ShaderKeyword("_MATERIAL_FEATURE_SUBSURFACE_SCATTERING");
//m_FeatureSSS = new ShaderKeyword("_MATERIAL_FEATURE_SUBSURFACE_SCATTERING");
}
bool LitShaderStripper(Shader shader, ShaderSnippetData snippet, ShaderCompilerData inputData)

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraEditor.Handlers.cs


EditorUtility.CopySerialized(cameraData, m_PreviewAdditionalCameraData);
var layer = c.GetComponent<PostProcessLayer>() ?? ComponentSingleton<PostProcessLayer>.instance;
EditorUtility.CopySerialized(layer, m_PreviewPostProcessLayer);
m_PreviewCamera.cameraType = CameraType.SceneView; // This is required else if we use Preview the image is flipped... (Unity...)
// We need to call UpdateDirtyFrameSettings to update the dirty flags that was set in the CopySerialized call
m_PreviewAdditionalCameraData.UpdateDirtyFrameSettings(true, cameraData.GetFrameSettings());
// And then to copy the runtime frame settings
// So this includes the runtime frame settings properly
cameraData.GetFrameSettings().CopyTo(m_PreviewAdditionalCameraData.GetFrameSettings());
m_PreviewHDCamera.Update(m_PreviewPostProcessLayer, m_PreviewAdditionalCameraData.GetFrameSettings(), null);
var previewTexture = GetPreviewTextureWithSize((int)previewSize.x, (int)previewSize.y);
m_PreviewCamera.targetTexture = previewTexture;

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraEditor.cs


Camera m_PreviewCamera;
HDAdditionalCameraData m_PreviewAdditionalCameraData;
PostProcessLayer m_PreviewPostProcessLayer;
HDCamera m_PreviewHDCamera;
void OnEnable()
{

m_PreviewCamera.enabled = false;
m_PreviewCamera.cameraType = CameraType.Preview; // Must be init before adding HDAdditionalCameraData
m_PreviewAdditionalCameraData = m_PreviewCamera.gameObject.AddComponent<HDAdditionalCameraData>();
// Say that we are a camera editor preview and not just a regular preview
m_PreviewAdditionalCameraData.isEditorCameraPreview = true;
m_PreviewHDCamera = new HDCamera(m_PreviewCamera);
m_PreviewHDCamera.Update(m_PreviewPostProcessLayer, m_PreviewAdditionalCameraData.GetFrameSettings(), null);
}
void OnDisable()

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


void DrawFeatures()
{
bool disabledScope = settings.isCompletelyBaked
|| m_LightShape == LightShape.Line
|| m_LightShape == LightShape.Rectangle;
bool disabledScope = m_LightShape == LightShape.Line || (m_LightShape == LightShape.Rectangle && settings.isRealtime);
using (new EditorGUI.DisabledScope(disabledScope))
{

m_AdditionalLightData.shapeHeight.floatValue = Mathf.Max(m_AdditionalLightData.shapeHeight.floatValue, k_MinAreaWidth);
settings.areaSizeX.floatValue = m_AdditionalLightData.shapeWidth.floatValue;
settings.areaSizeY.floatValue = m_AdditionalLightData.shapeHeight.floatValue;
settings.shadowsType.enumValueIndex = (int)LightShadows.None;
if (settings.isRealtime)
settings.shadowsType.enumValueIndex = (int)LightShadows.None;
break;
case LightShape.Line:

EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_AdditionalLightData.affectDiffuse, s_Styles.affectDiffuse);
EditorGUILayout.PropertyField(m_AdditionalLightData.affectSpecular, s_Styles.affectSpecular);
EditorGUILayout.PropertyField(m_AdditionalLightData.fadeDistance, s_Styles.fadeDistance);
if (m_LightShape != LightShape.Directional)
EditorGUILayout.PropertyField(m_AdditionalLightData.fadeDistance, s_Styles.fadeDistance);
EditorGUILayout.PropertyField(m_AdditionalLightData.applyRangeAttenuation, s_Styles.applyRangeAttenuation);
if (m_LightShape != LightShape.Directional)
EditorGUILayout.PropertyField(m_AdditionalLightData.applyRangeAttenuation, s_Styles.applyRangeAttenuation);
EditorGUI.indentLevel--;
}

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDReflectionProbeUI.Drawers.cs


public static readonly CED.IDrawer[] Inspector;
public static readonly CED.IDrawer SectionPrimarySettings = CED.Group(
CED.Action(Drawer_ReflectionProbeMode),
CED.FadeGroup((s, p, o, i) => s.IsSectionExpandedMode((ReflectionProbeMode)i),
FadeOption.Indent,

static void Drawer_CaptureSettings(HDReflectionProbeUI s, SerializedHDReflectionProbe p, Editor owner)
{
var renderPipelineAsset = (HDRenderPipelineAsset)GraphicsSettings.renderPipelineAsset;
p.resolution.intValue = renderPipelineAsset.GetRenderPipelineSettings().lightLoopSettings.reflectionCubemapSize;
p.resolution.intValue = (int)renderPipelineAsset.GetRenderPipelineSettings().lightLoopSettings.reflectionCubemapSize;
EditorGUILayout.LabelField(CoreEditorUtils.GetContent("Resolution"), CoreEditorUtils.GetContent(p.resolution.intValue.ToString()));
EditorGUILayout.PropertyField(p.shadowDistance, CoreEditorUtils.GetContent("Shadow Distance"));

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Decal/DecalProjectorComponentEditor.cs


private SerializedProperty m_MaterialProperty;
private SerializedProperty m_DrawDistanceProperty;
private SerializedProperty m_FadeScaleProperty;
private SerializedProperty m_UVScaleProperty;
private SerializedProperty m_UVBiasProperty;
public class DecalBoundsHandle : BoxBoundsHandle
{

m_MaterialProperty = serializedObject.FindProperty("m_Material");
m_DrawDistanceProperty = serializedObject.FindProperty("m_DrawDistance");
m_FadeScaleProperty = serializedObject.FindProperty("m_FadeScale");
m_UVScaleProperty = serializedObject.FindProperty("m_UVScale");
m_UVBiasProperty = serializedObject.FindProperty("m_UVBias");
}
private void OnDisable()

EditorGUILayout.PropertyField(m_MaterialProperty);
EditorGUILayout.PropertyField(m_DrawDistanceProperty);
EditorGUILayout.Slider(m_FadeScaleProperty, 0.0f, 1.0f, new GUIContent("Fade scale"));
EditorGUILayout.PropertyField(m_UVScaleProperty);
EditorGUILayout.PropertyField(m_UVBiasProperty);
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();

44
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/StackLit/StackLitUI.cs


protected const string k_CoatIor = "_CoatIor";
protected const string k_CoatThickness = "_CoatThickness";
protected const string k_CoatExtinction = "_CoatExtinction";
protected const string k_EnableCoatNormalMap = "_EnableCoatNormalMap";
protected const string k_CoatNormalMap = "_CoatNormalMap";
protected const string k_CoatNormalMapUV = "_CoatNormalMapUV";
protected const string k_CoatNormalScale = "_CoatNormalScale";
// SSS
protected const string k_EnableSubsurfaceScattering = "_EnableSubsurfaceScattering";

protected const string kStencilRefMV = "_StencilRefMV";
protected const string kStencilWriteMaskMV = "_StencilWriteMaskMV";
protected const string k_SpecularAntiAliasingEnabled = "_SpecularAntiAliasingEnabled";
protected const string k_NormalCurvatureToRoughnessEnabled = "_NormalCurvatureToRoughnessEnabled";
#endregion
// Add the properties into an array.

private Property EnableSSS;
private Property EnableTransmission;
private Property EnableCoat;
private Property EnableCoatNormalMap;
private Property EnableSpecularAA;
private Property EnableNormalCurvatureToRoughness;
public StackLitGUI()
{

EnableSSS = new Property(this, k_EnableSubsurfaceScattering, "Enable Subsurface Scattering", "Enable Subsurface Scattering", true);
EnableTransmission = new Property(this, k_EnableTransmission, "Enable Transmission", "Enable Transmission", true);
EnableCoat = new Property(this, k_EnableCoat, "Enable Coat", "Enable coat layer with true vertical physically based BSDF mixing", true);
EnableCoatNormalMap = new Property(this, k_EnableCoatNormalMap, "Enable Coat Normal Map", "Enable separate top coat normal map", true);
EnableSpecularAA = new Property(this, k_SpecularAntiAliasingEnabled, k_SpecularAntiAliasingEnabled, k_SpecularAntiAliasingEnabled, true);
EnableNormalCurvatureToRoughness = new Property(this, k_NormalCurvatureToRoughnessEnabled, k_NormalCurvatureToRoughnessEnabled, k_NormalCurvatureToRoughnessEnabled, true);
// All material properties
_materialProperties = new GroupProperty(this, "_Material", new BaseProperty[]
{

EnableAnisotropy,
EnableCoat,
EnableCoatNormalMap,
EnableIridescence,
EnableSSS,
EnableTransmission

new TextureProperty(this, k_MetallicMap, k_Metallic, "Metallic", "Metallic", false, false),
new Property(this, k_DielectricIor, "DieletricIor", "IOR use for dielectric material (i.e non metallic material)", false),
new TextureProperty(this, k_SmoothnessAMap, k_SmoothnessA, "Smoothness", "Smoothness", false, false),
new TextureProperty(this, k_NormalMap, k_NormalScale, "Normal", "Normal Map", false, false, true),
new TextureProperty(this, k_NormalMap, k_NormalScale, "Normal", "Normal Map", true, false, true),
new TextureProperty(this, k_AmbientOcclusionMap, k_AmbientOcclusion, "AmbientOcclusion", "AmbientOcclusion Map", false, false),
}),

new GroupProperty(this, "_Coat", "Coat", new BaseProperty[]
{
new TextureProperty(this, k_CoatSmoothnessMap, k_CoatSmoothness, "Coat smoothness", "Coat smoothness", false),
new TextureProperty(this, k_CoatNormalMap, k_CoatNormalScale, "Coat Normal Map", "Coat Normal Map", true, false, true, _ => EnableCoatNormalMap.BoolValue == true),
new Property(this, "_CoatIor", "Coat IOR", "Index of refraction", false),
new Property(this, "_CoatThickness", "Coat Thickness", "Coat thickness", false),
new Property(this, "_CoatExtinction", "Coat Absorption", "Coat absorption tint (the thicker the coat, the more that color is removed)", false),

new GroupProperty(this, "_Debug", "Debug", new BaseProperty[]
{
new Property(this, "_VlayerRecomputePerLight", "Vlayer Recompute Per Light", "", false),
new Property(this, "_VlayerUseRefractedAnglesForBase", "Vlayer Use Refracted Angles For Base", "", false),
new Property(this, "_DebugLobeMask", "DebugLobeMask", "xyz is Lobe 0 1 2 Enable, w is Enable VLayering", false),
new Property(this, "_DebugEnvLobeMask", "DebugEnvLobeMask", "xyz is Environments Lobe 0 1 2 Enable, w is Enable VLayering", false),
new Property(this, "_DebugLobeMask", "DebugLobeMask", "xyz is Analytical Lobe 0 1 2 Enable", false),
EnableSpecularAA,
new Property(this, "_SpecularAntiAliasingScreenSpaceVariance", "Specular Aliasing Enable", "Specular Aliasing Enable", false, _ => EnableSpecularAA.BoolValue == true),
new Property(this, "_SpecularAntiAliasingThreshold", "Specular Aliasing Enable", "Specular Aliasing Enable", false, _ => EnableSpecularAA.BoolValue == true),
EnableNormalCurvatureToRoughness,
new Property(this, "_NormalCurvatureToRoughnessScale", "Normal Curvature To Roughness Scale", "Normal Curvature To Roughness Scale", false, _ => EnableNormalCurvatureToRoughness.BoolValue == true),
new Property(this, "_NormalCurvatureToRoughnessBias", "Normal Curvature To Roughness Bias", "Normal Curvature To Roughness Bias", false, _ => EnableNormalCurvatureToRoughness.BoolValue == true),
new Property(this, "_NormalCurvatureToRoughnessExponent", "Normal Curvature To Roughness Exponent", "Normal Curvature To Roughness Exponent", false, _ => EnableNormalCurvatureToRoughness.BoolValue == true),
}),
});
}

(TextureProperty.UVMapping) material.GetFloat(k_AnisotropyMapUV),
(TextureProperty.UVMapping) material.GetFloat(k_IridescenceThicknessMapUV),
(TextureProperty.UVMapping) material.GetFloat(k_CoatSmoothnessMapUV),
(TextureProperty.UVMapping) material.GetFloat(k_CoatNormalMapUV),
};
// Set keyword for mapping

bool coatEnabled = material.HasProperty(k_EnableCoat) && material.GetFloat(k_EnableCoat) > 0.0f;
CoreUtils.SetKeyword(material, "_MATERIAL_FEATURE_COAT", coatEnabled);
bool coatNormalMapEnabled = material.HasProperty(k_EnableCoatNormalMap) && material.GetFloat(k_EnableCoatNormalMap) > 0.0f;
CoreUtils.SetKeyword(material, "_MATERIAL_FEATURE_COAT_NORMALMAP", coatNormalMapEnabled);
bool vlayerRecomputePerLight = material.HasProperty("_VlayerRecomputePerLight") && material.GetFloat("_VlayerRecomputePerLight") > 0.0f;
CoreUtils.SetKeyword(material, "_VLAYERED_RECOMPUTE_PERLIGHT", vlayerRecomputePerLight);
bool vlayerUseRefractedAnglesForBase = material.HasProperty("_VlayerUseRefractedAnglesForBase") && material.GetFloat("_VlayerUseRefractedAnglesForBase") > 0.0f;
CoreUtils.SetKeyword(material, "_VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE", vlayerUseRefractedAnglesForBase);
// Set the reference value for the stencil test - required for SSS

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/FrameSettingsUI.cs


EditorGUILayout.PropertyField(p.enableMotionVectors, _.GetContent("Enable Motion Vectors"));
EditorGUILayout.PropertyField(p.enableObjectMotionVectors, _.GetContent("Enable Object Motion Vectors"));
EditorGUILayout.PropertyField(p.enableDBuffer, _.GetContent("Enable DBuffer"));
EditorGUILayout.PropertyField(p.enableAtmosphericScattering, _.GetContent("Enable Atmospheric Scattering"));
EditorGUILayout.PropertyField(p.enableRoughRefraction, _.GetContent("Enable Rough Refraction"));
EditorGUILayout.PropertyField(p.enableDistortion, _.GetContent("Enable Distortion"));
EditorGUILayout.PropertyField(p.enablePostprocess, _.GetContent("Enable Postprocess"));

EditorGUILayout.PropertyField(p.enableSSAO, _.GetContent("Enable SSAO"));
EditorGUILayout.PropertyField(p.enableSubsurfaceScattering, _.GetContent("Enable Subsurface Scattering"));
EditorGUILayout.PropertyField(p.enableTransmission, _.GetContent("Enable Transmission"));
EditorGUILayout.PropertyField(p.enableAtmosphericScattering, _.GetContent("Enable Atmospheric Scattering"));
EditorGUILayout.PropertyField(p.enableVolumetric, _.GetContent(" Enable Volumetric"));
EditorGUILayout.PropertyField(p.enableShadow, _.GetContent("Enable Shadow"));
EditorGUILayout.PropertyField(p.enableContactShadow, _.GetContent("Enable Contact Shadows"));
EditorGUILayout.PropertyField(p.enableShadowMask, _.GetContent("Enable Shadow Masks"));

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/RenderPipelineSettingsUI.cs


EditorGUILayout.PropertyField(d.supportMotionVectors, _.GetContent("Support Motion Vectors"));
EditorGUILayout.PropertyField(d.supportStereo, _.GetContent("Support Stereo Rendering"));
EditorGUILayout.PropertyField(d.enableUltraQualitySSS, _.GetContent("Increase SSS Sample Count"));
EditorGUILayout.PropertyField(d.supportVolumetric, _.GetContent("Support volumetric"));
--EditorGUI.indentLevel;
}
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedFrameSettings.cs


public SerializedProperty enableSSAO;
public SerializedProperty enableSubsurfaceScattering;
public SerializedProperty enableTransmission;
public SerializedProperty enableAtmosphericScattering;
public SerializedProperty enableVolumetric;
public SerializedProperty diffuseGlobalDimmer;
public SerializedProperty specularGlobalDimmer;

public SerializedProperty enableMotionVectors;
public SerializedProperty enableObjectMotionVectors;
public SerializedProperty enableDBuffer;
public SerializedProperty enableAtmosphericScattering;
public SerializedProperty enableRoughRefraction;
public SerializedProperty enableTransparentPostpass;
public SerializedProperty enableDistortion;

enableSSAO = root.Find((FrameSettings d) => d.enableSSAO);
enableSubsurfaceScattering = root.Find((FrameSettings d) => d.enableSubsurfaceScattering);
enableTransmission = root.Find((FrameSettings d) => d.enableTransmission);
enableAtmosphericScattering = root.Find((FrameSettings d) => d.enableAtmosphericScattering);
enableVolumetric = root.Find((FrameSettings d) => d.enableVolumetric);
diffuseGlobalDimmer = root.Find((FrameSettings d) => d.diffuseGlobalDimmer);
specularGlobalDimmer = root.Find((FrameSettings d) => d.specularGlobalDimmer);
enableForwardRenderingOnly = root.Find((FrameSettings d) => d.enableForwardRenderingOnly);

enableObjectMotionVectors = root.Find((FrameSettings d) => d.enableObjectMotionVectors);
enableDBuffer = root.Find((FrameSettings d) => d.enableDBuffer);
enableAtmosphericScattering = root.Find((FrameSettings d) => d.enableAtmosphericScattering);
enableRoughRefraction = root.Find((FrameSettings d) => d.enableRoughRefraction);
enableTransparentPostpass = root.Find((FrameSettings d) => d.enableTransparentPostpass);
enableDistortion = root.Find((FrameSettings d) => d.enableDistortion);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedRenderPipelineSettings.cs


public SerializedProperty supportMotionVectors;
public SerializedProperty supportStereo;
public SerializedProperty enableUltraQualitySSS;
public SerializedProperty supportVolumetric;
public SerializedGlobalLightLoopSettings lightLoopSettings;
public SerializedShadowInitParameters shadowInitParams;

supportMotionVectors = root.Find((RenderPipelineSettings s) => s.supportMotionVectors);
supportStereo = root.Find((RenderPipelineSettings s) => s.supportStereo);
enableUltraQualitySSS = root.Find((RenderPipelineSettings s) => s.enableUltraQualitySSS);
supportVolumetric = root.Find((RenderPipelineSettings s) => s.supportVolumetric);
lightLoopSettings = new SerializedGlobalLightLoopSettings(root.Find((RenderPipelineSettings s) => s.lightLoopSettings));
shadowInitParams = new SerializedShadowInitParameters(root.Find((RenderPipelineSettings s) => s.shadowInitParams));

237
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


public Material GetBlitMaterial() { return m_Blit; }
FrameSettings m_FrameSettings; // Init every frame
#if UNITY_EDITOR
// HACK: Make debug windows work correctly with FrameSettings in Editor
DebugManager.renderPipelineIsRecreated = true;
#endif
m_ValidAPI = true;
if (!SetRenderingFeatures())

if (m_CurrentWidth > 0 && m_CurrentHeight > 0)
m_LightLoop.ReleaseResolutionDependentBuffers();
m_LightLoop.AllocResolutionDependentBuffers((int)hdCamera.screenSize.x, (int)hdCamera.screenSize.y, m_FrameSettings.enableStereo);
m_LightLoop.AllocResolutionDependentBuffers((int)hdCamera.screenSize.x, (int)hdCamera.screenSize.y, hdCamera.frameSettings.enableStereo);
}
// update recorded window resolution

using (new ProfilingSample(cmd, "Push Global Parameters", CustomSamplerId.PushGlobalParameters.GetSampler()))
{
// Set up UnityPerFrame CBuffer.
m_SSSBufferManager.PushGlobalParams(cmd, sssParameters, m_FrameSettings);
m_SSSBufferManager.PushGlobalParams(hdCamera, cmd, sssParameters);
m_DbufferManager.PushGlobalParams(cmd, m_FrameSettings);
m_DbufferManager.PushGlobalParams(hdCamera, cmd);
m_VolumetricLightingSystem.PushGlobalParams(hdCamera, cmd, m_FrameCount);

// Set up UnityPerView CBuffer.
hdCamera.SetupGlobalParams(cmd, m_Time, m_LastTime);
if (m_FrameSettings.enableStereo) hdCamera.SetupGlobalStereoParams(cmd);
if (hdCamera.frameSettings.enableStereo)
hdCamera.SetupGlobalStereoParams(cmd);
var previousDepthPyramidRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.DepthPyramid);
if (previousDepthPyramidRT != null)

}
}
public void UpdateShadowSettings()
public void UpdateShadowSettings(HDCamera hdCamera)
{
var shadowSettings = VolumeManager.instance.stack.GetComponent<HDShadowSettings>();

m_ShadowSettings.enabled = m_FrameSettings.enableShadow;
m_ShadowSettings.enabled = hdCamera.frameSettings.enableShadow;
}
public void ConfigureForShadowMask(bool enableBakeShadowMask, CommandBuffer cmd)

{
srcFrameSettings = m_Asset.GetFrameSettings();
}
FrameSettings currentFrameSettings = new FrameSettings();
FrameSettings.InitializeFrameSettings(camera, m_Asset.GetRenderPipelineSettings(), srcFrameSettings, ref m_FrameSettings);
FrameSettings.InitializeFrameSettings(camera, m_Asset.GetRenderPipelineSettings(), srcFrameSettings, ref currentFrameSettings);
// This is the main command buffer used for the frame.
var cmd = CommandBufferPool.Get("");

continue;
}
if (camera.cameraType != CameraType.Reflection
// Don't render reflection in Preview, it prevent them to display
if (camera.cameraType != CameraType.Reflection && camera.cameraType != CameraType.Preview
// Planar probes rendering is not currently supported for orthographic camera
// Avoid rendering to prevent error log spamming
&& !camera.orthographic)

using (new ProfilingSample(cmd, "HDRenderPipeline::Render", CustomSamplerId.HDRenderPipelineRender.GetSampler()))
{
// Do anything we need to do upon a new frame.
m_LightLoop.NewFrame(m_FrameSettings);
m_LightLoop.NewFrame(currentFrameSettings);
// If we render a reflection view or a preview we should not display any debug information
// This need to be call before ApplyDebugDisplaySettings()

// Disable post process if we enable debug mode or if the post process layer is disabled
if (m_CurrentDebugDisplaySettings.IsDebugDisplayRemovePostprocess() || !CoreUtils.IsPostProcessingActive(postProcessLayer))
{
m_FrameSettings.enablePostprocess = false;
currentFrameSettings.enablePostprocess = false;
}
var hdCamera = HDCamera.Get(camera);

hdCamera = HDCamera.Create(camera, m_VolumetricLightingSystem);
}
hdCamera.Update(postProcessLayer, m_FrameSettings, m_VolumetricLightingSystem);
// From this point, we should only use frame settings from the camera
hdCamera.Update(currentFrameSettings, postProcessLayer, m_VolumetricLightingSystem);
UpdateShadowSettings();
UpdateShadowSettings(hdCamera);
if (!CullResults.GetCullingParameters(camera, m_FrameSettings.enableStereo, out cullingParams))
if (!CullResults.GetCullingParameters(camera, hdCamera.frameSettings.enableStereo, out cullingParams))
{
renderContext.Submit();
continue;

hdCamera.UpdateStereoDependentState(m_FrameSettings, ref cullingParams);
hdCamera.UpdateStereoDependentState(ref cullingParams);
#if UNITY_EDITOR
// emit scene view UI

}
#endif
if (m_FrameSettings.enableDBuffer)
if (hdCamera.frameSettings.enableDBuffer)
{
// decal system needs to be updated with current camera, it needs it to set up culling and light list generation parameters
DecalSystem.instance.CurrentCamera = camera;

m_DbufferManager.vsibleDecalCount = 0;
using (new ProfilingSample(cmd, "DBufferPrepareDrawData", CustomSamplerId.DBufferPrepareDrawData.GetSampler()))
{
if (m_FrameSettings.enableDBuffer)
if (hdCamera.frameSettings.enableDBuffer)
{
DecalSystem.instance.EndCull();
m_DbufferManager.vsibleDecalCount = DecalSystem.m_DecalsVisibleThisFrame;

}
}
renderContext.SetupCameraProperties(camera, m_FrameSettings.enableStereo);
renderContext.SetupCameraProperties(camera, hdCamera.frameSettings.enableStereo);
PushGlobalParams(hdCamera, cmd, diffusionProfileSettings);

bool enableBakeShadowMask;
using (new ProfilingSample(cmd, "TP_PrepareLightsForGPU", CustomSamplerId.TPPrepareLightsForGPU.GetSampler()))
{
enableBakeShadowMask = m_LightLoop.PrepareLightsForGPU(cmd, camera, m_ShadowSettings, m_CullResults, m_ReflectionProbeCullResults, densityVolumes) && m_FrameSettings.enableShadowMask;
enableBakeShadowMask = m_LightLoop.PrepareLightsForGPU(cmd, hdCamera, m_ShadowSettings, m_CullResults, m_ReflectionProbeCullResults, densityVolumes);
StartStereoRendering(renderContext, hdCamera.camera);
StartStereoRendering(renderContext, hdCamera);
ClearBuffers(hdCamera, cmd);

RenderDepthPyramid(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);
StopStereoRendering(renderContext, hdCamera.camera);
StopStereoRendering(renderContext, hdCamera);
if (m_CurrentDebugDisplaySettings.IsDebugMaterialDisplayEnabled())
{

}
else
{
StartStereoRendering(renderContext, hdCamera.camera);
StartStereoRendering(renderContext, hdCamera);
using (new ProfilingSample(cmd, "Render SSAO", CustomSamplerId.RenderSSAO.GetSampler()))
{

}
}
StopStereoRendering(renderContext, hdCamera.camera);
StopStereoRendering(renderContext, hdCamera);
if (m_FrameSettings.enableAsyncCompute)
if (hdCamera.frameSettings.enableAsyncCompute)
{
GPUFence startFence = cmd.CreateGPUFence();
renderContext.ExecuteCommandBuffer(cmd);

m_LightLoop.RenderShadows(renderContext, cmd, m_CullResults);
// Overwrite camera properties set during the shadow pass with the original camera properties.
renderContext.SetupCameraProperties(camera, m_FrameSettings.enableStereo);
renderContext.SetupCameraProperties(camera, hdCamera.frameSettings.enableStereo);
if (m_FrameSettings.enableStereo) hdCamera.SetupGlobalStereoParams(cmd);
if (hdCamera.frameSettings.enableStereo)
hdCamera.SetupGlobalStereoParams(cmd);
}
using (new ProfilingSample(cmd, "Deferred directional shadows", CustomSamplerId.RenderDeferredDirectionalShadow.GetSampler()))

}
m_LightLoop.RenderDeferredDirectionalShadow(hdCamera, m_DeferredShadowBuffer, GetDepthTexture(), cmd);
PushFullScreenDebugTexture(cmd, m_DeferredShadowBuffer, hdCamera, FullScreenDebugMode.DeferredShadows);
PushFullScreenDebugTexture(hdCamera, cmd, m_DeferredShadowBuffer, FullScreenDebugMode.DeferredShadows);
if (m_FrameSettings.enableAsyncCompute)
if (hdCamera.frameSettings.enableAsyncCompute)
{
m_LightLoop.BuildGPULightListAsyncEnd(hdCamera, cmd, buildGPULightListsCompleteFence);
}

{
// Set fog parameters for volumetric lighting.
var visualEnv = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
visualEnv.PushFogShaderParameters(cmd, m_FrameSettings);
visualEnv.PushFogShaderParameters(hdCamera, cmd);
m_VolumetricLightingSystem.VolumeVoxelizationPass(densityVolumes, hdCamera, cmd, m_FrameSettings, m_FrameCount);
m_VolumetricLightingSystem.VolumeVoxelizationPass(hdCamera, cmd, m_FrameCount, densityVolumes);
m_VolumetricLightingSystem.VolumetricLightingPass(hdCamera, cmd, m_FrameSettings, m_FrameCount);
m_VolumetricLightingSystem.VolumetricLightingPass(hdCamera, cmd, m_FrameCount);
StartStereoRendering(renderContext, hdCamera.camera);
StartStereoRendering(renderContext, hdCamera);
m_SSSBufferManager.SubsurfaceScatteringPass(hdCamera, cmd, diffusionProfileSettings, m_FrameSettings,
m_SSSBufferManager.SubsurfaceScatteringPass(hdCamera, cmd, diffusionProfileSettings,
m_CameraColorBuffer, m_CameraSssDiffuseLightingBuffer, m_CameraDepthStencilBuffer, GetDepthTexture());
RenderSky(hdCamera, cmd);

RenderColorPyramid(hdCamera, cmd, renderContext, false);
AccumulateDistortion(m_CullResults, hdCamera, renderContext, cmd);
RenderDistortion(cmd, m_Asset.renderPipelineResources, hdCamera);
RenderDistortion(hdCamera, cmd, m_Asset.renderPipelineResources);
StopStereoRendering(renderContext, hdCamera.camera);
StopStereoRendering(renderContext, hdCamera);
PushFullScreenDebugTexture(cmd, m_CameraColorBuffer, hdCamera, FullScreenDebugMode.NanTracker);
PushColorPickerDebugTexture(cmd, m_CameraColorBuffer, hdCamera);
PushFullScreenDebugTexture(hdCamera, cmd, m_CameraColorBuffer, FullScreenDebugMode.NanTracker);
PushColorPickerDebugTexture(hdCamera, cmd, m_CameraColorBuffer);
StartStereoRendering(renderContext, hdCamera.camera);
StartStereoRendering(renderContext, hdCamera);
if (m_FrameSettings.enablePostprocess)
if (hdCamera.frameSettings.enablePostprocess)
{
RenderPostProcess(hdCamera, cmd, postProcessLayer);
}

}
}
StopStereoRendering(renderContext, hdCamera.camera);
StopStereoRendering(renderContext, hdCamera);
if (m_FrameSettings.enableStereo)
if (hdCamera.frameSettings.enableStereo)
renderContext.StereoEndRender(hdCamera.camera);
}

}
}
#endif
PushFullScreenDebugTexture(cmd, m_CameraColorBuffer, hdCamera, FullScreenDebugMode.ScreenSpaceTracing);
PushFullScreenDebugTexture(hdCamera, cmd, m_CameraColorBuffer, FullScreenDebugMode.ScreenSpaceTracing);
// Caution: RenderDebug need to take into account that we have flip the screen (so anything capture before the flip will be flipped)
RenderDebug(hdCamera, cmd);

}
void RenderOpaqueRenderList(CullResults cull,
Camera camera,
HDCamera hdCamera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName passName,

Material overrideMaterial = null)
{
m_SinglePassName[0] = passName;
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_SinglePassName, rendererConfiguration, inRenderQueueRange, stateBlock, overrideMaterial);
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_SinglePassName, rendererConfiguration, inRenderQueueRange, stateBlock, overrideMaterial);
Camera camera,
HDCamera hdCamera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName[] passNames,

Material overrideMaterial = null)
{
if (!m_FrameSettings.enableOpaqueObjects)
if (!hdCamera.frameSettings.enableOpaqueObjects)
return;
// This is done here because DrawRenderers API lives outside command buffers so we need to make call this before doing any DrawRenders

var drawSettings = new DrawRendererSettings(camera, HDShaderPassNames.s_EmptyName)
var drawSettings = new DrawRendererSettings(hdCamera.camera, HDShaderPassNames.s_EmptyName)
{
rendererConfiguration = rendererConfiguration,
sorting = { flags = SortFlags.CommonOpaque }

}
void RenderTransparentRenderList(CullResults cull,
Camera camera,
HDCamera hdCamera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName passName,

Material overrideMaterial = null)
{
m_SinglePassName[0] = passName;
RenderTransparentRenderList(cull, camera, renderContext, cmd, m_SinglePassName,
RenderTransparentRenderList(cull, hdCamera, renderContext, cmd, m_SinglePassName,
Camera camera,
HDCamera hdCamera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName[] passNames,

Material overrideMaterial = null
)
{
if (!m_FrameSettings.enableTransparentObjects)
if (!hdCamera.frameSettings.enableTransparentObjects)
return;
// This is done here because DrawRenderers API lives outside command buffers so we need to make call this before doing any DrawRenders

var drawSettings = new DrawRendererSettings(camera, HDShaderPassNames.s_EmptyName)
var drawSettings = new DrawRendererSettings(hdCamera.camera, HDShaderPassNames.s_EmptyName)
{
rendererConfiguration = rendererConfiguration,
sorting = { flags = SortFlags.CommonTransparent }

void AccumulateDistortion(CullResults cullResults, HDCamera hdCamera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
if (!m_FrameSettings.enableDistortion)
if (!hdCamera.frameSettings.enableDistortion)
return;
using (new ProfilingSample(cmd, "Distortion", CustomSamplerId.Distortion.GetSampler()))

// Only transparent object can render distortion vectors
RenderTransparentRenderList(cullResults, hdCamera.camera, renderContext, cmd, HDShaderPassNames.s_DistortionVectorsName);
RenderTransparentRenderList(cullResults, hdCamera, renderContext, cmd, HDShaderPassNames.s_DistortionVectorsName);
void RenderDistortion(CommandBuffer cmd, RenderPipelineResources resources, HDCamera hdCamera)
void RenderDistortion(HDCamera hdCamera, CommandBuffer cmd, RenderPipelineResources resources)
if (!m_FrameSettings.enableDistortion)
if (!hdCamera.frameSettings.enableDistortion)
return;
using (new ProfilingSample(cmd, "ApplyDistortion", CustomSamplerId.ApplyDistortion.GetSampler()))

// by using the pass "ForwardOnly". In this case the .shader should not have "Forward" but only a "ForwardOnly" pass.
// It must also have a "DepthForwardOnly" and no "DepthOnly" pass as forward material (either deferred or forward only rendering) have always a depth pass.
// If a forward material have no depth prepass, then lighting can be incorrect (deferred sahdowing, SSAO), this may be acceptable depends on usage
bool addFullDepthPrepass = forcePrepass || m_FrameSettings.enableForwardRenderingOnly || m_FrameSettings.enableDepthPrepassWithDeferredRendering;
var camera = hdCamera.camera;
bool addFullDepthPrepass = forcePrepass || hdCamera.frameSettings.enableForwardRenderingOnly || hdCamera.frameSettings.enableDepthPrepassWithDeferredRendering;
using (new ProfilingSample(cmd, !addFullDepthPrepass ? "Depth Prepass alpha test" : "Depth Prepass", CustomSamplerId.DepthPrepass.GetSampler()))
{

// We render first the opaque object as opaque alpha tested are more costly to render and could be reject by early-z (but not Hi-z as it is disable with clip instruction)
// This is handled automatically with the RenderQueue value (OpaqueAlphaTested have a different value and thus are sorted after Opaque)
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthOnlyAndDepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthOnlyAndDepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthForwardOnlyPassNames, 0, HDRenderQueue.k_RenderQueue_AllOpaque);
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_DepthOnlyPassNames, 0, renderQueueRange);
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_DepthOnlyPassNames, 0, renderQueueRange);
if (m_FrameSettings.enableTransparentPrepass)
if (hdCamera.frameSettings.enableTransparentPrepass)
RenderTransparentRenderList(cull, camera, renderContext, cmd, m_TransparentDepthPrepassNames);
RenderTransparentRenderList(cull, hdCamera, renderContext, cmd, m_TransparentDepthPrepassNames);
}
}
}

void RenderGBuffer(CullResults cull, HDCamera hdCamera, bool enableShadowMask, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
if (m_FrameSettings.enableForwardRenderingOnly)
if (hdCamera.frameSettings.enableForwardRenderingOnly)
var camera = hdCamera.camera;
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.s_GBufferName, m_currentRendererConfigurationBakedLighting, HDRenderQueue.k_RenderQueue_AllOpaque);
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, HDShaderPassNames.s_GBufferName, m_currentRendererConfigurationBakedLighting, HDRenderQueue.k_RenderQueue_AllOpaque);
void RenderDBuffer(HDCamera camera, CommandBuffer cmd)
void RenderDBuffer(HDCamera hdCamera, CommandBuffer cmd)
if (!m_FrameSettings.enableDBuffer)
if (!hdCamera.frameSettings.enableDBuffer)
return;
using (new ProfilingSample(cmd, "DBufferRender", CustomSamplerId.DBufferRender.GetSampler()))

// Depth texture is now ready, bind it.
cmd.SetGlobalTexture(HDShaderIDs._CameraDepthTexture, GetDepthTexture());
m_DbufferManager.ClearTargets(cmd, camera);
HDUtils.SetRenderTarget(cmd, camera, m_DbufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer); // do not clear anymore
m_DbufferManager.ClearTargets(cmd, hdCamera);
HDUtils.SetRenderTarget(cmd, hdCamera, m_DbufferManager.GetBuffersRTI(), m_CameraDepthStencilBuffer); // do not clear anymore
m_DbufferManager.SetHTile(m_DbufferManager.bufferCount, cmd);
DecalSystem.instance.RenderIntoDBuffer(cmd);
m_DbufferManager.UnSetHTile(cmd);

{
using (new ProfilingSample(cmd, "DisplayDebug ViewMaterial", CustomSamplerId.DisplayDebugViewMaterial.GetSampler()))
{
if (m_CurrentDebugDisplaySettings.materialDebugSettings.IsDebugGBufferEnabled() && !m_FrameSettings.enableForwardRenderingOnly)
if (m_CurrentDebugDisplaySettings.materialDebugSettings.IsDebugGBufferEnabled() && !hdCamera.frameSettings.enableForwardRenderingOnly)
{
using (new ProfilingSample(cmd, "DebugViewMaterialGBuffer", CustomSamplerId.DebugViewMaterialGBuffer.GetSampler()))
{

HDUtils.SetRenderTarget(cmd, hdCamera, m_CameraColorBuffer, m_CameraDepthStencilBuffer, ClearFlag.All, CoreUtils.clearColorAllBlack);
// Render Opaque forward
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, m_AllForwardOpaquePassNames, m_currentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque);
RenderOpaqueRenderList(cull, hdCamera, renderContext, cmd, m_AllForwardOpaquePassNames, m_currentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque);
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, cmd, m_AllTransparentPassNames, m_currentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque);
RenderTransparentRenderList(cull, hdCamera, renderContext, cmd, m_AllTransparentPassNames, m_currentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque);
}
}

var camera = hdCamera.camera;
// Apply SSAO from PostProcessLayer
if (m_FrameSettings.enableSSAO && postProcessLayer != null && postProcessLayer.enabled)
if (hdCamera.frameSettings.enableSSAO && postProcessLayer != null && postProcessLayer.enabled)
{
var settings = postProcessLayer.GetSettings<AmbientOcclusion>();

cmd.SetGlobalTexture(HDShaderIDs._AmbientOcclusionTexture, m_AmbientOcclusionBuffer);
cmd.SetGlobalVector(HDShaderIDs._AmbientOcclusionParam, new Vector4(settings.color.value.r, settings.color.value.g, settings.color.value.b, settings.directLightingStrength.value));
PushFullScreenDebugTexture(cmd, m_AmbientOcclusionBuffer, hdCamera, FullScreenDebugMode.SSAO);
PushFullScreenDebugTexture(hdCamera, cmd, m_AmbientOcclusionBuffer, FullScreenDebugMode.SSAO);
return;
}
}

void RenderDeferredLighting(HDCamera hdCamera, CommandBuffer cmd)
{
if (m_FrameSettings.enableForwardRenderingOnly)
if (hdCamera.frameSettings.enableForwardRenderingOnly)
return;
m_MRTCache2[0] = m_CameraColorBuffer;

var options = new LightLoop.LightingPassOptions();
if (m_FrameSettings.enableSubsurfaceScattering)
if (hdCamera.frameSettings.enableSubsurfaceScattering)
{
// Output split lighting for materials asking for it (masked in the stencil buffer)
options.outputSplitLighting = true;

if (pass == ForwardPass.Opaque)
{
// In case of forward SSS we will bind all the required target. It is up to the shader to write into it or not.
if (m_FrameSettings.enableSubsurfaceScattering)
if (hdCamera.frameSettings.enableSubsurfaceScattering)
{
RenderTargetIdentifier[] m_MRTWithSSS =
new RenderTargetIdentifier[2 + m_SSSBufferManager.sssBufferCount];

HDShaderPassNames.s_ForwardOnlyName;
m_ForwardAndForwardOnlyPassNames[1] = HDShaderPassNames.s_ForwardName;
var passNames = m_FrameSettings.enableForwardRenderingOnly
var passNames = hdCamera.frameSettings.enableForwardRenderingOnly
? m_ForwardAndForwardOnlyPassNames
: m_ForwardOnlyPassNames;
var debugSSTThisPass = debugScreenSpaceTracing && (m_CurrentDebugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.ScreenSpaceTracingReflection);

cmd.SetRandomWriteTarget(7, m_DebugScreenSpaceTracingData);
}
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, passNames, m_currentRendererConfigurationBakedLighting);
RenderOpaqueRenderList(cullResults, hdCamera, renderContext, cmd, passNames, m_currentRendererConfigurationBakedLighting);
if (debugSSTThisPass)
cmd.ClearRandomWriteTargets();
}

if ((m_FrameSettings.enableDBuffer) && (DecalSystem.m_DecalsVisibleThisFrame > 0)) // enable d-buffer flag value is being interpreted more like enable decals in general now that we have clustered
if ((hdCamera.frameSettings.enableDBuffer) && (DecalSystem.m_DecalsVisibleThisFrame > 0)) // enable d-buffer flag value is being interpreted more like enable decals in general now that we have clustered
{
DecalSystem.instance.SetAtlas(cmd); // for clustered decals
}

cmd.SetGlobalBuffer(HDShaderIDs._DebugScreenSpaceTracingData, m_DebugScreenSpaceTracingData);
cmd.SetRandomWriteTarget(7, m_DebugScreenSpaceTracingData);
}
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, m_AllTransparentPassNames, m_currentRendererConfigurationBakedLighting, pass == ForwardPass.PreRefraction ? HDRenderQueue.k_RenderQueue_PreRefraction : HDRenderQueue.k_RenderQueue_Transparent);
RenderTransparentRenderList(cullResults, hdCamera, renderContext, cmd, m_AllTransparentPassNames, m_currentRendererConfigurationBakedLighting, pass == ForwardPass.PreRefraction ? HDRenderQueue.k_RenderQueue_PreRefraction : HDRenderQueue.k_RenderQueue_Transparent);
if (debugSSTThisPass)
cmd.ClearRandomWriteTargets();
}

if (pass == ForwardPass.Opaque)
{
RenderOpaqueRenderList(cullResults, hdCamera.camera, renderContext, cmd, m_ForwardErrorPassNames, 0, null, null, m_ErrorMaterial);
RenderOpaqueRenderList(cullResults, hdCamera, renderContext, cmd, m_ForwardErrorPassNames, 0, null, null, m_ErrorMaterial);
RenderTransparentRenderList(cullResults, hdCamera.camera, renderContext, cmd, m_ForwardErrorPassNames, 0, pass == ForwardPass.PreRefraction ? HDRenderQueue.k_RenderQueue_PreRefraction : HDRenderQueue.k_RenderQueue_Transparent, null, m_ErrorMaterial);
RenderTransparentRenderList(cullResults, hdCamera, renderContext, cmd, m_ForwardErrorPassNames, 0, pass == ForwardPass.PreRefraction ? HDRenderQueue.k_RenderQueue_PreRefraction : HDRenderQueue.k_RenderQueue_Transparent, null, m_ErrorMaterial);
}
}
}

if (!m_FrameSettings.enableTransparentPostpass)
if (!hdCamera.frameSettings.enableTransparentPostpass)
RenderTransparentRenderList(cullResults, hdCamera.camera, renderContext, cmd, m_TransparentDepthPostpassNames);
RenderTransparentRenderList(cullResults, hdCamera, renderContext, cmd, m_TransparentDepthPostpassNames);
void RenderObjectsVelocity(CullResults cullResults, HDCamera hdcamera, ScriptableRenderContext renderContext, CommandBuffer cmd)
void RenderObjectsVelocity(CullResults cullResults, HDCamera hdCamera, ScriptableRenderContext renderContext, CommandBuffer cmd)
if (!m_FrameSettings.enableMotionVectors || !m_FrameSettings.enableObjectMotionVectors)
if (!hdCamera.frameSettings.enableMotionVectors || !hdCamera.frameSettings.enableObjectMotionVectors)
return;
using (new ProfilingSample(cmd, "Objects Velocity", CustomSamplerId.ObjectsVelocity.GetSampler()))

hdcamera.camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
hdCamera.camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
HDUtils.SetRenderTarget(cmd, hdcamera, m_VelocityBuffer, m_CameraDepthStencilBuffer);
RenderOpaqueRenderList(cullResults, hdcamera.camera, renderContext, cmd, HDShaderPassNames.s_MotionVectorsName, RendererConfiguration.PerObjectMotionVectors);
HDUtils.SetRenderTarget(cmd, hdCamera, m_VelocityBuffer, m_CameraDepthStencilBuffer);
RenderOpaqueRenderList(cullResults, hdCamera, renderContext, cmd, HDShaderPassNames.s_MotionVectorsName, RendererConfiguration.PerObjectMotionVectors);
void RenderCameraVelocity(CullResults cullResults, HDCamera hdcamera, ScriptableRenderContext renderContext, CommandBuffer cmd)
void RenderCameraVelocity(CullResults cullResults, HDCamera hdCamera, ScriptableRenderContext renderContext, CommandBuffer cmd)
if (!m_FrameSettings.enableMotionVectors)
if (!hdCamera.frameSettings.enableMotionVectors)
return;
using (new ProfilingSample(cmd, "Camera Velocity", CustomSamplerId.CameraVelocity.GetSampler()))

hdcamera.camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
hdCamera.camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
HDUtils.DrawFullScreen(cmd, hdcamera, m_CameraMotionVectorsMaterial, m_VelocityBuffer, m_CameraDepthStencilBuffer, null, 0);
PushFullScreenDebugTexture(cmd, m_VelocityBuffer, hdcamera, FullScreenDebugMode.MotionVectors);
HDUtils.DrawFullScreen(cmd, hdCamera, m_CameraMotionVectorsMaterial, m_VelocityBuffer, m_CameraDepthStencilBuffer, null, 0);
PushFullScreenDebugTexture(hdCamera, cmd, m_VelocityBuffer, FullScreenDebugMode.MotionVectors);
}
}

{
if (!m_FrameSettings.enableRoughRefraction)
if (!hdCamera.frameSettings.enableRoughRefraction)
if (!m_FrameSettings.enableDistortion && !m_FrameSettings.enablePostprocess && !m_FrameSettings.enableSSR)
if (!hdCamera.frameSettings.enableDistortion && !hdCamera.frameSettings.enablePostprocess && !hdCamera.frameSettings.enableSSR)
return;
}

m_BufferPyramid.RenderColorPyramid(hdCamera, cmd, renderContext, m_CameraColorBuffer, cameraRT);
Vector2 pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera, cameraRT);
PushFullScreenDebugTextureMip(cmd, cameraRT, m_BufferPyramid.GetPyramidLodCount(new Vector2Int(hdCamera.actualWidth, hdCamera.actualHeight)), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), hdCamera, isPreRefraction ? FullScreenDebugMode.PreRefractionColorPyramid : FullScreenDebugMode.FinalColorPyramid);
PushFullScreenDebugTextureMip(hdCamera, cmd, cameraRT, m_BufferPyramid.GetPyramidLodCount(new Vector2Int(hdCamera.actualWidth, hdCamera.actualHeight)), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), isPreRefraction ? FullScreenDebugMode.PreRefractionColorPyramid : FullScreenDebugMode.FinalColorPyramid);
if (!m_FrameSettings.enableRoughRefraction)
if (!hdCamera.frameSettings.enableRoughRefraction)
return;
var cameraRT = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.DepthPyramid)

m_BufferPyramid.RenderDepthPyramid(hdCamera, cmd, renderContext, GetDepthTexture(), cameraRT);
Vector2 pyramidScale = m_BufferPyramid.GetPyramidToScreenScale(hdCamera, cameraRT);
PushFullScreenDebugTextureMip(cmd, cameraRT, m_BufferPyramid.GetPyramidLodCount(new Vector2Int(hdCamera.actualWidth, hdCamera.actualHeight)), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), hdCamera, debugMode);
PushFullScreenDebugTextureMip(hdCamera, cmd, cameraRT, m_BufferPyramid.GetPyramidLodCount(new Vector2Int(hdCamera.actualWidth, hdCamera.actualHeight)), new Vector4(pyramidScale.x, pyramidScale.y, 0.0f, 0.0f), debugMode);
}
void RenderPostProcess(HDCamera hdcamera, CommandBuffer cmd, PostProcessLayer layer)

}
// TODO TEMP: Not sure I want to keep this special case. Gotta see how to get rid of it (not sure it will work correctly for non-full viewports.
public void PushColorPickerDebugTexture(CommandBuffer cmd, RenderTargetIdentifier textureID, HDCamera hdCamera)
public void PushColorPickerDebugTexture(HDCamera hdCamera, CommandBuffer cmd, RenderTargetIdentifier textureID)
{
if (m_CurrentDebugDisplaySettings.colorPickerDebugSettings.colorPickerMode != ColorPickerDebugMode.None)
{

}
}
public void PushFullScreenDebugTexture(CommandBuffer cmd, RTHandleSystem.RTHandle textureID, HDCamera hdCamera, FullScreenDebugMode debugMode)
public void PushFullScreenDebugTexture(HDCamera hdCamera, CommandBuffer cmd, RTHandleSystem.RTHandle textureID, FullScreenDebugMode debugMode)
{
if (debugMode == m_CurrentDebugDisplaySettings.fullScreenDebugMode)
{

}
void PushFullScreenDebugTextureMip(CommandBuffer cmd, RTHandleSystem.RTHandle texture, int lodCount, Vector4 scaleBias, HDCamera hdCamera, FullScreenDebugMode debugMode)
void PushFullScreenDebugTextureMip(HDCamera hdCamera, CommandBuffer cmd, RTHandleSystem.RTHandle texture, int lodCount, Vector4 scaleBias, FullScreenDebugMode debugMode)
{
if (debugMode == m_CurrentDebugDisplaySettings.fullScreenDebugMode)
{

m_DebugFullScreen.SetTexture(HDShaderIDs._DepthPyramidTexture, hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.DepthPyramid));
HDUtils.DrawFullScreen(cmd, hdCamera, m_DebugFullScreen, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);
PushColorPickerDebugTexture(cmd, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget, hdCamera);
PushColorPickerDebugTexture(hdCamera, cmd, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);
}
// Then overlays

(hdCamera.clearColorMode == HDAdditionalCameraData.ClearColorMode.Sky && !m_SkyManager.IsVisualSkyValid()) ||
// 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
HDUtils.IsRegularPreviewCamera(hdCamera.camera)
)
{
Color clearColor = hdCamera.backgroundColorHDR;

// 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 GBuffers
if (!m_FrameSettings.enableForwardRenderingOnly)
if (!hdCamera.frameSettings.enableForwardRenderingOnly)
{
using (new ProfilingSample(cmd, "Clear GBuffer", CustomSamplerId.ClearGBuffer.GetSampler()))
{

}
}
void StartStereoRendering(ScriptableRenderContext renderContext, Camera cam)
void StartStereoRendering(ScriptableRenderContext renderContext, HDCamera hdCamera)
if (m_FrameSettings.enableStereo)
renderContext.StartMultiEye(cam);
if (hdCamera.frameSettings.enableStereo)
renderContext.StartMultiEye(hdCamera.camera);
void StopStereoRendering(ScriptableRenderContext renderContext, Camera cam)
void StopStereoRendering(ScriptableRenderContext renderContext, HDCamera hdCamera)
if (m_FrameSettings.enableStereo)
renderContext.StopMultiEye(cam);
if (hdCamera.frameSettings.enableStereo)
renderContext.StopMultiEye(hdCamera.camera);
}
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.cs


{
maxPlanarReflectionProbePerCamera = renderPipelineSettings.lightLoopSettings.planarReflectionProbeCacheSize,
maxActivePlanarReflectionProbe = 512,
planarReflectionProbeSize = renderPipelineSettings.lightLoopSettings.planarReflectionTextureSize
planarReflectionProbeSize = (int)renderPipelineSettings.lightLoopSettings.planarReflectionTextureSize
};
}
}

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDUtils.cs


Vector2 mousePixelCoord = MousePositionDebug.instance.GetMouseClickPosition(camera.screenSize.y);
return new Vector4(mousePixelCoord.x, mousePixelCoord.y, camera.viewportScale.x * mousePixelCoord.x / camera.screenSize.x, camera.viewportScale.y * mousePixelCoord.y / camera.screenSize.y);
}
// This function check if camera is a CameraPreview, then check if this preview is a regular preview (i.e not a preview from the camera editor)
public static bool IsRegularPreviewCamera(Camera camera)
{
var additionalCameraData = camera.GetComponent<HDAdditionalCameraData>();
return camera.cameraType == CameraType.Preview && ((additionalCameraData == null) || (additionalCameraData && !additionalCameraData.isEditorCameraPreview));
}
}
}

35
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/GlobalIlluminationUtils.cs


ld.color = add.affectDiffuse ? LinearColor.Convert(l.color, l.intensity) : LinearColor.Black();
ld.indirectColor = add.affectDiffuse ? LightmapperUtils.ExtractIndirect(l) : LinearColor.Black();
// For HDRP we need to divide the analytic light color by PI (HDRP do explicit PI division for Lambert, but built in Unity and the GI don't)
// We apply it on both direct and indirect are they are separated, seems that direct is no used if we used mixed mode with indirect or shadowmask bake.
ld.color.red /= Mathf.PI;
ld.color.green /= Mathf.PI;
ld.color.blue /= Mathf.PI;
ld.indirectColor.red /= Mathf.PI;
ld.indirectColor.green /= Mathf.PI;
ld.indirectColor.blue /= Mathf.PI;
#if UNITY_EDITOR
#else
ld.mode = LightMode.Realtime;
#endif
// For HDRP we need to divide the analytic light color by PI (HDRP do explicit PI division for Lambert, but built in Unity and the GI don't for punctual lights)
// We apply it on both direct and indirect are they are separated, seems that direct is no used if we used mixed mode with indirect or shadowmask bake.
ld.color.intensity /= Mathf.PI;
ld.indirectColor.intensity /= Mathf.PI;
switch (l.type)
{
case LightType.Directional:

ld.shape1 = 0.0f;
#endif
// TEMP: for now, if we bake a rectangle type this will disable the light for runtime, need to speak with GI team about it!
// ld.type = UnityEngine.Experimental.GlobalIllumination.LightType.Rectangle;
ld.type = UnityEngine.Experimental.GlobalIllumination.LightType.Point;
ld.type = UnityEngine.Experimental.GlobalIllumination.LightType.Rectangle;
ld.InitNoBake(ld.instanceID);
}
else
{

for (int i = 0; i < requests.Length; i++)
{
Light l = requests[i];
LightDataGIExtract(l, ref ld);
#if UNITY_EDITOR
if (LightmapperUtils.Extract(l.lightmapBakeType) == LightMode.Realtime)
ld.InitNoBake(l.GetInstanceID());
else
LightDataGIExtract(l, ref ld);
#else
ld.InitNoBake(l.GetInstanceID());
#endif
lightsOutput[i] = ld;
}
};

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs


public Vector3 up; // Rescaled by (2 / shapeHeight)
public float diffuseScale;
public Vector2 fadeDistanceScaleAndBias; // Use with ShadowMask feature
public float unused0;
public float volumetricDimmer;
public float volumetricDimmer; // TODO: improve the cache locality
};
[GenerateHLSL]

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs.hlsl


float specularScale;
float3 up;
float diffuseScale;
float2 fadeDistanceScaleAndBias;
float unused0;
float volumetricDimmer;
float volumetricDimmer;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.LightData

{
return value.diffuseScale;
}
float2 GetFadeDistanceScaleAndBias(DirectionalLightData value)
{
return value.fadeDistanceScaleAndBias;
}
float GetUnused0(DirectionalLightData value)
float GetVolumetricDimmer(DirectionalLightData value)
return value.unused0;
return value.volumetricDimmer;
}
int GetDynamicShadowCasterOnly(DirectionalLightData value)
{

{
return value.shadowMaskSelector;
}
float GetVolumetricDimmer(DirectionalLightData value)
{
return value.volumetricDimmer;
}
//

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


#endif
#ifdef SHADOWS_SHADOWMASK
float fade = saturate(posInput.linearDepth * lightData.fadeDistanceScaleAndBias.x + lightData.fadeDistanceScaleAndBias.y);
// TODO: Optimize this code! Currently it is a bit like brute force to get the last transistion and fade to shadow mask, but there is
// certainly more efficient to do
// We reuse the transition from the cascade system to fade between shadow mask at max distance
uint payloadOffset;
real fade;
int cascadeCount;
int shadowSplitIndex = EvalShadow_GetSplitIndex(lightLoopContext.shadowContext, lightData.shadowIndex, positionWS, payloadOffset, fade, cascadeCount);
// we have a fade caclulation for each cascade but we must lerp with shadow mask only for the last one
fade = ((shadowSplitIndex + 1) == cascadeCount || shadowSplitIndex == -1.0) ? fade : 0.0;
shadow = lerp(shadow, shadowMask, fade); // Caution to lerp parameter: fade is the reverse of shadowDimmer
// In the transition code (both dithering and blend) we use shadow = lerp( shadow, 1.0, fade ) for last transition
// mean if we expend the code we have (shadow * (1 - fade) + fade). Here to make transition with shadow mask
// we will remove fade and add fade * shadowMask which mean we do a lerp with shadow mask
shadow = shadow - fade + fade * shadowMask;
// Note: There is no shadowDimmer when there is no shadow mask
#endif

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


// There is a dedicated RenderRenderPipelineSettings for each platform
[Serializable]
public enum CubeReflectionResolution
{
CubeReflectionResolution128 = 128,
CubeReflectionResolution256 = 256,
CubeReflectionResolution512 = 512,
CubeReflectionResolution1024 = 1024,
CubeReflectionResolution2048 = 2048,
CubeReflectionResolution4096 = 4096
}
[Serializable]
public enum PlanarReflectionResolution
{
PlanarReflectionResolution64 = 64,
PlanarReflectionResolution128 = 128,
PlanarReflectionResolution256 = 256,
PlanarReflectionResolution512 = 512,
PlanarReflectionResolution1024 = 1024,
PlanarReflectionResolution2048 = 2048,
PlanarReflectionResolution4096 = 4096,
PlanarReflectionResolution8192 = 8192,
PlanarReflectionResolution16384 = 16384
}
[Serializable]
public enum CookieResolution
{
CookieResolution64 = 64,
CookieResolution128 = 128,
CookieResolution256 = 256,
CookieResolution512 = 512,
CookieResolution1024 = 1024,
CookieResolution2048 = 2048,
CookieResolution4096 = 4096,
CookieResolution8192 = 8192,
CookieResolution16384 = 16384
}
[Serializable]
public enum CubeCookieResolution
{
CubeCookieResolution64 = 64,
CubeCookieResolution128 = 128,
CubeCookieResolution256 = 256,
CubeCookieResolution512 = 512,
CubeCookieResolution1024 = 1024,
CubeCookieResolution2048 = 2048,
CubeCookieResolution4096 = 4096
}
[Serializable]
public int cookieSize = 128;
public CookieResolution cookieSize = CookieResolution.CookieResolution128;
public int pointCookieSize = 128;
public CubeCookieResolution pointCookieSize = CubeCookieResolution.CubeCookieResolution128;
public int planarReflectionTextureSize = 1024;
public PlanarReflectionResolution planarReflectionTextureSize = PlanarReflectionResolution.PlanarReflectionResolution1024;
public int reflectionCubemapSize = 128;
public CubeReflectionResolution reflectionCubemapSize = CubeReflectionResolution.CubeReflectionResolution128;
public bool reflectionCacheCompressed = false;
public bool planarReflectionCacheCompressed = false;
public SkyResolution skyReflectionSize = SkyResolution.SkyResolution256;

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


int m_lightCount = 0;
int m_densityVolumeCount = 0;
bool m_enableBakeShadowMask = false; // Track if any light require shadow mask. In this case we will need to enable the keyword shadow mask
float m_maxShadowDistance = 0.0f; // Save value from shadow settings
private ComputeShader buildScreenAABBShader { get { return m_Resources.buildScreenAABBShader; } }
private ComputeShader buildPerTileLightListShader { get { return m_Resources.buildPerTileLightListShader; } }

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

directionalLightData.diffuseScale = additionalData.affectDiffuse ? diffuseDimmer : 0.0f;
directionalLightData.specularScale = additionalData.affectSpecular ? specularDimmer : 0.0f;
directionalLightData.volumetricDimmer = additionalData.volumetricDimmer;
directionalLightData.shadowIndex = directionalLightData.cookieIndex = -1;
if (light.light.cookie != null)

m_CurrentSunLightShadowIndex = shadowIdx;
}
float scale;
float bias;
GetScaleAndBiasForLinearDistanceFade(m_maxShadowDistance, out scale, out bias);
directionalLightData.fadeDistanceScaleAndBias = new Vector2(scale, bias);
directionalLightData.shadowMaskSelector = Vector4.zero;
if (IsBakedShadowMaskLight(light.light))

}
// Return true if BakedShadowMask are enabled
public bool PrepareLightsForGPU(CommandBuffer cmd, Camera camera, ShadowSettings shadowSettings, CullResults cullResults,
public bool PrepareLightsForGPU(CommandBuffer cmd, HDCamera hdCamera, ShadowSettings shadowSettings, CullResults cullResults,
Camera camera = hdCamera.camera;
m_maxShadowDistance = shadowSettings.maxShadowDistance;
m_lightList.Clear();
// We need to properly reset this here otherwise if we go from 1 light to no visible light we would keep the old reference active.

}
UpdateDataBuffers();
}
return m_enableBakeShadowMask;
}
m_enableBakeShadowMask = m_enableBakeShadowMask && hdCamera.frameSettings.enableShadowMask;
return m_enableBakeShadowMask;
}
static float CalculateProbeLogVolume(Bounds bounds)

64
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystemInternal.cs


#endif
// 1. Allocate if necessary target texture
var renderCamera = GetRenderCamera();
var hdCamera = HDCamera.Get(renderCamera);
if (hdCamera == null)
{
// Warning: this is a bad design pattern.
// An individual system should not create an HDCamera (which is a shared resource).
hdCamera = HDCamera.Create(renderCamera, null);
}
hdCamera.Update(null, probe.frameSettings, null);
if (!IsRealtimeTextureValid(probe.realtimeTexture, hdCamera))
if (!IsRealtimeTextureValid(probe.realtimeTexture))
{
if (probe.realtimeTexture != null)
probe.realtimeTexture.Release();

m_PlanarReflectionProbe_RequestRealtimeRender.Clear();
// 1. Allocate if necessary target texture
var camera = GetRenderCamera();
var hdCamera = HDCamera.Get(camera);
if (hdCamera == null)
{
// Warning: this is a bad design pattern.
// An individual system should not create an HDCamera (which is a shared resource).
hdCamera = HDCamera.Create(camera, null);
}
hdCamera.Update(null, probe.frameSettings, null);
if (!IsRealtimeTextureValid(probe.realtimeTexture, hdCamera))
if (!IsRealtimeTextureValid(probe.realtimeTexture))
{
if (probe.realtimeTexture != null)
probe.realtimeTexture.Release();

// }
//}
bool IsRealtimeTextureValid(RenderTexture renderTexture, HDCamera hdCamera)
bool IsRealtimeTextureValid(RenderTexture renderTexture)
{
return renderTexture != null
&& renderTexture.width == m_Parameters.planarReflectionProbeSize

public void Render(PlanarReflectionProbe probe, RenderTexture target, Camera viewerCamera = null)
{
var renderCamera = GetRenderHDCamera(probe);
renderCamera.camera.targetTexture = target;
var renderCamera = GetRenderCamera();
SetupCameraForRender(renderCamera.camera, probe, viewerCamera);
// Copy current frameSettings of this probe to the HDAdditionalData of the render camera
probe.frameSettings.CopyTo(s_RenderCameraData.GetFrameSettings());
renderCamera.targetTexture = target;
SetupCameraForRender(renderCamera, probe, viewerCamera);
renderCamera.camera.Render();
renderCamera.Render();
renderCamera.camera.targetTexture = null;
renderCamera.targetTexture = null;
target.IncrementUpdateCount();
}

var forward = reflectionMatrix.MultiplyVector(viewerCamera.transform.forward);
var up = reflectionMatrix.MultiplyVector(viewerCamera.transform.up);
captureRotation = Quaternion.LookRotation(forward, up);
}
public static HDCamera GetRenderHDCamera(PlanarReflectionProbe probe)
{
var camera = GetRenderCamera();
probe.frameSettings.CopyTo(s_RenderCameraData.GetFrameSettings());
var hdCamera = HDCamera.Get(camera);
if (hdCamera == null)
{
// Warning: this is a bad design pattern.
// An individual system should not create an HDCamera (which is a shared resource).
hdCamera = HDCamera.Create(camera, null);
}
hdCamera.Update(null, probe.frameSettings, null);
return hdCamera;
}
static Camera GetRenderCamera()

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/DensityVolumeManager.cs


{
volumeAtlas.RemoveTexture(volume.parameters.volumeMask);
}
//Upon removal we have to refresh the texture list.
TriggerVolumeAtlasRefresh();
}
public DensityVolume[] PrepareDensityVolumeData(CommandBuffer cmd)

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


// #pragma enable_d3d11_debug_symbols
#define SHADOW_USE_ONLY_VIEW_BASED_BIASING 1 // We don't use normal biasing as it is not available when doing volumetric
#include "../../ShaderPass/ShaderPass.cs.hlsl"
#define SHADERPASS SHADERPASS_VOLUMETRIC_LIGHTING

118
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


RTHandleSystem.RTHandle m_DensityBufferHandle;
RTHandleSystem.RTHandle m_LightingBufferHandle;
// Do we support volumetric or not?
bool m_supportVolumetric = false;
if (preset == VolumetricLightingPreset.Off) return;
m_supportVolumetric = asset.renderPipelineSettings.supportVolumetric;
if (!m_supportVolumetric)
return;
m_VolumeVoxelizationCS = asset.renderPipelineResources.volumeVoxelizationCS;
m_VolumetricLightingCS = asset.renderPipelineResources.volumetricLightingCS;

}
// For the initial allocation, no suballocation happens (the texture is full size).
VBufferParameters ComputeVBufferParameters(HDCamera camera, bool isInitialAllocation)
VBufferParameters ComputeVBufferParameters(HDCamera hdCamera, bool isInitialAllocation)
Vector3Int viewportResolution = ComputeVBufferResolution(preset, camera.camera.pixelWidth, camera.camera.pixelHeight);
Vector3Int viewportResolution = ComputeVBufferResolution(preset, hdCamera.camera.pixelWidth, hdCamera.camera.pixelHeight);
Vector3Int bufferResolution; // Could be higher due to sub-allocation (resource aliasing) in the RTHandle system
if (isInitialAllocation)

var controller = VolumeManager.instance.stack.GetComponent<VolumetricLightingController>();
// We must not allow the V-Buffer to extend outside of the camera's frustum.
float n = camera.camera.nearClipPlane;
float f = camera.camera.farClipPlane;
float n = hdCamera.camera.nearClipPlane;
float f = hdCamera.camera.farClipPlane;
Vector2 vBufferDepthRange = controller.depthRange.value;
vBufferDepthRange.y = Mathf.Clamp(vBufferDepthRange.y, n, f); // far

return new VBufferParameters(viewportResolution, bufferResolution, vBufferDepthRange, vBufferDepthDistributionUniformity);
}
public void InitializePerCameraData(HDCamera camera)
public void InitializePerCameraData(HDCamera hdCamera)
if (preset == VolumetricLightingPreset.Off) return;
// Note: Here we can't test framesettings as they are not initialize yet
// TODO: Here we allocate history even for camera that may not use volumetric
if (!m_supportVolumetric)
return;
var parameters = ComputeVBufferParameters(camera, true);
camera.vBufferParams = new VBufferParameters[2];
camera.vBufferParams[0] = parameters;
camera.vBufferParams[1] = parameters;
var parameters = ComputeVBufferParameters(hdCamera, true);
hdCamera.vBufferParams = new VBufferParameters[2];
hdCamera.vBufferParams[0] = parameters;
hdCamera.vBufferParams[1] = parameters;
if (camera.camera.cameraType == CameraType.Game ||
camera.camera.cameraType == CameraType.SceneView)
if (hdCamera.camera.cameraType == CameraType.Game ||
hdCamera.camera.cameraType == CameraType.SceneView)
// We don't need reprojection for other view types, such as reflection and preview.
camera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting, HistoryBufferAllocatorFunction);
// We don't need reprojection for other view types, such as reflection and preview.
hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting, HistoryBufferAllocatorFunction);
public void UpdatePerCameraData(HDCamera camera)
public void UpdatePerCameraData(HDCamera hdCamera)
if (preset == VolumetricLightingPreset.Off) return;
if (!hdCamera.frameSettings.enableVolumetric)
return;
var parameters = ComputeVBufferParameters(camera, false);
var parameters = ComputeVBufferParameters(hdCamera, false);
camera.vBufferParams[1] = camera.vBufferParams[0];
camera.vBufferParams[0] = parameters;
hdCamera.vBufferParams[1] = hdCamera.vBufferParams[0];
hdCamera.vBufferParams[0] = parameters;
// Note: resizing of history buffer is automatic (handled by the BufferedRTHandleSystem).
}

RTHandles.Release(m_DensityBufferHandle);
RTHandles.Release(m_LightingBufferHandle);
if (m_DensityBufferHandle != null)
RTHandles.Release(m_DensityBufferHandle);
if (m_LightingBufferHandle != null)
RTHandles.Release(m_LightingBufferHandle);
CoreUtils.SafeRelease(s_VisibleVolumeBoundsBuffer);
CoreUtils.SafeRelease(s_VisibleVolumeDataBuffer);

public void Cleanup()
{
if (preset == VolumetricLightingPreset.Off) return;
// Note: No need to test for support volumetric here, we do saferelease and null assignation
DestroyBuffers();
m_VolumeVoxelizationCS = null;

return (1.0f / (4.0f * Mathf.PI)) * 1.5f * (1.0f - g * g) / (2.0f + g * g);
}
public void PushGlobalParams(HDCamera camera, CommandBuffer cmd, uint frameIndex)
public void PushGlobalParams(HDCamera hdCamera, CommandBuffer cmd, uint frameIndex)
if (preset == VolumetricLightingPreset.Off) return;
if (!hdCamera.frameSettings.enableVolumetric)
return;
var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();

SetPreconvolvedAmbientLightProbe(cmd, fog.anisotropy);
var currFrameParams = camera.vBufferParams[0];
var prevFrameParams = camera.vBufferParams[1];
var currFrameParams = hdCamera.vBufferParams[0];
var prevFrameParams = hdCamera.vBufferParams[1];
cmd.SetGlobalVector( HDShaderIDs._VBufferResolution, currFrameParams.resolution);
cmd.SetGlobalVector( HDShaderIDs._VBufferSliceCount, currFrameParams.sliceCount);

cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, m_LightingBufferHandle);
}
public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera camera, CommandBuffer cmd)
public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera hdCamera, CommandBuffer cmd)
if (preset == VolumetricLightingPreset.Off) return densityVolumes;
if (!hdCamera.frameSettings.enableVolumetric)
return densityVolumes;
if (visualEnvironment.fogType != FogType.Volumetric) return densityVolumes;
if (visualEnvironment.fogType != FogType.Volumetric)
return densityVolumes;
Vector3 camPosition = camera.camera.transform.position;
Vector3 camPosition = hdCamera.camera.transform.position;
Vector3 camOffset = Vector3.zero; // World-origin-relative
if (ShaderConfig.s_CameraRelativeRendering != 0)

// Frustum cull on the CPU for now. TODO: do it on the GPU.
// TODO: account for custom near and far planes of the V-Buffer's frustum.
// It's typically much shorter (along the Z axis) than the camera's frustum.
if (GeometryUtils.Overlap(obb, camera.frustum, 6, 8))
if (GeometryUtils.Overlap(obb, hdCamera.frustum, 6, 8))
{
// TODO: cache these?
var data = volume.parameters.GetData();

}
}
public void VolumeVoxelizationPass(DensityVolumeList densityVolumes, HDCamera camera, CommandBuffer cmd, FrameSettings settings, uint frameIndex)
public void VolumeVoxelizationPass(HDCamera hdCamera, CommandBuffer cmd, uint frameIndex, DensityVolumeList densityVolumes)
if (preset == VolumetricLightingPreset.Off) return;
if (!hdCamera.frameSettings.enableVolumetric)
return;
if (visualEnvironment.fogType != FogType.Volumetric) return;
if (visualEnvironment.fogType != FogType.Volumetric)
return;
using (new ProfilingSample(cmd, "Volume Voxelization"))
{

// Use the workaround by running the full shader with 0 density
}
bool enableClustered = settings.lightLoopSettings.enableTileAndCluster;
bool enableClustered = hdCamera.frameSettings.lightLoopSettings.enableTileAndCluster;
var frameParams = camera.vBufferParams[0];
var frameParams = hdCamera.vBufferParams[0];
float vFoV = camera.camera.fieldOfView * Mathf.Deg2Rad;
float vFoV = hdCamera.camera.fieldOfView * Mathf.Deg2Rad;
Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, resolution, camera.viewMatrix, false);
Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, resolution, hdCamera.viewMatrix, false);
Texture3D volumeAtlas = DensityVolumeManager.manager.volumeAtlas.volumeAtlas;
Vector2 volumeAtlasDimensions = new Vector2(0.0f, 0.0f);

return coords;
}
public void VolumetricLightingPass(HDCamera camera, CommandBuffer cmd, FrameSettings settings, uint frameIndex)
public void VolumetricLightingPass(HDCamera hdCamera, CommandBuffer cmd, uint frameIndex)
if (preset == VolumetricLightingPreset.Off) return;
if (!hdCamera.frameSettings.enableVolumetric)
return;
if (visualEnvironment.fogType != FogType.Volumetric) return;
if (visualEnvironment.fogType != FogType.Volumetric)
return;
bool enableClustered = settings.lightLoopSettings.enableTileAndCluster;
bool enableReprojection = Application.isPlaying && camera.camera.cameraType == CameraType.Game;
bool enableClustered = hdCamera.frameSettings.lightLoopSettings.enableTileAndCluster;
bool enableReprojection = Application.isPlaying && hdCamera.camera.cameraType == CameraType.Game;
int kernel;

: "VolumetricLightingBruteforce");
}
var frameParams = camera.vBufferParams[0];
var frameParams = hdCamera.vBufferParams[0];
float vFoV = camera.camera.fieldOfView * Mathf.Deg2Rad;
float vFoV = hdCamera.camera.fieldOfView * Mathf.Deg2Rad;
Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, resolution, camera.viewMatrix, false);
Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, resolution, hdCamera.viewMatrix, false);
Vector2[] xySeq = GetHexagonalClosePackedSpheres7();

cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingIntegral, m_LightingBufferHandle); // Write
if (enableReprojection)
{
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingHistory, camera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting)); // Read
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingFeedback, camera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting)); // Write
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingHistory, hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting)); // Read
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingFeedback, hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting)); // Write
}
int w = (int)resolution.x;

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DBufferManager.cs


cmd.SetGlobalTexture(HDShaderIDs._DecalHTileTexture, m_HTile);
}
public void PushGlobalParams(CommandBuffer cmd, FrameSettings frameSettings)
public void PushGlobalParams(HDCamera hdCamera, CommandBuffer cmd)
if (frameSettings.enableDBuffer)
if (hdCamera.frameSettings.enableDBuffer)
{
cmd.SetGlobalInt(HDShaderIDs._EnableDBuffer, vsibleDecalCount > 0 ? 1 : 0);
cmd.SetGlobalVector(HDShaderIDs._DecalAtlasResolution, new Vector2(HDUtils.hdrpSettings.decalSettings.atlasWidth, HDUtils.hdrpSettings.decalSettings.atlasHeight));

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalData.hlsl


surfaceData.mask = float4(0,0,0,0);
surfaceData.HTileMask = 0;
float totalBlend = clamp(normalToWorld[0][3], 0.0f, 1.0f);
float2 scale = float2(normalToWorld[3][0], normalToWorld[3][1]);
float2 offset = float2(normalToWorld[3][2], normalToWorld[3][3]);
texCoordDS = texCoordDS * scale + offset;
#if _COLORMAP
surfaceData.baseColor = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, texCoordDS.xy);
surfaceData.baseColor.w *= totalBlend;

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalUtilities.hlsl


positionDS = positionDS * float3(1.0, -1.0, 1.0) + float3(0.5, 0.0f, 0.5); // decal clip space
if ((all(positionDS.xyz > 0.0f) && all(1.0f - positionDS.xyz > 0.0f)))
{
float2 uvScale = float2(decalData.normalToWorld[3][0], decalData.normalToWorld[3][1]);
float2 uvBias = float2(decalData.normalToWorld[3][2], decalData.normalToWorld[3][3]);
positionDS.xz = positionDS.xz * uvScale + uvBias;
positionDS.xz = frac(positionDS.xz);
// clamp by half a texel to avoid sampling neighboring textures in the atlas
float2 clampAmount = float2(0.5f / _DecalAtlasResolution.x, 0.5f / _DecalAtlasResolution.y);

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


float3x3 ltcTransformCoat; // Inverse transformation for GGX (4x VGPRs)
float ltcMagnitudeCoatFresnel;
#if HAS_REFRACTION
#endif
ZERO_INITIALIZE(PreLightData, preLightData);
// Don't init to zero to allow to track warning about uninitialized data
float3 N = bsdfData.normalWS;
preLightData.NdotV = dot(N, V);

ltcGGXFresnelMagnitude = ltcMagnitude.g;
preLightData.ltcMagnitudeCoatFresnel = (CLEAR_COAT_F0 * ltcGGXFresnelMagnitudeDiff + ltcGGXFresnelMagnitude) * bsdfData.coatMask;
}
else
{
preLightData.ltcTransformCoat = 0.0;
preLightData.ltcMagnitudeCoatFresnel = 0.0;
}
#ifdef REFRACTION_MODEL
#if HAS_REFRACTION
RefractionModelResult refraction = REFRACTION_MODEL(V, posInput, bsdfData);
preLightData.transparentRefractV = refraction.rayWS;
preLightData.transparentPositionWS = refraction.positionWS;

float3 R = preLightData.iblR;
#if HAS_REFRACTION
#endif
// Note: using influenceShapeType and projectionShapeType instead of (lightData|proxyData).shapeType allow to make compiler optimization in case the type is know (like for sky)
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, R, weight);

// Can't attenuate diffuse lighting here, may try to apply something on bakeLighting in PostEvaluateBSDF
}
}
#if HAS_REFRACTION
else
{
// No clear coat support with refraction

envLighting = (1.0 - F) * preLD.rgb * preLightData.transparentTransmittance;
}
#endif
#endif // LIT_DISPLAY_REFERENCE_IBL

if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
lighting.specularReflected = envLighting;
#if HAS_REFRACTION
#endif
return lighting;
}

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs


StackLitIridescence = 1 << 4,
StackLitSubsurfaceScattering = 1 << 5,
StackLitTransmission = 1 << 6,
StackLitCoatNormalMap = 1 << 7,
};
//-----------------------------------------------------------------------------

[SurfaceDataAttributes(new string[]{"Normal", "Normal View Space"}, true)]
public Vector3 normalWS;
[SurfaceDataAttributes(new string[]{"Geometric Normal", "Geometric Normal View Space"}, true)]
public Vector3 geomNormalWS;
[SurfaceDataAttributes(new string[]{"Coat Normal", "Coat Normal View Space"}, true)]
public Vector3 coatNormalWS;
[SurfaceDataAttributes("Smoothness A")]
public float perceptualSmoothnessA;

[SurfaceDataAttributes(new string[] { "Normal WS", "Normal View Space" }, true)]
public Vector3 normalWS;
[SurfaceDataAttributes(new string[]{"Geometric Normal", "Geometric Normal View Space"}, true)]
public Vector3 geomNormalWS;
[SurfaceDataAttributes(new string[]{"Coat Normal", "Coat Normal View Space"}, true)]
public Vector3 coatNormalWS;
public float perceptualRoughnessA;
// Dual specular lobe

111
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs.hlsl


#define MATERIALFEATUREFLAGS_STACK_LIT_IRIDESCENCE (16)
#define MATERIALFEATUREFLAGS_STACK_LIT_SUBSURFACE_SCATTERING (32)
#define MATERIALFEATUREFLAGS_STACK_LIT_TRANSMISSION (64)
#define MATERIALFEATUREFLAGS_STACK_LIT_COAT_NORMAL_MAP (128)
//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+SurfaceData: static fields

#define DEBUGVIEW_STACKLIT_SURFACEDATA_IOR (1304)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL (1305)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL_VIEW_SPACE (1306)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A (1307)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_B (1308)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_LOBE_MIXING (1309)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_TANGENT (1310)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY (1311)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_IOR (1312)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS (1313)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_ROUGHNESS (1314)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR (1315)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS (1316)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT (1317)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_DIFFUSION_PROFILE (1318)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SUBSURFACE_MASK (1319)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_THICKNESS (1320)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_GEOMETRIC_NORMAL (1307)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_GEOMETRIC_NORMAL_VIEW_SPACE (1308)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL (1309)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL_VIEW_SPACE (1310)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A (1311)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_B (1312)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_LOBE_MIXING (1313)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_TANGENT (1314)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY (1315)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_IOR (1316)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS (1317)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_SMOOTHNESS (1318)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR (1319)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS (1320)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT (1321)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_DIFFUSION_PROFILE (1322)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SUBSURFACE_MASK (1323)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_THICKNESS (1324)
//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+BSDFData: static fields

#define DEBUGVIEW_STACKLIT_BSDFDATA_AMBIENT_OCCLUSION (1403)
#define DEBUGVIEW_STACKLIT_BSDFDATA_NORMAL_WS (1404)
#define DEBUGVIEW_STACKLIT_BSDFDATA_NORMAL_VIEW_SPACE (1405)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_A (1406)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_B (1407)
#define DEBUGVIEW_STACKLIT_BSDFDATA_LOBE_MIX (1408)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TANGENT_WS (1409)
#define DEBUGVIEW_STACKLIT_BSDFDATA_BITANGENT_WS (1410)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AT (1411)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AB (1412)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BT (1413)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BB (1414)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ANISOTROPY (1415)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_ROUGHNESS (1416)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_PERCEPTUAL_ROUGHNESS (1417)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_IOR (1418)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_THICKNESS (1419)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_EXTINCTION (1420)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_IOR (1421)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_THICKNESS (1422)
#define DEBUGVIEW_STACKLIT_BSDFDATA_DIFFUSION_PROFILE (1423)
#define DEBUGVIEW_STACKLIT_BSDFDATA_SUBSURFACE_MASK (1424)
#define DEBUGVIEW_STACKLIT_BSDFDATA_THICKNESS (1425)
#define DEBUGVIEW_STACKLIT_BSDFDATA_USE_THICK_OBJECT_MODE (1426)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TRANSMITTANCE (1427)
#define DEBUGVIEW_STACKLIT_BSDFDATA_GEOMETRIC_NORMAL (1406)
#define DEBUGVIEW_STACKLIT_BSDFDATA_GEOMETRIC_NORMAL_VIEW_SPACE (1407)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_NORMAL (1408)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_NORMAL_VIEW_SPACE (1409)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_A (1410)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_B (1411)
#define DEBUGVIEW_STACKLIT_BSDFDATA_LOBE_MIX (1412)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TANGENT_WS (1413)
#define DEBUGVIEW_STACKLIT_BSDFDATA_BITANGENT_WS (1414)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AT (1415)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AB (1416)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BT (1417)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BB (1418)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ANISOTROPY (1419)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_ROUGHNESS (1420)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_PERCEPTUAL_ROUGHNESS (1421)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_IOR (1422)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_THICKNESS (1423)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_EXTINCTION (1424)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_IOR (1425)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_THICKNESS (1426)
#define DEBUGVIEW_STACKLIT_BSDFDATA_DIFFUSION_PROFILE (1427)
#define DEBUGVIEW_STACKLIT_BSDFDATA_SUBSURFACE_MASK (1428)
#define DEBUGVIEW_STACKLIT_BSDFDATA_THICKNESS (1429)
#define DEBUGVIEW_STACKLIT_BSDFDATA_USE_THICK_OBJECT_MODE (1430)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TRANSMITTANCE (1431)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.StackLit+SurfaceData
// PackingRules = Exact

float metallic;
float dielectricIor;
float3 normalWS;
float3 geomNormalWS;
float3 coatNormalWS;
float perceptualSmoothnessA;
float perceptualSmoothnessB;
float lobeMix;

float3 fresnel0;
float ambientOcclusion;
float3 normalWS;
float3 geomNormalWS;
float3 coatNormalWS;
float perceptualRoughnessA;
float perceptualRoughnessB;
float lobeMix;

case DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL_VIEW_SPACE:
result = surfacedata.normalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_GEOMETRIC_NORMAL:
result = surfacedata.geomNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_GEOMETRIC_NORMAL_VIEW_SPACE:
result = surfacedata.geomNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL:
result = surfacedata.coatNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL_VIEW_SPACE:
result = surfacedata.coatNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A:
result = surfacedata.perceptualSmoothnessA.xxx;
break;

case DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS:
result = surfacedata.iridescenceThickness.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_ROUGHNESS:
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_SMOOTHNESS:
result = surfacedata.coatPerceptualSmoothness.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR:

break;
case DEBUGVIEW_STACKLIT_BSDFDATA_NORMAL_VIEW_SPACE:
result = bsdfdata.normalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_GEOMETRIC_NORMAL:
result = bsdfdata.geomNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_GEOMETRIC_NORMAL_VIEW_SPACE:
result = bsdfdata.geomNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_COAT_NORMAL:
result = bsdfdata.coatNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_COAT_NORMAL_VIEW_SPACE:
result = bsdfdata.coatNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_A:
result = bsdfdata.perceptualRoughnessA.xxx;

713
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl


// Vlayer config options:
//#define VLAYERED_RECOMPUTE_PERLIGHT // TODO test more, make it a shader_features
#ifdef _VLAYERED_RECOMPUTE_PERLIGHT
#define VLAYERED_RECOMPUTE_PERLIGHT
// Now a shader_features
//#define VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
#endif
#ifdef _VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
#define VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
#endif
#define VLAYERED_DIFFUSE_ENERGY_HACKED_TERM
//#define VLAYERED_ANISOTROPY_IBL_DESTRETCH

// Mostly for struct array declarations, not really loops:
#ifdef _MATERIAL_FEATURE_COAT
#ifdef _MATERIAL_FEATURE_COAT_NORMALMAP
# define NB_NORMALS 2 // NB of interfaces with different normals (for additional clear coat normal map)
#else
# define NB_NORMALS 1
#endif
#if defined(VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE)
# define NB_LV_DIR 2 // NB of interfaces with different L or V directions to consider (see BSDF( ) )
#else
# define NB_LV_DIR 1
#endif
#else
#else // ! _MATERIAL_FEATURE_COAT
# undef VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
# undef _MATERIAL_FEATURE_COAT_NORMALMAP // enforce a "coat enabled subfeature" condition on this shader_feature
# define NB_NORMALS 1
# define NB_LV_DIR 1
#endif
#endif // #ifdef _MATERIAL_FEATURE_COAT
// For NB_NORMALS arrays:
#define COAT_NORMAL_IDX 0
#define BASE_NORMAL_IDX (NB_NORMALS-1)
// For NB_LV_DIR arrays: make sure these indices match the above
#define TOP_DIR_IDX 0
#define BOTTOM_DIR_IDX (NB_LV_DIR-1)
// TODO: if dual lobe base
//#define BASE_NB_LOBES 1

return (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT));
}
bool IsCoatNormalMapEnabled(BSDFData bsdfData)
{
return (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT_NORMAL_MAP));
}
// Assume that bsdfData.diffusionProfile is init
void FillMaterialSSS(uint diffusionProfile, float subsurfaceMask, inout BSDFData bsdfData)
{

return sssData;
}
// Specular antialiasing
float NormalCurvatureToRoughness(float3 n)
{
float3 dNdx = ddx(n);
float3 dNdy = ddy(n);
float curvature = pow(max(dot(dNdx, dNdx), dot(dNdy, dNdy)), _NormalCurvatureToRoughnessExponent);
return saturate(curvature * _NormalCurvatureToRoughnessScale + _NormalCurvatureToRoughnessBias);
}
float FilterRoughness_TOKUYOSHI(float3 n, float r)
{
float3 deltaU = ddx(n);
float3 deltaV = ddy(n);
float variance = _SpecularAntiAliasingScreenSpaceVariance * (dot(deltaU, deltaU) + dot(deltaV, deltaV));
float squaredRoughness = saturate(r * r + min(2.0 * variance, _SpecularAntiAliasingThreshold));
return sqrt(squaredRoughness);
}
//-----------------------------------------------------------------------------
// conversion function for forward
//-----------------------------------------------------------------------------

// IMPORTANT: In our forward only case, all enable flags are statically know at compile time, so the compiler can do compile time optimization
bsdfData.materialFeatures = surfaceData.materialFeatures;
bsdfData.geomNormalWS = surfaceData.geomNormalWS; // We should always have this whether we enable coat normals or not.
// Specular AA: NormalCurvatureToRoughness
float normalCurvatureToRoughnessA = max(NormalCurvatureToRoughness(bsdfData.normalWS), bsdfData.perceptualRoughnessA);
float normalCurvatureToRoughnessB = max(NormalCurvatureToRoughness(bsdfData.normalWS), bsdfData.perceptualRoughnessB);
bsdfData.perceptualRoughnessA = lerp(bsdfData.perceptualRoughnessA, normalCurvatureToRoughnessA, _NormalCurvatureToRoughnessEnabled);
bsdfData.perceptualRoughnessB = lerp(bsdfData.perceptualRoughnessB, normalCurvatureToRoughnessB, _NormalCurvatureToRoughnessEnabled);
// Specular AA: Tokuyoshi Filtering.
float filterRoughnessA = FilterRoughness_TOKUYOSHI(bsdfData.normalWS, bsdfData.perceptualRoughnessA);
float filterRoughnessB = FilterRoughness_TOKUYOSHI(bsdfData.normalWS, bsdfData.perceptualRoughnessB);
bsdfData.perceptualRoughnessA = lerp(bsdfData.perceptualRoughnessA, filterRoughnessA, _SpecularAntiAliasingEnabled);
bsdfData.perceptualRoughnessB = lerp(bsdfData.perceptualRoughnessB, filterRoughnessB, _SpecularAntiAliasingEnabled);
bsdfData.lobeMix = surfaceData.lobeMix;
// There is no metallic with SSS and specular color mode

if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT))
{
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT_NORMAL_MAP))
{
bsdfData.coatNormalWS = surfaceData.coatNormalWS;
}
FillMaterialCoatData(PerceptualSmoothnessToPerceptualRoughness(surfaceData.coatPerceptualSmoothness),
surfaceData.coatIor, surfaceData.coatThickness, surfaceData.coatExtinction, bsdfData);

// GetPreLightData prototype.
//-----------------------------------------------------------------------------
float NdotV; // Could be negative due to normal mapping, use ClampNdotV()
float NdotV[NB_NORMALS]; // Could be negative due to normal mapping, use ClampNdotV()
//float NdotV;
float bottomAngleFGD;
float TdotV; // Stored only when VLAYERED_RECOMPUTE_PERLIGHT
float BdotV;

return newAniso;
}
// Get the orthogonal component (or complement) of a vector V with regard to the vector N.
float3 GetOrthogonalComponent(float3 V, float3 N)
{
// V and N are supposed to be unit vectors
float VdotN = dot(V, N);
float3 VOrtho = V - VdotN * N;
float3 unitVOrtho = VOrtho * rsqrt(1.0 - Sq(VdotN));
return unitVOrtho;
}
float3 GetDirFromAngleAndOrthoFrame(float3 V, float3 N, float newVdotN)
{
float sintheta = sqrt(1.0 - Sq(newVdotN));
float3 newV = newVdotN * N + sintheta * V;
return newV;
}
void ComputeAdding_GetVOrthoGeomN(BSDFData bsdfData, float3 V, bool calledPerLight, out float3 vOrthoGeomN, out bool useGeomN)
{
vOrthoGeomN = (float3)0;
useGeomN = false;
if( !calledPerLight && IsCoatNormalMapEnabled(bsdfData) )
{
// In that case, since we have 2 normal maps we need to decide on a common orientation
// for our parallel interface model, otherwise the series expression doesn't make any
// sense. We will settle on using the geometric normal. It will be used for
// average mean propagation but all FGD or Fresnel terms will use the corresponding
// interface's normal map's normal for calculation. IBL fetches and lighting
// calculations (shading) for analytical lights should also use these.
// The rational for the later is that the resulting stats are still a local model, so
// all scattered rays should exit back up with the same normal as the ray that spawned
// them had on entry on top. So we assume bending is cancelled out.
//
// Also, since we are using a fake (and adjusted / lerped depending on roughness)
// refraction for the top (coat) interface, and this will be done, like stated,
// using the geometric normal, we will reconstruct a direction for the bottom
// interface using the "V and geomNormalWS" plane as a plane of incidence. So we
// calculate a pseudo-refracted angle in this plane, and with an orthogonal basis
// of it (2D basis embedded in 3D, ie basis formed by two 3D vectors)
// (using the orthogonal complement of V vs geomNormalWS), we will reconstruct
// the "V at the bottom interface". This V will then in turn be usable for further
// FGD / Fresnel calculations with the bottom interface normal (from the bottom
// normal map), which is not necessarily coplanar with V and geomNormalWS, hence
// this method.
//
// In all other cases: we either don't have a dual normal map, or we recompute the
// stats per light and in that case, the H vector serves as a common orientation
// and we calculate everything with it anyway (symmetric parametrization), so no
// normal map is involved.
vOrthoGeomN = GetOrthogonalComponent(V, bsdfData.geomNormalWS);
useGeomN = true;
}
}
//-----------------------------------------------------------------------------
// About layered BSDF statistical lobe data calculations:

// T12 should be multiplied by TIR.
// (more like p8, T21 <- T21*TIR, R21 <- R21 + (1-TIR)*T21 )
//
void ComputeStatistics(in float cti, in int i, in BSDFData bsdfData,
//ComputeStatistics(cti, V, vOrthoGeomN, useGeomN, i, bsdfData, preLightData, ctt, R12, T12, R21, T21, s_r12, s_t12, j12, s_r21, s_t21, j21);
void ComputeStatistics(in float cti, in float3 V, in float3 vOrthoGeomN, in bool useGeomN, in int i, in BSDFData bsdfData,
inout PreLightData preLightData,
out float ctt,
out float3 R12, out float3 T12, out float3 R21, out float3 T21,
out float s_r12, out float s_t12, out float j12,

n12 = GetCoatEta(bsdfData); //n2/n1;
R0 = FresnelUnpolarized(cti, n12, 1.0);
// At this point cti should be properly (coatNormalWS dot V) or NdotV or VdotH, see ComputeAdding.
// In the special case where we do have a coat normal, we will propagate a different angle than
// (coatNormalWS dot V) and vOrthoGeomN will be used.
// vOrthoGeomN is the orthogonal complement of V wrt geomNormalWS.
if (useGeomN)
{
cti = ClampNdotV(dot(bsdfData.geomNormalWS, V));
}
R12 = R0; // TODO: FGD
T12 = 1.0 - R12;

}
else
{
float ctiForFGD = cti;
// If we use the geometric normal propagation hack, we want to calculate FGD / Fresnel with
// an angle at the bottom interface between the average propagated direction and the normal from
// the bottom normal map. For that, we will recover a direction from the angle we propagated in
// the "V and geomNormalWS" plane of incidence. That direction will then serve to calculate an
// angle with the non-coplanar bottom normal from the normal map.
if (useGeomN)
{
float3 bottomDir = GetDirFromAngleAndOrthoFrame(vOrthoGeomN, bsdfData.geomNormalWS, cti);
ctiForFGD = ClampNdotV(dot(bsdfData.normalWS, bottomDir));
}
// We will also save this average bottom angle:
preLightData.bottomAngleFGD = ctiForFGD;
R12 = F_Schlick(bsdfData.fresnel0, cti);
R12 = F_Schlick(bsdfData.fresnel0, ctiForFGD);
T12 = 0.0;
#ifdef VLAYERED_DIFFUSE_ENERGY_HACKED_TERM
// Still should use FGD!

} //...ComputeStatistics()
void ComputeAdding(float _cti, in BSDFData bsdfData, inout PreLightData preLightData, bool calledPerLight = false)
void ComputeAdding(float _cti, float3 V, in BSDFData bsdfData, inout PreLightData preLightData, bool calledPerLight = false)
// _cti should be LdotH or VdotH if calledPerLight == true (symmetric parametrization), V is unused in this case.
// _cti should be NdotV if calledPerLight == false and no independent coat normal map is used (ie single normal map), V is unused in this case.
// _cti should be (coatNormalWS dot V) if calledPerLight == false and we have a coat normal map. V is used in this case
if( _DebugLobeMask.w == 0.0)
if( _DebugEnvLobeMask.w == 0.0)
{
preLightData.vLayerEnergyCoeff[COAT_LOBE_IDX] = 0.0 * F_Schlick(IorToFresnel0(bsdfData.coatIor), _cti);
preLightData.iblPerceptualRoughness[COAT_LOBE_IDX] = bsdfData.coatPerceptualRoughness;

#endif
// Global Variables
// Decide if we need the special path/hack for the coat normal map mode:
bool useGeomN;
float3 vOrthoGeomN; // only valid if useGeomN == true
ComputeAdding_GetVOrthoGeomN(bsdfData, V, calledPerLight, vOrthoGeomN, useGeomN);
float cti = _cti;
float3 R0i = float3(0.0, 0.0, 0.0), Ri0 = float3(0.0, 0.0, 0.0),
T0i = float3(1.0, 1.0, 1.0), Ti0 = float3(1.0, 1.0, 1.0);

float s_r21=0.0, s_t12=0.0, s_t21=0.0, j12=1.0, j21=1.0, ctt;
// Layer specific evaluation of the transmittance, reflectance, variance
ComputeStatistics(cti, i, bsdfData, ctt, R12, T12, R21, T21, s_r12, s_t12, j12, s_r21, s_t21, j21);
ComputeStatistics(cti, V, vOrthoGeomN, useGeomN, i, bsdfData, preLightData, ctt, R12, T12, R21, T21, s_r12, s_t12, j12, s_r21, s_t21, j21);
// Multiple scattering forms
float3 denom = (float3(1.0, 1.0, 1.0) - Ri0*R12); //i = new layer, 0 = cumulative top (llab3.1 to 3.4)

// Then we need anisotropic roughness updates again for the 2
// bottom lobes, for analytical lights.
//
// TODO: VLAYERED_RECOMPUTE_PERLIGHT and calledPerLight bool
// First, to be less messy, immediately transfer vLayerPerceptualRoughness
// data into the iblPerceptualRoughness[] array

}
#endif
if( !perLightOption )
if( !perLightOption || calledPerLight)
{
ConvertAnisotropyToClampRoughness(preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX], preLightData.iblAnisotropy[0],
preLightData.layeredRoughnessT[0], preLightData.layeredRoughnessB[0]);

// slnote dual map
float PreLightData_GetBaseNdotVForFGD(BSDFData bsdfData, PreLightData preLightData, float NdotV[NB_NORMALS])
{
float baseLayerNdotV;
if ( IsCoatNormalMapEnabled(bsdfData) )
{
baseLayerNdotV = preLightData.bottomAngleFGD;
}
else
{
//slnote: TODO TOTEST
//baseLayerNdotV = preLightData.bottomAngleFGD;
baseLayerNdotV = sqrt(1 + Sq(preLightData.coatIeta)*(Sq(NdotV[0]) - 1));
//TODO refactor with EvalIridescence, Lit::GetPreLightData
}
return baseLayerNdotV;
}
// slnote dual map
void PreLightData_SetupNormals(BSDFData bsdfData, inout PreLightData preLightData, float3 V, out float3 N[NB_NORMALS], out float NdotV[NB_NORMALS])
{
N[BASE_NORMAL_IDX] = bsdfData.normalWS;
preLightData.NdotV[BASE_NORMAL_IDX] = dot(N[BASE_NORMAL_IDX], V);
NdotV[BASE_NORMAL_IDX] = ClampNdotV(preLightData.NdotV[BASE_NORMAL_IDX]);
#ifdef _MATERIAL_FEATURE_COAT_NORMALMAP
if ( IsCoatNormalMapEnabled(bsdfData) )
{
N[COAT_NORMAL_IDX] = bsdfData.coatNormalWS;
preLightData.NdotV[COAT_NORMAL_IDX] = dot(N[COAT_NORMAL_IDX], V);
NdotV[COAT_NORMAL_IDX] = ClampNdotV(preLightData.NdotV[COAT_NORMAL_IDX]);
}
#endif
}
PreLightData GetPreLightData(float3 V, PositionInputs posInput, inout BSDFData bsdfData)
{

float3 N = bsdfData.normalWS;
preLightData.NdotV = dot(N, V);
float NdotV = ClampNdotV(preLightData.NdotV);
float3 N[NB_NORMALS];
float NdotV[NB_NORMALS];
PreLightData_SetupNormals(bsdfData, preLightData, V, N, NdotV);
preLightData.diffuseEnergy = float3(1.0, 1.0, 1.0);

// iblR (fetch direction compensated dominant spec)
// iblR (fetch direction in dominant spec direction / compensated for offspecular effect)
// energyCompensation (to a apply for each light sample since with multiple roughnesses, it becomes lobe specific)
// energyCompensation (to apply for each light sample since with multiple roughnesses, it becomes lobe specific)
//
// We also need for analytical lights:
//

float3 iblR[TOTAL_NB_LOBES];
float specularReflectivity[TOTAL_NB_LOBES];
float diffuseFGD[BASE_NB_LOBES];
float baseLayerNdotV = NdotV;
if( IsVLayeredEnabled(bsdfData) )
{

// --------------------------------------------------------------------
// A secondary coat normal map is possible here, NdotV[] and N[] are sized
// accordingly and are accessed by COAT|BASE_NORMAL_IDX
ComputeAdding(NdotV, bsdfData, preLightData, false);
ComputeAdding(NdotV[COAT_NORMAL_IDX], V, bsdfData, preLightData, false);
// After ComputeAdding, these are done for all lobes:
//

#ifndef VLAYERED_RECOMPUTE_PERLIGHT
// We can precalculate lambdaVs for all lights here since we're not doing ComputeAdding per light
preLightData.partLambdaV[COAT_LOBE_IDX] = GetSmithJointGGXPartLambdaV(NdotV, preLightData.layeredCoatRoughness);
preLightData.partLambdaV[BASE_LOBEA_IDX] = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, preLightData.layeredRoughnessT[0], preLightData.layeredRoughnessB[0]);
preLightData.partLambdaV[BASE_LOBEB_IDX] = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, preLightData.layeredRoughnessT[1], preLightData.layeredRoughnessB[1]);
preLightData.partLambdaV[COAT_LOBE_IDX] = GetSmithJointGGXPartLambdaV(NdotV[COAT_NORMAL_IDX], preLightData.layeredCoatRoughness);
preLightData.partLambdaV[BASE_LOBEA_IDX] = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV[BASE_NORMAL_IDX],
preLightData.layeredRoughnessT[0], preLightData.layeredRoughnessB[0]);
preLightData.partLambdaV[BASE_LOBEB_IDX] = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV[BASE_NORMAL_IDX],
preLightData.layeredRoughnessT[1], preLightData.layeredRoughnessB[1]);
#else
// Store those for eval analytical lights since we're going to
// recalculate lambdaV after each ComputeAdding for each light

stretch[0] = abs(preLightData.iblAnisotropy[0]) * saturate(5 * preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX]);
stretch[1] = abs(preLightData.iblAnisotropy[1]) * saturate(5 * preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX]);
iblN[COAT_LOBE_IDX] = N; // no anisotropy for coat.
iblN[BASE_LOBEA_IDX] = GetAnisotropicModifiedNormal(grainDirWS[0], N, V, stretch[0]);
iblN[BASE_LOBEB_IDX] = GetAnisotropicModifiedNormal(grainDirWS[1], N, V, stretch[1]);
iblN[COAT_LOBE_IDX] = N[COAT_NORMAL_IDX]; // no anisotropy for coat.
iblN[BASE_LOBEA_IDX] = GetAnisotropicModifiedNormal(grainDirWS[0], N[BASE_NORMAL_IDX], V, stretch[0]);
iblN[BASE_LOBEB_IDX] = GetAnisotropicModifiedNormal(grainDirWS[1], N[BASE_NORMAL_IDX], V, stretch[1]);
}
else

// We can precalculate lambdaVs for all lights here since we're not doing ComputeAdding per light
preLightData.partLambdaV[COAT_LOBE_IDX] = GetSmithJointGGXPartLambdaV(NdotV, preLightData.layeredCoatRoughness);
preLightData.partLambdaV[BASE_LOBEA_IDX] = GetSmithJointGGXPartLambdaV(NdotV, preLightData.layeredRoughnessT[0]);
preLightData.partLambdaV[BASE_LOBEB_IDX] = GetSmithJointGGXPartLambdaV(NdotV, preLightData.layeredRoughnessT[1]);
preLightData.partLambdaV[COAT_LOBE_IDX] = GetSmithJointGGXPartLambdaV(NdotV[COAT_NORMAL_IDX], preLightData.layeredCoatRoughness);
preLightData.partLambdaV[BASE_LOBEA_IDX] = GetSmithJointGGXPartLambdaV(NdotV[BASE_NORMAL_IDX], preLightData.layeredRoughnessT[0]);
preLightData.partLambdaV[BASE_LOBEB_IDX] = GetSmithJointGGXPartLambdaV(NdotV[BASE_NORMAL_IDX], preLightData.layeredRoughnessT[1]);
iblN[0] = iblN[1] = iblN[2] = N;
iblN[COAT_LOBE_IDX] = N[COAT_NORMAL_IDX];
iblN[BASE_LOBEA_IDX] = iblN[BASE_LOBEB_IDX] = N[BASE_NORMAL_IDX];
} // anisotropy
// IBL

// because our ComputeAdding formulation is with "energy" coefficients calculated with a
// chain of Fresnel terms instead of a correct chain computed with the true FGD.
baseLayerNdotV = sqrt(1 + Sq(preLightData.coatIeta)*(Sq(NdotV) - 1));
//TODO refactor with EvalIridescence, Lit::GetPreLightData
float baseLayerNdotV = PreLightData_GetBaseNdotVForFGD(bsdfData, preLightData, NdotV);
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV,
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV[COAT_NORMAL_IDX],
preLightData.iblPerceptualRoughness[COAT_LOBE_IDX],
preLightData.vLayerEnergyCoeff[TOP_VLAYER_IDX],
preLightData.specularFGD[COAT_LOBE_IDX],

// Notice again that the roughness and iblR properly use the output lobe statistics, but baseLayerNdotV
// is used for the offspecular correction because the true original offspecular tilt is parametrized by
// the angle at the base layer and the correction itself is influenced by that. See comments above.
preLightData.iblR[COAT_LOBE_IDX] = GetSpecularDominantDir(N, iblR[COAT_LOBE_IDX], preLightData.iblPerceptualRoughness[COAT_LOBE_IDX], NdotV);
preLightData.iblR[BASE_LOBEA_IDX] = GetSpecularDominantDir(N, iblR[BASE_LOBEA_IDX], preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX], baseLayerNdotV);
preLightData.iblR[BASE_LOBEB_IDX] = GetSpecularDominantDir(N, iblR[BASE_LOBEB_IDX], preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX], baseLayerNdotV);
preLightData.iblR[COAT_LOBE_IDX] = GetSpecularDominantDir(N[COAT_NORMAL_IDX], iblR[COAT_LOBE_IDX], preLightData.iblPerceptualRoughness[COAT_LOBE_IDX], NdotV[COAT_NORMAL_IDX]);
preLightData.iblR[BASE_LOBEA_IDX] = GetSpecularDominantDir(N[BASE_NORMAL_IDX], iblR[BASE_LOBEA_IDX], preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX], baseLayerNdotV);
preLightData.iblR[BASE_LOBEB_IDX] = GetSpecularDominantDir(N[BASE_NORMAL_IDX], iblR[BASE_LOBEB_IDX], preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX], baseLayerNdotV);
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
// TODOENERGY:

// NO VLAYERING:
// --------------------------------------------------------------------
// Only a single normal map possible here, NdotV[] and N[] are sized to 1
// See ConvertSurfaceDataToBSDFData : The later are already clamped if
// vlayering is disabled, so could be used directly, but for later
// refactoring (instead of BSDFdata A and B values, we should really

float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
preLightData.partLambdaV[0] = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, preLightData.layeredRoughnessT[0], preLightData.layeredRoughnessB[0]);
preLightData.partLambdaV[1] = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, preLightData.layeredRoughnessT[1], preLightData.layeredRoughnessB[1]);
preLightData.partLambdaV[0] = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV[0], preLightData.layeredRoughnessT[0], preLightData.layeredRoughnessB[0]);
preLightData.partLambdaV[1] = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV[0], preLightData.layeredRoughnessT[1], preLightData.layeredRoughnessB[1]);
// For GGX aniso and IBL we have done an empirical (eye balled) approximation compare to the reference.
// We use a single fetch, and we stretch the normal to use based on various criteria.

float stretch[2];
stretch[0] = abs(bsdfData.anisotropy) * saturate(5 * preLightData.iblPerceptualRoughness[0]);
stretch[1] = abs(bsdfData.anisotropy) * saturate(5 * preLightData.iblPerceptualRoughness[1]);
iblN[0] = GetAnisotropicModifiedNormal(grainDirWS, N, V, stretch[0]);
iblN[1] = GetAnisotropicModifiedNormal(grainDirWS, N, V, stretch[1]);
iblN[0] = GetAnisotropicModifiedNormal(grainDirWS, N[0], V, stretch[0]);
iblN[1] = GetAnisotropicModifiedNormal(grainDirWS, N[0], V, stretch[1]);
preLightData.partLambdaV[0] = GetSmithJointGGXPartLambdaV(NdotV, preLightData.layeredRoughnessT[0]);
preLightData.partLambdaV[1] = GetSmithJointGGXPartLambdaV(NdotV, preLightData.layeredRoughnessT[1]);
iblN[0] = iblN[1] = N;
preLightData.partLambdaV[0] = GetSmithJointGGXPartLambdaV(NdotV[0], preLightData.layeredRoughnessT[0]);
preLightData.partLambdaV[1] = GetSmithJointGGXPartLambdaV(NdotV[0], preLightData.layeredRoughnessT[1]);
iblN[0] = iblN[1] = N[0];
} // ...no anisotropy

GetPreIntegratedFGDGGXAndDisneyDiffuse(baseLayerNdotV, // just NdotV here...
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV[0],
preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX],
bsdfData.fresnel0,
preLightData.specularFGD[BASE_LOBEA_IDX],

GetPreIntegratedFGDGGXAndDisneyDiffuse(baseLayerNdotV,
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV[0],
preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX],
bsdfData.fresnel0,
preLightData.specularFGD[BASE_LOBEB_IDX],

preLightData.iblPerceptualRoughness[0] *= fact;
preLightData.iblPerceptualRoughness[1] *= fact;
// Correction of reflected direction for better handling of rough material
preLightData.iblR[0] = GetSpecularDominantDir(N, iblR[0], preLightData.iblPerceptualRoughness[0], NdotV);
preLightData.iblR[1] = GetSpecularDominantDir(N, iblR[1], preLightData.iblPerceptualRoughness[1], NdotV);
preLightData.iblR[0] = GetSpecularDominantDir(N[0], iblR[0], preLightData.iblPerceptualRoughness[0], NdotV[0]);
preLightData.iblR[1] = GetSpecularDominantDir(N[0], iblR[1], preLightData.iblPerceptualRoughness[1], NdotV[0]);
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
// Here, since this compensation term is already an average applied to a sum

// BSDF share between directional light, punctual light and area light (reference)
//-----------------------------------------------------------------------------
// helpers
void CalculateAnisoAngles(BSDFData bsdfData, float3 L, float3 V, float invLenLV, out float TdotH, out float TdotL, out float BdotH, out float BdotL)
{
float3 H = (L + V) * invLenLV;
// BSDF helpers
// For anisotropy we must not saturate these values
TdotH = dot(bsdfData.tangentWS, H);
TdotL = dot(bsdfData.tangentWS, L);
BdotH = dot(bsdfData.bitangentWS, H);
BdotL = dot(bsdfData.bitangentWS, L);
}
//
// The following is to streamline the usage (in the BSDF evaluations) of NdotL[] and NdotV[]
// regardless of the reason why we need [2] sized arrays:
//
#if defined(VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE) || defined(_MATERIAL_FEATURE_COAT_NORMALMAP)
#define DNLV_COAT_IDX 0
#define DNLV_BASE_IDX 1
#else
#define DNLV_COAT_IDX 0
#define DNLV_BASE_IDX 0
#endif
#if ((DNLV_BASE_IDX != BASE_NORMAL_IDX) && (DNLV_BASE_IDX != BOTTOM_DIR_IDX)) || ((DNLV_COAT_IDX != COAT_NORMAL_IDX) && (DNLV_BASE_IDX != COAT_DIR_IDX))
#error "DIR and NORMAL indices should match"
#endif
void CalculateAngles(float3 L, float3 V, float NdotL, float unclampedNdotV,
out float LdotV, out float invLenLV, out float NdotH, out float LdotH, out float NdotV)
#if defined(VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE)
// static assert:
#if defined(_MATERIAL_FEATURE_COAT_NORMALMAP) && ((NB_LV_DIR != 2) || ( NB_NORMALS != 2) || (BASE_NORMAL_IDX != BOTTOM_DIR_IDX) || (COAT_NORMAL_IDX != TOP_DIR_IDX))
#error "Unexpected NB_NORMALS and/or NB_LV_DIR, should be 2 or unmatching indices between DIR_IDX vs NORMAL_IDX"
#endif
#define NDOTLV_SIZE NB_LV_DIR
#else
#define NDOTLV_SIZE NB_NORMALS
#endif //...defined(VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE)
//BSDF_SetupNormalsAndAngles(bsdfData, preLightData, inNdotL,
// L, V, N, NdotL,
// H, NdotH, savedLdotH, NdotV);
void BSDF_SetupNormalsAndAngles(BSDFData bsdfData, inout PreLightData preLightData, float inNdotL,
inout float3 L[NB_LV_DIR], inout float3 V[NB_LV_DIR], out float3 N[NB_NORMALS], out float NdotL[NDOTLV_SIZE],
out float3 H, out float NdotH[NB_NORMALS], out float savedLdotH, out float NdotV[NDOTLV_SIZE])
// Optimized math. Ref: PBR Diffuse Lighting for GGX + Smith Microsurfaces (slide 114).
LdotV = dot(L, V);
invLenLV = rsqrt(max(2.0 * LdotV + 2.0, FLT_EPS)); // invLenLV = rcp(length(L + V)), clamp to avoid rsqrt(0) = NaN
NdotH = saturate((NdotL + unclampedNdotV) * invLenLV); // Do not clamp NdotV here
LdotH = saturate(invLenLV * LdotV + invLenLV);
NdotV = ClampNdotV(unclampedNdotV);
}
H = float3(0.0, 0.0, 0.0);
N[BASE_NORMAL_IDX] = bsdfData.normalWS;
#if defined(_MATERIAL_FEATURE_COAT_NORMALMAP)
if ( IsCoatNormalMapEnabled(bsdfData) )
{
N[COAT_NORMAL_IDX] = bsdfData.coatNormalWS;
}
#endif
// This function apply BSDF. Assumes that NdotL is positive.
void BSDF( float3 V, float3 L, float NdotL, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
{
float3 N = bsdfData.normalWS;
// preLightData.NdotV is sized with NB_NORMALS, not NDOTLV_SIZE, because the only useful
// precalculation that is not per light is NdotV with the coat normal (if it exists) and
// NdotV with the base normal (if coat normal exists), with the same V.
// But if VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE is used, V is different at the bottom,
// and we will recalculate a refracted (along H) V here, per light, and the resulting base
// NdotV.
float unclampedNdotV[NB_NORMALS] = preLightData.NdotV;
float LdotV, invLenLV, NdotH, LdotH, NdotV;
// Optimized math. Ref: PBR Diffuse Lighting for GGX + Smith Microsurfaces (slide 114).
//float LdotV = dot(L, V);
//float invLenLV = rsqrt(max(2.0 * LdotV + 2.0, FLT_EPS)); // invLenLV = rcp(length(L + V)), clamp to avoid rsqrt(0) = NaN
//float NdotH = saturate((NdotL + preLightData.NdotV) * invLenLV); // Do not clamp NdotV here
//float LdotH = saturate(invLenLV * LdotV + invLenLV);
//float NdotV = ClampNdotV(preLightData.NdotV);
CalculateAngles(L, V, NdotL, preLightData.NdotV, LdotV, invLenLV, NdotH, LdotH, NdotV);
// static assert (to simplify code, COAT_NORMAL_IDX == BASE_NORMAL_IDX when no coat normal):
#if !defined(_MATERIAL_FEATURE_COAT_NORMALMAP) && (BASE_NORMAL_IDX != COAT_NORMAL_IDX)
#error "COAT_NORMAL_IDX shoud equal BASE_NORMAL_IDX when no coat normal map"
#endif
float3 DV[TOTAL_NB_LOBES];
// We will compute everything needed for top interface lighting, and this will alias to the
// (only) bottom interface when we're not vlayered (if we are and have a coat normal, we will
// use it as we transfered coatNormalWS above and if we don't, again, the only existing
// normal will be used)
// TODO: Proper Fresnel
float3 F = F_Schlick(bsdfData.fresnel0, LdotH);
// todo: inNdotL is with geometric N for now, so we don't use it.
NdotL[DNLV_COAT_IDX] = dot(N[COAT_NORMAL_IDX], L[TOP_DIR_IDX]);
// TODO: with iridescence, will be optionally per light sample
// Optimized math. Ref: PBR Diffuse Lighting for GGX + Smith Microsurfaces (slide 114).
float LdotV = dot(L[TOP_DIR_IDX], V[TOP_DIR_IDX]); // note: LdotV isn't reused elsewhere, just here.
float invLenLV = rsqrt(max(2.0 * LdotV + 2.0, FLT_EPS)); // invLenLV = rcp(length(L + V)), clamp to avoid rsqrt(0) = NaN
savedLdotH = saturate(invLenLV * LdotV + invLenLV);
NdotH[COAT_NORMAL_IDX] = saturate((NdotL[DNLV_COAT_IDX] + unclampedNdotV[COAT_NORMAL_IDX]) * invLenLV); // Do not clamp NdotV here
NdotV[DNLV_COAT_IDX] = ClampNdotV(unclampedNdotV[COAT_NORMAL_IDX]);
// --------------------------------------------------------------------
// VLAYERING:
// --------------------------------------------------------------------
// Save top angles in case VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE option is used
float topLdotH = LdotH; // == VdotH)
float topNdotH = NdotH;
float topNdotL = NdotL;
float topNdotV = NdotV;
#if VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
// NdotH[] is size 2 only if we have two normal maps, but it doesn't change if we refract along
// H itself, so refracted angles considerations don't matter for it. Still we need to calculate
// it if we have two normal maps. Note we don't even test _MATERIAL_FEATURE_COAT_NORMALMAP, as
// BASE_NORMAL_IDX should alias COAT_NORMAL_IDX if there's no coat normalmap, and this line
// becomes a nop.
// We still reuse the top directions to be able to reuse computations above, regardless of
// refracted angle option since NdotH is invariant to it.
NdotH[BASE_NORMAL_IDX] = saturate((dot(N[BASE_NORMAL_IDX], L[TOP_DIR_IDX]) + unclampedNdotV[BASE_NORMAL_IDX]) * invLenLV); // Do not clamp NdotV here
#if defined(VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE) || defined(_MATERIAL_FEATURE_ANISOTROPY)
// In both of these cases, we need H, so get this out of the way now:
H = (L[TOP_DIR_IDX] + V[TOP_DIR_IDX]) * invLenLV; // H stays the same so calculate it one time
#endif
#ifdef VLAYERED_RECOMPUTE_PERLIGHT
// TODOWIP
// Must call ComputeAdding and update partLambdaV
ComputeAdding(savedLdotH, V[TOP_DIR_IDX], bsdfData, preLightData, true);
// Notice the top LdotH as interface angle, symmetric model parametrization (see paper sec. 6 and comments
// on ComputeAdding)
// layered*Roughness* and vLayerEnergyCoeff are now updated for the proper light direction.
// !Updates to PartLambdaV are now needed, will be done later when we consider anisotropy.
// Note (see p9 eq(39)): if we don't recompute per light, we just reuse the IBL energy terms as the fresnel
// terms for our LdotH, too bad (similar to what we do with iridescence), along with the "wrongly" calculated
// energy.
// In any case, we should have used FGD terms (except for R12 at the start of the process) for the analytical
// light case, see comments at the top of ComputeAdding
#endif //...VLAYERED_RECOMPUTE_PERLIGHT
#ifdef VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
// Also, we will use the base normal map automatically if we have dual normal maps (coat normals)
// since we use generically N[BASE_NORMAL_IDX]
// TODOWIP
// Use the refracted angle at the bottom interface for BSDF calculations:

// an output lobe parametrization, but multiple-scattering is not accounted fully
// byt ComputeAdding (by deriving azimuth dependent covariance operators).
// by ComputeAdding (for anisotropy by deriving azimuth dependent covariance operators).
// In both cases we need to work around it, so just to test:
float3 H = (L + V) * invLenLV;
// H stays the same so calculate it one time
V = CoatRefract(V, H, preLightData.coatIeta);
L = reflect(-V, H);
NdotL = dot(N,L);
// In both cases we need to work around it.
//
// Using refracted angles for BSDF eval for the base in the case of analytical lights
// must be seen as a hack on top of the ComputeAdding method in which we consider that
// even though the output (energy coefficients) of the method are statistical averages
// over all incoming light directions and so to be used in the context of a split sum
// approximation, the analytical lights have all their energy in a specific ray direction
// and moreover, currently, the output coefficients of the method are formed from straight
// Fresnel terms, and not FGD terms.
//
V[BOTTOM_DIR_IDX] = CoatRefract(V[TOP_DIR_IDX], H, preLightData.coatIeta);
L[BOTTOM_DIR_IDX] = reflect(-V[BOTTOM_DIR_IDX], H);
NdotL[DNLV_BASE_IDX] = dot(N[BASE_NORMAL_IDX], L[BOTTOM_DIR_IDX]);
//LdotV = dot(L, V);
//invLenLV = rsqrt(max(2.0 * LdotV + 2.0, FLT_EPS)); // invLenLV = rcp(length(L + V)), clamp to avoid rsqrt(0) = NaN
//NdotH = saturate((NdotL + dot(N, V)) * invLenLV); // Do not clamp NdotV here
//LdotH = saturate(invLenLV * LdotV + invLenLV);
//NdotV = ClampNdotV(dot(N, V));
CalculateAngles(L, V, NdotL, dot(N, V), LdotV, invLenLV, NdotH, LdotH, NdotV);
float unclampedBaseNdotV = dot(N[BASE_NORMAL_IDX], V[BOTTOM_DIR_IDX]);
NdotV[DNLV_BASE_IDX] = ClampNdotV(unclampedBaseNdotV);
//NdotH[BASE_NORMAL_IDX] = already calculated, see above
#endif // #if VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
#else //, don't use refracted angles for bottom interface:
#ifdef VLAYERED_RECOMPUTE_PERLIGHT
// TODOWIP
// Must call ComputeAdding and update partLambdaV
ComputeAdding(topLdotH, bsdfData, preLightData, true);
// Notice topLdotH as interface angle, symmetric model parametrization (see sec. 6 and comments
// on ComputeAdding)
// layered*Roughness* and vLayerEnergyCoeff are now updated for the proper light direction.
preLightData.partLambdaV[COAT_LOBE_IDX] = GetSmithJointGGXPartLambdaV(topNdotV, preLightData.layeredCoatRoughness);
#if defined(_MATERIAL_FEATURE_COAT_NORMALMAP)
if ( IsCoatNormalMapEnabled(bsdfData) )
{
// Just to be clean we test the above, but since BASE_NORMAL_IDX should alias COAT_NORMAL_IDX
// if we don't have coat normals and no refracted angle to account, this is already computed
// and the compiler would remove this.
NdotL[DNLV_BASE_IDX] = dot(N[BASE_NORMAL_IDX], L[BOTTOM_DIR_IDX]);
//NdotH[BASE_NORMAL_IDX] = saturate((NdotL[DNLV_BASE_IDX] + unclampedNdotV[BASE_NORMAL_IDX]) * invLenLV); // Do not clamp NdotV here
NdotV[DNLV_BASE_IDX] = ClampNdotV(unclampedNdotV[BASE_NORMAL_IDX]);
}
// p9 eq(39): if we don't recompute per light, we just reuse the IBL energy terms as the fresnel terms
// for our LdotH, too bad (similar to what we do with iridescence), along with the "wrongly" calculated energy.
// Note that in any case, we should have used FGD terms (except for R12 at the start of the process)
// for the analytical light case, see comments at the top of ComputeAdding
#endif // #ifdef VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
// Finally, we will update the partLambdaV if we did ComputeAdding per light, having the proper
// angles wrt to refraction option and/or dual normal maps and considering anisotropy:
// we just changed V, update those:
preLightData.TdotV = dot(bsdfData.tangentWS, V);
preLightData.BdotV = dot(bsdfData.bitangentWS, V);
// we changed V, update those:
preLightData.TdotV = dot(bsdfData.tangentWS, V[BOTTOM_DIR_IDX]);
preLightData.BdotV = dot(bsdfData.bitangentWS, V[BOTTOM_DIR_IDX]);
preLightData.partLambdaV[BASE_LOBEA_IDX] = GetSmithJointGGXAnisoPartLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV,
// we need to update partLambdaV as we recomputed the layering for this light (these depend on roughness):
preLightData.partLambdaV[COAT_LOBE_IDX] = GetSmithJointGGXPartLambdaV(NdotV[DNLV_COAT_IDX], preLightData.layeredCoatRoughness);
preLightData.partLambdaV[BASE_LOBEA_IDX] = GetSmithJointGGXAnisoPartLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV[DNLV_BASE_IDX],
preLightData.partLambdaV[BASE_LOBEB_IDX] = GetSmithJointGGXAnisoPartLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV,
preLightData.partLambdaV[BASE_LOBEB_IDX] = GetSmithJointGGXAnisoPartLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV[DNLV_BASE_IDX],
} // anisotropy
else
{
#ifdef VLAYERED_RECOMPUTE_PERLIGHT
// we need to update partLambdaV as we recomputed the layering for this light (these depend on roughness):
preLightData.partLambdaV[COAT_LOBE_IDX] = GetSmithJointGGXPartLambdaV(NdotV[DNLV_COAT_IDX], preLightData.layeredCoatRoughness);
preLightData.partLambdaV[BASE_LOBEA_IDX] = GetSmithJointGGXPartLambdaV(NdotV[DNLV_BASE_IDX], preLightData.layeredRoughnessT[0]);
preLightData.partLambdaV[BASE_LOBEB_IDX] = GetSmithJointGGXPartLambdaV(NdotV[DNLV_BASE_IDX], preLightData.layeredRoughnessT[1]);
#endif
} //...no anisotropy
//float3 H = (L + V) * invLenLV;
#endif // _MATERIAL_FEATURE_COAT
}
else
{
// No vlayering, just check if we need H:
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY))
{
H = (L[0] + V[0]) * invLenLV;
}
}
} //...BSDF_SetupNormalsAndAngles
void CalculateAnisoAngles(BSDFData bsdfData, float3 H, float3 L, float3 V, out float TdotH, out float TdotL, out float BdotH, out float BdotL)
{
// For anisotropy we must not saturate these values
TdotH = dot(bsdfData.tangentWS, H);
TdotL = dot(bsdfData.tangentWS, L);
BdotH = dot(bsdfData.bitangentWS, H);
BdotL = dot(bsdfData.bitangentWS, L);
}
// This function apply BSDF. Assumes that NdotL is positive.
void BSDF(float3 inV, float3 inL, float inNdotL, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
{
float NdotL[NDOTLV_SIZE];
float NdotV[NDOTLV_SIZE];
// IMPORTANT: use DNLV_COAT_IDX and DNLV_BASE_IDX to index NdotL and NdotV since they can be sized 2
// either if we have to deal with refraction or if we use dual normal maps: NB_LV_DIR is for L or V,
// while NB_NORMALS is for N, but in the cases of NdotL, NdotV, they will be sized
// max(NB_LV_DIR, NB_NORMALS)
float3 L[NB_LV_DIR], V[NB_LV_DIR];
float3 N[NB_NORMALS];
float savedLdotH;
// ...only one needed: when vlayered, only top needed for input to ComputeAdding and even then, only if we recompute per light,
// otherwise, no vlayered and base one is used for a standard Fresnel calculation.
float3 H = (float3)0; // might not be needed if no refracted_angles option and no anisotropy...
float NdotH[NB_NORMALS]; // NdotH[NB_LV_DIR] not needed since it stays the same wrt a refraction along H itself.
float3 DV[TOTAL_NB_LOBES]; // BSDF results per lobe
// Note that we're never missing an initialization for the following as the arrays are sized 1 in the cases
// we use only the "bottom" parts (which are the same as the top: ie in case we have dual normal maps but no
// refracted angles to account for).
L[TOP_DIR_IDX] = inL;
V[TOP_DIR_IDX] = inV;
BSDF_SetupNormalsAndAngles(bsdfData, preLightData, inNdotL, L, V, N, NdotL, H, NdotH, savedLdotH, NdotV);
// TODO: with iridescence, will be optionally per light sample
if( IsVLayeredEnabled(bsdfData) )
{
#ifdef _MATERIAL_FEATURE_COAT
// --------------------------------------------------------------------
// VLAYERING:
// --------------------------------------------------------------------
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY))
{
CalculateAnisoAngles(bsdfData, L, V, invLenLV, TdotH, TdotL, BdotH, BdotL);
CalculateAnisoAngles(bsdfData, H, L[BOTTOM_DIR_IDX], V[BOTTOM_DIR_IDX], TdotH, TdotL, BdotH, BdotL);
DV[BASE_LOBEA_IDX] = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, NdotV, TdotL, BdotL, NdotL,
DV[BASE_LOBEA_IDX] = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH[BASE_NORMAL_IDX], NdotV[DNLV_BASE_IDX], TdotL, BdotL, NdotL[DNLV_BASE_IDX],
DV[BASE_LOBEB_IDX] = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, NdotV, TdotL, BdotL, NdotL,
DV[BASE_LOBEB_IDX] = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH[BASE_NORMAL_IDX], NdotV[DNLV_BASE_IDX], TdotL, BdotL, NdotL[DNLV_BASE_IDX],
DV[COAT_LOBE_IDX] = DV_SmithJointGGX(topNdotH, topNdotL, topNdotV, preLightData.layeredCoatRoughness, preLightData.partLambdaV[COAT_LOBE_IDX]);
DV[COAT_LOBE_IDX] = DV_SmithJointGGX(NdotH[COAT_NORMAL_IDX], NdotL[DNLV_COAT_IDX], NdotV[DNLV_COAT_IDX], preLightData.layeredCoatRoughness, preLightData.partLambdaV[COAT_LOBE_IDX]);
#ifdef VLAYERED_RECOMPUTE_PERLIGHT
preLightData.partLambdaV[BASE_LOBEA_IDX] = GetSmithJointGGXPartLambdaV(NdotV, preLightData.layeredRoughnessT[0]);
preLightData.partLambdaV[BASE_LOBEB_IDX] = GetSmithJointGGXPartLambdaV(NdotV, preLightData.layeredRoughnessT[1]);
#endif
DV[COAT_LOBE_IDX] = DV_SmithJointGGX(topNdotH, topNdotL, topNdotV, preLightData.layeredCoatRoughness, preLightData.partLambdaV[COAT_LOBE_IDX]);
DV[BASE_LOBEA_IDX] = DV_SmithJointGGX(NdotH, NdotL, NdotV, preLightData.layeredRoughnessT[0], preLightData.partLambdaV[BASE_LOBEA_IDX]);
DV[BASE_LOBEB_IDX] = DV_SmithJointGGX(NdotH, NdotL, NdotV, preLightData.layeredRoughnessT[1], preLightData.partLambdaV[BASE_LOBEB_IDX]);
DV[COAT_LOBE_IDX] = DV_SmithJointGGX(NdotH[COAT_NORMAL_IDX], NdotL[DNLV_COAT_IDX], NdotV[DNLV_COAT_IDX], preLightData.layeredCoatRoughness, preLightData.partLambdaV[COAT_LOBE_IDX]);
DV[BASE_LOBEA_IDX] = DV_SmithJointGGX(NdotH[BASE_NORMAL_IDX], NdotL[DNLV_BASE_IDX], NdotV[DNLV_BASE_IDX],
preLightData.layeredRoughnessT[0], preLightData.partLambdaV[BASE_LOBEA_IDX]);
DV[BASE_LOBEB_IDX] = DV_SmithJointGGX(NdotH[BASE_NORMAL_IDX], NdotL[DNLV_BASE_IDX], NdotV[DNLV_BASE_IDX],
preLightData.layeredRoughnessT[1], preLightData.partLambdaV[BASE_LOBEB_IDX]);
IF_DEBUG( if(_DebugLobeMask.x == 0.0) DV[COAT_LOBE_IDX] = (float3)0; )
IF_DEBUG( if(_DebugLobeMask.y == 0.0) DV[BASE_LOBEA_IDX] = (float3)0; )
IF_DEBUG( if(_DebugLobeMask.z == 0.0) DV[BASE_LOBEB_IDX] = (float3)0; )
specularLighting = preLightData.vLayerEnergyCoeff[BOTTOM_VLAYER_IDX]
* lerp(DV[BASE_LOBEA_IDX] * preLightData.energyCompensationFactor[BASE_LOBEA_IDX],

// --------------------------------------------------------------------
// NO VLAYERING:
// --------------------------------------------------------------------
// TODO: Proper Fresnel
float3 F = F_Schlick(bsdfData.fresnel0, savedLdotH);
float3 H = (L + V) * invLenLV;
CalculateAnisoAngles(bsdfData, L, V, invLenLV, TdotH, TdotL, BdotH, BdotL);
DV[0] = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, NdotV, TdotL, BdotL, NdotL,
CalculateAnisoAngles(bsdfData, H, L[0], V[0], TdotH, TdotL, BdotH, BdotL);
DV[0] = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH[0], NdotV[0], TdotL, BdotL, NdotL[0],
DV[1] = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, NdotV, TdotL, BdotL, NdotL,
DV[1] = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH[0], NdotV[0], TdotL, BdotL, NdotL[0],
DV[0] = DV_SmithJointGGX(NdotH, NdotL, NdotV, bsdfData.roughnessAT, preLightData.partLambdaV[0]);
DV[1] = DV_SmithJointGGX(NdotH, NdotL, NdotV, bsdfData.roughnessBT, preLightData.partLambdaV[1]);
DV[0] = DV_SmithJointGGX(NdotH[0], NdotL[0], NdotV[0], bsdfData.roughnessAT, preLightData.partLambdaV[0]);
DV[1] = DV_SmithJointGGX(NdotH[0], NdotL[0], NdotV[0], bsdfData.roughnessBT, preLightData.partLambdaV[1]);
IF_DEBUG( if(_DebugLobeMask.y == 0.0) DV[BASE_LOBEA_IDX] = (float3)0; )
IF_DEBUG( if(_DebugLobeMask.z == 0.0) DV[BASE_LOBEB_IDX] = (float3)0; )
specularLighting = F * lerp(DV[0]*preLightData.energyCompensationFactor[BASE_LOBEA_IDX],
DV[1]*preLightData.energyCompensationFactor[BASE_LOBEB_IDX],
bsdfData.lobeMix);

}//...BSDF
float3 EvaluateTransmission(BSDFData bsdfData, float3 transmittance, float NdotL, float NdotV, float LdotV, float attenuation)
{
// Apply wrapped lighting to better handle thin objects at grazing angles.

return intensity * transmittance;
}
void EvaluateBSDF_GetNormalUnclampedNdotV(BSDFData bsdfData, PreLightData preLightData, float3 V, out float3 N, out float unclampedNdotV)
{
#ifdef _MATERIAL_FEATURE_COAT_NORMALMAP
//TODOWIP for now just return geometric normal:
if ( IsCoatNormalMapEnabled(bsdfData) )
{
N = bsdfData.geomNormalWS;
unclampedNdotV = dot(N, V);
}
else
#endif
{
// TODOWIP, for now, preserve previous behavior
N = bsdfData.normalWS;
unclampedNdotV = preLightData.NdotV[BASE_NORMAL_IDX];
}
}
//-----------------------------------------------------------------------------
// EvaluateBSDF_Directional
//-----------------------------------------------------------------------------

DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 N = bsdfData.normalWS;
//slnote dual map
float3 N; float unclampedNdotV;
EvaluateBSDF_GetNormalUnclampedNdotV(bsdfData, preLightData, V, N, unclampedNdotV);
//float3 N = bsdfData.normalWS;
float NdotV = ClampNdotV(preLightData.NdotV);
//float NdotV = ClampNdotV(preLightData.NdotV);
float NdotV = ClampNdotV(unclampedNdotV);
float NdotL = dot(N, L);
float LdotV = dot(L, V);

distances.xyz = float3(dist, distSq, distRcp);
}
float3 N = bsdfData.normalWS;
float NdotV = ClampNdotV(preLightData.NdotV);
//slnote dual map
float3 N; float unclampedNdotV;
EvaluateBSDF_GetNormalUnclampedNdotV(bsdfData, preLightData, V, N, unclampedNdotV);
//float3 N = bsdfData.normalWS;
//float NdotV = ClampNdotV(preLightData.NdotV);
float NdotV = ClampNdotV(unclampedNdotV);
float NdotL = dot(N, L);
float LdotV = dot(L, V);

// Since the weights are influence blending weights, we can correctly
// use our lobe weight and mix them.
// -Fudge the sampling direction to dampen boundary artefacts.
// -Do early discard for planar reflections.
// -Fetch samples of preintegrated environment lighting
// (see preLD, first part of the split-sum approx.)
// -Use the BSDF preintegration terms we pre-fetched in preLightData

// Note: using influenceShapeType and projectionShapeType instead of (lightData|proxyData).shapeType allow to make compiler optimization in case the type is know (like for sky)
//slnote dual map
float3 influenceNormal; float unclampedNdotV;
EvaluateBSDF_GetNormalUnclampedNdotV(bsdfData, preLightData, V, influenceNormal, unclampedNdotV);
IF_FEATURE_COAT( if( (i == 0) && _DebugLobeMask.x == 0.0) continue; )
if( (i == (0 IF_FEATURE_COAT(+1))) && _DebugLobeMask.y == 0.0) continue;
if( (i == (1 IF_FEATURE_COAT(+1))) && _DebugLobeMask.z == 0.0) continue;
IF_FEATURE_COAT( if( (i == 0) && _DebugEnvLobeMask.x == 0.0) continue; )
if( (i == (0 IF_FEATURE_COAT(+1))) && _DebugEnvLobeMask.y == 0.0) continue;
if( (i == (1 IF_FEATURE_COAT(+1))) && _DebugEnvLobeMask.z == 0.0) continue;
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, R[i], tempWeight[i]);
//slnote dual map
//EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, R[i], tempWeight[i]);
EvaluateLight_EnvIntersection(positionWS, influenceNormal, lightData, influenceShapeType, R[i], tempWeight[i]);
// When we are rough, we tend to see outward shifting of the reflection when at the boundary of the projection volume
// Also it appear like more sharp. To avoid these artifact and at the same time get better match to reference we lerp to original unmodified reflection.

{
float3 bakeDiffuseLighting = bakeLightingData.bakeDiffuseLighting;
float3 N; float unclampedNdotV;
EvaluateBSDF_GetNormalUnclampedNdotV(bsdfData, preLightData, V, N, unclampedNdotV);
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix), bsdfData.ambientOcclusion, 1.0, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
//GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix), bsdfData.ambientOcclusion, 1.0, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, unclampedNdotV, lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix), bsdfData.ambientOcclusion, 1.0, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
// Add indirect diffuse + emissive (if any) - Ambient occlusion is multiply by emissive which is wrong but not a big deal
bakeDiffuseLighting *= aoFactor.indirectAmbientOcclusion;

23
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.shader


[HideInInspector] _SmoothnessBRange("SmoothnessB Range", Vector) = (0, 1, 0, 0)
_LobeMix("Lobe Mix", Range(0.0, 1.0)) = 0
[ToggleUI] _VlayerRecomputePerLight("Vlayer Recompute Per Light", Float) = 0.0 // UI only
[ToggleUI] _VlayerUseRefractedAnglesForBase("Vlayer Use Refracted Angles For Base", Float) = 0.0 // UI only
_DebugEnvLobeMask("DebugEnvLobeMask", Vector) = (1, 1, 1, 1)
_DebugLobeMask("DebugLobeMask", Vector) = (1, 1, 1, 1)
_DebugAniso("DebugAniso", Vector) = (1, 0, 0, 1000.0)

_CoatIor("Coat IOR", Range(1.0001, 2.0)) = 1.5
_CoatThickness("Coat Thickness", Range(0.0, 0.99)) = 0.0
_CoatExtinction("Coat Extinction Coefficient", Color) = (1,1,1) // in thickness^-1 units
[ToggleUI] _EnableCoatNormalMap("Enable Coat Normal Map", Float) = 0.0 // UI only
[HideInInspector] _CoatNormalMapShow("Coat NormalMap Show", Float) = 0.0
_CoatNormalMap("Coat NormalMap", 2D) = "bump" {} // Tangent space normal map
_CoatNormalMapUV("Coat NormalMapUV", Float) = 0.0
_CoatNormalMapUVLocal("Coat NormalMapUV Local", Float) = 0.0
_CoatNormalMapObjSpace("Coat NormalMap ObjSpace", Float) = 0.0
_CoatNormalScale("Coat NormalMap Scale", Range(0.0, 2.0)) = 1
[HideInInspector] _NormalMapShow("NormalMap Show", Float) = 0.0
_NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map

[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal
[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8
[ToggleUI] _SpecularAntiAliasingEnabled("Specular Anti Aliasing Enabled", Float) = 0.0
_SpecularAntiAliasingScreenSpaceVariance("SpecularAntiAliasingScreenSpaceVariance", Range(0.0, 1.0)) = 1.0
_SpecularAntiAliasingThreshold("SpecularAntiAliasingThreshold", Range(0.0, 1.0)) = 0.18
[ToggleUI] _NormalCurvatureToRoughnessEnabled("_NormalCurvatureToRoughnessEnabled", Float) = 0.0
_NormalCurvatureToRoughnessScale("_NormalCurvatureToRoughnessScale", Range(0.0, 2.0)) = 1.0
_NormalCurvatureToRoughnessBias("_NormalCurvatureToRoughnessBias", Range(-1.0, 1.0)) = 0.0
_NormalCurvatureToRoughnessExponent("_NormalCurvatureToRoughnessExponent", Range(0.05, 20.0)) = 0.333
[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleUI] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0

#pragma shader_feature _MATERIAL_FEATURE_DUAL_SPECULAR_LOBE
#pragma shader_feature _MATERIAL_FEATURE_ANISOTROPY
#pragma shader_feature _MATERIAL_FEATURE_COAT
#pragma shader_feature _MATERIAL_FEATURE_COAT_NORMALMAP
#pragma shader_feature _VLAYERED_RECOMPUTE_PERLIGHT
#pragma shader_feature _VLAYERED_USE_REFRACTED_ANGLES_FOR_BASE
#pragma shader_feature _STACKLIT_DEBUG

13
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitData.hlsl


}
#endif
float2 deriv = UnpackDerivativeNormalRGorAG(SampleTexture2DScaleBias(TEXTURE2D_PARAM(textureName, samplerName), textureNameUV, textureNameUVLocal, textureNameST, uvMapping));
float2 deriv = UnpackDerivativeNormalRGorAG(SampleTexture2DScaleBias(TEXTURE2D_PARAM(textureName, samplerName), textureNameUV, textureNameUVLocal, textureNameST, uvMapping), scale);
if (textureNameUV <= TEXCOORD_INDEX_UV3)
{

#endif
surfaceData.tangentWS = normalize(input.worldToTangent[0].xyz); // The tangent is not normalize in worldToTangent for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
float3 coatGradient = float3(0.0, 0.0, 0.0);
#ifdef _MATERIAL_FEATURE_COAT
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_STACK_LIT_COAT;
surfaceData.coatPerceptualSmoothness = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_CoatSmoothnessMap), _CoatSmoothnessMapChannelMask);

surfaceData.coatThickness = _CoatThickness;
surfaceData.coatExtinction = _CoatExtinction; // in thickness^-1 units
#ifdef _MATERIAL_FEATURE_COAT_NORMALMAP
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_STACK_LIT_COAT_NORMAL_MAP;
coatGradient = SAMPLE_TEXTURE2D_NORMAL_SCALE_BIAS(_CoatNormalMap, _CoatNormalScale);
#endif
#endif
#endif // _MATERIAL_FEATURE_COAT
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_STACK_LIT_IRIDESCENCE;

// Surface Data Part 2 (outsite GetSurfaceData( ) in Lit shader):
// -------------------------------------------------------------
surfaceData.geomNormalWS = input.worldToTangent[2];
surfaceData.coatNormalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], coatGradient);
// TODO: decal etc.

21
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitProperties.hlsl


TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURE2D(_CoatNormalMap);
SAMPLER(sampler_CoatNormalMap);
TEXTURE2D(_SmoothnessBMap);
SAMPLER(sampler_SmoothnessBMap);

float4 _SmoothnessAMapChannelMask;
float4 _SmoothnessARange;
float4 _DebugEnvLobeMask;
float4 _DebugLobeMask;
float4 _DebugAniso;

float _CoatThickness;
float3 _CoatExtinction;
float _CoatNormalScale;
float _CoatNormalMapUV;
float _CoatNormalMapUVLocal;
float _CoatNormalMapObjSpace;
float4 _CoatNormalMap_ST;
float4 _CoatNormalMap_TexelSize;
float4 _CoatNormalMap_MipInfo;
float _IridescenceThickness;
float _IridescenceThicknessUseMap;
float _IridescenceThicknessMapUV;

float _EmissiveColorMapUVLocal;
float _EmissiveIntensity;
float _AlbedoAffectEmissive;
float _SpecularAntiAliasingEnabled;
float _SpecularAntiAliasingScreenSpaceVariance;
float _SpecularAntiAliasingThreshold;
float _NormalCurvatureToRoughnessEnabled;
float _NormalCurvatureToRoughnessScale;
float _NormalCurvatureToRoughnessBias;
float _NormalCurvatureToRoughnessExponent;
float _AlphaCutoff;
float4 _DoubleSidedConstants;

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs


RTHandles.Release(m_HTile);
}
public void PushGlobalParams(CommandBuffer cmd, DiffusionProfileSettings sssParameters, FrameSettings frameSettings)
public void PushGlobalParams(HDCamera hdCamera, CommandBuffer cmd, DiffusionProfileSettings sssParameters)
cmd.SetGlobalInt(HDShaderIDs._EnableSubsurfaceScattering, frameSettings.enableSubsurfaceScattering ? 1 : 0);
cmd.SetGlobalInt(HDShaderIDs._EnableSubsurfaceScattering, hdCamera.frameSettings.enableSubsurfaceScattering ? 1 : 0);
unsafe
{
// Warning: Unity is not able to losslessly transfer integers larger than 2^24 to the shader system.

cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParams, sssParameters.shapeParams);
cmd.SetGlobalVectorArray(HDShaderIDs._HalfRcpVariancesAndWeights, sssParameters.halfRcpVariancesAndWeights);
// To disable transmission, we simply nullify the transmissionTint
cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTintsAndFresnel0, frameSettings.enableTransmission ? sssParameters.transmissionTintsAndFresnel0 : sssParameters.disabledTransmissionTintsAndFresnel0);
cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTintsAndFresnel0, hdCamera.frameSettings.enableTransmission ? sssParameters.transmissionTintsAndFresnel0 : sssParameters.disabledTransmissionTintsAndFresnel0);
cmd.SetGlobalVectorArray(HDShaderIDs._WorldScales, sssParameters.worldScales);
}

}
// Combines specular lighting and diffuse lighting with subsurface scattering.
public void SubsurfaceScatteringPass(HDCamera hdCamera, CommandBuffer cmd, DiffusionProfileSettings sssParameters, FrameSettings frameSettings,
public void SubsurfaceScatteringPass(HDCamera hdCamera, CommandBuffer cmd, DiffusionProfileSettings sssParameters,
if (sssParameters == null || !frameSettings.enableSubsurfaceScattering)
if (sssParameters == null || !hdCamera.frameSettings.enableSubsurfaceScattering)
return;
// TODO: For MSAA, at least initially, we can only support Jimenez, because we can't

30
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/FrameSettings.cs


public bool enableSSAO = true;
public bool enableSubsurfaceScattering = true;
public bool enableTransmission = true; // Caution: this is only for debug, it doesn't save the cost of Transmission execution
public bool enableAtmosphericScattering = true;
public bool enableVolumetric = true;
// Setup by system
public float diffuseGlobalDimmer = 1.0f;

public bool enableMotionVectors = true; // Enable/disable whole motion vectors pass (Camera + Object).
public bool enableObjectMotionVectors = true;
public bool enableDBuffer = true;
public bool enableAtmosphericScattering = true;
public bool enableRoughRefraction = true; // Depends on DepthPyramid - If not enable, just do a copy of the scene color (?) - how to disable rough refraction ?
public bool enableTransparentPostpass = true;
public bool enableDistortion = true;

frameSettings.enableSSAO = this.enableSSAO;
frameSettings.enableSubsurfaceScattering = this.enableSubsurfaceScattering;
frameSettings.enableTransmission = this.enableTransmission;
frameSettings.enableAtmosphericScattering = this.enableAtmosphericScattering;
frameSettings.enableVolumetric = this.enableVolumetric;
frameSettings.diffuseGlobalDimmer = this.diffuseGlobalDimmer;
frameSettings.specularGlobalDimmer = this.specularGlobalDimmer;

frameSettings.enableMotionVectors = this.enableMotionVectors;
frameSettings.enableObjectMotionVectors = this.enableObjectMotionVectors;
frameSettings.enableDBuffer = this.enableDBuffer;
frameSettings.enableAtmosphericScattering = this.enableAtmosphericScattering;
frameSettings.enableRoughRefraction = this.enableRoughRefraction;
frameSettings.enableTransparentPostpass = this.enableTransparentPostpass;
frameSettings.enableDistortion = this.enableDistortion;

aggregate.enableSSAO = srcFrameSettings.enableSSAO && renderPipelineSettings.supportSSAO;
aggregate.enableSubsurfaceScattering = camera.cameraType != CameraType.Reflection && srcFrameSettings.enableSubsurfaceScattering && renderPipelineSettings.supportSubsurfaceScattering;
aggregate.enableTransmission = srcFrameSettings.enableTransmission;
aggregate.enableAtmosphericScattering = srcFrameSettings.enableAtmosphericScattering;
// We must take care of the scene view fog flags in the editor
if (!CoreUtils.IsSceneViewFogEnabled(camera))
aggregate.enableAtmosphericScattering = false;
// Volumetric are disabled if there is no atmospheric scattering
aggregate.enableVolumetric = srcFrameSettings.enableVolumetric && renderPipelineSettings.supportVolumetric && aggregate.enableAtmosphericScattering;
// TODO: Add support of volumetric in planar reflection
if (camera.cameraType == CameraType.Reflection)
aggregate.enableVolumetric = false;
// We have to fall back to forward-only rendering when scene view is using wireframe rendering mode
// as rendering everything in wireframe + deferred do not play well together

aggregate.enableMotionVectors = camera.cameraType != CameraType.Reflection && srcFrameSettings.enableMotionVectors && renderPipelineSettings.supportMotionVectors;
aggregate.enableObjectMotionVectors = camera.cameraType != CameraType.Reflection && srcFrameSettings.enableObjectMotionVectors && renderPipelineSettings.supportMotionVectors;
aggregate.enableDBuffer = srcFrameSettings.enableDBuffer && renderPipelineSettings.supportDBuffer;
aggregate.enableAtmosphericScattering = srcFrameSettings.enableAtmosphericScattering;
// We must take care of the scene view fog flags in the editor
if (!CoreUtils.IsSceneViewFogEnabled(camera))
aggregate.enableAtmosphericScattering = false;
aggregate.enableRoughRefraction = srcFrameSettings.enableRoughRefraction;
aggregate.enableTransparentPostpass = srcFrameSettings.enableTransparentPostpass;
aggregate.enableDistortion = camera.cameraType != CameraType.Reflection && srcFrameSettings.enableDistortion;

aggregate.ConfigureMSAADependentSettings();
aggregate.ConfigureStereoDependentSettings();
if (camera.cameraType == CameraType.Preview)
// Disable various option for the preview except if we are a Camera Editor preview
if (HDUtils.IsRegularPreviewCamera(camera))
// remove undesired feature in preview
aggregate.enableAtmosphericScattering = false;
aggregate.enableVolumetric = false;
aggregate.enableAtmosphericScattering = false;
aggregate.enableTransparentPostpass = false;
aggregate.enableDistortion = false;
aggregate.enablePostprocess = false;

new DebugUI.BoolField { displayName = "Enable Motion Vectors", getter = () => frameSettings.enableMotionVectors, setter = value => frameSettings.enableMotionVectors = value },
new DebugUI.BoolField { displayName = "Enable Object Motion Vectors", getter = () => frameSettings.enableObjectMotionVectors, setter = value => frameSettings.enableObjectMotionVectors = value },
new DebugUI.BoolField { displayName = "Enable DBuffer", getter = () => frameSettings.enableDBuffer, setter = value => frameSettings.enableDBuffer = value },
new DebugUI.BoolField { displayName = "Enable Atmospheric Scattering", getter = () => frameSettings.enableAtmosphericScattering, setter = value => frameSettings.enableAtmosphericScattering = value },
new DebugUI.BoolField { displayName = "Enable Rough Refraction", getter = () => frameSettings.enableRoughRefraction, setter = value => frameSettings.enableRoughRefraction = value },
new DebugUI.BoolField { displayName = "Enable Distortion", getter = () => frameSettings.enableDistortion, setter = value => frameSettings.enableDistortion = value },
new DebugUI.BoolField { displayName = "Enable Postprocess", getter = () => frameSettings.enablePostprocess, setter = value => frameSettings.enablePostprocess = value },

new DebugUI.BoolField { displayName = "Enable Shadows", getter = () => frameSettings.enableShadow, setter = value => frameSettings.enableShadow = value },
new DebugUI.BoolField { displayName = "Enable Contact Shadows", getter = () => frameSettings.enableContactShadows, setter = value => frameSettings.enableContactShadows = value },
new DebugUI.BoolField { displayName = "Enable ShadowMask", getter = () => frameSettings.enableShadowMask, setter = value => frameSettings.enableShadowMask = value },
new DebugUI.BoolField { displayName = "Enable Atmospheric Scattering", getter = () => frameSettings.enableAtmosphericScattering, setter = value => frameSettings.enableAtmosphericScattering = value },
new DebugUI.BoolField { displayName = " Enable volumetric", getter = () => frameSettings.enableVolumetric, setter = value => frameSettings.enableVolumetric = value },
}
}
});

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/RenderPipelineSettings.cs


public bool supportSubsurfaceScattering = true;
public bool supportForwardOnly = false;
public bool enableUltraQualitySSS = false;
public bool supportVolumetric = true;
// Engine
public bool supportDBuffer = false;

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassLightTransport.hlsl


output.vmesh.positionWS = positionWS;
#endif
// Not required for meta pass but to silent the shader compiler warning in case it is declare
output.vmesh.normalWS = float3(0.0, 0.0, 0.0);
output.vmesh.tangentWS = float4(0.0, 0.0, 0.0, 0.0);
// Normal is required for triplanar mapping
output.vmesh.normalWS = TransformObjectToWorldNormal(inputMesh.normalOS);
// Not required but assign to silent compiler warning
output.vmesh.tangentWS = float4(1.0, 0.0, 0.0, 0.0);
#endif
#ifdef VARYINGS_NEED_TEXCOORD0

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.cs


[Tooltip("Distance at which maximum mip of blurred sky texture is used as fog color.")]
public MinFloatParameter mipFogFar = new MinFloatParameter(1000.0f, 0.0f);
public abstract void PushShaderParameters(CommandBuffer cmd, FrameSettings frameSettings);
public abstract void PushShaderParameters(HDCamera hdCamera, CommandBuffer cmd);
public static void PushNeutralShaderParameters(CommandBuffer cmd)
public static void PushNeutralShaderParameters(HDCamera hdCamera, CommandBuffer cmd)
if (ShaderConfig.s_VolumetricLightingPreset != 0)
if (hdCamera.frameSettings.enableVolumetric)
{
var data = DensityVolumeData.GetNeutralValues();

}
// Not used by the volumetric fog.
public void PushShaderParametersCommon(CommandBuffer cmd, FogType type, FrameSettings frameSettings)
public void PushShaderParametersCommon(HDCamera hdCamera, CommandBuffer cmd, FogType type)
Debug.Assert(frameSettings.enableAtmosphericScattering);
Debug.Assert(hdCamera.frameSettings.enableAtmosphericScattering);
cmd.SetGlobalInt(HDShaderIDs._AtmosphericScatteringType, (int)type);

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/ExponentialFog.cs


public FloatParameter fogBaseHeight = new FloatParameter(0.0f);
public ClampedFloatParameter fogHeightAttenuation = new ClampedFloatParameter(0.2f, 0.0f, 1.0f);
public override void PushShaderParameters(CommandBuffer cmd, FrameSettings frameSettings)
public override void PushShaderParameters(HDCamera hdCamera, CommandBuffer cmd)
PushShaderParametersCommon(cmd, FogType.Exponential, frameSettings);
PushShaderParametersCommon(hdCamera, cmd, FogType.Exponential);
}
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/LinearFog.cs


public FloatParameter fogHeightStart = new FloatParameter(0.0f);
public FloatParameter fogHeightEnd = new FloatParameter(10.0f);
public override void PushShaderParameters(CommandBuffer cmd, FrameSettings frameSettings)
public override void PushShaderParameters(HDCamera hdCamera, CommandBuffer cmd)
PushShaderParametersCommon(cmd, FogType.Linear, frameSettings);
PushShaderParametersCommon(hdCamera,cmd, FogType.Linear);
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/VolumetricFog.cs


}
}
public override void PushShaderParameters(CommandBuffer cmd, FrameSettings frameSettings)
public override void PushShaderParameters(HDCamera hdCamera, CommandBuffer cmd)
{
DensityVolumeParameters param = new DensityVolumeParameters(albedo, meanFreePath, anisotropy);

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


}
}
public void UpdateCurrentSkySettings(HDCamera camera)
public void UpdateCurrentSkySettings(HDCamera hdCamera)
if (camera.camera.cameraType == CameraType.Preview)
if (HDUtils.IsRegularPreviewCamera(hdCamera.camera))
{
m_VisualSky.skySettings = GetDefaultPreviewSkyInstance();
}

// Update needs to happen before testing if the component is active other internal data structure are not properly updated yet.
VolumeManager.instance.Update(m_LightingOverrideVolumeStack, camera.camera.transform, m_LightingOverrideLayerMask);
VolumeManager.instance.Update(m_LightingOverrideVolumeStack, hdCamera.camera.transform, m_LightingOverrideLayerMask);
if(VolumeManager.instance.IsComponentActiveInMask<VisualEnvironment>(m_LightingOverrideLayerMask))
{
SkySettings newSkyOverride = GetSkySetting(m_LightingOverrideVolumeStack);

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


public IntParameter skyType = new IntParameter(0);
public FogTypeParameter fogType = new FogTypeParameter(FogType.None);
public void PushFogShaderParameters(CommandBuffer cmd, FrameSettings frameSettings)
public void PushFogShaderParameters(HDCamera hdCamera, CommandBuffer cmd)
if (!frameSettings.enableAtmosphericScattering)
if (!hdCamera.frameSettings.enableAtmosphericScattering)
AtmosphericScattering.PushNeutralShaderParameters(cmd);
AtmosphericScattering.PushNeutralShaderParameters(hdCamera, cmd);
return;
}

{
AtmosphericScattering.PushNeutralShaderParameters(cmd);
AtmosphericScattering.PushNeutralShaderParameters(hdCamera, cmd);
fogSettings.PushShaderParameters(cmd, frameSettings);
fogSettings.PushShaderParameters(hdCamera, cmd);
fogSettings.PushShaderParameters(cmd, frameSettings);
fogSettings.PushShaderParameters(hdCamera, cmd);
fogSettings.PushShaderParameters(cmd, frameSettings);
fogSettings.PushShaderParameters(hdCamera, cmd);
break;
}
}

573
ScriptableRenderPipeline/LightweightPipeline/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs


[FormerName("UnityEditor.ShaderGraph.LightWeightPBRSubShader")]
public class LightWeightPBRSubShader : IPBRSubShader
{
static NeededCoordinateSpace m_VertexCoordinateSpace = NeededCoordinateSpace.Object;
static NeededCoordinateSpace m_PixelCoordinateSpace = NeededCoordinateSpace.World;
struct Pass
{
public string Name;

PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
}
};

PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
},
VertexShaderSlots = new List<int>()
{
PBRMasterNode.PositionSlotId
private static string GetShaderPassFromTemplate(string template, PBRMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions)
public string GetSubshader(IMasterNode inMasterNode, GenerationMode mode)
var builder = new ShaderStringBuilder();
builder.IncreaseIndent();
builder.IncreaseIndent();
var vertexInputs = new ShaderGenerator();
var surfaceVertexShader = new ShaderGenerator();
var surfaceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var functionRegistry = new FunctionRegistry(builder);
var surfaceInputs = new ShaderGenerator();
var templatePath = GetTemplatePath("lightweightPBRForwardPass.template");
var extraPassesTemplatePath = GetTemplatePath("lightweightPBRExtraPasses.template");
if (!File.Exists(templatePath) || !File.Exists(extraPassesTemplatePath))
return string.Empty;
string forwardTemplate = File.ReadAllText(templatePath);
string extraTemplate = File.ReadAllText(extraPassesTemplatePath);
var masterNode = inMasterNode as PBRMasterNode;
var pass = masterNode.model == PBRMasterNode.Model.Metallic ? m_ForwardPassMetallic : m_ForwardPassSpecular;
var subShader = new ShaderStringBuilder();
subShader.AppendLine("SubShader");
using (subShader.BlockScope())
{
subShader.AppendLine("Tags{ \"RenderPipeline\" = \"LightweightPipeline\"}");
var materialOptions = ShaderGenerator.GetMaterialOptions(masterNode.surfaceType, masterNode.alphaMode, masterNode.twoSided.isOn);
var tagsBuilder = new ShaderStringBuilder(0);
materialOptions.GetTags(tagsBuilder);
subShader.AppendLines(tagsBuilder.ToString());
subShader.AppendLines(GetShaderPassFromTemplate(
forwardTemplate,
masterNode,
pass,
mode,
materialOptions));
subShader.AppendLines(GetExtraPassesFromTemplate(extraTemplate, masterNode, pass, mode, materialOptions));
}
return subShader.ToString();
}
static string GetTemplatePath(string templateName)
{
string relativeTemplatePath = Path.Combine("LWRP", Path.Combine("Editor", Path.Combine("ShaderGraph", templateName)));
foreach (var path in LightweightIncludePaths.GetPaths())
{
var templatePath = Path.Combine(path, relativeTemplatePath);
if (File.Exists(templatePath))
return templatePath;
}
throw new FileNotFoundException(string.Format(@"Cannot find a template with name ""{0}"".", templateName));
}
static string GetShaderPassFromTemplate(string template, PBRMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions)
{
// ----------------------------------------------------- //
// SETUP //
// ----------------------------------------------------- //
// -------------------------------------
// String builders
var functionBuilder = new ShaderStringBuilder(1);
var functionRegistry = new FunctionRegistry(functionBuilder);
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();
var defines = new ShaderStringBuilder(1);
var graph = new ShaderStringBuilder(0);
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
var vertexDescriptionInputStruct = new ShaderStringBuilder(1);
var vertexDescriptionStruct = new ShaderStringBuilder(1);
var vertexDescriptionFunction = new ShaderStringBuilder(1);
var requirements = ShaderGraphRequirements.FromNodes(activeNodeList);
var surfaceDescriptionInputStruct = new ShaderStringBuilder(1);
var surfaceDescriptionStruct = new ShaderStringBuilder(1);
var surfaceDescriptionFunction = new ShaderStringBuilder(1);
var vertexInputStruct = new ShaderStringBuilder(1);
var vertexOutputStruct = new ShaderStringBuilder(2);
var vertexShader = new ShaderStringBuilder(2);
var vertexShaderDescriptionInputs = new ShaderStringBuilder(2);
var vertexShaderOutputs = new ShaderStringBuilder(2);
var pixelShader = new ShaderStringBuilder(2);
var pixelShaderSurfaceInputs = new ShaderStringBuilder(2);
var pixelShaderSurfaceRemap = new ShaderStringBuilder(2);
// -------------------------------------
// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
var pixelSlots = pass.PixelShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var pixelNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(pixelNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
// -------------------------------------
// Get Requirements
var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false);
var pixelRequirements = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment);
var surfaceRequirements = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false);
modelRequiements.requiresNormal |= NeededCoordinateSpace.World;
modelRequiements.requiresTangent |= NeededCoordinateSpace.World;
modelRequiements.requiresBitangent |= NeededCoordinateSpace.World;
modelRequiements.requiresPosition |= NeededCoordinateSpace.World;
modelRequiements.requiresViewDir |= NeededCoordinateSpace.World;
modelRequiements.requiresNormal |= m_PixelCoordinateSpace;
modelRequiements.requiresTangent |= m_PixelCoordinateSpace;
modelRequiements.requiresBitangent |= m_PixelCoordinateSpace;
modelRequiements.requiresPosition |= m_PixelCoordinateSpace;
modelRequiements.requiresViewDir |= m_PixelCoordinateSpace;
GraphUtil.GenerateApplicationVertexInputs(requirements.Union(modelRequiements), vertexInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, InterpolatorType.Normal, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, InterpolatorType.Tangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, InterpolatorType.BiTangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresViewDir, InterpolatorType.ViewDirection, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, InterpolatorType.Position, surfaceInputs);
// ----------------------------------------------------- //
// START SHADER GENERATION //
// ----------------------------------------------------- //
// -------------------------------------
// Calculate material options
var blendingBuilder = new ShaderStringBuilder(1);
var cullingBuilder = new ShaderStringBuilder(1);
var zTestBuilder = new ShaderStringBuilder(1);
var zWriteBuilder = new ShaderStringBuilder(1);
materialOptions.GetBlend(blendingBuilder);
materialOptions.GetCull(cullingBuilder);
materialOptions.GetDepthTest(zTestBuilder);
materialOptions.GetDepthWrite(zWriteBuilder);
if (requirements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.VertexColor), false);
// -------------------------------------
// Generate defines
if (masterNode.IsSlotConnected(PBRMasterNode.NormalSlotId))
defines.AppendLine("#define _NORMALMAP 1");
if (masterNode.model == PBRMasterNode.Model.Specular)
defines.AppendLine("#define _SPECULAR_SETUP 1");
if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId))
defines.AppendLine("#define _AlphaClip 1");
if(masterNode.surfaceType == SurfaceType.Transparent && masterNode.alphaMode == AlphaMode.Premultiply)
defines.AppendLine("#define _ALPHAPREMULTIPLY_ON 1");
// ----------------------------------------------------- //
// START VERTEX DESCRIPTION //
// ----------------------------------------------------- //
// -------------------------------------
// Generate Input structure for Vertex Description function
// TODO - Vertex Description Input requirements are needed to exclude intermediate translation spaces
vertexDescriptionInputStruct.AppendLine("struct VertexDescriptionInputs");
using (vertexDescriptionInputStruct.BlockSemicolonScope())
{
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresNormal, InterpolatorType.Normal, vertexDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresTangent, InterpolatorType.Tangent, vertexDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresBitangent, InterpolatorType.BiTangent, vertexDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresViewDir, InterpolatorType.ViewDirection, vertexDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresPosition, InterpolatorType.Position, vertexDescriptionInputStruct);
if (vertexRequirements.requiresVertexColor)
vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor);
if (vertexRequirements.requiresScreenPosition)
vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
foreach (var channel in vertexRequirements.requiresMeshUVs.Distinct())
vertexDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
}
// -------------------------------------
// Generate Output structure for Vertex Description function
GraphUtil.GenerateVertexDescriptionStruct(vertexDescriptionStruct, vertexSlots);
// -------------------------------------
// Generate Vertex Description function
GraphUtil.GenerateVertexDescriptionFunction(
masterNode.owner as AbstractMaterialGraph,
vertexDescriptionFunction,
functionRegistry,
shaderProperties,
mode,
vertexNodes,
vertexSlots);
// ----------------------------------------------------- //
// START SURFACE DESCRIPTION //
// ----------------------------------------------------- //
// -------------------------------------
// Generate Input structure for Surface Description function
// Surface Description Input requirements are needed to exclude intermediate translation spaces
surfaceDescriptionInputStruct.AppendLine("struct SurfaceDescriptionInputs");
using (surfaceDescriptionInputStruct.BlockSemicolonScope())
{
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresNormal, InterpolatorType.Normal, surfaceDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresTangent, InterpolatorType.Tangent, surfaceDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresBitangent, InterpolatorType.BiTangent, surfaceDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresViewDir, InterpolatorType.ViewDirection, surfaceDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresPosition, InterpolatorType.Position, surfaceDescriptionInputStruct);
if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);
if (surfaceRequirements.requiresVertexColor)
surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor);
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("half4 {0};", channel.GetUVName()), false);
if (surfaceRequirements.requiresScreenPosition)
surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
surfaceInputs.Deindent();
surfaceInputs.AddShaderChunk("};", false);
foreach (var channel in surfaceRequirements.requiresMeshUVs.Distinct())
surfaceDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
}
surfaceVertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false);
surfaceVertexShader.Indent();
surfaceVertexShader.AddShaderChunk("return v;", false);
surfaceVertexShader.Deindent();
surfaceVertexShader.AddShaderChunk("}", false);
// -------------------------------------
// Generate Output structure for Surface Description function
var slots = new List<MaterialSlot>();
foreach (var id in pass.PixelShaderSlots)
slots.Add(masterNode.FindSlot<MaterialSlot>(id));
GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, pixelSlots, true);
var usedSlots = new List<MaterialSlot>();
foreach (var id in pass.PixelShaderSlots)
usedSlots.Add(masterNode.FindSlot<MaterialSlot>(id));
// -------------------------------------
// Generate Surface Description function
GraphUtil.GenerateSurfaceDescription(
activeNodeList,
GraphUtil.GenerateSurfaceDescriptionFunction(
pixelNodes,
requirements,
pixelRequirements,
usedSlots);
pixelSlots);
var graph = new ShaderGenerator();
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(builder.ToString(), false);
graph.AddShaderChunk(vertexInputs.GetShaderString(2), false);
graph.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false);
graph.AddShaderChunk(surfaceVertexShader.GetShaderString(2), false);
graph.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);
// ----------------------------------------------------- //
// GENERATE VERTEX > PIXEL PIPELINE //
// ----------------------------------------------------- //
var blendingVisitor = new ShaderGenerator();
var cullingVisitor = new ShaderGenerator();
var zTestVisitor = new ShaderGenerator();
var zWriteVisitor = new ShaderGenerator();
// -------------------------------------
// Generate Input structure for Vertex shader
materialOptions.GetBlend(blendingVisitor);
materialOptions.GetCull(cullingVisitor);
materialOptions.GetDepthTest(zTestVisitor);
materialOptions.GetDepthWrite(zWriteVisitor);
GraphUtil.GenerateApplicationVertexInputs(vertexRequirements.Union(pixelRequirements.Union(modelRequiements)), vertexInputStruct);
var interpolators = new ShaderGenerator();
var localVertexShader = new ShaderGenerator();
var localPixelShader = new ShaderGenerator();
var localSurfaceInputs = new ShaderGenerator();
var surfaceOutputRemap = new ShaderGenerator();
// -------------------------------------
// Generate standard transformations
// This method ensures all required transform data is available in vertex and pixel stages
interpolators,
localVertexShader,
localPixelShader,
localSurfaceInputs,
requirements,
vertexOutputStruct,
vertexShader,
vertexShaderDescriptionInputs,
vertexShaderOutputs,
pixelShader,
pixelShaderSurfaceInputs,
pixelRequirements,
surfaceRequirements,
vertexRequirements,
ShaderGenerator defines = new ShaderGenerator();
// -------------------------------------
// Generate pixel shader surface remap
if (masterNode.IsSlotConnected(PBRMasterNode.NormalSlotId))
defines.AddShaderChunk("#define _NORMALMAP 1", true);
foreach (var slot in pixelSlots)
{
pixelShaderSurfaceRemap.AppendLine("{0} = surf.{0};", slot.shaderOutputName);
}
if (masterNode.model == PBRMasterNode.Model.Specular)
defines.AddShaderChunk("#define _SPECULAR_SETUP 1", true);
// ----------------------------------------------------- //
// FINALIZE //
// ----------------------------------------------------- //
if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId))
defines.AddShaderChunk("#define _AlphaClip 1", true);
// -------------------------------------
// Combine Graph sections
if (masterNode.surfaceType == SurfaceType.Transparent && masterNode.alphaMode == AlphaMode.Premultiply)
defines.AddShaderChunk("#define _ALPHAPREMULTIPLY_ON 1", true);
graph.AppendLine(shaderProperties.GetPropertiesDeclaration(1));
var templateLocation = GetTemplatePath(template);
graph.AppendLine(vertexDescriptionInputStruct.ToString());
graph.AppendLine(surfaceDescriptionInputStruct.ToString());
foreach (var slot in usedSlots)
{
surfaceOutputRemap.AddShaderChunk(string.Format("{0} = surf.{0};", slot.shaderOutputName), true);
}
graph.AppendLine(functionBuilder.ToString());
graph.AppendLine(vertexDescriptionStruct.ToString());
graph.AppendLine(vertexDescriptionFunction.ToString());
graph.AppendLine(surfaceDescriptionStruct.ToString());
graph.AppendLine(surfaceDescriptionFunction.ToString());
graph.AppendLine(vertexInputStruct.ToString());
// -------------------------------------
// Generate final subshader
var resultPass = template.Replace("${Tags}", string.Empty);
resultPass = resultPass.Replace("${Blending}", blendingBuilder.ToString());
resultPass = resultPass.Replace("${Culling}", cullingBuilder.ToString());
resultPass = resultPass.Replace("${ZTest}", zTestBuilder.ToString());
resultPass = resultPass.Replace("${ZWrite}", zWriteBuilder.ToString());
resultPass = resultPass.Replace("${Defines}", defines.ToString());
resultPass = resultPass.Replace("${Graph}", graph.ToString());
resultPass = resultPass.Replace("${VertexOutputStruct}", vertexOutputStruct.ToString());
if (!File.Exists(templateLocation))
return string.Empty;
resultPass = resultPass.Replace("${VertexShader}", vertexShader.ToString());
resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexShaderDescriptionInputs.ToString());
resultPass = resultPass.Replace("${VertexShaderOutputs}", vertexShaderOutputs.ToString());
var subShaderTemplate = File.ReadAllText(templateLocation);
var resultPass = subShaderTemplate.Replace("${Defines}", defines.GetShaderString(3));
resultPass = resultPass.Replace("${Graph}", graph.GetShaderString(3));
resultPass = resultPass.Replace("${Interpolators}", interpolators.GetShaderString(3));
resultPass = resultPass.Replace("${VertexShader}", localVertexShader.GetShaderString(3));
resultPass = resultPass.Replace("${LocalPixelShader}", localPixelShader.GetShaderString(3));
resultPass = resultPass.Replace("${SurfaceInputs}", localSurfaceInputs.GetShaderString(3));
resultPass = resultPass.Replace("${SurfaceOutputRemap}", surfaceOutputRemap.GetShaderString(3));
resultPass = resultPass.Replace("${PixelShader}", pixelShader.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceInputs}", pixelShaderSurfaceInputs.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceRemap}", pixelShaderSurfaceRemap.ToString());
resultPass = resultPass.Replace("${Tags}", string.Empty);
resultPass = resultPass.Replace("${Blending}", blendingVisitor.GetShaderString(2));
resultPass = resultPass.Replace("${Culling}", cullingVisitor.GetShaderString(2));
resultPass = resultPass.Replace("${ZTest}", zTestVisitor.GetShaderString(2));
resultPass = resultPass.Replace("${ZWrite}", zWriteVisitor.GetShaderString(2));
static string GetTemplatePath(string templateName)
static string GetExtraPassesFromTemplate(string template, PBRMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions)
string relativeTemplatePath = Path.Combine("LWRP", Path.Combine("Editor", Path.Combine("ShaderGraph", templateName)));
foreach (var path in LightweightIncludePaths.GetPaths())
{
var templatePath = Path.Combine(path, relativeTemplatePath);
if (File.Exists(templatePath))
return templatePath;
}
throw new FileNotFoundException(string.Format(@"Cannot find a template with name ""{0}"".", templateName));
}
// ----------------------------------------------------- //
// SETUP //
// ----------------------------------------------------- //
// -------------------------------------
// String builders
public string GetSubshader(IMasterNode inMasterNode, GenerationMode mode)
{
var masterNode = inMasterNode as PBRMasterNode;
var subShader = new ShaderGenerator();
subShader.AddShaderChunk("SubShader", true);
subShader.AddShaderChunk("{", true);
subShader.Indent();
subShader.AddShaderChunk("Tags{ \"RenderPipeline\" = \"LightweightPipeline\"}", true);
var dummyBuilder = new ShaderStringBuilder(0);
var shaderProperties = new PropertyCollector();
var functionBuilder = new ShaderStringBuilder(1);
var functionRegistry = new FunctionRegistry(functionBuilder);
var materialOptions = ShaderGenerator.GetMaterialOptions(masterNode.surfaceType, masterNode.alphaMode, masterNode.twoSided.isOn);
var tagsVisitor = new ShaderGenerator();
materialOptions.GetTags(tagsVisitor);
subShader.AddShaderChunk(tagsVisitor.GetShaderString(0), true);
var defines = new ShaderStringBuilder(2);
var graph = new ShaderStringBuilder(0);
subShader.AddShaderChunk(
GetShaderPassFromTemplate(
"lightweightPBRForwardPass.template",
masterNode,
masterNode.model == PBRMasterNode.Model.Metallic ? m_ForwardPassMetallic : m_ForwardPassSpecular,
mode,
materialOptions),
true);
var vertexDescriptionInputStruct = new ShaderStringBuilder(1);
var vertexDescriptionStruct = new ShaderStringBuilder(1);
var vertexDescriptionFunction = new ShaderStringBuilder(1);
var extraPassesTemplateLocation = GetTemplatePath("lightweightPBRExtraPasses.template");
if (File.Exists(extraPassesTemplateLocation))
var vertexInputStruct = new ShaderStringBuilder(1);
var vertexShader = new ShaderStringBuilder(2);
var vertexDescriptionInputs = new ShaderStringBuilder(2);
// -------------------------------------
// Get Slot and Node lists per stage
var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot<MaterialSlot>).ToList();
var vertexNodes = ListPool<AbstractMaterialNode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);
// -------------------------------------
// Get requirements
var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false);
var modelRequiements = ShaderGraphRequirements.none;
modelRequiements.requiresNormal |= m_VertexCoordinateSpace;
modelRequiements.requiresPosition |= m_VertexCoordinateSpace;
modelRequiements.requiresMeshUVs.Add(UVChannel.UV1);
// ----------------------------------------------------- //
// START SHADER GENERATION //
// ----------------------------------------------------- //
// -------------------------------------
// Calculate material options
var cullingBuilder = new ShaderStringBuilder(1);
materialOptions.GetCull(cullingBuilder);
// -------------------------------------
// Generate defines
if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId))
defines.AppendLine("#define _AlphaClip 1");
// ----------------------------------------------------- //
// START VERTEX DESCRIPTION //
// ----------------------------------------------------- //
// -------------------------------------
// Generate Input structure for Vertex Description function
// TODO - Vertex Description Input requirements are needed to exclude intermediate translation spaces
vertexDescriptionInputStruct.AppendLine("struct VertexDescriptionInputs");
using (vertexDescriptionInputStruct.BlockSemicolonScope())
var extraPassesTemplate = File.ReadAllText(extraPassesTemplateLocation);
extraPassesTemplate = extraPassesTemplate.Replace("${Culling}", materialOptions.cullMode.ToString());
subShader.AddShaderChunk(extraPassesTemplate, true);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresNormal, InterpolatorType.Normal, vertexDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresTangent, InterpolatorType.Tangent, vertexDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresBitangent, InterpolatorType.BiTangent, vertexDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresViewDir, InterpolatorType.ViewDirection, vertexDescriptionInputStruct);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresPosition, InterpolatorType.Position, vertexDescriptionInputStruct);
if (vertexRequirements.requiresVertexColor)
vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor);
if (vertexRequirements.requiresScreenPosition)
vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
foreach (var channel in vertexRequirements.requiresMeshUVs.Distinct())
vertexDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
subShader.Deindent();
subShader.AddShaderChunk("}", true);
// -------------------------------------
// Generate Output structure for Vertex Description function
GraphUtil.GenerateVertexDescriptionStruct(vertexDescriptionStruct, vertexSlots);
// -------------------------------------
// Generate Vertex Description function
GraphUtil.GenerateVertexDescriptionFunction(
masterNode.owner as AbstractMaterialGraph,
vertexDescriptionFunction,
functionRegistry,
shaderProperties,
mode,
vertexNodes,
vertexSlots);
// ----------------------------------------------------- //
// GENERATE VERTEX > PIXEL PIPELINE //
// ----------------------------------------------------- //
// -------------------------------------
// Generate Input structure for Vertex shader
GraphUtil.GenerateApplicationVertexInputs(vertexRequirements.Union(modelRequiements), vertexInputStruct);
// -------------------------------------
// Generate standard transformations
// This method ensures all required transform data is available in vertex and pixel stages
ShaderGenerator.GenerateStandardTransforms(
3,
10,
dummyBuilder,
vertexShader,
vertexDescriptionInputs,
dummyBuilder,
dummyBuilder,
dummyBuilder,
ShaderGraphRequirements.none,
ShaderGraphRequirements.none,
modelRequiements,
vertexRequirements,
CoordinateSpace.World);
// ----------------------------------------------------- //
// FINALIZE //
// ----------------------------------------------------- //
// -------------------------------------
// Combine Graph sections
graph.AppendLine(shaderProperties.GetPropertiesDeclaration(1));
graph.AppendLine(vertexDescriptionInputStruct.ToString());
graph.AppendLine(functionBuilder.ToString());
graph.AppendLine(vertexDescriptionStruct.ToString());
graph.AppendLine(vertexDescriptionFunction.ToString());
graph.AppendLine(vertexInputStruct.ToString());
// -------------------------------------
// Generate final subshader
var resultPass = template.Replace("${Culling}", cullingBuilder.ToString());
resultPass = resultPass.Replace("${Defines}", defines.ToString());
resultPass = resultPass.Replace("${Graph}", graph.ToString());
resultPass = resultPass.Replace("${VertexShader}", vertexShader.ToString());
resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexDescriptionInputs.ToString());
return subShader.GetShaderString(0);
return resultPass;
}
}

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

正在加载...
取消
保存