浏览代码

Merge pull request #470 from Unity-Technologies/Unity-2017.3

Unity 2017.3
/main
GitHub 7 年前
当前提交
6213cc0b
共有 91 个文件被更改,包括 3044 次插入3221 次删除
  1. 41
      SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Rock.mat
  2. 53
      SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood triplanar.mat
  3. 27
      SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood.mat
  4. 39
      SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Rock.mat
  5. 31
      SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Wood.mat
  6. 38
      SampleScenes/HDTest/GraphicTest/Triplanar/Material/Wood triplanar.mat
  7. 48
      SampleScenes/HDTest/HDRenderLoopTest.unity
  8. 4
      SampleScenes/OnTileDeferredTest/Common/MobileTestSceneManager.cs
  9. 19
      ScriptableRenderPipeline/Core/CommandBufferPool.cs
  10. 37
      ScriptableRenderPipeline/Core/CoreUtils.cs
  11. 8
      ScriptableRenderPipeline/Core/Debugging/DebugItemHandler.cs
  12. 2
      ScriptableRenderPipeline/Core/Debugging/DebugItemUI.cs
  13. 16
      ScriptableRenderPipeline/Core/Debugging/DebugMenuState.cs
  14. 2
      ScriptableRenderPipeline/Core/Debugging/DebugPanel.cs
  15. 41
      ScriptableRenderPipeline/Core/Debugging/DebugPanelUI.cs
  16. 38
      ScriptableRenderPipeline/Core/Editor/CoreEditorUtils.cs
  17. 58
      ScriptableRenderPipeline/Core/Editor/PropertyFetcher.cs
  18. 177
      ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl
  19. 16
      ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl
  20. 12
      ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl
  21. 9
      ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl
  22. 6
      ScriptableRenderPipeline/HDRenderPipeline/Camera/HDCamera.cs
  23. 5
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  24. 7
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl
  25. 16
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.hlsl
  26. 4
      ScriptableRenderPipeline/HDRenderPipeline/Debug/LightingDebugPanel.cs
  27. 250
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  28. 16
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs
  29. 332
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  30. 601
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.asset
  31. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.cs
  32. 46
      ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs
  33. 29
      ScriptableRenderPipeline/HDRenderPipeline/HDUtils.cs
  34. 42
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs
  35. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  36. 106
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  37. 52
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  38. 52
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  39. 168
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  40. 110
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  41. 5
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs
  42. 76
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  43. 36
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  44. 709
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  45. 82
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  46. 21
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  47. 43
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  48. 38
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  49. 6
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitDepthPass.hlsl
  50. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitDistortionPass.hlsl
  51. 6
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitVelocityPass.hlsl
  52. 107
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs
  53. 7
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader
  54. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/UnlitData.hlsl
  55. 9
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/TessellationShare.hlsl
  56. 19
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VaryingMesh.hlsl
  57. 20
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VertMesh.hlsl
  58. 9
      ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs
  59. 16
      ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkySettings.cs
  60. 41
      ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkySettings.cs
  61. 49
      ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs
  62. 178
      ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs
  63. 5
      ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyRenderer.cs
  64. 35
      ScriptableRenderPipeline/HDRenderPipeline/Sky/SkySettings.cs
  65. 6
      ScriptableRenderPipeline/HDRenderPipeline/Sky/SkySettingsSingleton.cs
  66. 2
      ScriptableRenderPipeline/LightweightPipeline/Editor/ShaderGUI/LightweightStandardGUI.cs
  67. 27
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  68. 4
      TestbedPipelines/Fptl/FptlLighting.cs
  69. 2
      TestbedPipelines/Fptl/SkyboxHelper.cs
  70. 2
      TestbedPipelines/OnTileDeferredPipeline/OnTileDeferredRenderPipeline.cs
  71. 53
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDBaseEditor.cs
  72. 13
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDBaseEditor.cs.meta
  73. 56
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.Styles.cs
  74. 13
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.Styles.cs.meta
  75. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs.meta
  76. 258
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.cs
  77. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.cs.meta
  78. 85
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SSS Settings.asset
  79. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SSS Settings.asset.meta
  80. 508
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs
  81. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs.meta
  82. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringProfileEditor.Styles.cs.meta
  83. 170
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringProfileEditor.cs
  84. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringProfileEditor.cs.meta
  85. 9
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/FoliageSSSProfile.asset.meta
  86. 9
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset.meta
  87. 116
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/FoliageSSSProfile.asset
  88. 116
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset
  89. 12
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.meta
  90. 637
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  91. 0
      /ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs

41
SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Rock.mat


m_PrefabInternal: {fileID: 0}
m_Name: POM - Rock
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _HEIGHTMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE _PER_PIXEL_DISPLACEMENT
m_ShaderKeywords: _DISPLACEMENT_LOCK_TILING_SCALE _HEIGHTMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
_PER_PIXEL_DISPLACEMENT _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE _PER_PIXEL_DISPLACEMENT_TILING_SCALE
_PIXEL_DISPLACEMENT _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE _PIXEL_DISPLACEMENT_LOCK_TILING_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 25f2c87d04c2d19479e747dc71259c7d, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _ATDistance: 1
- _AlbedoAffectEmissive: 0
- _CoatCoverage: 1
- _CoatIOR: 0.5
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0

- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 2
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0

- _EmissiveColorMode: 1
- _EmissiveIntensity: 0
- _EnablePerPixelDisplacement: 1
- _EnableSpecularOcclusion: 0
- _EnableVertexDisplacement: 0
- _HeightAmplitude: 0.8
- _HeightCenter: 0.5
- _HeightAmplitude: 1
- _HeightCenter: 1
- _HeightMax: 100
- _HeightMin: 0
- _IOR: 1
- _InvTilingScale: 1
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0

- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMinSamples: 5
- _PPDPrimitiveLength: 10
- _PPDPrimitiveWidth: 10
- _PerPixelDisplacementObjectScale: 1
- _PerPixelDisplacementTilingScale: 1
- _RefractionMode: 0
- _SmoothnessRemapMax: 1
- _SmoothnessRemapMin: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1

- _SurfaceType: 0
- _TexWorldScale: 1
- _Thickness: 1
- _ThicknessMultiplier: 1
- _VertexDisplacementObjectScale: 1
- _VertexDisplacementTilingScale: 1
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 0.1, g: 0.1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}

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


m_PrefabInternal: {fileID: 0}
m_Name: POM - Wood triplanar
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _HEIGHTMAP _MAPPING_TRIPLANAR _NORMALMAP _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _DEPTHOFFSET_ON _HEIGHTMAP _MAPPING_TRIPLANAR _NORMALMAP _NORMALMAP_TANGENT_SPACE
_PER_PIXEL_DISPLACEMENT _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE _PER_PIXEL_DISPLACEMENT_TILING_SCALE
_PIXEL_DISPLACEMENT _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE _PIXEL_DISPLACEMENT_LOCK_TILING_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 927434958f610214aa6a4179f134f5fd, type: 3}
m_Scale: {x: 2, y: 2}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _ATDistance: 1
- _AlbedoAffectEmissive: 0
- _CoatCoverage: 1
- _CoatIOR: 0.5
- _DepthOffsetEnable: 0
- _DepthOffsetEnable: 1
- _DetailAOScale: 1
- _DetailAlbedoScale: 1
- _DetailHeightScale: 1

- _DetailSmoothnessScale: 1
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 2
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0

- _DstBlend: 0
- _EmissiveColorMode: 1
- _EmissiveIntensity: 0
- _EnablePerPixelDisplacement: 0
- _EnablePerPixelDisplacement: 1
- _EnableSpecularOcclusion: 0
- _EnableVertexDisplacement: 0
- _HeightAmplitude: 0.17
- _HeightAmplitude: 0.5
- _HeightMax: 50
- _HeightMin: 0
- _IOR: 1
- _InvTilingScale: 1
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0

- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMaxSamples: 64
- _PPDPrimitiveLength: 1
- _PPDPrimitiveWidth: 1
- _PerPixelDisplacementObjectScale: 1
- _PerPixelDisplacementTilingScale: 1
- _RefractionMode: 0
- _SmoothnessRemapMax: 1
- _SmoothnessRemapMin: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1

- _SubsurfaceRadius: 1
- _SurfaceType: 0
- _TexWorldScale: 0.1
- _TexWorldScale: 0.2
- _UVBase: 2
- _ThicknessMultiplier: 1
- _UVBase: 5
- _VertexDisplacementObjectScale: 1
- _VertexDisplacementTilingScale: 1
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 0, g: 0, b: 0, a: 0}

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


m_PrefabInternal: {fileID: 0}
m_Name: POM - Wood
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _DEPTHOFFSET_ON _HEIGHTMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
_PER_PIXEL_DISPLACEMENT
m_ShaderKeywords: _DEPTHOFFSET_ON _DISPLACEMENT_LOCK_TILING_SCALE _HEIGHTMAP _NORMALMAP
_NORMALMAP_TANGENT_SPACE _PER_PIXEL_DISPLACEMENT _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
_PER_PIXEL_DISPLACEMENT_TILING_SCALE _PIXEL_DISPLACEMENT _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
_PIXEL_DISPLACEMENT_LOCK_TILING_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 927434958f610214aa6a4179f134f5fd, type: 3}
m_Scale: {x: 2, y: 2}
m_Scale: {x: 3, y: 2}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _ATDistance: 1
- _AlbedoAffectEmissive: 0
- _AlphaCutoff: 0.5
- _AlphaCutoffEnable: 0

- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 2
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0

- _EmissiveIntensity: 0
- _EnablePerPixelDisplacement: 1
- _EnableSpecularOcclusion: 0
- _EnableVertexDisplacement: 0
- _EnableWind: 0
- _GlossMapScale: 1
- _Glossiness: 0.5

- _HeightMax: 100
- _HeightMin: 0
- _HorizonFade: 1
- _IOR: 1
- _InvTilingScale: 0.4
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0

- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMaxSamples: 64
- _PPDPrimitiveLength: 10
- _PPDPrimitiveWidth: 10
- _PerPixelDisplacementObjectScale: 1
- _PerPixelDisplacementTilingScale: 1
- _RefractionMode: 0
- _ShiverDirectionality: 0.5
- _ShiverDrag: 0.2
- _Smoothness: 0.5

- _SurfaceType: 0
- _TexWorldScale: 0.2
- _Thickness: 1
- _ThicknessMultiplier: 1
- _VertexDisplacementObjectScale: 1
- _VertexDisplacementTilingScale: 1
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 0.1, g: 0.1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}

39
SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Rock.mat


m_PrefabInternal: {fileID: 0}
m_Name: Tessellation - Rock
m_Shader: {fileID: 4800000, guid: 756bac9090102564582875f4c7e30202, type: 3}
m_ShaderKeywords: _EMISSIVE_COLOR _HEIGHTMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
_TESSELLATION_DISPLACEMENT _TESSELLATION_TILING_SCALE
m_ShaderKeywords: _DISPLACEMENT_LOCK_TILING_SCALE _EMISSIVE_COLOR _HEIGHTMAP _NORMALMAP
_NORMALMAP_TANGENT_SPACE _TESSELLATION_DISPLACEMENT _TESSELLATION_TILING_SCALE
_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE _VERTEX_DISPLACEMENT_LOCK_TILING_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 25f2c87d04c2d19479e747dc71259c7d, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _ATDistance: 1
- _AlbedoAffectEmissive: 0
- _CoatCoverage: 1
- _CoatIOR: 0.5
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0

- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 3
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0

- _EmissiveColorMode: 0
- _EmissiveIntensity: 0
- _EnablePerPixelDisplacement: 0
- _EnableSpecularOcclusion: 0
- _HeightAmplitude: 0.8
- _HeightCenter: 0.5
- _HeightAmplitude: 1
- _HeightCenter: 1
- _HeightMax: 100
- _HeightMin: 0
- _IOR: 1
- _InvTilingScale: 1
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0

- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMinSamples: 5
- _PPDPrimitiveLength: 1
- _PPDPrimitiveWidth: 1
- _RefractionMode: 0
- _SmoothnessRemapMax: 1
- _SmoothnessRemapMin: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1

- _TessellationFactorMaxDistance: 50
- _TessellationFactorMinDistance: 20
- _TessellationFactorTriangleSize: 100
- _TessellationMode: 1
- _TessellationMode: 0
- _ThicknessMultiplier: 1
- _UVBase: 0
- _UVDetail: 0
- _UVMappingPlanar: 0

- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}

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


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

m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 927434958f610214aa6a4179f134f5fd, type: 3}
m_Scale: {x: 2, y: 2}
m_Scale: {x: 3, y: 2}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _ATDistance: 1
- _AlbedoAffectEmissive: 0
- _AlphaCutoff: 0.5
- _AlphaCutoffEnable: 0

- _CoatIOR: 0.5
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DepthOffsetEnable: 1
- _DetailAOScale: 1
- _DetailAlbedoScale: 1
- _DetailHeightScale: 1

- _DetailSmoothnessScale: 1
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 3
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0

- _EmissiveIntensity: 0
- _EnablePerPixelDisplacement: 0
- _EnableSpecularOcclusion: 0
- _EnableVertexDisplacement: 1
- _EnableWind: 0
- _GlossMapScale: 1
- _Glossiness: 0.5

- _HeightMax: 100
- _HeightMin: 0
- _HorizonFade: 1
- _IOR: 1
- _InvTilingScale: 0.4
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0

- _PPDLodThreshold: 5
- _PPDMaxSamples: 64
- _PPDMinSamples: 1
- _PPDPrimitiveLength: 10
- _PPDPrimitiveWidth: 10
- _PerPixelDisplacementObjectScale: 1
- _PerPixelDisplacementTilingScale: 1
- _RefractionMode: 0
- _ShiverDirectionality: 0.5
- _ShiverDrag: 0.2
- _Smoothness: 0.5

- _TessellationFactorMaxDistance: 50
- _TessellationFactorMinDistance: 20
- _TessellationFactorTriangleSize: 100
- _TessellationMode: 1
- _TessellationMode: 0
- _TexWorldScale: 1
- _TexWorldScale: 0.2
- _ThicknessMultiplier: 1
- _VertexDisplacementObjectScale: 1
- _VertexDisplacementTilingScale: 1
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 0.1, g: 0.1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}

38
SampleScenes/HDTest/GraphicTest/Triplanar/Material/Wood triplanar.mat


m_Name: Wood triplanar
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _HEIGHTMAP _MAPPING_TRIPLANAR _NORMALMAP _NORMALMAP_TANGENT_SPACE
_PER_PIXEL_DISPLACEMENT
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 927434958f610214aa6a4179f134f5fd, type: 3}
m_Scale: {x: 2, y: 2}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _ATDistance: 1
- _AlbedoAffectEmissive: 0
- _CoatCoverage: 1
- _CoatIOR: 0.5
- _CullMode: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0

- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 0
- _DistortionDepthTest: 0
- _DistortionEnable: 0
- _DistortionOnly: 0

- _EmissiveColorMode: 1
- _EmissiveIntensity: 0
- _EnablePerPixelDisplacement: 1
- _EnableSpecularOcclusion: 0
- _EnableVertexDisplacement: 0
- _HeightAmplitude: 0.17
- _HeightAmplitude: 0.02
- _HeightMax: 1
- _HeightMin: -1
- _IOR: 1
- _InvTilingScale: 0.5
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0

- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMinSamples: 1
- _PPDPrimitiveLength: 1
- _PPDPrimitiveWidth: 1
- _RefractionMode: 0
- _SmoothnessRemapMax: 1
- _SmoothnessRemapMin: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1

- _SurfaceType: 0
- _TexWorldScale: 0.1
- _Thickness: 1
- _UVBase: 2
- _ThicknessMultiplier: 1
- _UVBase: 5
- _VertexDisplacementObjectScale: 1
- _VertexDisplacementTilingScale: 1
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:

- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 0, g: 0, b: 0, a: 0}

48
SampleScenes/HDTest/HDRenderLoopTest.unity


maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &113580756
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &192903506
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &269387786
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &476925264
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &563884888
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &580932149
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &682868819
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &710116622
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &726298023
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!114 &733865597
MonoBehaviour:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!114 &785457128
MonoBehaviour:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &827169275
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!114 &834722899
MonoBehaviour:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &858501141
Light:

m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 874252441}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 10, y: 1, z: -14}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: 12.5, y: 1, z: -16}
m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
m_Children:
- {fileID: 1950745466}
- {fileID: 122368351}

m_RootOrder: 13
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!1 &885480687
GameObject:
m_ObjectHideFlags: 0

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &903116312
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &970745599
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &990293191
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1013563954
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1046252902
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1063426086
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1083738370
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1085128924
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1148469246
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1161056799
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!114 &1220024537
MonoBehaviour:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1235762390
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1308071701
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1309651670
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1352160402
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1555751258
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1559142270
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1640077385
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1737381190
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!114 &1854618468
MonoBehaviour:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1879857774
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1943835614
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1945509647
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1950745469
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &1988224188
Light:

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!108 &2015022936
Light:

4
SampleScenes/OnTileDeferredTest/Common/MobileTestSceneManager.cs


int detectSwipe() {
if (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Ended) {
Vector2 endPosition = Input.GetTouch (0).position;
Vector2 delta = endPosition - startPosition;
//Vector2 delta = endPosition - startPosition;
if (startPosition.x < endPosition.x)
return 1;

detectTouchBegan();
#endif
}
}
}

19
ScriptableRenderPipeline/Core/CommandBufferPool.cs


namespace UnityEngine.Experimental.Rendering
{
internal class ObjectPool<T> where T : new()
class ObjectPool<T> where T : new()
private readonly Stack<T> m_Stack = new Stack<T>();
private readonly UnityAction<T> m_ActionOnGet;
private readonly UnityAction<T> m_ActionOnRelease;
readonly Stack<T> m_Stack = new Stack<T>();
readonly UnityAction<T> m_ActionOnGet;
readonly UnityAction<T> m_ActionOnRelease;
public int countAll { get; private set; }
public int countActive { get { return countAll - countInactive; } }

m_Stack.Push(element);
}
}
private static ObjectPool<CommandBuffer> m_BufferPool = new ObjectPool<CommandBuffer>(null, x => x.Clear());
static ObjectPool<CommandBuffer> s_BufferPool = new ObjectPool<CommandBuffer>(null, x => x.Clear());
var cmd = m_BufferPool.Get();
var cmd = s_BufferPool.Get();
var cmd = m_BufferPool.Get();
var cmd = s_BufferPool.Get();
cmd.name = name;
return cmd;
}

m_BufferPool.Release(buffer);
s_BufferPool.Release(buffer);
}
}
}

37
ScriptableRenderPipeline/Core/CoreUtils.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;

public static class CoreUtils
{
public static List<RenderPipelineMaterial> GetRenderPipelineMaterialList()
{
var baseType = typeof(RenderPipelineMaterial);
var assembly = baseType.Assembly;
var types = assembly.GetTypes()
.Where(t => t.IsSubclassOf(baseType))
.Select(Activator.CreateInstance)
.Cast<RenderPipelineMaterial>()
.ToList();
// Note: If there is a need for an optimization in the future of this function, user can
// simply fill the materialList manually by commenting the code abode and returning a
// custom list of materials they use in their game.
//
// return new List<RenderPipelineMaterial>
// {
// new Lit(),
// new Unlit(),
// ...
// };
return types;
}
// Render Target Management.
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{

UnityObject.Destroy(obj);
#endif
}
}
public static void Destroy(params UnityObject[] objs)
{
if (objs == null)
return;
foreach (var o in objs)
Destroy(o);
}
public static void SafeRelease(ComputeBuffer buffer)

8
ScriptableRenderPipeline/Core/Debugging/DebugItemHandler.cs


m_DebugItem = item;
}
// Method user needs to override for specific value clamping.
public virtual void ClampValues(Func<object> getter, Action<object> setter) {}
// Method user needs to override for specific value validation.
public virtual void ValidateValues(Func<object> getter, Action<object> setter) {}
// Method that will create UI items for runtime debug menu.
public abstract DebugItemUI BuildGUI(GameObject parent);

m_Max = max;
}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
setter(Mathf.Clamp((float)getter(), m_Min, m_Max));
}

m_Max = max;
}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
setter(Math.Min(m_Max, Math.Max(m_Min, (uint)getter())));
}

2
ScriptableRenderPipeline/Core/Debugging/DebugItemUI.cs


public bool dynamicDisplay { get { return (m_DebugItem.flags & DebugItemFlag.DynamicDisplay) != 0; } }
public DebugItem debugItem { get { return m_DebugItem; } }
protected DebugItemUI(DebugItem debugItem)
{
m_DebugItem = debugItem;

16
ScriptableRenderPipeline/Core/Debugging/DebugMenuState.cs


namespace UnityEngine.Experimental.Rendering
{
[Serializable]
public abstract class DebugItemState
: ScriptableObject
{

if (debugItemState == null)
{
debugItemState = item.handler.CreateDebugItemState();
debugItemState.hideFlags = HideFlags.DontSave;
debugItemState.Initialize(item);
debugItemState.SetValue(item.GetValue());
AddDebugItemState(debugItemState);
if(debugItemState != null)
{
debugItemState.hideFlags = HideFlags.DontSave;
debugItemState.Initialize(item);
debugItemState.SetValue(item.GetValue());
AddDebugItemState(debugItemState);
}
else
{
Debug.LogWarning(String.Format("DebugItemState for item {0} of type {1} is not provided.\nDid you implement CreateDebugItemState in your custom Handler?", item.name, item.type));
}
}
}
}

2
ScriptableRenderPipeline/Core/Debugging/DebugPanel.cs


if(m_Setter != null)
{
m_Setter(value);
m_Handler.ClampValues(m_Getter, m_Setter);
m_Handler.ValidateValues(m_Getter, m_Setter);
}
if (record && OnItemDirty != null)

41
ScriptableRenderPipeline/Core/Debugging/DebugPanelUI.cs


GameObject.Destroy(child.gameObject);
}
m_ItemsUI.Clear();
protected void AddDebugItemUI(DebugItem item, GameObject parent)
{
#if UNITY_EDITOR
// We don't want runtime only items even in the "player" debug menu if we are in the editor.
if (item.runtimeOnly)
return;
#endif
if(item.editorOnly)
return;
DebugItemUI itemUI = item.handler.BuildGUI(parent);
if(itemUI == null)
{
Debug.LogWarning(String.Format("DebugItemUI not provided for item {0} of type {1}.\n Did you implement BuildGUI for your custom Handler?", item.name, item.type));
}
else
{
m_ItemsUI.Add(itemUI);
}
}
m_ItemsUI.Clear();
#if UNITY_EDITOR
// We don't want runtime only items even in the "player" debug menu if we are in the editor.
if (item.runtimeOnly)
continue;
#endif
if(!item.editorOnly)
{
DebugItemHandler handler = item.handler; // Should never be null, we have at least the default handler
m_ItemsUI.Add(handler.BuildGUI(parent));
}
AddDebugItemUI(item, parent);
}
}

{
if (m_SelectedItem != -1)
{
return m_DebugPanel.GetDebugItem(m_SelectedItem);
return m_ItemsUI[m_SelectedItem].debugItem;
}
return null;

public void OnMoveHorizontal(float value)
{
if (m_SelectedItem != -1 && !m_DebugPanel.GetDebugItem(m_SelectedItem).readOnly)
if (m_SelectedItem != -1 && !m_ItemsUI[m_SelectedItem].debugItem.readOnly)
{
if (value > 0.0f)
m_ItemsUI[m_SelectedItem].OnIncrement();

public void OnValidate()
{
if (m_SelectedItem != -1 && !m_DebugPanel.GetDebugItem(m_SelectedItem).readOnly)
if (m_SelectedItem != -1 && !m_ItemsUI[m_SelectedItem].debugItem.readOnly)
m_ItemsUI[m_SelectedItem].OnValidate();
}

38
ScriptableRenderPipeline/Core/Editor/CoreEditorUtils.cs


using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using UnityEngine;
// Serialization helpers
public static string FindProperty<T, TValue>(Expression<Func<T, TValue>> expr)
{
// Get the field path as a string
MemberExpression me;
switch (expr.Body.NodeType)
{
case ExpressionType.MemberAccess:
me = expr.Body as MemberExpression;
break;
default:
throw new InvalidOperationException();
}
var members = new List<string>();
while (me != null)
{
members.Add(me.Member.Name);
me = me.Expression as MemberExpression;
}
var sb = new StringBuilder();
for (int i = members.Count - 1; i >= 0; i--)
{
sb.Append(members[i]);
if (i > 0) sb.Append('.');
}
return sb.ToString();
}
// UI Helpers
public static void DrawSplitter()
{

// Title
EditorGUI.LabelField(labelRect, title, EditorStyles.boldLabel);
EditorGUILayout.Space();
}
public static bool DrawHeaderFoldout(string title, bool state)

58
ScriptableRenderPipeline/Core/Editor/PropertyFetcher.cs


using System;
using System.Collections.Generic;
using System.Text;
public class PropertyFetcher<T> : IDisposable
public sealed class PropertyFetcher<T> : IDisposable
{
public readonly SerializedObject obj;

this.obj = obj;
}
public SerializedProperty FindProperty(string str)
public SerializedProperty Find(string str)
public SerializedProperty FindProperty<TValue>(Expression<Func<T, TValue>> expr)
public SerializedProperty Find<TValue>(Expression<Func<T, TValue>> expr)
// Get the field path as a string
MemberExpression me;
switch (expr.Body.NodeType)
{
case ExpressionType.MemberAccess:
me = expr.Body as MemberExpression;
break;
default:
throw new InvalidOperationException();
}
string path = CoreEditorUtils.FindProperty(expr);
return obj.FindProperty(path);
}
var members = new List<string>();
while (me != null)
{
members.Add(me.Member.Name);
me = me.Expression as MemberExpression;
}
public void Dispose()
{
// Nothing to do here, still needed so we can rely on the using/IDisposable pattern
}
}
var sb = new StringBuilder();
for (int i = members.Count - 1; i >= 0; i--)
{
sb.Append(members[i]);
if (i > 0) sb.Append('.');
}
public sealed class RelativePropertyFetcher<T> : IDisposable
{
public readonly SerializedProperty obj;
public RelativePropertyFetcher(SerializedProperty obj)
{
Assert.IsNotNull(obj);
this.obj = obj;
}
var path = sb.ToString();
public SerializedProperty Find(string str)
{
return obj.FindPropertyRelative(str);
}
// Fetch the SerializedProperty using Unity's method
return obj.FindProperty(path);
public SerializedProperty Find<TValue>(Expression<Func<T, TValue>> expr)
{
string path = CoreEditorUtils.FindProperty(expr);
return obj.FindPropertyRelative(path);
}
public void Dispose()

177
ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl


}
// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, p. 19, 29.
float G_MaskingSmithGGX(float NdotV, float VdotH, float roughness)
float G_MaskingSmithGGX(float NdotV, float roughness)
{
// G1(V, H) = HeavisideStep(VdotH) / (1 + Λ(V)).
// Λ(V) = -0.5 + 0.5 * sqrt(1 + 1 / a²).

// Assume that (VdotH > 0), e.i. (acos(LdotV) < Pi).
float hs = VdotH > 0.0 ? 1.0 : 0.0;
return hs / (0.5 + 0.5 * sqrt(1.0 + a2 * (1.0 / z2 - 1.0)));
return 1 / (0.5 + 0.5 * sqrt(1.0 + a2 * (1.0 / z2 - 1.0)));
// Note that we pass 1.0 instead of 'VdotH' since the multiplication will already clamp.
return D_GGX(NdotH, roughness) * G_MaskingSmithGGX(NdotV, 1.0, roughness) * VdotH / NdotV;
return D_GGX(NdotH, roughness) * G_MaskingSmithGGX(NdotV, roughness) * VdotH / NdotV;
}
// Precompute part of lambdaV
float GetSmithJointGGXPreLambdaV(float NdotV, float roughness)
{
float a2 = roughness * roughness;
return sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
float V_SmithJointGGX(float NdotL, float NdotV, float roughness)
float V_SmithJointGGX(float NdotL, float NdotV, float roughness, float preLambdaV)
float a2 = roughness * roughness;
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
// lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;
// G = 1 / (1 + lambda_v + lambda_l);
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5
// lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5
// G = 1 / (1 + lambda_v + lambda_l);
float a = roughness;
float a2 = a * a;
// Reorder code to be more optimal
float lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
// Reorder code to be more optimal:
float lambdaV = NdotL * preLambdaV;
float lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
// Simplify visibility term: (2.0 * NdotL * NdotV) / ((4.0 * NdotL * NdotV) * (lambda_v + lambda_l));

// Precompute part of lambdaV
float GetSmithJointGGXLambdaV(float NdotV, float roughness)
float V_SmithJointGGX(float NdotL, float NdotV, float roughness)
float a = roughness;
float a2 = a * a;
return sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
float preLambdaV = GetSmithJointGGXPreLambdaV(NdotV, roughness);
return V_SmithJointGGX(NdotL, NdotV, roughness, preLambdaV);
float V_SmithJointGGX(float NdotL, float NdotV, float roughness, float lambdaV)
// Inline D_GGX() * V_SmithJointGGX() together for better code generation.
float DV_SmithJointGGX(float NdotH, float NdotL, float NdotV, float roughness, float preLambdaV)
float a = roughness;
float a2 = a * a;
// Reorder code to be more optimal
lambdaV *= NdotL;
float a2 = roughness * roughness;
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
float2 D = float2(a2, f * f); // Fraction without the constant (1/Pi)
float lambdaV = NdotL * preLambdaV;
// Simplify visibility term: (2.0 * NdotL * NdotV) / ((4.0 * NdotL * NdotV) * (lambda_v + lambda_l));
return 0.5 / (lambdaV + lambdaL);
float2 G = float2(1, lambdaV + lambdaL); // Fraction without the constant (0.5)
return (INV_PI * 0.5) * (D.x * G.x) / (D.y * G.y);
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness)
float DV_SmithJointGGX(float NdotH, float NdotL, float NdotV, float roughness)
float a = roughness;
// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)
float lambdaV = NdotL * (NdotV * (1 - a) + a);
float lambdaL = NdotV * (NdotL * (1 - a) + a);
return 0.5 / (lambdaV + lambdaL);
float preLambdaV = GetSmithJointGGXPreLambdaV(NdotV, roughness);
return DV_SmithJointGGX(NdotH, NdotL, NdotV, roughness, preLambdaV);
// Precompute part of LambdaV
float GetSmithJointGGXApproxLambdaV(float NdotV, float roughness)
// Precompute a part of LambdaV.
// Note on this linear approximation.
// Exact for roughness values of 0 and 1. Also, exact when the cosine is 0 or 1.
// Otherwise, the worst case relative error is around 10%.
// https://www.desmos.com/calculator/wtp8lnjutx
float GetSmithJointGGXPreLambdaVApprox(float NdotV, float roughness)
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness, float lambdaV)
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness, float preLambdaV)
// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)
lambdaV *= NdotL;
float lambdaV = NdotL * preLambdaV;
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness)
{
float preLambdaV = GetSmithJointGGXPreLambdaVApprox(NdotV, roughness);
return V_SmithJointGGXApprox(NdotL, NdotV, roughness, preLambdaV);
}
float f = TdotH * TdotH / (roughnessT * roughnessT) + BdotH * BdotH / (roughnessB * roughnessB) + NdotH * NdotH;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
float f = TdotH * TdotH / aT2 + BdotH * BdotH / aB2 + NdotH * NdotH;
return 1.0 / (roughnessT * roughnessB * f * f);
}

}
float GetSmithJointGGXAnisoPreLambdaV(float TdotV, float BdotV, float NdotV, float roughnessT, float roughnessB)
{
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
return sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB)
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB, float preLambdaV)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
float lambdaV = NdotL * sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
float lambdaV = NdotL * preLambdaV;
float GetSmithJointGGXAnisoLambdaV(float TdotV, float BdotV, float NdotV, float roughnessT, float roughnessB)
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
return sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
float preLambdaV = GetSmithJointGGXAnisoPreLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return V_SmithJointGGXAniso(TdotV, BdotV, NdotV, TdotL, BdotL, NdotL, roughnessT, roughnessB, preLambdaV);
float V_SmithJointGGXAnisoLambdaV(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB, float lambdaV)
// Inline D_GGXAniso() * V_SmithJointGGXAniso() together for better code generation.
float DV_SmithJointGGXAniso(float TdotH, float BdotH, float NdotH,
float TdotV, float BdotV, float NdotV,
float TdotL, float BdotL, float NdotL,
float roughnessT, float roughnessB, float preLambdaV)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
lambdaV *= NdotL;
float f = TdotH * TdotH / aT2 + BdotH * BdotH / aB2 + NdotH * NdotH;
float2 D = float2(1, roughnessT * roughnessB * f * f); // Fraction without the constant (1/Pi)
float lambdaV = NdotL * preLambdaV;
return 0.5 / (lambdaV + lambdaL);
float2 G = float2(1, lambdaV + lambdaL); // Fraction without the constant (0.5)
return (INV_PI * 0.5) * (D.x * G.x) / (D.y * G.y);
}
float DV_SmithJointGGXAniso(float TdotH, float BdotH, float NdotH,
float TdotV, float BdotV, float NdotV,
float TdotL, float BdotL, float NdotL,
float roughnessT, float roughnessB)
{
float preLambdaV = GetSmithJointGGXAnisoPreLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return DV_SmithJointGGXAniso(TdotH, BdotH, NdotH,
TdotV, BdotV, NdotV,
TdotL, BdotL, NdotL,
roughnessT, roughnessB, preLambdaV);
}
//-----------------------------------------------------------------------------

return INV_PI;
}
float DisneyDiffuseNoPI(float NdotV, float NdotL, float LdotH, float perceptualRoughness)
float DisneyDiffuseNoPI(float NdotV, float NdotL, float LdotV, float perceptualRoughness)
float fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
// (2 * LdotH * LdotH) = 1 + LdotV
// float fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
float fd90 = 0.5 + (perceptualRoughness + perceptualRoughness * LdotV);
float viewScatter = F_Schlick(1.0, fd90, NdotV);
float viewScatter = F_Schlick(1.0, fd90, NdotV);
return lightScatter * viewScatter;
// Normalize the BRDF for polar view angles of up to (Pi/4).
// We use the worst case of (roughness = albedo = 1), and, for each view angle,
// integrate (brdf * cos(theta_light)) over all light directions.
// The resulting value is for (theta_view = 0), which is actually a little bit larger
// than the value of the integral for (theta_view = Pi/4).
// Hopefully, the compiler folds the constant together with (1/Pi).
return rcp(1.03571) * (lightScatter * viewScatter);
float DisneyDiffuse(float NdotV, float NdotL, float LdotH, float perceptualRoughness)
float DisneyDiffuse(float NdotV, float NdotL, float LdotV, float perceptualRoughness)
return INV_PI * DisneyDiffuseNoPI(NdotV, NdotL, LdotH, perceptualRoughness);
return INV_PI * DisneyDiffuseNoPI(NdotV, NdotL, LdotV, perceptualRoughness);
float facing = 0.5 + 0.5 * LdotV;
float facing = 0.5 + 0.5 * LdotV; // (LdotH)^2
// This constant is picked s.t. setting perceptualRoughness, albedo and all angles to 1
// This constant is picked s.t. setting perceptualRoughness, albedo and all cosines to 1
// allows us to match the Lambertian and the Disney Diffuse models. Original value: 0.1159.
float multiple = perceptualRoughness * (0.079577 * PI); // Rescaled by PI

16
ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl


return x * x;
}
// Acos in 14 cycles.
// Ref: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
float FastACos(float inX)
// Input [0, 1] and output [0, PI/2]
// 9 VALU
float FastACosPos(float inX)
return res;
}
// Ref: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
// Input [-1, 1] and output [0, PI]
// 12 VALU
float FastACos(float inX)
{
float res = FastACosPos(inX);
return (inX >= 0) ? res : PI - res; // Undo range reduction
}

12
ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl


// Convert anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction) to roughness
void ConvertAnisotropyToRoughness(float roughness, float anisotropy, out float roughnessT, out float roughnessB)
{
// (0 <= anisotropy <= 1), therefore (0 <= anisoAspect <= 1)
// The 0.9 factor limits the aspect ratio to 10:1.
float anisoAspect = sqrt(1.0 - 0.9 * anisotropy);
roughnessT = roughness / anisoAspect; // Distort along tangent (rougher)
roughnessB = roughness * anisoAspect; // Straighten along bitangent (smoother)
// Use the parametrization of Sony Imageworks.
// Ref: Revisiting Physically Based Shading at Imageworks, p. 15.
roughnessT = roughness * (1 + anisotropy);
roughnessB = roughness * (1 - anisotropy);
}
// Ref: Donald Revie - Implementing Fur Using Deferred Shading (GPU Pro 2)

return cross(B, grainDir);
}
// Fake anisotropic by distorting the normal.
// Fake anisotropy by distorting the normal (non-negative anisotropy values only).
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to N.
// Anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction)
float3 GetAnisotropicModifiedNormal(float3 grainDir, float3 N, float3 V, float anisotropy)

9
ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl


// it return the offset to apply to the UVSet provide in PerPixelHeightDisplacementParam
// viewDirTS is view vector in texture space matching the UVSet
// ref: https://www.gamedev.net/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262
float2 ParallaxOcclusionMapping(float lod, float lodThreshold, int numSteps, float3 viewDirTS, float maxHeight, PerPixelHeightDisplacementParam ppdParam, out float outHeight)
float2 ParallaxOcclusionMapping(float lod, float lodThreshold, int numSteps, float3 viewDirTS, PerPixelHeightDisplacementParam ppdParam, out float outHeight)
// TODO: explain this factor! Necessary to achieve parity between tessellation and POM w.r.t. height.
maxHeight *= 0.1;
// Convention: 1.0 is top, 0.0 is bottom - POM is always inward, no extrusion
float stepSize = 1.0 / (float)numSteps;

// float2 parallaxDir = normalize(Out.viewDirTS.xy);
// float2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
// Above code simplify to
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z) * maxHeight;
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z);
float2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS;
// Do a first step before the loop to init all value correctly

// Secant method to affine the search
// Ref: Faster Relief Mapping Using the Secant Method - Eric Risser
for (int i = 0; i < 5; ++i)
for (int i = 0; i < 3; ++i)
{
// intersectionHeight is the height [0..1] for the intersection between view ray and heightfield line
float intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);

6
ScriptableRenderPipeline/HDRenderPipeline/Camera/HDCamera.cs


public Matrix4x4 projMatrix;
public Matrix4x4 nonJitteredProjMatrix;
public Vector4 screenSize;
public Plane[] frustumPlanes;
public Vector4[] frustumPlaneEquations;
public Camera camera;

public HDCamera(Camera cam)
{
camera = cam;
frustumPlanes = new Plane[6];
frustumPlaneEquations = new Vector4[6];
Reset();
}

cameraPos = pos;
screenSize = new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight);
var planes = GeometryUtility.CalculateFrustumPlanes(viewProjMatrix);
GeometryUtility.CalculateFrustumPlanes(viewProjMatrix, frustumPlanes);
frustumPlaneEquations[i] = new Vector4(planes[i].normal.x, planes[i].normal.y, planes[i].normal.z, planes[i].distance);
frustumPlaneEquations[i] = new Vector4(frustumPlanes[i].normal.x, frustumPlanes[i].normal.y, frustumPlanes[i].normal.z, frustumPlanes[i].distance);
}
m_LastFrameActive = Time.frameCount;

5
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs


{
if (!isDebugViewMaterialInit)
{
List<RenderPipelineMaterial> materialList = CoreUtils.GetRenderPipelineMaterialList();
List<RenderPipelineMaterial> materialList = HDUtils.GetRenderPipelineMaterialList();
// TODO: Share this code to retrieve deferred material with HDRenderPipeline
// Find first material that have non 0 Gbuffer count and assign it as deferredMaterial

{
None = 0,
Tessellation = DebugViewGbuffer.BakeDiffuseLightingWithAlbedoPlusEmissive + 1,
PerPixelDisplacement,
PixelDisplacement,
TessellationDisplacement,
DepthOffset,
Lightmap,
}

7
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl


//
#define DEBUGVIEWPROPERTIES_NONE (0)
#define DEBUGVIEWPROPERTIES_TESSELLATION (12)
#define DEBUGVIEWPROPERTIES_PER_PIXEL_DISPLACEMENT (13)
#define DEBUGVIEWPROPERTIES_PIXEL_DISPLACEMENT (13)
#define DEBUGVIEWPROPERTIES_DEPTH_OFFSET (15)
#define DEBUGVIEWPROPERTIES_LIGHTMAP (16)
#define DEBUGVIEWPROPERTIES_TESSELLATION_DISPLACEMENT (15)
#define DEBUGVIEWPROPERTIES_DEPTH_OFFSET (16)
#define DEBUGVIEWPROPERTIES_LIGHTMAP (17)
//
// UnityEngine.Experimental.Rendering.HDPipeline.FullScreenDebugMode: static fields

16
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.hlsl


#endif
break;
case DEBUGVIEWPROPERTIES_PER_PIXEL_DISPLACEMENT:
#ifdef _PER_PIXEL_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD
case DEBUGVIEWPROPERTIES_PIXEL_DISPLACEMENT:
#ifdef _PIXEL_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);

case DEBUGVIEWPROPERTIES_VERTEX_DISPLACEMENT:
#ifdef _VERTEX_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD
#ifdef _VERTEX_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);
#endif
break;
case DEBUGVIEWPROPERTIES_TESSELLATION_DISPLACEMENT:
#ifdef _TESSELLATION_DISPLACEMENT // Caution: This define is related to a shader features (But it may become a standard features for HD)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);

case DEBUGVIEWPROPERTIES_DEPTH_OFFSET:
#ifdef _DEPTHOFFSET_ON // Caution: This define is related to a shader features (But it may become a standard features for HD
#ifdef _DEPTHOFFSET_ON // Caution: This define is related to a shader features (But it may become a standard features for HD)
result = float3(1.0, 0.0, 0.0);
#else
result = float3(0.0, 0.0, 0.0);

4
ScriptableRenderPipeline/HDRenderPipeline/Debug/LightingDebugPanel.cs


}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
m_Max = (uint)hdPipeline.GetShadowAtlasCount() - 1;

}
public override void ClampValues(Func<object> getter, Action<object> setter)
public override void ValidateValues(Func<object> getter, Action<object> setter)
{
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
m_Max = (uint)hdPipeline.GetCurrentShadowCount() - 1;

250
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs


using System;
using UnityEditor;
using UnityEditor.Experimental.Rendering;
//using EditorGUIUtility=UnityEditor.EditorGUIUtility;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.Rendering.HDPipeline
namespace UnityEditor.Experimental.Rendering.HDPipeline
public class HDRenderPipelineInspector : Editor
public sealed partial class HDRenderPipelineInspector : HDBaseEditor<HDRenderPipelineAsset>
private class Styles
{
public static GUIContent defaults = new GUIContent("Defaults");
public static GUIContent defaultDiffuseMaterial = new GUIContent("Default Diffuse Material", "Material to use when creating objects");
public static GUIContent defaultShader = new GUIContent("Default Shader", "Shader to use when creating materials");
public readonly GUIContent settingsLabel = new GUIContent("Settings");
// Rendering Settings
public readonly GUIContent renderingSettingsLabel = new GUIContent("Rendering Settings");
public readonly GUIContent useForwardRenderingOnly = new GUIContent("Use Forward Rendering Only");
public readonly GUIContent useDepthPrepassWithDeferredRendering = new GUIContent("Use Depth Prepass with Deferred rendering");
public readonly GUIContent renderAlphaTestOnlyInDeferredPrepass = new GUIContent("Alpha Test only");
// Texture Settings
public readonly GUIContent textureSettings = new GUIContent("Texture Settings");
public readonly GUIContent spotCookieSize = new GUIContent("Spot cookie size");
public readonly GUIContent pointCookieSize = new GUIContent("Point cookie size");
public readonly GUIContent reflectionCubemapSize = new GUIContent("Reflection cubemap size");
public readonly GUIContent sssSettings = new GUIContent("Subsurface Scattering Settings");
// Shadow Settings
public readonly GUIContent shadowSettings = new GUIContent("Shadow Settings");
public readonly GUIContent shadowsAtlasWidth = new GUIContent("Atlas width");
public readonly GUIContent shadowsAtlasHeight = new GUIContent("Atlas height");
// Subsurface Scattering Settings
public readonly GUIContent[] sssProfiles = new GUIContent[SssConstants.SSS_N_PROFILES - 1] { new GUIContent("Profile #1"), new GUIContent("Profile #2"), new GUIContent("Profile #3"), new GUIContent("Profile #4"), new GUIContent("Profile #5"),
new GUIContent("Profile #6"), new GUIContent("Profile #7")/*, new GUIContent("Profile #8"), new GUIContent("Profile #9"), new GUIContent("Profile #10"),
new GUIContent("Profile #11"), new GUIContent("Profile #12"), new GUIContent("Profile #13"), new GUIContent("Profile #14"), new GUIContent("Profile #15")*/ };
public readonly GUIContent sssNumProfiles = new GUIContent("Number of profiles");
// Tile pass Settings
public readonly GUIContent tileLightLoopSettings = new GUIContent("Tile Light Loop Settings");
public readonly GUIContent enableTileAndCluster = new GUIContent("Enable tile/clustered");
public readonly GUIContent enableComputeLightEvaluation = new GUIContent("Enable Compute Light Evaluation");
public readonly GUIContent enableComputeLightVariants = new GUIContent("Enable Compute Light Variants");
public readonly GUIContent enableComputeMaterialVariants = new GUIContent("Enable Compute Material Variants");
public readonly GUIContent enableClustered = new GUIContent("Enable clustered");
public readonly GUIContent enableFptlForOpaqueWhenClustered = new GUIContent("Enable Fptl For Opaque When Clustered");
public readonly GUIContent enableBigTilePrepass = new GUIContent("Enable big tile prepass");
public readonly GUIContent tileDebugByCategory = new GUIContent("Enable Debug By Category");
// Sky Settings
public readonly GUIContent skyParams = new GUIContent("Sky Settings");
}
private static Styles s_Styles = null;
private static Styles styles
{
get
{
if (s_Styles == null)
s_Styles = new Styles();
return s_Styles;
}
}
private SerializedProperty m_DefaultDiffuseMaterial;
private SerializedProperty m_DefaultShader;
SerializedProperty m_DefaultDiffuseMaterial;
SerializedProperty m_DefaultShader;
// TilePass settings
SerializedProperty m_enableTileAndCluster;

SerializedProperty m_enableBigTilePrepass;
// Rendering Settings
SerializedProperty m_RenderingUseForwardOnly = null;
SerializedProperty m_RenderingUseDepthPrepass = null;
SerializedProperty m_RenderingUseDepthPrepassAlphaTestOnly = null;
SerializedProperty m_RenderingUseForwardOnly;
SerializedProperty m_RenderingUseDepthPrepass;
SerializedProperty m_RenderingUseDepthPrepassAlphaTestOnly;
// Old SSS Model >>>
SerializedProperty m_UseDisneySSS = null;
// <<< Old SSS Model
SerializedProperty m_Profiles = null;
SerializedProperty m_NumProfiles = null;
SerializedProperty m_SubsurfaceScatteringSettings;
SerializedProperty m_ShadowAtlasWidth = null;
SerializedProperty m_ShadowAtlasHeight = null;
SerializedProperty m_ShadowAtlasWidth;
SerializedProperty m_ShadowAtlasHeight;
SerializedProperty m_SpotCookieSize = null;
SerializedProperty m_PointCookieSize = null;
SerializedProperty m_ReflectionCubemapSize = null;
SerializedProperty m_SpotCookieSize;
SerializedProperty m_PointCookieSize;
SerializedProperty m_ReflectionCubemapSize;
using (var p = new PropertyFetcher<HDRenderPipelineAsset>(serializedObject))
{
m_DefaultDiffuseMaterial = p.FindProperty("m_DefaultDiffuseMaterial");
m_DefaultShader = p.FindProperty("m_DefaultShader");
m_DefaultDiffuseMaterial = properties.Find("m_DefaultDiffuseMaterial");
m_DefaultShader = properties.Find("m_DefaultShader");
// Tile settings
m_enableTileAndCluster = p.FindProperty(x => x.tileSettings.enableTileAndCluster);
m_enableComputeLightEvaluation = p.FindProperty(x => x.tileSettings.enableComputeLightEvaluation);
m_enableComputeLightVariants = p.FindProperty(x => x.tileSettings.enableComputeLightVariants);
m_enableComputeMaterialVariants = p.FindProperty(x => x.tileSettings.enableComputeMaterialVariants);
m_enableClustered = p.FindProperty(x => x.tileSettings.enableClustered);
m_enableFptlForOpaqueWhenClustered = p.FindProperty(x => x.tileSettings.enableFptlForOpaqueWhenClustered);
m_enableBigTilePrepass = p.FindProperty(x => x.tileSettings.enableBigTilePrepass);
// Tile settings
m_enableTileAndCluster = properties.Find(x => x.tileSettings.enableTileAndCluster);
m_enableComputeLightEvaluation = properties.Find(x => x.tileSettings.enableComputeLightEvaluation);
m_enableComputeLightVariants = properties.Find(x => x.tileSettings.enableComputeLightVariants);
m_enableComputeMaterialVariants = properties.Find(x => x.tileSettings.enableComputeMaterialVariants);
m_enableClustered = properties.Find(x => x.tileSettings.enableClustered);
m_enableFptlForOpaqueWhenClustered = properties.Find(x => x.tileSettings.enableFptlForOpaqueWhenClustered);
m_enableBigTilePrepass = properties.Find(x => x.tileSettings.enableBigTilePrepass);
// Shadow settings
m_ShadowAtlasWidth = p.FindProperty(x => x.shadowInitParams.shadowAtlasWidth);
m_ShadowAtlasHeight = p.FindProperty(x => x.shadowInitParams.shadowAtlasHeight);
// Shadow settings
m_ShadowAtlasWidth = properties.Find(x => x.shadowInitParams.shadowAtlasWidth);
m_ShadowAtlasHeight = properties.Find(x => x.shadowInitParams.shadowAtlasHeight);
// Texture settings
m_SpotCookieSize = p.FindProperty(x => x.textureSettings.spotCookieSize);
m_PointCookieSize = p.FindProperty(x => x.textureSettings.pointCookieSize);
m_ReflectionCubemapSize = p.FindProperty(x => x.textureSettings.reflectionCubemapSize);
// Texture settings
m_SpotCookieSize = properties.Find(x => x.textureSettings.spotCookieSize);
m_PointCookieSize = properties.Find(x => x.textureSettings.pointCookieSize);
m_ReflectionCubemapSize = properties.Find(x => x.textureSettings.reflectionCubemapSize);
// Rendering settings
m_RenderingUseForwardOnly = p.FindProperty(x => x.renderingSettings.useForwardRenderingOnly);
m_RenderingUseDepthPrepass = p.FindProperty(x => x.renderingSettings.useDepthPrepassWithDeferredRendering);
m_RenderingUseDepthPrepassAlphaTestOnly = p.FindProperty(x => x.renderingSettings.renderAlphaTestOnlyInDeferredPrepass);
// Rendering settings
m_RenderingUseForwardOnly = properties.Find(x => x.renderingSettings.useForwardRenderingOnly);
m_RenderingUseDepthPrepass = properties.Find(x => x.renderingSettings.useDepthPrepassWithDeferredRendering);
m_RenderingUseDepthPrepassAlphaTestOnly = properties.Find(x => x.renderingSettings.renderAlphaTestOnlyInDeferredPrepass);
// Subsurface Scattering Settings
// Old SSS Model >>>
m_UseDisneySSS = p.FindProperty(x => x.sssSettings.useDisneySSS);
// <<< Old SSS Model
m_Profiles = p.FindProperty(x => x.sssSettings.profiles);
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}
// Subsurface Scattering Settings
m_SubsurfaceScatteringSettings = properties.Find(x => x.sssSettings);
}
static void HackSetDirty(RenderPipelineAsset asset)

method.Invoke(asset, new object[0]);
}
private void TileSettingsUI(HDRenderPipelineAsset renderContext)
void TileSettingsUI(HDRenderPipelineAsset renderContext)
EditorGUILayout.LabelField(styles.tileLightLoopSettings);
EditorGUILayout.LabelField(s_Styles.tileLightLoopSettings);
EditorGUILayout.PropertyField(m_enableTileAndCluster, styles.enableTileAndCluster);
EditorGUILayout.PropertyField(m_enableTileAndCluster, s_Styles.enableTileAndCluster);
EditorGUILayout.PropertyField(m_enableBigTilePrepass, styles.enableBigTilePrepass);
EditorGUILayout.PropertyField(m_enableClustered, styles.enableClustered);
EditorGUILayout.PropertyField(m_enableBigTilePrepass, s_Styles.enableBigTilePrepass);
EditorGUILayout.PropertyField(m_enableClustered, s_Styles.enableClustered);
// Tag: SUPPORT_COMPUTE_CLUSTER_OPAQUE - Uncomment this if you want to do cluster opaque with compute shader (by default we support only fptl on opaque)
// if (m_enableClustered.boolValue)

EditorGUILayout.PropertyField(m_enableFptlForOpaqueWhenClustered, styles.enableFptlForOpaqueWhenClustered);
EditorGUILayout.PropertyField(m_enableFptlForOpaqueWhenClustered, s_Styles.enableFptlForOpaqueWhenClustered);
EditorGUILayout.PropertyField(m_enableComputeLightEvaluation, styles.enableComputeLightEvaluation);
EditorGUILayout.PropertyField(m_enableComputeLightEvaluation, s_Styles.enableComputeLightEvaluation);
if (m_enableComputeLightEvaluation.boolValue)
{
// Tag: SUPPORT_COMPUTE_CLUSTER_OPAQUE - Uncomment this if you want to do cluster opaque with compute shader (by default we support only fptl on opaque)

EditorGUILayout.PropertyField(m_enableComputeLightVariants, styles.enableComputeLightVariants);
EditorGUILayout.PropertyField(m_enableComputeMaterialVariants, styles.enableComputeMaterialVariants);
EditorGUILayout.PropertyField(m_enableComputeLightVariants, s_Styles.enableComputeLightVariants);
EditorGUILayout.PropertyField(m_enableComputeMaterialVariants, s_Styles.enableComputeMaterialVariants);
if (EditorGUI.EndChangeCheck())
{

}
private void SssSettingsUI(HDRenderPipelineAsset renderContext)
void SssSettingsUI(HDRenderPipelineAsset renderContext)
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssSettings);
EditorGUI.BeginChangeCheck();
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
// Old SSS Model >>>
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_UseDisneySSS);
if (EditorGUI.EndChangeCheck())
{
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
hdPipeline.CreateSssMaterials(m_UseDisneySSS.boolValue);
}
// <<< Old SSS Model
EditorGUILayout.PropertyField(m_NumProfiles, styles.sssNumProfiles);
for (int i = 0, n = m_Profiles.arraySize; i < n; i++)
{
SerializedProperty profile = m_Profiles.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(profile, styles.sssProfiles[i]);
}
EditorGUI.indentLevel--;
EditorGUILayout.PropertyField(m_SubsurfaceScatteringSettings, s_Styles.sssSettings);
private void SettingsUI(HDRenderPipelineAsset renderContext)
void SettingsUI(HDRenderPipelineAsset renderContext)
EditorGUILayout.LabelField(styles.settingsLabel);
EditorGUILayout.LabelField(s_Styles.settingsLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
SssSettingsUI(renderContext);

EditorGUI.indentLevel--;
}
private void ShadowSettingsUI(HDRenderPipelineAsset renderContext)
void ShadowSettingsUI(HDRenderPipelineAsset renderContext)
EditorGUILayout.LabelField(styles.shadowSettings);
EditorGUILayout.LabelField(s_Styles.shadowSettings);
EditorGUILayout.PropertyField(m_ShadowAtlasWidth, styles.shadowsAtlasWidth);
EditorGUILayout.PropertyField(m_ShadowAtlasHeight, styles.shadowsAtlasHeight);
EditorGUILayout.PropertyField(m_ShadowAtlasWidth, s_Styles.shadowsAtlasWidth);
EditorGUILayout.PropertyField(m_ShadowAtlasHeight, s_Styles.shadowsAtlasHeight);
if (EditorGUI.EndChangeCheck())
{

}
private void RendereringSettingsUI(HDRenderPipelineAsset renderContext)
void RendereringSettingsUI(HDRenderPipelineAsset renderContext)
EditorGUILayout.LabelField(styles.renderingSettingsLabel);
EditorGUILayout.LabelField(s_Styles.renderingSettingsLabel);
EditorGUILayout.PropertyField(m_RenderingUseForwardOnly, styles.useForwardRenderingOnly);
EditorGUILayout.PropertyField(m_RenderingUseForwardOnly, s_Styles.useForwardRenderingOnly);
EditorGUILayout.PropertyField(m_RenderingUseDepthPrepass, styles.useDepthPrepassWithDeferredRendering);
EditorGUILayout.PropertyField(m_RenderingUseDepthPrepass, s_Styles.useDepthPrepassWithDeferredRendering);
EditorGUILayout.PropertyField(m_RenderingUseDepthPrepassAlphaTestOnly, styles.renderAlphaTestOnlyInDeferredPrepass);
EditorGUILayout.PropertyField(m_RenderingUseDepthPrepassAlphaTestOnly, s_Styles.renderAlphaTestOnlyInDeferredPrepass);
EditorGUI.indentLevel--;
}
}

private void TextureSettingsUI(HDRenderPipelineAsset renderContext)
void TextureSettingsUI(HDRenderPipelineAsset renderContext)
EditorGUILayout.LabelField(styles.textureSettings);
EditorGUILayout.LabelField(s_Styles.textureSettings);
EditorGUILayout.PropertyField(m_SpotCookieSize, styles.spotCookieSize);
EditorGUILayout.PropertyField(m_PointCookieSize, styles.pointCookieSize);
EditorGUILayout.PropertyField(m_ReflectionCubemapSize, styles.reflectionCubemapSize);
EditorGUILayout.PropertyField(m_SpotCookieSize, s_Styles.spotCookieSize);
EditorGUILayout.PropertyField(m_PointCookieSize, s_Styles.pointCookieSize);
EditorGUILayout.PropertyField(m_ReflectionCubemapSize, s_Styles.reflectionCubemapSize);
if (EditorGUI.EndChangeCheck())
{

}
public void OnEnable()
protected override void OnEnable()
base.OnEnable();
var renderContext = target as HDRenderPipelineAsset;
HDRenderPipeline renderpipeline = UnityEngine.Experimental.Rendering.RenderPipelineManager.currentPipeline as HDRenderPipeline;
if (!renderContext || renderpipeline == null)
if (!m_Target || m_HDPipeline == null)
CheckStyles();
EditorGUILayout.LabelField(Styles.defaults, EditorStyles.boldLabel);
EditorGUILayout.LabelField(s_Styles.defaults, EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_DefaultDiffuseMaterial, Styles.defaultDiffuseMaterial);
EditorGUILayout.PropertyField(m_DefaultShader, Styles.defaultShader);
EditorGUILayout.PropertyField(m_DefaultDiffuseMaterial, s_Styles.defaultDiffuseMaterial);
EditorGUILayout.PropertyField(m_DefaultShader, s_Styles.defaultShader);
EditorGUILayout.Space();
SettingsUI(renderContext);
SettingsUI(m_Target);
serializedObject.ApplyModifiedProperties();
}

16
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs


}
}
class DoCreateNewAssetSSSProfile : DoCreateNewAsset<SubsurfaceScatteringProfile> {}
[MenuItem("Assets/Create/HDRenderPipeline/Subsurface Scattering Profile", priority = 666)]
static void MenuCreateSubsurfaceScatteringProfile()
{
var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon");
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<DoCreateNewAssetSSSProfile>(), "New SSS Profile.asset", icon, null);
}
class DoCreateNewAssetSubsurfaceScatteringSettings : DoCreateNewAsset<SubsurfaceScatteringSettings> {}
[MenuItem("Assets/Create/HDRenderPipeline/Common Settings", priority = 677)]
static void MenuCreateCommonSettings()

{
var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon");
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<DoCreateNewAssetSSAOSettings>(), "New AmbientOcclusionSettings.asset", icon, null);
}
[MenuItem("Assets/Create/HDRenderPipeline/Subsurface Scattering Settings", priority = 681)]
static void MenuCreateSubsurfaceScatteringSettings()
{
var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon");
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<DoCreateNewAssetSubsurfaceScatteringSettings>(), "New SSS Settings.asset", icon, null);
}
}
}

332
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


using UnityEngine.Rendering;
using System;
using System.Diagnostics;
using System.Linq;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.Experimental.Rendering.HDPipeline.TilePass;

[Serializable]
public class RenderingSettings
{
public bool useForwardRenderingOnly = false; // TODO: Currently there is no way to strip the extra forward shaders generated by the shaders compiler, so we can switch dynamically.
public bool useDepthPrepassWithDeferredRendering = false;
public bool renderAlphaTestOnlyInDeferredPrepass = false;
public bool useForwardRenderingOnly; // TODO: Currently there is no way to strip the extra forward shaders generated by the shaders compiler, so we can switch dynamically.
public bool useDepthPrepassWithDeferredRendering;
public bool renderAlphaTestOnlyInDeferredPrepass;
// 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

public class GBufferManager
{
public const int MaxGbuffer = 8;
public const int k_MaxGbuffer = 8;
public int gbufferCount { get; set; }
int[] m_IDs = new int[k_MaxGbuffer];
RenderTargetIdentifier[] m_ColorMRTs;
RenderTargetIdentifier[] m_RTIDs = new RenderTargetIdentifier[k_MaxGbuffer];
RenderTextureFormat[] m_Formats = new RenderTextureFormat[k_MaxGbuffer];
RenderTextureReadWrite[] m_sRGBWrites = new RenderTextureReadWrite[k_MaxGbuffer];
IDs[index] = Shader.PropertyToID(stringId);
RTIDs[index] = new RenderTargetIdentifier(IDs[index]);
formats[index] = inFormat;
sRGBWrites[index] = inSRGBWrite;
m_IDs[index] = Shader.PropertyToID(stringId);
m_RTIDs[index] = new RenderTargetIdentifier(m_IDs[index]);
m_Formats[index] = inFormat;
m_sRGBWrites[index] = inSRGBWrite;
}
public void InitGBuffers(int width, int height, CommandBuffer cmd)

cmd.GetTemporaryRT(IDs[index], width, height, 0, FilterMode.Point, formats[index], sRGBWrites[index]);
cmd.GetTemporaryRT(m_IDs[index], width, height, 0, FilterMode.Point, m_Formats[index], m_sRGBWrites[index]);
private RenderTargetIdentifier[] m_ColorMRTs;
public RenderTargetIdentifier[] GetGBuffers()
{
if (m_ColorMRTs == null || m_ColorMRTs.Length != gbufferCount)

{
m_ColorMRTs[index] = RTIDs[index];
m_ColorMRTs[index] = m_RTIDs[index];
public int gbufferCount { get; set; }
int[] IDs = new int[MaxGbuffer];
RenderTargetIdentifier[] RTIDs = new RenderTargetIdentifier[MaxGbuffer];
RenderTextureFormat[] formats = new RenderTextureFormat[MaxGbuffer];
RenderTextureReadWrite[] sRGBWrites = new RenderTextureReadWrite[MaxGbuffer];
}
public partial class HDRenderPipeline : RenderPipeline

readonly RenderPipelineMaterial m_DeferredMaterial;
readonly List<RenderPipelineMaterial> m_MaterialList = new List<RenderPipelineMaterial>();
readonly GBufferManager m_gbufferManager = new GBufferManager();
readonly GBufferManager m_GbufferManager = new GBufferManager();
Material m_CopyStencilForSplitLighting;
Material m_CopyStencilForRegularLighting;

readonly RenderTargetIdentifier m_DeferredShadowBufferRT;
private RenderTexture m_CameraDepthStencilBuffer = null;
private RenderTexture m_CameraDepthBufferCopy = null;
private RenderTexture m_CameraStencilBufferCopy = null;
private RenderTexture m_HTile = null; // If the hardware does not expose it, we compute our own, optimized to only contain the SSS bit
RenderTexture m_CameraDepthStencilBuffer;
RenderTexture m_CameraDepthBufferCopy;
RenderTexture m_CameraStencilBufferCopy;
RenderTexture m_HTile; // If the hardware does not expose it, we compute our own, optimized to only contain the SSS bit
RenderTargetIdentifier m_CameraDepthStencilBufferRT;
RenderTargetIdentifier m_CameraDepthBufferCopyRT;
RenderTargetIdentifier m_CameraStencilBufferCopyRT;
RenderTargetIdentifier m_HTileRT;
// The pass "SRPDefaultUnlit" is a fallback to legacy unlit rendering and is required to support unity 2d + unity UI that render in the scene.
ShaderPassName[] m_ForwardPassNames = { new ShaderPassName(), HDShaderPassNames.s_SRPDefaultUnlitName};
ShaderPassName[] m_ForwardErrorPassNames = { HDShaderPassNames.s_AlwaysName, HDShaderPassNames.s_ForwardBaseName, HDShaderPassNames.s_DeferredName, HDShaderPassNames.s_PrepassBaseName, HDShaderPassNames.s_VertexName, HDShaderPassNames.s_VertexLMRGBMName, HDShaderPassNames.s_VertexLMName };
ShaderPassName[] m_SinglePassName = new ShaderPassName[1];
private RenderTargetIdentifier m_CameraDepthStencilBufferRT;
private RenderTargetIdentifier m_CameraDepthBufferCopyRT;
private RenderTargetIdentifier m_CameraStencilBufferCopyRT;
private RenderTargetIdentifier m_HTileRT;
RenderTargetIdentifier[] m_MRTCache2 = new RenderTargetIdentifier[2];
// Post-processing context and screen-space effects (recycled on every frame to avoid GC alloc)
readonly PostProcessRenderContext m_PostProcessContext;

MaterialPropertyBlock m_SharedPropertyBlock = new MaterialPropertyBlock();
DebugDisplaySettings m_DebugDisplaySettings = new DebugDisplaySettings();
static DebugDisplaySettings s_NeutralDebugDisplaySettings = new DebugDisplaySettings();
DebugDisplaySettings m_CurrentDebugDisplaySettings = null;
DebugDisplaySettings m_CurrentDebugDisplaySettings;
private int m_DebugFullScreenTempRT;
private bool m_FullScreenDebugPushed = false;
int m_DebugFullScreenTempRT;
bool m_FullScreenDebugPushed;
SubsurfaceScatteringSettings m_InternalSSSAsset;
get { return m_Asset.sssSettings; }
get
{
// If no SSS asset is set, build / reuse an internal one for simplicity
var asset = m_Asset.sssSettings;
if (asset == null)
{
if (m_InternalSSSAsset == null)
m_InternalSSSAsset = ScriptableObject.CreateInstance<SubsurfaceScatteringSettings>();
asset = m_InternalSSSAsset;
}
return asset;
}
private CommonSettings.Settings m_CommonSettings = CommonSettings.Settings.s_Defaultsettings;
private SkySettings m_SkySettings = null;
private ScreenSpaceAmbientOcclusionSettings.Settings m_SsaoSettings = ScreenSpaceAmbientOcclusionSettings.Settings.s_Defaultsettings;
CommonSettings.Settings m_CommonSettings = CommonSettings.Settings.s_Defaultsettings;
SkySettings m_SkySettings = null;
ScreenSpaceAmbientOcclusionSettings.Settings m_SsaoSettings = ScreenSpaceAmbientOcclusionSettings.Settings.s_Defaultsettings;
public CommonSettings.Settings commonSettingsToUse
{

m_GPUCopy = new GPUCopy(asset.renderPipelineResources.copyChannelCS);
// Scan material list and assign it
m_MaterialList = CoreUtils.GetRenderPipelineMaterialList();
m_MaterialList = HDUtils.GetRenderPipelineMaterialList();
foreach (RenderPipelineMaterial material in m_MaterialList)
foreach (var material in m_MaterialList)
{
}
}
// TODO: Handle the case of no Gbuffer material

m_CameraFilteringBuffer = HDShaderIDs._CameraFilteringBuffer;
m_CameraFilteringBufferRT = new RenderTargetIdentifier(m_CameraFilteringBuffer);
CreateSssMaterials(sssSettings.useDisneySSS);
CreateSssMaterials();
m_CopyStencilForSplitLighting = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/CopyStencilBuffer");
m_CopyStencilForSplitLighting.EnableKeyword("EXPORT_HTILE");

InitializeDebugMaterials();
// Init Gbuffer description
m_gbufferManager.gbufferCount = m_DeferredMaterial.GetMaterialGBufferCount();
RenderTextureFormat[] RTFormat;
RenderTextureReadWrite[] RTReadWrite;
m_DeferredMaterial.GetMaterialGBufferDescription(out RTFormat, out RTReadWrite);
m_GbufferManager.gbufferCount = m_DeferredMaterial.GetMaterialGBufferCount();
RenderTextureFormat[] rtFormat;
RenderTextureReadWrite[] rtReadWrite;
m_DeferredMaterial.GetMaterialGBufferDescription(out rtFormat, out rtReadWrite);
for (int gbufferIndex = 0; gbufferIndex < m_gbufferManager.gbufferCount; ++gbufferIndex)
for (int gbufferIndex = 0; gbufferIndex < m_GbufferManager.gbufferCount; ++gbufferIndex)
m_gbufferManager.SetBufferDescription(gbufferIndex, "_GBufferTexture" + gbufferIndex, RTFormat[gbufferIndex], RTReadWrite[gbufferIndex]);
m_GbufferManager.SetBufferDescription(gbufferIndex, "_GBufferTexture" + gbufferIndex, rtFormat[gbufferIndex], rtReadWrite[gbufferIndex]);
}
m_VelocityBuffer = HDShaderIDs._VelocityTexture;

m_gbufferManager.SetBufferDescription(m_gbufferManager.gbufferCount, "_VelocityTexture", Builtin.GetVelocityBufferFormat(), Builtin.GetVelocityBufferReadWrite());
m_gbufferManager.gbufferCount++;
m_GbufferManager.SetBufferDescription(m_GbufferManager.gbufferCount, "_VelocityTexture", Builtin.GetVelocityBufferFormat(), Builtin.GetVelocityBufferReadWrite());
m_GbufferManager.gbufferCount++;
}
m_VelocityBufferRT = new RenderTargetIdentifier(m_VelocityBuffer);

void RegisterDebug()
{
// These need to be Runtime Only because those values are hold by the HDRenderPipeline asset so if user change them through the editor debug menu they might change the value in the asset without noticing it.
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Forward Only", () => (bool)m_Asset.renderingSettings.useForwardRenderingOnly, (value) => m_Asset.renderingSettings.useForwardRenderingOnly = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Deferred Depth Prepass", () => (bool)m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering, (value) => m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Deferred Depth Prepass ATest Only", () => (bool)m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass, (value) => m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Forward Only", () => m_Asset.renderingSettings.useForwardRenderingOnly, (value) => m_Asset.renderingSettings.useForwardRenderingOnly = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Deferred Depth Prepass", () => m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering, (value) => m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Deferred Depth Prepass ATest Only", () => m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass, (value) => m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Tile/Cluster", () => (bool)m_Asset.tileSettings.enableTileAndCluster, (value) => m_Asset.tileSettings.enableTileAndCluster = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Big Tile", () => (bool)m_Asset.tileSettings.enableBigTilePrepass, (value) => m_Asset.tileSettings.enableBigTilePrepass = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Cluster", () => (bool)m_Asset.tileSettings.enableClustered, (value) => m_Asset.tileSettings.enableClustered = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Compute Lighting", () => (bool)m_Asset.tileSettings.enableComputeLightEvaluation, (value) => m_Asset.tileSettings.enableComputeLightEvaluation = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Light Classification", () => (bool)m_Asset.tileSettings.enableComputeLightVariants, (value) => m_Asset.tileSettings.enableComputeLightVariants = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Material Classification", () => (bool)m_Asset.tileSettings.enableComputeMaterialVariants, (value) => m_Asset.tileSettings.enableComputeMaterialVariants = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Tile/Cluster", () => m_Asset.tileSettings.enableTileAndCluster, (value) => m_Asset.tileSettings.enableTileAndCluster = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Big Tile", () => m_Asset.tileSettings.enableBigTilePrepass, (value) => m_Asset.tileSettings.enableBigTilePrepass = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Cluster", () => m_Asset.tileSettings.enableClustered, (value) => m_Asset.tileSettings.enableClustered = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Compute Lighting", () => m_Asset.tileSettings.enableComputeLightEvaluation, (value) => m_Asset.tileSettings.enableComputeLightEvaluation = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Light Classification", () => m_Asset.tileSettings.enableComputeLightVariants, (value) => m_Asset.tileSettings.enableComputeLightVariants = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Enable Material Classification", () => m_Asset.tileSettings.enableComputeMaterialVariants, (value) => m_Asset.tileSettings.enableComputeMaterialVariants = (bool)value, DebugItemFlag.RuntimeOnly);
}
void InitializeDebugMaterials()

m_ErrorMaterial = CoreUtils.CreateEngineMaterial("Hidden/InternalErrorShader");
}
public void CreateSssMaterials(bool useDisneySSS)
public void CreateSssMaterials()
{
m_SubsurfaceScatteringKernel = m_SubsurfaceScatteringCS.FindKernel("SubsurfaceScattering");

void InitializeRenderStateBlocks()
{
m_DepthStateOpaque.depthState = new DepthState(true, CompareFunction.LessEqual);
m_DepthStateOpaque.mask = RenderStateMask.Depth;
m_DepthStateOpaque = new RenderStateBlock
{
depthState = new DepthState(true, CompareFunction.LessEqual),
mask = RenderStateMask.Depth
};
m_DepthStateOpaqueWithPrepass.depthState = new DepthState(false, CompareFunction.Equal);
m_DepthStateOpaqueWithPrepass.mask = RenderStateMask.Depth;
m_DepthStateOpaqueWithPrepass = new RenderStateBlock
{
depthState = new DepthState(false, CompareFunction.Equal),
mask = RenderStateMask.Depth
};
}
public void OnSceneLoad()

CoreUtils.Destroy(m_DebugDisplayLatlong);
CoreUtils.Destroy(m_DebugFullScreen);
CoreUtils.Destroy(m_ErrorMaterial);
CoreUtils.Destroy(m_InternalSSSAsset);
m_SkyManager.Cleanup();

}
#if UNITY_EDITOR
private static readonly SupportedRenderingFeatures s_NeededFeatures = new SupportedRenderingFeatures()
static readonly SupportedRenderingFeatures s_NeededFeatures = new SupportedRenderingFeatures()
{
reflectionProbe = SupportedRenderingFeatures.ReflectionProbe.Rotation
};

{
if (m_CameraDepthStencilBuffer != null)
{
}
m_CameraDepthStencilBuffer = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Depth);
m_CameraDepthStencilBuffer.filterMode = FilterMode.Point;

if (NeedDepthBufferCopy())
{
if (m_CameraDepthBufferCopy != null)
{
}
m_CameraDepthBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Depth);
m_CameraDepthBufferCopy.filterMode = FilterMode.Point;
m_CameraDepthBufferCopy.Create();

if (NeedStencilBufferCopy())
{
if (m_CameraStencilBufferCopy != null)
{
}
m_CameraStencilBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); // DXGI_FORMAT_R8_UINT is not supported by Unity
m_CameraStencilBufferCopy.filterMode = FilterMode.Point;
m_CameraStencilBufferCopy.Create();

if (NeedHTileCopy())
{
if (m_HTile!= null)
{
}
// We use 8x8 tiles in order to match the native GCN HTile as closely as possible.
m_HTile = new RenderTexture((camera.pixelWidth + 7) / 8, (camera.pixelHeight + 7) / 8, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); // DXGI_FORMAT_R8_UINT is not supported by Unity
m_HTile.filterMode = FilterMode.Point;

bool resolutionChanged = camera.pixelWidth != m_CurrentWidth || camera.pixelHeight != m_CurrentHeight;
if (resolutionChanged || m_CameraDepthStencilBuffer == null)
{
}
{
}
{
}
// update recorded window resolution
m_CurrentWidth = camera.pixelWidth;

// Broadcast SSS parameters to all shaders.
Shader.SetGlobalInt( HDShaderIDs._EnableSSSAndTransmission, m_CurrentDebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission ? 1 : 0);
Shader.SetGlobalInt( HDShaderIDs._TexturingModeFlags, (int)sssParameters.texturingModeFlags);
Shader.SetGlobalInt( HDShaderIDs._TransmissionFlags, (int)sssParameters.transmissionFlags);
Shader.SetGlobalInt( HDShaderIDs._TexturingModeFlags, sssParameters.texturingModeFlags);
Shader.SetGlobalInt( HDShaderIDs._TransmissionFlags, sssParameters.transmissionFlags);
Shader.SetGlobalInt( HDShaderIDs._UseDisneySSS, sssParameters.useDisneySSS ? 1 : 0);
cmd.SetGlobalVectorArray(HDShaderIDs._ThicknessRemaps, sssParameters.thicknessRemaps);
cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParams, sssParameters.shapeParams);

return m_HTileRT;
}
private void CopyDepthBufferIfNeeded(CommandBuffer cmd)
void CopyDepthBufferIfNeeded(CommandBuffer cmd)
{
using (new ProfilingSample(cmd, NeedDepthBufferCopy() ? "Copy DepthBuffer" : "Set DepthBuffer"))
{

}
}
private void PrepareAndBindStencilTexture(CommandBuffer cmd)
void PrepareAndBindStencilTexture(CommandBuffer cmd)
{
if (NeedStencilBufferCopy())
{

}
// This is the main command buffer used for the frame.
CommandBuffer cmd = CommandBufferPool.Get("");
var cmd = CommandBufferPool.Get("");
m_MaterialList.ForEach(material => material.RenderInit(cmd));
foreach (var material in m_MaterialList)
material.RenderInit(cmd);
// Do anything we need to do upon a new frame.
m_LightLoop.NewFrame();

Camera camera = null;
foreach (var cam in cameras)
{

break;
}
}

renderContext.SetupCameraProperties(camera);
var postProcessLayer = camera.GetComponent<PostProcessLayer>();
HDCamera hdCamera = HDCamera.Get(camera, postProcessLayer);
PushGlobalParams(hdCamera, cmd, m_Asset.sssSettings);
var hdCamera = HDCamera.Get(camera, postProcessLayer);
PushGlobalParams(hdCamera, cmd, sssSettings);
// TODO: Find a correct place to bind these material textures
// We have to bind the material specific global parameters in this mode

using (new ProfilingSample(cmd, "Forward"))
{
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.Color | ClearFlag.Depth);
ShaderPassName[] arrayShaderPassName = { HDShaderPassNames.s_ForwardName };
RenderOpaqueRenderList(m_CullResults, camera, renderContext, cmd, arrayShaderPassName);
RenderTransparentRenderList(m_CullResults, camera, renderContext, cmd, arrayShaderPassName);
RenderOpaqueRenderList(m_CullResults, camera, renderContext, cmd, HDShaderPassNames.s_ForwardName);
RenderTransparentRenderList(m_CullResults, camera, renderContext, cmd, HDShaderPassNames.s_ForwardName);
}
renderContext.ExecuteCommandBuffer(cmd);

m_LightLoop.BuildGPULightLists(camera, cmd, m_CameraDepthStencilBufferRT, GetStencilTexture());
}
// Don't update the sky environment if we are rendering a cubemap (it should be update already)
if (camera.cameraType != CameraType.Reflection)
{

// We compute subsurface scattering here. Therefore, no objects rendered afterwards will exhibit SSS.
// Currently, there is no efficient way to switch between SRT and MRT for the forward pass;
// therefore, forward-rendered objects do not output split lighting required for the SSS pass.
SubsurfaceScatteringPass(hdCamera, cmd, m_Asset.sssSettings);
SubsurfaceScatteringPass(hdCamera, cmd, sssSettings);
RenderForward(m_CullResults, camera, renderContext, cmd, true);
RenderForwardError(m_CullResults, camera, renderContext, cmd, true);

RenderGaussianPyramidColor(camera, cmd);
// Do a depth pre-pass for transparent objects that want it that will fill the depth buffer to reduce the overdraw (typical usage is hair rendering)
RenderTransparentDepthPrepass(m_CullResults, camera, renderContext, cmd);
// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
RenderForward(m_CullResults, camera, renderContext, cmd, false);
RenderForwardError(m_CullResults, camera, renderContext, cmd, false);

// Simple blit
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget);
}
}
else
{

#if UNITY_EDITOR
// bind depth surface for editor grid/gizmo/selection rendering
if (camera.cameraType == CameraType.SceneView)
{
}
#endif
renderContext.ExecuteCommandBuffer(cmd);

CommandBuffer cmd,
ShaderPassName passName,
RendererConfiguration rendererConfiguration = 0,
RenderQueueRange? inRenderQueueRange = null,
RenderQueueRange? inRenderQueueRange = null,
RenderOpaqueRenderList(cull, camera, renderContext, cmd, new ShaderPassName[] { passName }, rendererConfiguration, inRenderQueueRange, stateBlock, overrideMaterial);
m_SinglePassName[0] = passName;
RenderOpaqueRenderList(cull, camera, renderContext, cmd, m_SinglePassName, rendererConfiguration, inRenderQueueRange, stateBlock, overrideMaterial);
}
void RenderOpaqueRenderList(CullResults cull,

}
if (overrideMaterial != null)
drawSettings.SetOverrideMaterial(overrideMaterial, 0);
var filterSettings = new FilterRenderersSettings(true)
drawSettings.SetOverrideMaterial(overrideMaterial, 0);
}
renderQueueRange = inRenderQueueRange == null
? RenderQueueRange.opaque
: inRenderQueueRange.Value
};
var filterSettings = new FilterRenderersSettings(true) { renderQueueRange = inRenderQueueRange == null ? RenderQueueRange.opaque : inRenderQueueRange.Value };
if(stateBlock == null)
renderContext.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);
else

void RenderTransparentRenderList( CullResults cull,
Camera camera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName passName,
RendererConfiguration rendererConfiguration = 0,
RenderStateBlock? stateBlock = null,
Material overrideMaterial = null)
void RenderTransparentRenderList(CullResults cull,
Camera camera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName passName,
RendererConfiguration rendererConfiguration = 0,
RenderStateBlock? stateBlock = null,
Material overrideMaterial = null)
RenderTransparentRenderList(cull, camera, renderContext, cmd, new ShaderPassName[] { passName }, rendererConfiguration, stateBlock, overrideMaterial);
m_SinglePassName[0] = passName;
RenderTransparentRenderList(cull, camera, renderContext, cmd, m_SinglePassName, rendererConfiguration, stateBlock, overrideMaterial);
void RenderTransparentRenderList( CullResults cull,
Camera camera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName[] passNames,
RendererConfiguration rendererConfiguration = 0,
RenderStateBlock? stateBlock = null,
Material overrideMaterial = null)
void RenderTransparentRenderList(CullResults cull,
Camera camera,
ScriptableRenderContext renderContext,
CommandBuffer cmd,
ShaderPassName[] passNames,
RendererConfiguration rendererConfiguration = 0,
RenderStateBlock? stateBlock = null,
Material overrideMaterial = null)
{
if (!m_CurrentDebugDisplaySettings.renderingDebugSettings.displayTransparentObjects)
return;

}
if (overrideMaterial != null)
{
}
if(stateBlock == null)
renderContext.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);
else

using (new ProfilingSample(cmd, addDepthPrepass ? "Depth Prepass" : "Depth Prepass forward opaque"))
{
// Default depth prepass (forward and deferred) will render all opaque geometry.
RenderQueueRange renderQueueRange = RenderQueueRange.opaque;
var renderQueueRange = RenderQueueRange.opaque;
// If we want only alpha tested geometry in prepass for deferred we change the RenderQueueRange
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() && m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering && m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass)
renderQueueRange = new RenderQueueRange { min = (int)RenderQueue.AlphaTest, max = (int)RenderQueue.GeometryLast - 1 };

using (new ProfilingSample(cmd, m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled() ? "GBufferDebugDisplay" : "GBuffer"))
{
// setup GBuffer for rendering
CoreUtils.SetRenderTarget(cmd, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT);
CoreUtils.SetRenderTarget(cmd, m_GbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT);
// Render opaque objects into GBuffer
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled())

{
if (m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering)
{
RenderQueueRange rangeOpaqueNoAlphaTest = new RenderQueueRange { min = (int)RenderQueue.Geometry, max = (int)RenderQueue.AlphaTest - 1 };
RenderQueueRange rangeOpaqueAlphaTest = new RenderQueueRange { min = (int)RenderQueue.AlphaTest, max = (int)RenderQueue.GeometryLast - 1 };
var rangeOpaqueNoAlphaTest = new RenderQueueRange { min = (int)RenderQueue.Geometry, max = (int)RenderQueue.AlphaTest - 1 };
var rangeOpaqueAlphaTest = new RenderQueueRange { min = (int)RenderQueue.AlphaTest, max = (int)RenderQueue.GeometryLast - 1 };
// When using depth prepass for opaque alpha test only we need to use regular depth test for normal opaque objects.
RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.s_GBufferName, HDUtils.k_RendererConfigurationBakedLighting, rangeOpaqueNoAlphaTest, m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass ? m_DepthStateOpaque : m_DepthStateOpaqueWithPrepass);

{
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.All, Color.black);
// Render Opaque forward
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, HDShaderPassNames.s_ForwardDisplayDebugName, HDUtils.k_RendererConfigurationBakedLighting);
RenderOpaqueRenderList(cull, hdCamera.camera, renderContext, cmd, HDShaderPassNames.s_ForwardDebugDisplayName, HDUtils.k_RendererConfigurationBakedLighting);
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, cmd, HDShaderPassNames.s_ForwardDisplayDebugName, HDUtils.k_RendererConfigurationBakedLighting);
RenderTransparentRenderList(cull, hdCamera.camera, renderContext, cmd, HDShaderPassNames.s_ForwardDebugDisplayName, HDUtils.k_RendererConfigurationBakedLighting);
}
}

void RenderDeferredLighting(HDCamera hdCamera, CommandBuffer cmd)
{
if (m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
{
}
RenderTargetIdentifier[] colorRTs = { m_CameraColorBufferRT, m_CameraSssDiffuseLightingBufferRT };
RenderTargetIdentifier depthTexture = GetDepthTexture();
m_MRTCache2[0] = m_CameraColorBufferRT;
m_MRTCache2[1] = m_CameraSssDiffuseLightingBufferRT;
var depthTexture = GetDepthTexture();
LightLoop.LightingPassOptions options = new LightLoop.LightingPassOptions();
var options = new LightLoop.LightingPassOptions();
options.volumetricLightingEnabled = m_VolumetricLightingEnabled;
if (m_CurrentDebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission)

m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_CurrentDebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, m_DeferredShadowBuffer, options);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_CurrentDebugDisplaySettings, m_MRTCache2, m_CameraDepthStencilBufferRT, depthTexture, m_DeferredShadowBuffer, options);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_CurrentDebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, m_DeferredShadowBuffer, options);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_CurrentDebugDisplaySettings, m_MRTCache2, m_CameraDepthStencilBufferRT, depthTexture, m_DeferredShadowBuffer, options);
}
// Combines specular lighting and diffuse lighting with subsurface scattering.

cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._FilterKernels, sssParameters.filterKernels);
cmd.SetComputeVectorArrayParam(m_SubsurfaceScatteringCS, HDShaderIDs._ShapeParams, sssParameters.shapeParams);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture0, m_gbufferManager.GetGBuffers()[0]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture1, m_gbufferManager.GetGBuffers()[1]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture2, m_gbufferManager.GetGBuffers()[2]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture3, m_gbufferManager.GetGBuffers()[3]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture0, m_GbufferManager.GetGBuffers()[0]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture1, m_GbufferManager.GetGBuffers()[1]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture2, m_GbufferManager.GetGBuffers()[2]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._GBufferTexture3, m_GbufferManager.GetGBuffers()[3]);
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._DepthTexture, GetDepthTexture());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._StencilTexture, GetStencilTexture());
cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._HTile, GetHTile());

string profileName;
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled())
{
passName = addForwardPass ? HDShaderPassNames.s_ForwardDisplayDebugName : HDShaderPassNames.s_ForwardOnlyOpaqueDisplayDebugName;
profileName = addForwardPass ? (renderOpaque ? "Forward Opaque Display Debug" : "Forward Transparent Display Debug") : "ForwardOnlyOpaqueDisplayDebug";
passName = addForwardPass ? HDShaderPassNames.s_ForwardDebugDisplayName : HDShaderPassNames.s_ForwardOnlyOpaqueDebugDisplayName;
profileName = addForwardPass ? (renderOpaque ? "Forward Opaque Debug Display" : "Forward Transparent Debug Display") : "ForwardOnlyOpaqueDebugDisplay";
}
else
{

m_LightLoop.RenderForward(camera, cmd, renderOpaque);
// The pass "SRPDefaultUnlit" is a fallback to legacy unlit rendering and is required to support unity 2d + unity UI that render in the scene.
ShaderPassName[] arrayNames = { passName, HDShaderPassNames.s_SRPDefaultUnlitName};
m_ForwardPassNames[0] = passName;
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, arrayNames, HDUtils.k_RendererConfigurationBakedLighting, null, m_DepthStateOpaqueWithPrepass);
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, m_ForwardPassNames, HDUtils.k_RendererConfigurationBakedLighting, null, m_DepthStateOpaqueWithPrepass);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, arrayNames, HDUtils.k_RendererConfigurationBakedLighting);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, m_ForwardPassNames, HDUtils.k_RendererConfigurationBakedLighting);
void RenderTransparentDepthPrepass(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
using (new ProfilingSample(cmd,"Forward Transparent Depth Prepass"))
{
CoreUtils.SetRenderTarget(cmd, m_CameraDepthStencilBufferRT);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, HDShaderPassNames.s_TransparentDepthPrepassName);
}
}
// This is use to Display legacy shader with an error shader
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
void RenderForwardError(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd, bool renderOpaque)

CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
ShaderPassName[] arrayNames = { HDShaderPassNames.s_AlwaysName, HDShaderPassNames.s_ForwardBaseName, HDShaderPassNames.s_DeferredName, HDShaderPassNames.s_PrepassBaseName, HDShaderPassNames.s_VertexName, HDShaderPassNames.s_VertexLMRGBMName, HDShaderPassNames.s_VertexLMName };
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, arrayNames, 0, null, null, m_ErrorMaterial);
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, m_ForwardErrorPassNames, 0, null, null, m_ErrorMaterial);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, arrayNames, 0, null, m_ErrorMaterial);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, m_ForwardErrorPassNames, 0, null, m_ErrorMaterial);
}
}
}

{
m_ShadowSettings.enabled = m_CurrentDebugDisplaySettings.lightingDebugSettings.enableShadows;
LightingDebugSettings lightingDebugSettings = m_CurrentDebugDisplaySettings.lightingDebugSettings;
Vector4 debugAlbedo = new Vector4(lightingDebugSettings.debugLightingAlbedo.r, lightingDebugSettings.debugLightingAlbedo.g, lightingDebugSettings.debugLightingAlbedo.b, 0.0f);
Vector4 debugSmoothness = new Vector4(lightingDebugSettings.overrideSmoothness ? 1.0f : 0.0f, lightingDebugSettings.overrideSmoothnessValue, 0.0f, 0.0f);
var lightingDebugSettings = m_CurrentDebugDisplaySettings.lightingDebugSettings;
var debugAlbedo = new Vector4(lightingDebugSettings.debugLightingAlbedo.r, lightingDebugSettings.debugLightingAlbedo.g, lightingDebugSettings.debugLightingAlbedo.b, 0.0f);
var debugSmoothness = new Vector4(lightingDebugSettings.overrideSmoothness ? 1.0f : 0.0f, lightingDebugSettings.overrideSmoothnessValue, 0.0f, 0.0f);
Shader.SetGlobalInt(HDShaderIDs._DebugViewMaterial, (int)m_CurrentDebugDisplaySettings.GetDebugMaterialIndex());
Shader.SetGlobalInt(HDShaderIDs._DebugLightingMode, (int)m_CurrentDebugDisplaySettings.GetDebugLightingMode());

float overlaySize = Math.Min(camera.camera.pixelHeight, camera.camera.pixelWidth) * overlayRatio;
float y = camera.camera.pixelHeight - overlaySize;
LightingDebugSettings lightingDebug = m_CurrentDebugDisplaySettings.lightingDebugSettings;
var lightingDebug = m_CurrentDebugDisplaySettings.lightingDebugSettings;
Texture skyReflection = m_SkyManager.skyReflection;
var skyReflection = m_SkyManager.skyReflection;
m_SharedPropertyBlock.SetTexture(HDShaderIDs._InputCubemap, skyReflection);
m_SharedPropertyBlock.SetFloat(HDShaderIDs._Mipmap, lightingDebug.skyReflectionMipmap);
cmd.SetViewport(new Rect(x, y, overlaySize, overlaySize));

// End
if (!m_Asset.renderingSettings.ShouldUseForwardRenderingOnly())
{
m_gbufferManager.InitGBuffers(w, h, cmd);
}
m_GbufferManager.InitGBuffers(w, h, cmd);
CoreUtils.SetRenderTarget(cmd, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.Depth);
}

}
if (m_VolumetricLightingEnabled)
{
}
// TEMP: 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.

{
using (new ProfilingSample(cmd, "Clear GBuffer"))
{
CoreUtils.SetRenderTarget(cmd, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT, ClearFlag.Color, Color.black);
CoreUtils.SetRenderTarget(cmd, m_GbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT, ClearFlag.Color, Color.black);
}
}
// END TEMP

601
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.asset


useForwardRenderingOnly: 0
useDepthPrepassWithDeferredRendering: 0
renderAlphaTestOnlyInDeferredPrepass: 0
sssSettings:
numProfiles: 2
profiles:
- {fileID: 11400000, guid: 906339bac2066fc4aa22a3652e1283ef, type: 2}
- {fileID: 11400000, guid: d6ee4403015766f4093158d69216c0bf, type: 2}
texturingModeFlags: 0
transmissionFlags: 5462
thicknessRemaps:
- {x: 0, y: 8.152544, z: 0, w: 0}
- {x: 0, y: 0.2873168, z: 0, w: 0}
- {x: 0, y: 5, z: 0, w: 0}
- {x: 0, y: 12.031147, z: 0, w: 0}
- {x: 0, y: 12.031147, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
worldScales:
- {x: 1, y: 0, z: 0, w: 0}
- {x: 1, y: 0, z: 0, w: 0}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
shapeParams:
- {x: 1.3192612, y: 3.1152647, z: 4.9751244, w: 7.84603}
- {x: 1.3203883, y: 1.4268992, z: 4.0812, w: 7.839332}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
transmissionTints:
- {x: 0.1892157, y: 0.08039216, z: 0.050000004, w: 0.25}
- {x: 0.25, y: 0.25, z: 0.25, w: 0.25}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 100, y: 0, z: 100, w: 1}
- {x: 0, y: 0, z: 0, w: 0}
filterKernels:
- {x: 0.013865918, y: 1.5345725, z: 0.03667902, w: 1.5654991}
- {x: 0.04211352, y: 1.5729346, z: 0.11374626, w: 1.6734134}
- {x: 0.07107388, y: 1.6130018, z: 0.19626758, w: 1.7949444}
- {x: 0.100779116, y: 1.6548817, z: 0.28494877, w: 1.9325867}
- {x: 0.13126306, y: 1.6986896, z: 0.38062802, w: 2.0894418}
- {x: 0.16256203, y: 1.7445502, z: 0.48430943, w: 2.2694077}
- {x: 0.1947145, y: 1.7925992, z: 0.59720695, w: 2.4774427}
- {x: 0.22776169, y: 1.8429838, z: 0.72080237, w: 2.7199378}
- {x: 0.26174724, y: 1.8958628, z: 0.8569269, w: 3.005264}
- {x: 0.29671827, y: 1.9514104, z: 1.007873, w: 3.3445888}
- {x: 0.33272493, y: 2.0098157, z: 1.1765549, w: 3.7531407}
- {x: 0.369821, y: 2.0712852, z: 1.3667475, w: 4.252257}
- {x: 0.40806437, y: 2.1360447, z: 1.5834517, w: 4.872841}
- {x: 0.44751683, y: 2.2043417, z: 1.8334827, w: 5.6615734}
- {x: 0.48824534, y: 2.276447, z: 2.126473, w: 6.692844}
- {x: 0.5303216, y: 2.3526597, z: 2.4767098, w: 8.093767}
- {x: 0.5738235, y: 2.433308, z: 2.9068332, w: 10.102725}
- {x: 0.61883456, y: 2.5187542, z: 3.4562516, w: 13.228675}
- {x: 0.665446, y: 2.609401, z: 4.2041187, w: 18.793621}
- {x: 0.713756, y: 2.7056925, z: 5.3538504, w: 31.646347}
- {x: 0.763872, y: 2.808125, z: 7.84603, w: 95.44374}
- {x: 0.8159103, y: 2.91725, z: 0, w: 1}
- {x: 0.8699981, y: 3.0336854, z: 0, w: 1}
- {x: 0.9262747, y: 3.1581244, z: 0, w: 1}
- {x: 0.98489225, y: 3.2913465, z: 0, w: 1}
- {x: 1.0460185, y: 3.434234, z: 0, w: 1}
- {x: 1.1098381, y: 3.5877857, z: 0, w: 1}
- {x: 1.1765549, y: 3.7531407, z: 0, w: 1}
- {x: 1.2463952, y: 3.9316032, z: 0, w: 1}
- {x: 1.319611, y: 4.124672, z: 0, w: 1}
- {x: 1.3964823, y: 4.3340797, z: 0, w: 1}
- {x: 1.4773248, y: 4.561845, z: 0, w: 1}
- {x: 1.5624928, y: 4.810328, z: 0, w: 1}
- {x: 1.6523882, y: 5.082317, z: 0, w: 1}
- {x: 1.747467, y: 5.381122, z: 0, w: 1}
- {x: 1.8482518, y: 5.710715, z: 0, w: 1}
- {x: 1.9553448, y: 6.0759025, z: 0, w: 1}
- {x: 2.069445, y: 6.482568, z: 0, w: 1}
- {x: 2.1913698, y: 6.9379897, z: 0, w: 1}
- {x: 2.3220856, y: 7.4513016, z: 0, w: 1}
- {x: 2.4627466, y: 8.0341215, z: 0, w: 1}
- {x: 2.614747, y: 8.701484, z: 0, w: 1}
- {x: 2.7797952, y: 9.473195, z: 0, w: 1}
- {x: 2.9600194, y: 10.375936, z: 0, w: 1}
- {x: 3.1581159, y: 11.446505, z: 0, w: 1}
- {x: 3.3775842, y: 12.737201, z: 0, w: 1}
- {x: 3.6230793, y: 14.324919, z: 0, w: 1}
- {x: 3.9009922, y: 16.327562, z: 0, w: 1}
- {x: 4.220452, y: 18.935623, z: 0, w: 1}
- {x: 4.5951686, y: 22.478209, z: 0, w: 1}
- {x: 5.047148, y: 27.57712, z: 0, w: 1}
- {x: 5.615129, y: 35.564823, z: 0, w: 1}
- {x: 6.3776174, y: 49.90625, z: 0, w: 1}
- {x: 7.5374603, y: 83.30668, z: 0, w: 1}
- {x: 10.03481, y: 250.11497, z: 0, w: 1}
- {x: 0.013854082, y: 1.5332626, z: 0.036647703, w: 1.5641627}
- {x: 0.04207757, y: 1.5715919, z: 0.113649175, w: 1.671985}
- {x: 0.07101321, y: 1.611625, z: 0.19610003, w: 1.7934121}
- {x: 0.10069309, y: 1.653469, z: 0.28470552, w: 1.9309369}
- {x: 0.13115102, y: 1.6972395, z: 0.38030306, w: 2.0876582}
- {x: 0.16242325, y: 1.743061, z: 0.48389605, w: 2.2674706}
- {x: 0.19454831, y: 1.791069, z: 0.5966971, w: 2.4753277}
- {x: 0.22756726, y: 1.8414105, z: 0.72018707, w: 2.717616}
- {x: 0.2615238, y: 1.8942443, z: 0.85619545, w: 3.0026984}
- {x: 0.29646498, y: 1.9497447, z: 1.0070126, w: 3.3417335}
- {x: 0.33244094, y: 2.0081, z: 1.1755506, w: 3.749937}
- {x: 0.36950532, y: 2.069517, z: 1.3655809, w: 4.248627}
- {x: 0.40771604, y: 2.1342213, z: 1.5821002, w: 4.868682}
- {x: 0.44713485, y: 2.2024598, z: 1.8319175, w: 5.6567397}
- {x: 0.48782852, y: 2.274504, z: 2.1246579, w: 6.6871305}
- {x: 0.5298689, y: 2.3506513, z: 2.4745958, w: 8.086858}
- {x: 0.5733336, y: 2.4312308, z: 2.9043517, w: 10.094101}
- {x: 0.6183063, y: 2.5166042, z: 3.4533012, w: 13.217383}
- {x: 0.66487795, y: 2.6071734, z: 4.20053, w: 18.777578}
- {x: 0.71314675, y: 2.703383, z: 5.349281, w: 31.61934}
- {x: 0.76321995, y: 2.805728, z: 7.839332, w: 95.36225}
- {x: 0.81521386, y: 2.9147599, z: 0, w: 1}
- {x: 0.86925554, y: 3.031096, z: 0, w: 1}
- {x: 0.92548406, y: 3.1554284, z: 0, w: 1}
- {x: 0.9840515, y: 3.288537, z: 0, w: 1}
- {x: 1.0451256, y: 3.431302, z: 0, w: 1}
- {x: 1.1088905, y: 3.5847225, z: 0, w: 1}
- {x: 1.1755506, y: 3.749937, z: 0, w: 1}
- {x: 1.2453312, y: 3.9282467, z: 0, w: 1}
- {x: 1.3184844, y: 4.1211514, z: 0, w: 1}
- {x: 1.3952904, y: 4.3303804, z: 0, w: 1}
- {x: 1.4760638, y: 4.5579505, z: 0, w: 1}
- {x: 1.5611593, y: 4.8062224, z: 0, w: 1}
- {x: 1.650978, y: 5.0779796, z: 0, w: 1}
- {x: 1.7459753, y: 5.3765287, z: 0, w: 1}
- {x: 1.8466738, y: 5.7058387, z: 0, w: 1}
- {x: 1.9536757, y: 6.070716, z: 0, w: 1}
- {x: 2.0676782, y: 6.4770336, z: 0, w: 1}
- {x: 2.189499, y: 6.9320674, z: 0, w: 1}
- {x: 2.3201032, y: 7.4449396, z: 0, w: 1}
- {x: 2.4606442, y: 8.027264, z: 0, w: 1}
- {x: 2.612515, y: 8.694056, z: 0, w: 1}
- {x: 2.777422, y: 9.465107, z: 0, w: 1}
- {x: 2.9574924, y: 10.367077, z: 0, w: 1}
- {x: 3.1554203, y: 11.436736, z: 0, w: 1}
- {x: 3.3747015, y: 12.726331, z: 0, w: 1}
- {x: 3.6199868, y: 14.312694, z: 0, w: 1}
- {x: 3.897662, y: 16.313623, z: 0, w: 1}
- {x: 4.2168484, y: 18.919455, z: 0, w: 1}
- {x: 4.5912457, y: 22.459015, z: 0, w: 1}
- {x: 5.042839, y: 27.553566, z: 0, w: 1}
- {x: 5.610336, y: 35.534466, z: 0, w: 1}
- {x: 6.3721733, y: 49.863647, z: 0, w: 1}
- {x: 7.53103, y: 83.235695, z: 0, w: 1}
- {x: 10.026244, y: 249.90146, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
- {x: 0, y: 1, z: 0, w: 1}
useDisneySSS: 1
halfRcpWeightedVariances:
- {x: 2.4691355, y: 12.5, z: 12.5, w: 2.4691355}
- {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
halfRcpVariancesAndWeights:
- {x: 0.5, y: 1.125, z: 1.125, w: 2}
- {x: 0.125, y: 1.125, z: 1.125, w: 2}
- {x: 0.5, y: 0.5, z: 0.5, w: 2}
- {x: 0.125, y: 0.125, z: 0.125, w: 2}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 1, y: 1, z: 1, w: 1}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
filterKernelsBasic:
- {x: 0.09090909, y: 0.21162307, z: 0.21162307, w: -0.000000048879357}
- {x: 0.09090909, y: 0.18990478, z: 0.18990478, w: -0.11381993}
- {x: 0.09090909, y: 0.13233659, z: 0.13233659, w: -0.23580086}
- {x: 0.09090909, y: 0.061445467, z: 0.061445467, w: -0.37865555}
- {x: 0.09090909, y: 0.010501689, z: 0.010501689, w: -0.57677805}
- {x: 0.09090909, y: 2.9458339e-10, z: 2.9458339e-10, w: -1.3907351}
- {x: 0.09090909, y: 0.18990476, z: 0.18990476, w: 0.11382001}
- {x: 0.09090909, y: 0.13233659, z: 0.13233659, w: 0.23580086}
- {x: 0.09090909, y: 0.061445467, z: 0.061445467, w: 0.37865555}
- {x: 0.09090909, y: 0.010501689, z: 0.010501689, w: 0.57677805}
- {x: 0.09090909, y: 2.9456845e-10, z: 2.9456845e-10, w: 1.3907368}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.11381993}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.23580086}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.37865555}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.57677805}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -1.3907351}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.11382001}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.23580086}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.37865555}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.57677805}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 1.3907368}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
- {x: 1, y: 1, z: 1, w: 0}
sssSettings: {fileID: 11400000, guid: 873499ce7a6f749408981f512a9683f7, type: 2}
tileSettings:
enableTileAndCluster: 1
enableComputeLightEvaluation: 1

3
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.cs


// Renderer Settings
public RenderingSettings renderingSettings = new RenderingSettings();
public SubsurfaceScatteringSettings sssSettings = new SubsurfaceScatteringSettings();
public SubsurfaceScatteringSettings sssSettings;
public TileSettings tileSettings = new TileSettings();
// Shadow Settings

public void OnValidate()
{
sssSettings.OnValidate();
}
}
}

46
ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs


{
public static class HDShaderPassNames
{
// ShaderPass string - use to have consistent name through the code
public static readonly string s_EmptyStr = "";
public static readonly string s_ForwardStr = "Forward";
public static readonly string s_ForwardDebugDisplayStr = "ForwardDebugDisplay";
public static readonly string s_DepthOnlyStr = "DepthOnly";
public static readonly string s_ForwardOnlyOpaqueDepthOnlyStr = "ForwardOnlyOpaqueDepthOnly";
public static readonly string s_ForwardOnlyOpaqueStr = "ForwardOnlyOpaque";
public static readonly string s_ForwardOnlyOpaqueDebugDisplayStr = "ForwardOnlyOpaqueDebugDisplay";
public static readonly string s_GBufferStr = "GBuffer";
public static readonly string s_GBufferWithPrepassStr = "GBufferWithPrepass";
public static readonly string s_GBufferDebugDisplayStr = "GBufferDebugDisplay";
public static readonly string s_SRPDefaultUnlitStr = "SRPDefaultUnlit";
public static readonly string s_MotionVectorsStr = "MotionVectors";
public static readonly string s_DistortionVectorsStr = "DistortionVectors";
public static readonly string s_TransparentDepthPrepassStr = "TransparentDepthPrepass";
public static readonly string s_MetaStr = "Meta";
public static readonly string s_ShadowCasterStr = "ShadowCaster";
public static readonly ShaderPassName s_EmptyName = new ShaderPassName("");
public static readonly ShaderPassName s_ForwardName = new ShaderPassName("Forward");
public static readonly ShaderPassName s_ForwardDisplayDebugName = new ShaderPassName("ForwardDisplayDebug");
public static readonly ShaderPassName s_DepthOnlyName = new ShaderPassName("DepthOnly");
public static readonly ShaderPassName s_ForwardOnlyOpaqueDepthOnlyName = new ShaderPassName("ForwardOnlyOpaqueDepthOnly");
public static readonly ShaderPassName s_ForwardOnlyOpaqueName = new ShaderPassName("ForwardOnlyOpaque");
public static readonly ShaderPassName s_ForwardOnlyOpaqueDisplayDebugName = new ShaderPassName("ForwardOnlyOpaqueDisplayDebug");
public static readonly ShaderPassName s_GBufferName = new ShaderPassName("GBuffer");
public static readonly ShaderPassName s_GBufferWithPrepassName = new ShaderPassName("GBufferWithPrepass");
public static readonly ShaderPassName s_GBufferDebugDisplayName = new ShaderPassName("GBufferDebugDisplay");
public static readonly ShaderPassName s_SRPDefaultUnlitName = new ShaderPassName("SRPDefaultUnlit");
public static readonly ShaderPassName s_MotionVectorsName = new ShaderPassName("MotionVectors");
public static readonly ShaderPassName s_DistortionVectorsName = new ShaderPassName("DistortionVectors");
public static readonly ShaderPassName s_EmptyName = new ShaderPassName(s_EmptyStr);
public static readonly ShaderPassName s_ForwardName = new ShaderPassName(s_ForwardStr);
public static readonly ShaderPassName s_ForwardDebugDisplayName = new ShaderPassName(s_ForwardDebugDisplayStr);
public static readonly ShaderPassName s_DepthOnlyName = new ShaderPassName(s_DepthOnlyStr);
public static readonly ShaderPassName s_ForwardOnlyOpaqueDepthOnlyName = new ShaderPassName(s_ForwardOnlyOpaqueDepthOnlyStr);
public static readonly ShaderPassName s_ForwardOnlyOpaqueName = new ShaderPassName(s_ForwardOnlyOpaqueStr);
public static readonly ShaderPassName s_ForwardOnlyOpaqueDebugDisplayName = new ShaderPassName(s_ForwardOnlyOpaqueDebugDisplayStr);
public static readonly ShaderPassName s_GBufferName = new ShaderPassName(s_GBufferStr);
public static readonly ShaderPassName s_GBufferWithPrepassName = new ShaderPassName(s_GBufferWithPrepassStr);
public static readonly ShaderPassName s_GBufferDebugDisplayName = new ShaderPassName(s_GBufferDebugDisplayStr);
public static readonly ShaderPassName s_SRPDefaultUnlitName = new ShaderPassName(s_SRPDefaultUnlitStr);
public static readonly ShaderPassName s_MotionVectorsName = new ShaderPassName(s_MotionVectorsStr);
public static readonly ShaderPassName s_DistortionVectorsName = new ShaderPassName(s_DistortionVectorsStr);
public static readonly ShaderPassName s_TransparentDepthPrepassName = new ShaderPassName(s_TransparentDepthPrepassStr);
// Legacy name
public static readonly ShaderPassName s_AlwaysName = new ShaderPassName("Always");

public static readonly int _InputCubemap = Shader.PropertyToID("_InputCubemap");
public static readonly int _Mipmap = Shader.PropertyToID("_Mipmap");
public static readonly int _SubsurfaceProfile = Shader.PropertyToID("_SubsurfaceProfile");
public static readonly int _MaxRadius = Shader.PropertyToID("_MaxRadius");
public static readonly int _ShapeParam = Shader.PropertyToID("_ShapeParam");
public static readonly int _StdDev1 = Shader.PropertyToID("_StdDev1");

29
ScriptableRenderPipeline/HDRenderPipeline/HDUtils.cs


using UnityEngine.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{

public static List<RenderPipelineMaterial> GetRenderPipelineMaterialList()
{
var baseType = typeof(RenderPipelineMaterial);
var assembly = baseType.Assembly;
var types = assembly.GetTypes()
.Where(t => t.IsSubclassOf(baseType))
.Select(Activator.CreateInstance)
.Cast<RenderPipelineMaterial>()
.ToList();
// Note: If there is a need for an optimization in the future of this function, user can
// simply fill the materialList manually by commenting the code abode and returning a
// custom list of materials they use in their game.
//
// return new List<RenderPipelineMaterial>
// {
// new Lit(),
// new Unlit(),
// ...
// };
return types;
}
public static Matrix4x4 GetViewProjectionMatrix(Matrix4x4 worldToViewMatrix, Matrix4x4 projectionMatrix)
{

42
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs


using (var o = new PropertyFetcher<HDAdditionalLightData>(m_SerializedAdditionalLightData))
m_AdditionalLightData = new SerializedLightData
{
spotInnerPercent = o.FindProperty(x => x.m_InnerSpotPercent),
lightDimmer = o.FindProperty(x => x.lightDimmer),
fadeDistance = o.FindProperty(x => x.fadeDistance),
affectDiffuse = o.FindProperty(x => x.affectDiffuse),
affectSpecular = o.FindProperty(x => x.affectSpecular),
lightTypeExtent = o.FindProperty(x => x.lightTypeExtent),
spotLightShape = o.FindProperty(x => x.spotLightShape),
shapeLength = o.FindProperty(x => x.shapeLength),
shapeWidth = o.FindProperty(x => x.shapeWidth),
shapeRadius = o.FindProperty(x => x.shapeRadius),
maxSmoothness = o.FindProperty(x => x.maxSmoothness),
applyRangeAttenuation = o.FindProperty(x => x.applyRangeAttenuation),
spotInnerPercent = o.Find(x => x.m_InnerSpotPercent),
lightDimmer = o.Find(x => x.lightDimmer),
fadeDistance = o.Find(x => x.fadeDistance),
affectDiffuse = o.Find(x => x.affectDiffuse),
affectSpecular = o.Find(x => x.affectSpecular),
lightTypeExtent = o.Find(x => x.lightTypeExtent),
spotLightShape = o.Find(x => x.spotLightShape),
shapeLength = o.Find(x => x.shapeLength),
shapeWidth = o.Find(x => x.shapeWidth),
shapeRadius = o.Find(x => x.shapeRadius),
maxSmoothness = o.Find(x => x.maxSmoothness),
applyRangeAttenuation = o.Find(x => x.applyRangeAttenuation),
useOldInspector = o.FindProperty(x => x.useOldInspector),
showFeatures = o.FindProperty(x => x.featuresFoldout),
showAdditionalSettings = o.FindProperty(x => x.showAdditionalSettings)
useOldInspector = o.Find(x => x.useOldInspector),
showFeatures = o.Find(x => x.featuresFoldout),
showAdditionalSettings = o.Find(x => x.showAdditionalSettings)
};
// TODO: Review this once AdditionalShadowData is refactored

dimmer = o.FindProperty(x => x.shadowDimmer),
fadeDistance = o.FindProperty(x => x.shadowFadeDistance),
cascadeCount = o.FindProperty("shadowCascadeCount"),
cascadeRatios = o.FindProperty("shadowCascadeRatios"),
cascadeBorders = o.FindProperty("shadowCascadeBorders"),
resolution = o.FindProperty(x => x.shadowResolution)
dimmer = o.Find(x => x.shadowDimmer),
fadeDistance = o.Find(x => x.shadowFadeDistance),
cascadeCount = o.Find("shadowCascadeCount"),
cascadeRatios = o.Find("shadowCascadeRatios"),
cascadeBorders = o.Find("shadowCascadeBorders"),
resolution = o.Find(x => x.shadowResolution)
};
}

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


var invProjscr = projscr.inverse;
bool isOrthographic = camera.orthographic;
cmd.SetRenderTarget(new RenderTargetIdentifier((Texture)null));
cmd.SetRenderTarget(BuiltinRenderTextureType.None);
// generate screen-space AABBs (used for both fptl and clustered).
if (m_lightCount != 0)

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


public readonly GUIContent layerInfluenceMapMaskText = new GUIContent("Layer Influence Mask", "Layer mask");
public readonly GUIContent vertexColorModeText = new GUIContent("Vertex Color Mode", "Mode multiply: vertex color is multiply with the mask. Mode additive: vertex color values are remapped between -1 and 1 and added to the mask (neutral at 0.5 vertex color).");
public readonly GUIContent layerCountText = new GUIContent("Layer Count", "Number of layers.");
public readonly GUIContent layerTilingBlendMaskText = new GUIContent("Tiling", "Tiling for the blend mask.");
public readonly GUIContent objectScaleAffectTileText = new GUIContent("Lock layers 0123 tiling with object Scale", "Tiling of each layers will be affected by the object scale.");
public readonly GUIContent objectScaleAffectTileText2 = new GUIContent("Lock layers 123 tiling with object Scale", "Tiling of each influenced layers (all except main layer) will be affected by the object scale.");

public readonly GUIContent inheritBaseColorText = new GUIContent("BaseColor influence", "Inherit the base color from the base layer.");
public readonly GUIContent heightOffset = new GUIContent("Height Offset", "Offset applied to the height before layering.");
public readonly GUIContent heightTransition = new GUIContent("Height Transition", "Size in world units of the smooth transition between layers.");
public readonly GUIContent perPixelDisplacementLayersWarning = new GUIContent("For pixel displacement to work correctly, all layers with a heightmap must use the same UV mapping");
public readonly GUIContent materialReferencesText = new GUIContent("Material References");

const string kUVBlendMask = "_UVBlendMask";
MaterialProperty UVMappingMaskBlendMask = null;
const string kUVMappingMaskBlendMask = "_UVMappingMaskBlendMask";
MaterialProperty layerTilingBlendMask = null;
const string kLayerTilingBlendMask = "_LayerTilingBlendMask";
MaterialProperty texWorldScaleBlendMask = null;
const string kTexWorldScaleBlendMask = "_TexWorldScaleBlendMask";
MaterialProperty useMainLayerInfluence = null;

objectScaleAffectTile = FindProperty(kObjectScaleAffectTile, props);
UVBlendMask = FindProperty(kUVBlendMask, props);
UVMappingMaskBlendMask = FindProperty(kUVMappingMaskBlendMask, props);
layerTilingBlendMask = FindProperty(kLayerTilingBlendMask, props);
texWorldScaleBlendMask = FindProperty(kTexWorldScaleBlendMask, props);
useMainLayerInfluence = FindProperty(kkUseMainLayerInfluence, props);

bool mainLayerInfluenceEnable = useMainLayerInfluence.floatValue > 0.0f;
bool heightBasedBlend = useHeightBasedBlend.floatValue > 0.0f;
EditorGUILayout.LabelField(styles.layeringOptionText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
if(layerIndex > 0 || heightBasedBlend )
if (layerIndex > 0)
EditorGUILayout.LabelField(styles.layeringOptionText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
// influence
if (layerIndex > 0)
{
int paramIndex = layerIndex - 1;
int paramIndex = layerIndex - 1;
m_MaterialEditor.ShaderProperty(opacityAsDensity[layerIndex], styles.opacityAsDensityText);
m_MaterialEditor.ShaderProperty(opacityAsDensity[layerIndex], styles.opacityAsDensityText);
if (mainLayerInfluenceEnable)
{
m_MaterialEditor.ShaderProperty(inheritBaseColor[paramIndex], styles.inheritBaseColorText);
m_MaterialEditor.ShaderProperty(inheritBaseNormal[paramIndex], styles.inheritBaseNormalText);
// Main height influence is only available if the shader use the heightmap for displacement (per vertex or per level)
// We always display it as it can be tricky to know when per pixel displacement is enabled or not
m_MaterialEditor.ShaderProperty(inheritBaseHeight[paramIndex], styles.inheritBaseHeightText);
}
if (mainLayerInfluenceEnable)
{
m_MaterialEditor.ShaderProperty(inheritBaseColor[paramIndex], styles.inheritBaseColorText);
m_MaterialEditor.ShaderProperty(inheritBaseNormal[paramIndex], styles.inheritBaseNormalText);
// Main height influence is only available if the shader use the heightmap for displacement (per vertex or per level)
// We always display it as it can be tricky to know when per pixel displacement is enabled or not
m_MaterialEditor.ShaderProperty(inheritBaseHeight[paramIndex], styles.inheritBaseHeightText);
if (heightBasedBlend)
}
else
{
if (!useMainLayerInfluence.hasMixedValue && useMainLayerInfluence.floatValue != 0.0f)
m_MaterialEditor.ShaderProperty(heightOffset[layerIndex], styles.heightOffset);
m_MaterialEditor.TexturePropertySingleLine(styles.layerInfluenceMapMaskText, layerInfluenceMaskMap);
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
if (heightBasedBlend)
{
m_MaterialEditor.ShaderProperty(heightOffset[layerIndex], styles.heightOffset);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
DoLayerGUI(material, layerIndex);

{
m_MaterialEditor.ShaderProperty(texWorldScaleBlendMask, styles.layerTexWorldScaleText);
}
else
{
m_MaterialEditor.ShaderProperty(layerTilingBlendMask, styles.layerTilingBlendMaskText);
}
m_MaterialEditor.TextureScaleOffsetProperty(layerMaskMap);
EditorGUI.indentLevel--;
m_MaterialEditor.ShaderProperty(vertexColorMode, styles.vertexColorModeText);

if (EditorGUI.EndChangeCheck())
{
useMainLayerInfluence.floatValue = mainLayerModeInfluenceEnable ? 1.0f : 0.0f;
}
if (!useMainLayerInfluence.hasMixedValue && useMainLayerInfluence.floatValue != 0.0f)
{
EditorGUI.indentLevel++;
m_MaterialEditor.TexturePropertySingleLine(styles.layerInfluenceMapMaskText, layerInfluenceMaskMap);
EditorGUI.indentLevel--;
}
EditorGUI.BeginChangeCheck();

SetKeyword(material, "_HEIGHTMAP" + i, material.GetTexture(kHeightMap + i));
}
SetKeyword(material, "_INFLUENCEMASK_MAP", material.GetTexture(kLayerInfluenceMaskMap) && material.GetFloat(kkUseMainLayerInfluence) != 0.0f);
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
SetKeyword(material, "_ENABLESPECULAROCCLUSION", material.GetFloat(kEnableSpecularOcclusion) > 0.0f);

{
optionsChanged = true;
}
// In case of pixel displacement and layered shader, all layers must used the same texture mapping for layer that have a heightmap
// (Else the algorithm will not work correctly)
if ((DisplacementMode)displacementMode.floatValue == DisplacementMode.Pixel)
{
float compareValue = -1.0f;
bool match = true;
if (material.GetTexture(kHeightMap + 0))
{
compareValue = UVBase[0].floatValue;
}
if (material.GetTexture(kHeightMap + 1))
{
if (compareValue == -1.0f)
compareValue = UVBase[1].floatValue;
else if (compareValue != UVBase[1].floatValue)
match = false;
}
if (material.GetTexture(kHeightMap + 2))
{
if (compareValue == -1.0f)
compareValue = UVBase[2].floatValue;
else if (compareValue != UVBase[2].floatValue)
match = false;
}
if (material.GetTexture(kHeightMap + 3))
{
if (compareValue == -1.0f)
compareValue = UVBase[3].floatValue;
else if (compareValue != UVBase[3].floatValue)
match = false;
}
if (!match)
{
EditorGUILayout.HelpBox(styles.perPixelDisplacementLayersWarning.text, MessageType.Warning);
}
}
bool layerChanged = DoLayersGUI(materialImporter);
DoEmissiveGUI(material);

52
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


_DetailMap2("DetailMap2", 2D) = "black" {}
_DetailMap3("DetailMap3", 2D) = "black" {}
_DetailAlbedoScale0("_DetailAlbedoScale0", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale1("_DetailAlbedoScale1", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale2("_DetailAlbedoScale2", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale3("_DetailAlbedoScale3", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale0("_DetailAlbedoScale0", Range(0.0, 2.0)) = 1
_DetailAlbedoScale1("_DetailAlbedoScale1", Range(0.0, 2.0)) = 1
_DetailAlbedoScale2("_DetailAlbedoScale2", Range(0.0, 2.0)) = 1
_DetailAlbedoScale3("_DetailAlbedoScale3", Range(0.0, 2.0)) = 1
_DetailNormalScale0("_DetailNormalScale0", Range(0.0, 2.0)) = 1
_DetailNormalScale1("_DetailNormalScale1", Range(0.0, 2.0)) = 1

_DetailSmoothnessScale0("_DetailSmoothnessScale0", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale1("_DetailSmoothnessScale1", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale2("_DetailSmoothnessScale2", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale3("_DetailSmoothnessScale3", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale0("_DetailSmoothnessScale0", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale1("_DetailSmoothnessScale1", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale2("_DetailSmoothnessScale2", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale3("_DetailSmoothnessScale3", Range(0.0, 2.0)) = 1
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace0("NormalMap space", Float) = 0
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace1("NormalMap space", Float) = 0

[ToggleOff] _OpacityAsDensity1("_OpacityAsDensity1", Float) = 0.0
[ToggleOff] _OpacityAsDensity2("_OpacityAsDensity2", Float) = 0.0
[ToggleOff] _OpacityAsDensity3("_OpacityAsDensity3", Float) = 0.0
_LayerTilingBlendMask("_LayerTilingBlendMask", Float) = 1
[HideInInspector] _LayerCount("_LayerCount", Float) = 2.0

[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0
[Enum(None, 0, Vertex displacement, 1, Pixel displacement, 2)] _DisplacementMode("DisplacementMode", Int) = 0
[ToggleOff] _DisplacementLockObjectScale("displacement lock object scale", Float) = 1.0
[ToggleOff] _DisplacementLockTilingScale("displacement lock tiling scale", Float) = 1.0
[ToggleOff] _PerPixelDisplacementObjectScale("Per pixel displacement object scale", Float) = 1.0
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[HideInInspector] _InvPrimScale("Inverse primitive scale for non-planar POM", Vector) = (1, 1, 0, 0)
// Displacement map
[ToggleOff] _EnableVertexDisplacement("Enable vertex displacement", Float) = 0.0
[ToggleOff] _VertexDisplacementObjectScale("Vertex displacement object scale", Float) = 1.0
[ToggleOff] _VertexDisplacementTilingScale("Vertex displacement tiling height scale", Float) = 1.0
// Wind
[ToggleOff] _EnableWind("Enable Wind", Float) = 0.0

_TexWorldScale2("Tiling", Float) = 1.0
_TexWorldScale3("Tiling", Float) = 1.0
[HideInInspector] _InvTilingScale0("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[HideInInspector] _InvTilingScale1("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[HideInInspector] _InvTilingScale2("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[HideInInspector] _InvTilingScale3("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0 // no UV1/2/3 for main layer (matching Lit.shader and for PPDisplacement restriction)
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase2("UV Set for base2", Float) = 0

// #pragma enable_d3d11_debug_symbols
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _VERTEX_WIND
#pragma shader_feature _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE

#pragma shader_feature _DETAIL_MAP3
#pragma shader_feature _ _LAYER_MASK_VERTEX_COLOR_MUL _LAYER_MASK_VERTEX_COLOR_ADD
#pragma shader_feature _MAIN_LAYER_INFLUENCE_MODE
#pragma shader_feature _INFLUENCEMASK_MAP
#pragma shader_feature _DENSITY_MODE
#pragma shader_feature _HEIGHT_BASED_BLEND
#pragma shader_feature _ _LAYEREDLIT_3_LAYERS _LAYEREDLIT_4_LAYERS

Pass
{
Name "ForwardDisplayDebug" // Name is not used
Tags{ "LightMode" = "ForwardDisplayDebug" } // This will be only for transparent object based on the RenderQueue index
Name "ForwardDebugDisplay" // Name is not used
Tags{ "LightMode" = "ForwardDebugDisplay" } // This will be only for transparent object based on the RenderQueue index
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]

52
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader


_DetailMap2("DetailMap2", 2D) = "black" {}
_DetailMap3("DetailMap3", 2D) = "black" {}
_DetailAlbedoScale0("_DetailAlbedoScale0", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale1("_DetailAlbedoScale1", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale2("_DetailAlbedoScale2", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale3("_DetailAlbedoScale3", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale0("_DetailAlbedoScale0", Range(0.0, 2.0)) = 1
_DetailAlbedoScale1("_DetailAlbedoScale1", Range(0.0, 2.0)) = 1
_DetailAlbedoScale2("_DetailAlbedoScale2", Range(0.0, 2.0)) = 1
_DetailAlbedoScale3("_DetailAlbedoScale3", Range(0.0, 2.0)) = 1
_DetailNormalScale0("_DetailNormalScale0", Range(0.0, 2.0)) = 1
_DetailNormalScale1("_DetailNormalScale1", Range(0.0, 2.0)) = 1

_DetailSmoothnessScale0("_DetailSmoothnessScale0", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale1("_DetailSmoothnessScale1", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale2("_DetailSmoothnessScale2", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale3("_DetailSmoothnessScale3", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale0("_DetailSmoothnessScale0", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale1("_DetailSmoothnessScale1", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale2("_DetailSmoothnessScale2", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale3("_DetailSmoothnessScale3", Range(0.0, 2.0)) = 1
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace0("NormalMap space", Float) = 0
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace1("NormalMap space", Float) = 0

[ToggleOff] _OpacityAsDensity1("_OpacityAsDensity1", Float) = 0.0
[ToggleOff] _OpacityAsDensity2("_OpacityAsDensity2", Float) = 0.0
[ToggleOff] _OpacityAsDensity3("_OpacityAsDensity3", Float) = 0.0
_LayerTilingBlendMask("_LayerTilingBlendMask", Float) = 1
[HideInInspector] _LayerCount("_LayerCount", Float) = 2.0

[Enum(None, 0, Mirror, 1, Flip, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0
[Enum(None, 0, Vertex displacement, 1, Pixel displacement, 2, Tessellation displacement, 3)] _DisplacementMode("DisplacementMode", Int) = 0
[ToggleOff] _DisplacementLockObjectScale("displacement lock object scale", Float) = 1.0
[ToggleOff] _DisplacementLockTilingScale("displacement lock tiling scale", Float) = 1.0
[ToggleOff] _PerPixelDisplacementObjectScale("Per pixel displacement object scale", Float) = 1.0
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[HideInInspector] _InvPrimScale("Inverse primitive scale for non-planar POM", Vector) = (1, 1, 0, 0)
// Displacement map
[ToggleOff] _EnableVertexDisplacement("Enable vertex displacement", Float) = 0.0
[ToggleOff] _VertexDisplacementObjectScale("Vertex displacement object scale", Float) = 1.0
[ToggleOff] _VertexDisplacementTilingScale("Vertex displacement tiling height scale", Float) = 1.0
// Wind
[ToggleOff] _EnableWind("Enable Wind", Float) = 0.0

_TexWorldScale2("Tiling", Float) = 1.0
_TexWorldScale3("Tiling", Float) = 1.0
[HideInInspector] _InvTilingScale0("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[HideInInspector] _InvTilingScale1("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[HideInInspector] _InvTilingScale2("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[HideInInspector] _InvTilingScale3("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0 // no UV1/2/3 for main layer (matching Lit.shader and for PPDisplacement restriction)
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase2("UV Set for base2", Float) = 0

// #pragma enable_d3d11_debug_symbols
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT _TESSELLATION_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _VERTEX_WIND
#pragma shader_feature _TESSELLATION_PHONG

#pragma shader_feature _DETAIL_MAP3
#pragma shader_feature _ _LAYER_MASK_VERTEX_COLOR_MUL _LAYER_MASK_VERTEX_COLOR_ADD
#pragma shader_feature _MAIN_LAYER_INFLUENCE_MODE
#pragma shader_feature _INFLUENCEMASK_MAP
#pragma shader_feature _DENSITY_MODE
#pragma shader_feature _HEIGHT_BASED_BLEND
#pragma shader_feature _ _LAYEREDLIT_3_LAYERS _LAYEREDLIT_4_LAYERS

Pass
{
Name "ForwardDisplayDebug" // Name is not used
Tags{ "LightMode" = "ForwardDisplayDebug" } // This will be only for transparent object based on the RenderQueue index
Name "ForwardDebugDisplay" // Name is not used
Tags{ "LightMode" = "ForwardDebugDisplay" } // This will be only for transparent object based on the RenderQueue index
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]

168
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs


public static GUIContent doubleSidedNormalModeText = new GUIContent("Normal mode", "This will modify the normal base on the selected mode. None: untouch, Mirror: Mirror the normal with vertex normal plane, Flip: Flip the normal");
public static GUIContent depthOffsetEnableText = new GUIContent("Enable Depth Offset", "EnableDepthOffset on this shader (Use with heightmap)");
// Displacement mapping (POM, tessellation, per vertex)
//public static GUIContent enablePerPixelDisplacementText = new GUIContent("Enable Per Pixel Displacement", "");
public static GUIContent displacementModeText = new GUIContent("Displacement mode", "Apply heightmap displacement to the selected element: Vertex, pixel or tessellated vertex. Pixel displacement must be use with flat surfaces, it is an expensive features and typical usage is paved road.");
public static GUIContent lockWithObjectScaleText = new GUIContent("Lock with object scale", "Displacement mapping will take the absolute value of the scale of the object into account.");
public static GUIContent lockWithTilingRateText = new GUIContent("Lock with height map tiling rate", "Displacement mapping will take the absolute value of the tiling rate of the height map into account.");
// Per pixel displacement
public static GUIContent enablePerPixelDisplacementText = new GUIContent("Enable Per Pixel Displacement", "Per pixel displacement work best with flat surfaces. This is an expensive features and should be enable wisely. Typical use case is paved road.");
// Per pixel displacement
public static GUIContent perPixelDisplacementObjectScaleText = new GUIContent("Lock with object scale", "Per Pixel displacement will take into account the tiling scale - Only work with uniform positive scale");
// Vertex displacement
public static string vertexDisplacementText = "Vertex displacement";
public static GUIContent enableVertexDisplacementText = new GUIContent("Enable vertex displacement", "Use heightmap as a displacement map. Displacement map is use to move vertex position in local space");
public static GUIContent vertexDisplacementObjectScaleText = new GUIContent("Lock with object scale", "Vertex displacement will take into account the object scale - Only work with uniform positive scale");
public static GUIContent vertexDisplacementTilingScaleText = new GUIContent("Lock with heightmap tiling", "Vertex displacement will take into account the tiling scale - Only work with uniform positive scale");
public static GUIContent ppdPrimitiveLength = new GUIContent("Primitive length", "Dimensions of the primitive (with the scale of 1) to which the per-pixel displacement mapping is being applied. For example, the standard quad is 1 x 1 meter, while the standard plane is 10 x 10 meters.");
public static GUIContent ppdPrimitiveWidth = new GUIContent("Primitive width", "Dimensions of the primitive (with the scale of 1) to which the per-pixel displacement mapping is being applied. For example, the standard quad is 1 x 1 meter, while the standard plane is 10 x 10 meters.");
public static string tessellationModeText = "Tessellation Mode";
public static string tessellationModeStr = "Tessellation Mode";
public static readonly string[] tessellationModeNames = Enum.GetNames(typeof(TessellationMode));
public static GUIContent tessellationText = new GUIContent("Tessellation options", "Tessellation options");

Phong
}
public enum DisplacementMode
{
None,
Vertex,
Pixel,
Tessellation
}
protected MaterialProperty doubleSidedNormalMode = null;
protected const string kDoubleSidedNormalMode = "_DoubleSidedNormalMode";
protected MaterialProperty depthOffsetEnable = null;

protected const string kStencilRef = "_StencilRef";
protected MaterialProperty displacementMode = null;
protected const string kDisplacementMode = "_DisplacementMode";
protected MaterialProperty displacementLockObjectScale = null;
protected const string kDisplacementLockObjectScale = "_DisplacementLockObjectScale";
protected MaterialProperty displacementLockTilingScale = null;
protected const string kDisplacementLockTilingScale = "_DisplacementLockTilingScale";
protected MaterialProperty enablePerPixelDisplacement = null;
protected const string kEnablePerPixelDisplacement = "_EnablePerPixelDisplacement";
protected MaterialProperty ppdMinSamples = null;
protected const string kPpdMinSamples = "_PPDMinSamples";
protected MaterialProperty ppdMaxSamples = null;

protected MaterialProperty perPixelDisplacementObjectScale = null;
protected const string kPerPixelDisplacementObjectScale = "_PerPixelDisplacementObjectScale";
// Vertex displacement
protected MaterialProperty enableVertexDisplacement = null;
protected const string kEnableVertexDisplacement = "_EnableVertexDisplacement";
protected MaterialProperty vertexDisplacementObjectScale = null;
protected const string kVertexDisplacementObjectScale = "_VertexDisplacementObjectScale";
protected MaterialProperty vertexDisplacementTilingScale = null;
protected const string kVertexDisplacementTilingScale = "_VertexDisplacementTilingScale";
protected MaterialProperty ppdPrimitiveLength = null;
protected const string kPpdPrimitiveLength = "_PPDPrimitiveLength";
protected MaterialProperty ppdPrimitiveWidth = null;
protected const string kPpdPrimitiveWidth = "_PPDPrimitiveWidth";
protected MaterialProperty invPrimScale = null;
protected const string kInvPrimScale = "_InvPrimScale";
// Wind
protected MaterialProperty windEnable = null;

// MaterialID
materialID = FindProperty(kMaterialID, props, false); // LayeredLit is force to be standard for now, so materialID could not exist
displacementMode = FindProperty(kDisplacementMode, props);
displacementLockObjectScale = FindProperty(kDisplacementLockObjectScale, props);
displacementLockTilingScale = FindProperty(kDisplacementLockTilingScale, props);
enablePerPixelDisplacement = FindProperty(kEnablePerPixelDisplacement, props);
perPixelDisplacementObjectScale = FindProperty(kPerPixelDisplacementObjectScale, props);
// vertex displacement
enableVertexDisplacement = FindProperty(kEnableVertexDisplacement, props);
vertexDisplacementObjectScale = FindProperty(kVertexDisplacementObjectScale, props);
vertexDisplacementTilingScale = FindProperty(kVertexDisplacementTilingScale, props);
ppdPrimitiveLength = FindProperty(kPpdPrimitiveLength, props);
ppdPrimitiveWidth = FindProperty(kPpdPrimitiveWidth, props);
invPrimScale = FindProperty(kInvPrimScale, props);
// tessellation specific, silent if not found
tessellationMode = FindProperty(kTessellationMode, props, false);

var mode = (TessellationMode)tessellationMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (TessellationMode)EditorGUILayout.Popup(StylesBaseLit.tessellationModeText, (int)mode, StylesBaseLit.tessellationModeNames);
mode = (TessellationMode)EditorGUILayout.Popup(StylesBaseLit.tessellationModeStr, (int)mode, StylesBaseLit.tessellationModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Tessellation Mode");

if (materialID != null)
m_MaterialEditor.ShaderProperty(materialID, StylesBaseLit.materialIDText);
m_MaterialEditor.ShaderProperty(enablePerPixelDisplacement, StylesBaseLit.enablePerPixelDisplacementText);
if (enablePerPixelDisplacement.floatValue > 0.0f)
m_MaterialEditor.ShaderProperty(displacementMode, StylesBaseLit.displacementModeText);
if ((DisplacementMode)displacementMode.floatValue != DisplacementMode.None)
m_MaterialEditor.ShaderProperty(ppdMinSamples, StylesBaseLit.ppdMinSamplesText);
m_MaterialEditor.ShaderProperty(ppdMaxSamples, StylesBaseLit.ppdMaxSamplesText);
ppdMinSamples.floatValue = Mathf.Min(ppdMinSamples.floatValue, ppdMaxSamples.floatValue);
m_MaterialEditor.ShaderProperty(ppdLodThreshold, StylesBaseLit.ppdLodThresholdText);
//m_MaterialEditor.ShaderProperty(perPixelDisplacementObjectScale, StylesBaseLit.perPixelDisplacementObjectScaleText);
m_MaterialEditor.ShaderProperty(depthOffsetEnable, StylesBaseLit.depthOffsetEnableText);
m_MaterialEditor.ShaderProperty(displacementLockObjectScale, StylesBaseLit.lockWithObjectScaleText);
m_MaterialEditor.ShaderProperty(displacementLockTilingScale, StylesBaseLit.lockWithTilingRateText);
EditorGUI.indentLevel--;
// Vertex displacement options
EditorGUILayout.Space();
EditorGUILayout.LabelField(StylesBaseLit.vertexDisplacementText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(enableVertexDisplacement, StylesBaseLit.enableVertexDisplacementText);
if (enableVertexDisplacement.floatValue > 0.0f)
if ((DisplacementMode)displacementMode.floatValue == DisplacementMode.Pixel)
EditorGUILayout.Space();
m_MaterialEditor.ShaderProperty(vertexDisplacementObjectScale, StylesBaseLit.vertexDisplacementObjectScaleText);
m_MaterialEditor.ShaderProperty(vertexDisplacementTilingScale, StylesBaseLit.vertexDisplacementTilingScaleText);
m_MaterialEditor.ShaderProperty(ppdMinSamples, StylesBaseLit.ppdMinSamplesText);
m_MaterialEditor.ShaderProperty(ppdMaxSamples, StylesBaseLit.ppdMaxSamplesText);
ppdMinSamples.floatValue = Mathf.Min(ppdMinSamples.floatValue, ppdMaxSamples.floatValue);
m_MaterialEditor.ShaderProperty(ppdLodThreshold, StylesBaseLit.ppdLodThresholdText);
m_MaterialEditor.ShaderProperty(ppdPrimitiveLength, StylesBaseLit.ppdPrimitiveLength);
ppdPrimitiveLength.floatValue = Mathf.Max(0.01f, ppdPrimitiveLength.floatValue);
m_MaterialEditor.ShaderProperty(ppdPrimitiveWidth, StylesBaseLit.ppdPrimitiveWidth);
ppdPrimitiveWidth.floatValue = Mathf.Max(0.01f, ppdPrimitiveWidth.floatValue);
invPrimScale.vectorValue = new Vector4(1.0f / ppdPrimitiveLength.floatValue, 1.0f / ppdPrimitiveWidth.floatValue); // Precompute
m_MaterialEditor.ShaderProperty(depthOffsetEnable, StylesBaseLit.depthOffsetEnableText);
EditorGUI.indentLevel--;
}

}
}
// Depth offset is only enabled if per pixel displacement is
bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && (material.GetFloat(kEnablePerPixelDisplacement) > 0.0f);
SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable);
// Set the reference value for the stencil test.
int stencilRef = (int)StencilLightingUsage.RegularLighting;
if (material.HasProperty(kMaterialID))

}
material.SetInt(kStencilRef, stencilRef);
bool enablePerPixelDisplacement = material.GetFloat(kEnablePerPixelDisplacement) > 0.0f;
SetKeyword(material, "_PER_PIXEL_DISPLACEMENT", enablePerPixelDisplacement);
bool perPixelDisplacementObjectScale = material.GetFloat(kPerPixelDisplacementObjectScale) > 0.0;
SetKeyword(material, "_PER_PIXEL_DISPLACEMENT_OBJECT_SCALE", perPixelDisplacementObjectScale && enablePerPixelDisplacement);
bool enableDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) != DisplacementMode.None;
bool enableVertexDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Vertex;
bool enablePixelDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Pixel;
bool enableTessellationDisplacement = ((DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation) && material.HasProperty(kTessellationMode);
bool enableVertexDisplacement = material.GetFloat(kEnableVertexDisplacement) > 0.0f;
bool vertexDisplacementObjectScaleEnable = material.GetFloat(kVertexDisplacementObjectScale) > 0.0;
SetKeyword(material, "_VERTEX_DISPLACEMENT_OBJECT_SCALE", vertexDisplacementObjectScaleEnable && enableVertexDisplacement);
bool vertexDisplacementTilingScaleEnable = material.GetFloat(kVertexDisplacementTilingScale) > 0.0;
SetKeyword(material, "_VERTEX_DISPLACEMENT_TILING_SCALE", vertexDisplacementTilingScaleEnable && enableVertexDisplacement);
SetKeyword(material, "_PIXEL_DISPLACEMENT", enablePixelDisplacement);
// Only set if tessellation exist
SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement);
bool displacementLockObjectScale = material.GetFloat(kDisplacementLockObjectScale) > 0.0;
bool displacementLockTilingScale = material.GetFloat(kDisplacementLockTilingScale) > 0.0;
// Tessellation reuse vertex flag.
SetKeyword(material, "_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && (enableVertexDisplacement || enableTessellationDisplacement));
SetKeyword(material, "_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && enablePixelDisplacement);
SetKeyword(material, "_DISPLACEMENT_LOCK_TILING_SCALE", displacementLockTilingScale && enableDisplacement);
// Depth offset is only enabled if per pixel displacement is
bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && enablePixelDisplacement;
SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable);
if (material.HasProperty(kTessellationMode))
{
TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode);

static public void SetupBaseLitMaterialPass(Material material)
{
bool distortionEnable = material.GetFloat(kDistortionEnable) > 0.0f;
bool distortionOnly = material.GetFloat(kDistortionOnly) > 0.0f;
if (distortionEnable && distortionOnly)
{
// Disable all passes except distortion (setup in BaseUnlitUI.cs) and debug passes (to visualize distortion)
material.SetShaderPassEnabled("GBuffer", false);
material.SetShaderPassEnabled("GBufferDisplayDebug", true);
material.SetShaderPassEnabled("Meta", false);
material.SetShaderPassEnabled("ShadowCaster", false);
material.SetShaderPassEnabled("DepthOnly", false);
material.SetShaderPassEnabled("MotionVectors", false);
material.SetShaderPassEnabled("Forward", false);
material.SetShaderPassEnabled("ForwardDisplayDebug", true);
}
else
{
// Enable all passes except distortion (setup in BaseUnlitUI.cs)
material.SetShaderPassEnabled("GBuffer", true);
material.SetShaderPassEnabled("GBufferDisplayDebug", true);
material.SetShaderPassEnabled("Meta", true);
material.SetShaderPassEnabled("ShadowCaster", true);
material.SetShaderPassEnabled("DepthOnly", true);
material.SetShaderPassEnabled("MotionVectors", true);
material.SetShaderPassEnabled("Forward", true);
material.SetShaderPassEnabled("ForwardDisplayDebug", true);
}
SetupBaseUnlitMaterialPass(material);
}
}
} // namespace UnityEditor

110
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


using System;
using System;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;

public static GUIContent detailAlbedoScaleText = new GUIContent("Detail AlbedoScale", "Detail Albedo Scale factor");
public static GUIContent detailNormalScaleText = new GUIContent("Detail NormalScale", "Normal Scale factor");
public static GUIContent detailSmoothnessScaleText = new GUIContent("Detail SmoothnessScale", "Smoothness Scale factor");
public static GUIContent linkDetailsWithBaseText = new GUIContent("Lock to Base Tiling/Offset", "Lock details Tiling/Offset to Base Tiling/Offset");
// Subsurface
public static GUIContent subsurfaceProfileText = new GUIContent("Subsurface profile", "A profile determines the shape of the blur filter.");

// Transparency absorption
public static GUIContent transmittanceColorText = new GUIContent("Transmittance Color", "Absorption color (RGB)");
public static GUIContent atDistanceText = new GUIContent("Transmittance Absorption Distance", "Absorption distance reference");
public static GUIContent perPixelDisplacementDetailsWarning = new GUIContent("For pixel displacement to work correctly, details and base map must use same UV mapping");
}
// Lit shader is not layered but some layered materials inherit from it. In order to share code we need LitUI to account for this.

protected const string kUVBase = "_UVBase";
protected MaterialProperty[] TexWorldScale = new MaterialProperty[kMaxLayerCount];
protected const string kTexWorldScale = "_TexWorldScale";
protected MaterialProperty[] InvTilingScale = new MaterialProperty[kMaxLayerCount];
protected const string kInvTilingScale = "_InvTilingScale";
protected MaterialProperty[] UVMappingMask = new MaterialProperty[kMaxLayerCount];
protected const string kUVMappingMask = "_UVMappingMask";

protected const string kUVDetailsMappingMask = "_UVDetailsMappingMask";
protected MaterialProperty[] detailMap = new MaterialProperty[kMaxLayerCount];
protected const string kDetailMap = "_DetailMap";
protected MaterialProperty[] linkDetailsWithBase = new MaterialProperty[kMaxLayerCount];
protected const string kLinkDetailsWithBase = "_LinkDetailsWithBase";
protected MaterialProperty[] detailAlbedoScale = new MaterialProperty[kMaxLayerCount];
protected const string kDetailAlbedoScale = "_DetailAlbedoScale";
protected MaterialProperty[] detailNormalScale = new MaterialProperty[kMaxLayerCount];

protected MaterialProperty anisotropyMap = null;
protected const string kAnisotropyMap = "_AnisotropyMap";
protected SubsurfaceScatteringProfile subsurfaceProfile = null;
protected MaterialProperty subsurfaceProfileID = null;
protected const string kSubsurfaceProfileID = "_SubsurfaceProfile";
protected MaterialProperty subsurfaceRadius = null;

{
UVBase[i] = FindProperty(string.Format("{0}{1}", kUVBase, m_PropertySuffixes[i]), props);
TexWorldScale[i] = FindProperty(string.Format("{0}{1}", kTexWorldScale, m_PropertySuffixes[i]), props);
InvTilingScale[i] = FindProperty(string.Format("{0}{1}", kInvTilingScale, m_PropertySuffixes[i]), props);
UVMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVMappingMask, m_PropertySuffixes[i]), props);
baseColor[i] = FindProperty(string.Format("{0}{1}", kBaseColor, m_PropertySuffixes[i]), props);

// Details
UVDetail[i] = FindProperty(string.Format("{0}{1}", kUVDetail, m_PropertySuffixes[i]), props);
UVDetailsMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVDetailsMappingMask, m_PropertySuffixes[i]), props);
linkDetailsWithBase[i] = FindProperty(string.Format("{0}{1}", kLinkDetailsWithBase, m_PropertySuffixes[i]), props);
detailMap[i] = FindProperty(string.Format("{0}{1}", kDetailMap, m_PropertySuffixes[i]), props);
detailAlbedoScale[i] = FindProperty(string.Format("{0}{1}", kDetailAlbedoScale, m_PropertySuffixes[i]), props);
detailNormalScale[i] = FindProperty(string.Format("{0}{1}", kDetailNormalScale, m_PropertySuffixes[i]), props);

protected void ShaderSSSInputGUI(Material material)
{
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
var hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
var sssSettings = hdPipeline.sssSettings;
if (subsurfaceProfile == null)
if (sssSettings == null)
// Attempt to load the profile from the SSS Settings.
int profileID = (int)subsurfaceProfileID.floatValue;
if (0 <= profileID && profileID < hdPipeline.sssSettings.profiles.Length &&
hdPipeline.sssSettings.profiles[profileID] != null)
{
// This is a valid profile ID.
subsurfaceProfile = hdPipeline.sssSettings.profiles[profileID];
// Refresh the ID of the profile.
hdPipeline.sssSettings.OnValidate();
}
EditorGUILayout.HelpBox("No Subsurface Scattering Settings have been assigned to the render pipeline asset.", MessageType.Warning);
return;
subsurfaceProfile = EditorGUILayout.ObjectField(Styles.subsurfaceProfileText, subsurfaceProfile, typeof(SubsurfaceScatteringProfile), false) as SubsurfaceScatteringProfile;
// TODO: Optimize me
var profiles = hdPipeline.sssSettings.profiles;
var names = new GUIContent[profiles.Length + 1];
names[0] = new GUIContent("None");
bool validProfile = false;
var values = new int[names.Length];
values[0] = SssConstants.SSS_NEUTRAL_PROFILE_ID;
// Set the profile ID.
if (subsurfaceProfile != null)
for (int i = 0; i < profiles.Length; i++)
// Load the profile from the GUI field.
int profileID = subsurfaceProfile.settingsIndex;
names[i + 1] = new GUIContent(profiles[i].name);
values[i + 1] = i;
}
if (0 <= profileID && profileID < hdPipeline.sssSettings.profiles.Length &&
hdPipeline.sssSettings.profiles[profileID] != null &&
hdPipeline.sssSettings.profiles[profileID] == subsurfaceProfile)
{
validProfile = true;
material.SetInt("_SubsurfaceProfile", profileID);
}
else
using (var scope = new EditorGUI.ChangeCheckScope())
{
int profileID = (int)subsurfaceProfileID.floatValue;
using (new EditorGUILayout.HorizontalScope())
subsurfaceProfile = null;
Debug.LogError("The SSS Profile assigned to the material has an invalid index. First, add the Profile to the SSS Settings, and then reassign it to the material.");
EditorGUILayout.PrefixLabel(Styles.subsurfaceProfileText);
using (new EditorGUILayout.HorizontalScope())
{
profileID = EditorGUILayout.IntPopup(profileID, names, values);
if (GUILayout.Button("Goto", EditorStyles.miniButton, GUILayout.Width(50f)))
Selection.activeObject = sssSettings;
}
}
if (!validProfile)
{
// Disable SSS for this object.
material.SetInt("_SubsurfaceProfile", SssConstants.SSS_NEUTRAL_PROFILE_ID);
if (scope.changed)
subsurfaceProfileID.floatValue = profileID;
}
m_MaterialEditor.ShaderProperty(subsurfaceRadius, Styles.subsurfaceRadiusText);

if (!heightMap[layerIndex].hasMixedValue && heightMap[layerIndex].textureValue != null)
{
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
heightAmplitude[layerIndex].floatValue = (heightMax[layerIndex].floatValue - heightMin[layerIndex].floatValue) * 0.01f; // Conversion centimeters to meters.
if (EditorGUI.EndChangeCheck())
{
heightAmplitude[layerIndex].floatValue = (heightMax[layerIndex].floatValue - heightMin[layerIndex].floatValue) * 0.01f; // Conversion centimeters to meters.
}
m_MaterialEditor.ShaderProperty(heightCenter[layerIndex], Styles.heightMapCenterText);
EditorGUI.showMixedValue = false;
EditorGUI.indentLevel--;

}
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
m_MaterialEditor.ShaderProperty(UVBase[layerIndex], Styles.UVBaseMappingText);
UVBaseMapping uvBaseMapping = (UVBaseMapping)UVBase[layerIndex].floatValue;

W = (uvBaseMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;
UVMappingMask[layerIndex].colorValue = new Color(X, Y, Z, W);
if (EditorGUI.EndChangeCheck())
{
// Precompute.
InvTilingScale[layerIndex].floatValue = 2.0f / (Mathf.Abs(baseColorMap[layerIndex].textureScaleAndOffset.x) + Mathf.Abs(baseColorMap[layerIndex].textureScaleAndOffset.y));
if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar))
{
InvTilingScale[layerIndex].floatValue = InvTilingScale[layerIndex].floatValue / TexWorldScale[layerIndex].floatValue;
}
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();

else
{
m_MaterialEditor.ShaderProperty(UVDetail[layerIndex], Styles.UVDetailMappingText);
}
}
// Setup the UVSet for detail, if planar/triplanar is use for base, it will override the mapping of detail (See shader code)
X = ((UVDetailMapping)UVDetail[layerIndex].floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;

UVDetailsMappingMask[layerIndex].colorValue = new Color(X, Y, Z, W);
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(linkDetailsWithBase[layerIndex], Styles.linkDetailsWithBaseText);
EditorGUI.indentLevel--;
if ((DisplacementMode)displacementMode.floatValue == DisplacementMode.Pixel && (UVDetail[layerIndex].floatValue != UVBase[layerIndex].floatValue))
{
if (material.GetTexture(kDetailMap + m_PropertySuffixes[layerIndex]))
EditorGUILayout.HelpBox(Styles.perPixelDisplacementDetailsWarning.text, MessageType.Warning);
}
m_MaterialEditor.ShaderProperty(detailAlbedoScale[layerIndex], Styles.detailAlbedoScaleText);
m_MaterialEditor.ShaderProperty(detailNormalScale[layerIndex], Styles.detailNormalScaleText);
m_MaterialEditor.ShaderProperty(detailSmoothnessScale[layerIndex], Styles.detailSmoothnessScaleText);

// TODO: display warning if we don't have bent normal (either OS or TS) and ambient occlusion
//if (enableSpecularOcclusion.floatValue > 0.0f)
{
//EditorGUILayout.HelpBox(Styles.specularOcclusionWarning.text, MessageType.Error);
//EditorGUILayout.HelpBox(Styles.specularOcclusionWarning.text, MessageType.Error);
EditorGUI.indentLevel++;
EditorGUI.indentLevel++;
m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);
m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText);
m_MaterialEditor.ShaderProperty(albedoAffectEmissive, Styles.albedoAffectEmissiveText);

5
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs


namespace UnityEditor.Experimental.Rendering.HDPipeline
{
partial class SubsurfaceScatteringProfileEditor
public sealed partial class SubsurfaceScatteringSettingsEditor
// TODO: missing tooltips
public readonly GUIContent useDisneySSS = new GUIContent("Use Disney SSS");
public readonly GUIContent profilePreview0 = new GUIContent("Profile Preview");
public readonly GUIContent profilePreview1 = new GUIContent("Shows the fraction of light scattered from the source (center).");
public readonly GUIContent profilePreview2 = new GUIContent("The distance to the boundary of the image corresponds to the Max Radius.");

76
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


// Encode normal on 20bit with oct compression + 2bit of sign
float2 octNormalWS = PackNormalOctEncode((surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT) ? surfaceData.coatNormalWS : surfaceData.normalWS);
// To have more precision encode the sign of xy in a separate uint
uint octNormalSign = (octNormalWS.x > 0.0 ? 1 : 0) + (octNormalWS.y > 0.0 ? 2 : 0);
uint octNormalSign = (octNormalWS.x < 0.0 ? 1 : 0) | (octNormalWS.y < 0.0 ? 2 : 0);
// Store octNormalSign on two bits with perceptualRoughness
outGBuffer1 = float4(abs(octNormalWS), PackFloatInt10bit(PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness), octNormalSign, 4.0), PackMaterialId(surfaceData.materialId));

{
// Encode tangent on 16bit with oct compression
float2 octTangentWS = PackNormalOctEncode(surfaceData.tangentWS);
outGBuffer2 = float4(octTangentWS * 0.5 + 0.5, surfaceData.anisotropy, PackFloatInt8bit(surfaceData.metallic, 0.0, 4.0));
// To have more precision encode the sign of xy in a separate uint
uint octTangentSign = (octTangentWS.x < 0.0 ? 1 : 0) | (octTangentWS.y < 0.0 ? 2 : 0);
outGBuffer2 = float4(abs(octTangentWS), surfaceData.anisotropy * 0.5 + 0.5, PackFloatInt8bit(surfaceData.metallic, octTangentSign, 4.0));
}
else if (surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT)
{

int octNormalSign;
UnpackFloatInt10bit(inGBuffer1.b, 4.0, bsdfData.perceptualRoughness, octNormalSign);
inGBuffer1.r *= (octNormalSign & 1) ? 1.0 : -1.0;
inGBuffer1.g *= (octNormalSign & 2) ? 1.0 : -1.0;
inGBuffer1.r = (octNormalSign & 1) ? -inGBuffer1.r : inGBuffer1.r;
inGBuffer1.g = (octNormalSign & 2) ? -inGBuffer1.g : inGBuffer1.g;
bsdfData.normalWS = UnpackNormalOctEncode(float2(inGBuffer1.r, inGBuffer1.g));
bsdfData.roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);

else if (bsdfData.materialId == MATERIALID_LIT_ANISO && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_ANISO))
{
float metallic;
int unused;
UnpackFloatInt8bit(inGBuffer2.a, 4.0, metallic, unused);
int octTangentSign;
UnpackFloatInt8bit(inGBuffer2.a, 4.0, metallic, octTangentSign);
float3 tangentWS = UnpackNormalOctEncode(float2(inGBuffer2.rg * 2.0 - 1.0));
float anisotropy = inGBuffer2.b;
inGBuffer2.r = (octTangentSign & 1) ? -inGBuffer2.r : inGBuffer2.r;
inGBuffer2.g = (octTangentSign & 2) ? -inGBuffer2.g : inGBuffer2.g;
float3 tangentWS = UnpackNormalOctEncode(inGBuffer2.rg);
float anisotropy = inGBuffer2.b * 2 - 1;
FillMaterialIdAnisoData(bsdfData.roughness, bsdfData.normalWS, tangentWS, anisotropy, bsdfData);
}
else if (bsdfData.materialId == MATERIALID_LIT_CLEAR_COAT && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))

float NdotV; // Geometric version (could be negative)
// GGX iso
float ggxLambdaV;
float ggxPreLambdaV;
float anisoGGXLambdaV;
float anisoGGXPreLambdaV;
// Clear coat
float coatNdotV;

// Clear coat IBL
// In the case of IBL we want shift a bit the normal that are not toward the viewver to reduce artifact
float3 coatIblNormalWS = GetViewShiftedNormal(bsdfData.coatNormalWS, V, preLightData.coatNdotV, MIN_N_DOT_V);
float3 coatIblNormalWS = GetViewShiftedNormal(bsdfData.coatNormalWS, V, preLightData.coatNdotV, MIN_N_DOT_V); // Use non-clamped NdotV
float coatNdotV = max(preLightData.coatNdotV, MIN_N_DOT_V); // Use the modified (clamped) version
float theta = FastACos(preLightData.coatNdotV);
float theta = FastACosPos(coatNdotV);
float2 uv = LTC_LUT_OFFSET + LTC_LUT_SCALE * float2(0.0, theta * INV_HALF_PI); // Use Roughness of 0.0 for clearCoat roughness
// Get the inverse LTC matrix for GGX

}
preLightData.NdotV = dot(bsdfData.normalWS, V); // Store the unaltered (geometric) version
float NdotV = preLightData.NdotV;
float3 iblNormalWS = GetViewShiftedNormal(bsdfData.normalWS, V, NdotV, MIN_N_DOT_V); // Use non clamped NdotV
float3 iblNormalWS = GetViewShiftedNormal(bsdfData.normalWS, V, preLightData.NdotV, MIN_N_DOT_V); // Use non-clamped NdotV
NdotV = max(NdotV, MIN_N_DOT_V); // Use the modified (clamped) version
float NdotV = max(preLightData.NdotV, MIN_N_DOT_V); // Use the modified (clamped) version
preLightData.ggxLambdaV = GetSmithJointGGXLambdaV(NdotV, bsdfData.roughness);
preLightData.ggxPreLambdaV = GetSmithJointGGXPreLambdaV(NdotV, bsdfData.roughness);
// GGX aniso
preLightData.TdotV = 0.0;

preLightData.TdotV = dot(bsdfData.tangentWS, V);
preLightData.BdotV = dot(bsdfData.bitangentWS, V);
preLightData.anisoGGXLambdaV = GetSmithJointGGXAnisoLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// Tangent = highlight stretch (anisotropy) direction. Bitangent = grain (brush) direction.
float3 anisoIblNormalWS = GetAnisotropicModifiedNormal(bsdfData.bitangentWS, iblNormalWS, V, bsdfData.anisotropy);
preLightData.anisoGGXPreLambdaV = GetSmithJointGGXAnisoPreLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For positive anisotropy values: tangent = highlight stretch (anisotropy) direction, bitangent = grain (brush) direction.
float3 grainDirWS = (bsdfData.anisotropy >= 0) ? bsdfData.bitangentWS : bsdfData.tangentWS;
float3 anisoIblNormalWS = GetAnisotropicModifiedNormal(grainDirWS, iblNormalWS, V, abs(bsdfData.anisotropy));
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NdotV) and use iblNormalWS
// into function like GetSpecularDominantDir(). However modified normal is just a hack. The goal is just to stretch a cubemap, no accuracy here.

// Area light
// UVs for sampling the LUTs
float theta = FastACos(NdotV); // For Area light - UVs for sampling the LUTs
float theta = FastACosPos(NdotV); // For Area light - UVs for sampling the LUTs
float2 uv = LTC_LUT_OFFSET + LTC_LUT_SCALE * float2(bsdfData.perceptualRoughness, theta * INV_HALF_PI);
// Note we load the matrix transpose (avoid to have to transpose it in shader)

F *= F_Schlick(bsdfData.fresnel0, LdotH);
float Vis;
float D;
float DV;
if (bsdfData.materialId == MATERIALID_LIT_ANISO && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_ANISO))
{

bsdfData.roughnessT = ClampRoughnessForAnalyticalLights(bsdfData.roughnessT);
bsdfData.roughnessB = ClampRoughnessForAnalyticalLights(bsdfData.roughnessB);
// TODO: Do comparison between this correct version and the one from isotropic and see if there is any visual difference
DV = DV_SmithJointGGXAniso(TdotH, BdotH, NdotH,
preLightData.TdotV, preLightData.BdotV, preLightData.NdotV,
TdotL, BdotL, NdotL,
bsdfData.roughnessT, bsdfData.roughnessB
Vis = V_SmithJointGGXAnisoLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV, TdotL, BdotL, NdotL,
bsdfData.roughnessT, bsdfData.roughnessB, preLightData.anisoGGXLambdaV);
, preLightData.preLambdaV);
// TODO: Do comparison between this correct version and the one from isotropic and see if there is any visual difference
Vis = V_SmithJointGGXAniso(preLightData.TdotV, preLightData.BdotV, NdotV, TdotL, BdotL, NdotL,
bsdfData.roughnessT, bsdfData.roughnessB);
);
D = D_GGXAniso(TdotH, BdotH, NdotH, bsdfData.roughnessT, bsdfData.roughnessB);
DV = DV_SmithJointGGX(NdotH, NdotL, NdotV, bsdfData.roughness
Vis = V_SmithJointGGX(NdotL, NdotV, bsdfData.roughness, preLightData.ggxLambdaV);
, preLightData preLambdaV);
Vis = V_SmithJointGGX(NdotL, NdotV, bsdfData.roughness);
);
D = D_GGX(NdotH, bsdfData.roughness);
specularLighting += F * (Vis * D);
specularLighting += F * DV;
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
float diffuseTerm = Lambert();

float diffuseTerm = DisneyDiffuse(NdotV, NdotL, LdotH, bsdfData.perceptualRoughness);
float diffuseTerm = DisneyDiffuse(NdotV, NdotL, LdotV, bsdfData.perceptualRoughness);
#endif
diffuseLighting = bsdfData.diffuseColor * diffuseTerm;

36
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader


_HeightCenter("Height Center", Range(0.0, 1.0)) = 0.5 // In texture space
_DetailMap("DetailMap", 2D) = "black" {}
_DetailAlbedoScale("_DetailAlbedoScale", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale("_DetailAlbedoScale", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale("_DetailSmoothnessScale", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale("_DetailSmoothnessScale", Range(0.0, 2.0)) = 1
_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0
_Anisotropy("Anisotropy", Range(-1.0, 1.0)) = 0
_AnisotropyMap("AnisotropyMap", 2D) = "white" {}
_SubsurfaceProfile("Subsurface Profile", Int) = 0

[Enum(UV0, 0, Planar, 4, TriPlanar, 5)] _UVBase("UV Set for base", Float) = 0
_TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _InvTilingScale("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0
[Enum(None, 0, Vertex displacement, 1, Pixel displacement, 2)] _DisplacementMode("DisplacementMode", Int) = 0
[ToggleOff] _DisplacementLockObjectScale("displacement lock object scale", Float) = 1.0
[ToggleOff] _DisplacementLockTilingScale("displacement lock tiling scale", Float) = 1.0
[ToggleOff] _PerPixelDisplacementObjectScale("Per pixel displacement object scale", Float) = 1.0
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[HideInInspector] _InvPrimScale("Inverse primitive scale for non-planar POM", Vector) = (1, 1, 0, 0)
[ToggleOff] _LinkDetailsWithBase("LinkDetailsWithBase", Float) = 1.0
// Displacement map
[ToggleOff] _EnableVertexDisplacement("Enable vertex displacement", Float) = 0.0
[ToggleOff] _VertexDisplacementObjectScale("Vertex displacement object scale", Float) = 1.0
[ToggleOff] _VertexDisplacementTilingScale("Vertex displacement tiling height scale", Float) = 1.0
// Wind
[ToggleOff] _EnableWind("Enable Wind", Float) = 0.0

//-------------------------------------------------------------------------------------
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _VERTEX_WIND
#pragma shader_feature _ _REFRACTION_THINPLANE _REFRACTION_THICKPLANE _REFRACTION_THICKSPHERE

Pass
{
Name "ForwardDisplayDebug" // Name is not used
Tags{ "LightMode" = "ForwardDisplayDebug" } // This will be only for transparent object based on the RenderQueue index
Name "ForwardDebugDisplay" // Name is not used
Tags{ "LightMode" = "ForwardDebugDisplay" } // This will be only for transparent object based on the RenderQueue index
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]

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


builtinData.velocity = float2(0.0, 0.0);
#ifdef _DISTORTION_ON
#if (SHADERPASS == SHADERPASS_DISTORTION)
float3 distortion = SAMPLE_TEXTURE2D(_DistortionVectorMap, sampler_DistortionVectorMap, input.texCoord0).rgb;
builtinData.distortion = distortion.rg;
builtinData.distortionBlur = distortion.b;

}
#endif
// Share by Lit and LayeredLit. Return object scaling for displacement map depends if it is vertex (affect vertex displacement) or pixel displacement (affect tiling)
float3 GetDisplacementObjectScale(bool vertexDisplacement)
{
float3 objectScale = float3(1.0, 1.0, 1.0);
// TODO: This should be an uniform for the object, this code should be remove once we have it. - Workaround for now
// To handle object scaling with pixel displacement we need to multiply the view vector by the inverse scale.
// To Handle object scaling with vertex/tessellation displacement we must multiply displacement by object scale
// Currently we extract either the scale (ObjectToWorld) or the inverse scale (worldToObject) directly by taking the transform matrix
float4x4 worldTransform;
if (vertexDisplacement)
{
worldTransform = GetObjectToWorldMatrix();
}
else
{
worldTransform = GetWorldToObjectMatrix();
}
objectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
// In the specific case of pixel displacement mapping, to get a consistent behavior compare to tessellation we require to not take into account y scale if lock object scale is not enabled
#if !defined(_PIXEL_DISPLACEMENT) || (defined(_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE))
objectScale.y = length(float3(worldTransform._m10, worldTransform._m11, worldTransform._m12));
#endif
objectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
return objectScale;
}
#ifndef LAYERED_LIT_SHADER

// Be sure that the compiler is aware that we don't use UV1 to UV3 for main layer so it can optimize code
ComputeLayerTexCoord( texCoord0, texCoord1, texCoord2, texCoord3, float4(1.0, 0.0, 0.0, 0.0), _UVDetailsMappingMask,
positionWS, mappingType, _TexWorldScale, layerTexCoord);
_BaseColorMap_ST.xy, _BaseColorMap_ST.zw, _DetailMap_ST.xy, _DetailMap_ST.zw, 1.0, _LinkDetailsWithBase,
positionWS, _TexWorldScale,
mappingType, layerTexCoord);
}
// This is call only in this file

float2 uv;
};
// Calculate displacement for per vertex displacement mapping
float ComputePerPixelHeightDisplacement(float2 texOffsetCurrent, float lod, PerPixelHeightDisplacementParam param)
{
// Note: No multiply by amplitude here. This is include in the maxHeight provide to POM

#include "../../../Core/ShaderLibrary/PerPixelDisplacement.hlsl"
void ApplyDisplacementTileScale(inout float height)
{
// Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y)
// Inverse tiling scale *= (1 / _TexWorldScale) if planar or triplanar
#ifdef _DISPLACEMENT_LOCK_TILING_SCALE
height *= _InvTilingScale;
#endif
}
bool ppdEnable = false;
bool isPlanar = false;
bool isTriplanar = false;
#if defined(_PIXEL_DISPLACEMENT) && defined(_HEIGHTMAP)
// These variables are known at the compile time.
bool isPlanar = layerTexCoord.base.mappingType == UV_MAPPING_PLANAR;
bool isTriplanar = layerTexCoord.base.mappingType == UV_MAPPING_TRIPLANAR;
#if defined(_PER_PIXEL_DISPLACEMENT) && defined(_HEIGHTMAP)
// All variable are compile time value
ppdEnable = true;
isPlanar = layerTexCoord.base.mappingType == UV_MAPPING_PLANAR;
isTriplanar = layerTexCoord.base.mappingType == UV_MAPPING_TRIPLANAR;
#endif
// See comment in layered version for details
float maxHeight = GetMaxDisplacement();
ApplyDisplacementTileScale(maxHeight);
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
if (ppdEnable)
{
// See comment in layered version for details
float maxHeight = GetMaxDisplacement();
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
// TODO: precompute uvSpaceScale
float2 invPrimScale = (isPlanar || isTriplanar) ? float2(1.0, 1.0) : _InvPrimScale.xy;
float worldScale = (isPlanar || isTriplanar) ? _TexWorldScale : 1.0;
float2 uvSpaceScale = invPrimScale * _BaseColorMap_ST.xy * (worldScale * maxHeight);
float2 scaleOffsetDetails = _DetailMap_ST.xy;
PerPixelHeightDisplacementParam ppdParam;
PerPixelHeightDisplacementParam ppdParam;
float height; // final height processed
float NdotV;
float height = 0; // final height processed
float NdotV = 0;
// planar/triplanar
float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(V, uvXZ, uvXY, uvZY);
// planar/triplanar
float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(V, uvXZ, uvXY, uvZY);
// TODO: support object space planar/triplanar ?
// TODO: support object space planar/triplanar ?
// We need to calculate the texture space direction. It depends on the mapping.
if (isTriplanar)
// We need to calculate the texture space direction. It depends on the mapping.
if (isTriplanar)
{
float planeHeight;
// Perform a POM in each direction and modify appropriate texture coordinate
[branch] if (layerTexCoord.triplanarWeights.x >= 0.001)
float3 viewDirTS;
float planeHeight;
int numSteps;
// Perform a POM in each direction and modify appropriate texture coordinate
ppdParam.uv = layerTexCoord.base.uvZY;
viewDirTS = float3(V.x > 0.0 ? uvZY : -uvZY, V.x);
numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offsetZY = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, planeHeight);
ppdParam.uv = layerTexCoord.base.uvZY;
float3 viewDirTS = float3(uvZY, abs(V.x));
float3 viewDirUV = normalize(float3(viewDirTS.xy * uvSpaceScale, viewDirTS.z)); // TODO: skip normalize
float unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize
int numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, ppdParam, planeHeight);
layerTexCoord.base.uvZY += offsetZY;
layerTexCoord.details.uvZY += offsetZY;
height = layerTexCoord.triplanarWeights.x * planeHeight;
layerTexCoord.base.uvZY += offset;
layerTexCoord.details.uvZY += offset * scaleOffsetDetails;
height += layerTexCoord.triplanarWeights.x * planeHeight;
NdotV += layerTexCoord.triplanarWeights.x * viewDirTS.z;
}
ppdParam.uv = layerTexCoord.base.uvXZ;
viewDirTS = float3(V.y > 0.0 ? uvXZ : -uvXZ, V.y);
numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offsetXZ = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, planeHeight);
[branch] if (layerTexCoord.triplanarWeights.y >= 0.001)
{
ppdParam.uv = layerTexCoord.base.uvXZ;
float3 viewDirTS = float3(uvXZ, abs(V.y));
float3 viewDirUV = normalize(float3(viewDirTS.xy * uvSpaceScale, viewDirTS.z)); // TODO: skip normalize
float unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize
int numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, ppdParam, planeHeight);
layerTexCoord.base.uvXZ += offsetXZ;
layerTexCoord.details.uvXZ += offsetXZ;
layerTexCoord.base.uvXZ += offset;
layerTexCoord.details.uvXZ += offset * scaleOffsetDetails;
NdotV += layerTexCoord.triplanarWeights.y * viewDirTS.z;
}
ppdParam.uv = layerTexCoord.base.uvXY;
viewDirTS = float3(V.z > 0.0 ? uvXY : -uvXY, V.z);
numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offsetXY = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, planeHeight);
[branch] if (layerTexCoord.triplanarWeights.z >= 0.001)
{
ppdParam.uv = layerTexCoord.base.uvXY;
float3 viewDirTS = float3(uvXY, abs(V.z));
float3 viewDirUV = normalize(float3(viewDirTS.xy * uvSpaceScale, viewDirTS.z)); // TODO: skip normalize
float unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize
int numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, ppdParam, planeHeight);
layerTexCoord.base.uvXY += offsetXY;
layerTexCoord.details.uvXY += offsetXY;
layerTexCoord.base.uvXY += offset;
layerTexCoord.details.uvXY += offset * scaleOffsetDetails;
NdotV = 1; // TODO.
NdotV += layerTexCoord.triplanarWeights.z * viewDirTS.z;
else
{
ppdParam.uv = layerTexCoord.base.uv; // For planar it is uv too, not uvXZ
}
else
{
ppdParam.uv = layerTexCoord.base.uv; // For planar it is uv too, not uvXZ
float3x3 worldToTangent = input.worldToTangent;
// Note: The TBN is not normalize as it is based on mikkt. We should normalize it, but POM is always use on simple enough surfarce that mean it is not required (save 2 normalize). Tag: SURFACE_GRADIENT
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, input.worldToTangent) * GetDisplacementObjectScale(false).xzy; // Switch from Y-up to Z-up (as we move to tangent space)
NdotV = viewDirTS.z;
// Note: The TBN is not normalize as it is based on mikkt. We should normalize it, but POM is always use on simple enough surfarce that mean it is not required (save 2 normalize). Tag: SURFACE_GRADIENT
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, worldToTangent);
// Transform the view vector into the UV space.
float3 viewDirUV = normalize(float3(viewDirTS.xy * uvSpaceScale, viewDirTS.z)); // TODO: skip normalize
float unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize
int numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, ppdParam, height);
NdotV = viewDirTS.z;
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, height);
// Apply offset to all UVSet0 / planar
layerTexCoord.base.uv += offset;
layerTexCoord.details.uv += isPlanar ? offset : _UVDetailsMappingMask.x * offset; // Only apply offset if details map use UVSet0 _UVDetailsMappingMask.x will be 1 in this case, else 0
}
// Since POM "pushes" geometry inwards (rather than extrude it), { height = height - 1 }.
// Since the result is used as a 'depthOffsetVS', it needs to be positive, so we flip the sign.
float verticalDisplacement = maxHeight - height * maxHeight;
// IDEA: precompute the tiling scale? MOV-MUL vs MOV-MOV-MAX-RCP-MUL.
float tilingScale = rcp(max(_BaseColorMap_ST.x, _BaseColorMap_ST.y));
return tilingScale * verticalDisplacement / NdotV;
// Apply offset to all UVSet0 / planar
layerTexCoord.base.uv += offset;
// Note: Applying offset on detail uv is only correct if it use the same UVSet or is planar or triplanar. It is up to the user to do the correct thing.
layerTexCoord.details.uv += offset * scaleOffsetDetails;
// Since POM "pushes" geometry inwards (rather than extrude it), { height = height - 1 }.
// Since the result is used as a 'depthOffsetVS', it needs to be positive, so we flip the sign.
float verticalDisplacement = maxHeight - height * maxHeight;
return verticalDisplacement / max(NdotV, 0.001);
#else
#endif
float ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod)
float3 ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod)
#ifdef _VERTEX_DISPLACEMENT_TILING_SCALE
// When we change the tiling, we have want to conserve the ratio with the displacement (and this is consistent with per pixel displacement)
// IDEA: precompute the tiling scale? MOV-MUL vs MOV-MOV-MAX-RCP-MUL.
float tilingScale = rcp(max(_BaseColorMap_ST.x, _BaseColorMap_ST.y));
height *= tilingScale;
#endif
return height;
// Height is affected by tiling property and by object scale (depends on option).
// Apply scaling from tiling properties (TexWorldScale and tiling from BaseColor)
ApplyDisplacementTileScale(height);
// Applying scaling of the object if requested
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
float3 objectScale = GetDisplacementObjectScale(true);
// Reminder: mappingType is know statically, so code below is optimize by the compiler
// Planar and Triplanar are in world space thus it is independent of object scale
return height.xxx * ((layerTexCoord.base.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0));
#else
return height.xxx;
#endif
}
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)

#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
float3 interpolatedVertexNormal = input.worldToTangent[2].xyz;
// We perform the conversion to world of the normalTS outside of the GetSurfaceData
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders

GetBuiltinData(input, surfaceData, alpha, bentNormalWS, depthOffset, builtinData);
}
#else
#else // if LAYERED_LIT_SHADER
#define LAYERS_HEIGHTMAP_ENABLE (defined(_HEIGHTMAP0) || defined(_HEIGHTMAP1) || (_LAYER_COUNT > 2 && defined(_HEIGHTMAP2)) || (_LAYER_COUNT > 3 && defined(_HEIGHTMAP3)))
// Number of sampler are limited, we need to share sampler as much as possible with lit material
// for this we put the constraint that the sampler are the same in a layered material for all textures of the same type

#endif
// Define a helper macro
#define ADD_ZERO_IDX(Name) Name##0

// Note: Blend mask have its dedicated mapping and tiling.
// To share code, we simply call the regular code from the main layer for it then save the result, then do regular call for all layers.
ComputeLayerTexCoord0( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMaskBlendMask, _UVMappingMaskBlendMask,
positionWS, mappingType, _TexWorldScaleBlendMask, layerTexCoord, _LayerTilingBlendMask);
_LayerMaskMap_ST.xy, _LayerMaskMap_ST.zw, float2(0.0, 0.0), float2(0.0, 0.0), 1.0, false,
positionWS, _TexWorldScaleBlendMask,
mappingType, layerTexCoord);
layerTexCoord.blendMask = layerTexCoord.base0;

#endif
ComputeLayerTexCoord0( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask0, _UVDetailsMappingMask0,
positionWS, mappingType, _TexWorldScale0, layerTexCoord, 1.0
_BaseColorMap0_ST.xy, _BaseColorMap0_ST.zw, _DetailMap0_ST.xy, _DetailMap0_ST.zw, 1.0
);
, _LinkDetailsWithBase0
, positionWS, _TexWorldScale0,
mappingType, layerTexCoord);
mappingType = UV_MAPPING_UVSET;
#if defined(_LAYER_MAPPING_PLANAR1)

#endif
ComputeLayerTexCoord1( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask1, _UVDetailsMappingMask1,
positionWS, mappingType, _TexWorldScale1, layerTexCoord, tileObjectScale);
_BaseColorMap1_ST.xy, _BaseColorMap1_ST.zw, _DetailMap1_ST.xy, _DetailMap1_ST.zw, tileObjectScale, _LinkDetailsWithBase1,
positionWS, _TexWorldScale1,
mappingType, layerTexCoord);
mappingType = UV_MAPPING_UVSET;
#if defined(_LAYER_MAPPING_PLANAR2)

#endif
ComputeLayerTexCoord2( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask2, _UVDetailsMappingMask2,
positionWS, mappingType, _TexWorldScale2, layerTexCoord, tileObjectScale);
_BaseColorMap2_ST.xy, _BaseColorMap2_ST.zw, _DetailMap2_ST.xy, _DetailMap2_ST.zw, tileObjectScale, _LinkDetailsWithBase2,
positionWS, _TexWorldScale2,
mappingType, layerTexCoord);
mappingType = UV_MAPPING_UVSET;
#if defined(_LAYER_MAPPING_PLANAR3)

#endif
ComputeLayerTexCoord3( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask3, _UVDetailsMappingMask3,
positionWS, mappingType, _TexWorldScale3, layerTexCoord, tileObjectScale);
_BaseColorMap3_ST.xy, _BaseColorMap3_ST.zw, _DetailMap3_ST.xy, _DetailMap3_ST.zw, tileObjectScale, _LinkDetailsWithBase3,
positionWS, _TexWorldScale3,
mappingType, layerTexCoord);
}
// This is call only in this file

void ApplyDisplacementTileScale(inout float height0, inout float height1, inout float height2, inout float height3)
{
// When we change the tiling, we have want to conserve the ratio with the displacement (and this is consistent with per pixel displacement)
#ifdef _VERTEX_DISPLACEMENT_TILING_SCALE
#ifdef _DISPLACEMENT_LOCK_TILING_SCALE
float tileObjectScale = 1.0;
#ifdef _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE
// Extract scaling from world transform

#endif
height0 /= max(_BaseColorMap0_ST.x, _BaseColorMap0_ST.y);
// TODO: precompute all these scaling factors!
height0 *= _InvTilingScale0;
height0 *= tileObjectScale; // We only affect layer0 in case we are not in influence mode (i.e we should not change the base object)
height0 /= tileObjectScale; // We only affect layer0 in case we are not in influence mode (i.e we should not change the base object)
height1 /= tileObjectScale * max(_BaseColorMap1_ST.x, _BaseColorMap1_ST.y);
height2 /= tileObjectScale * max(_BaseColorMap2_ST.x, _BaseColorMap2_ST.y);
height3 /= tileObjectScale * max(_BaseColorMap3_ST.x, _BaseColorMap3_ST.y);
height1 = (height1 / tileObjectScale) * _InvTilingScale1;
height2 = (height2 / tileObjectScale) * _InvTilingScale2;
height3 = (height3 / tileObjectScale) * _InvTilingScale3;
#endif
}

float GetInfluenceMask(LayerTexCoord layerTexCoord, bool useLodSampling = false, float lod = 0)
{
return useLodSampling ? SAMPLE_UVMAPPING_TEXTURE2D_LOD(_LayerInfluenceMaskMap, sampler_LayerMaskMap, layerTexCoord.blendMask, lod).r : SAMPLE_UVMAPPING_TEXTURE2D(_LayerInfluenceMaskMap, sampler_LayerMaskMap, layerTexCoord.blendMask).r;
// Sample influence mask with same mapping as Main layer
return useLodSampling ? SAMPLE_UVMAPPING_TEXTURE2D_LOD(_LayerInfluenceMaskMap, sampler_LayerInfluenceMaskMap, layerTexCoord.base0, lod).r : SAMPLE_UVMAPPING_TEXTURE2D(_LayerInfluenceMaskMap, sampler_LayerInfluenceMaskMap, layerTexCoord.base0).r;
}
float GetMaxHeight(float4 heights)
{
float maxHeight = max(heights.r, heights.g);
#ifdef _LAYEREDLIT_4_LAYERS
maxHeight = max(Max3(heights.r, heights.g, heights.b), heights.a);
#endif
#ifdef _LAYEREDLIT_3_LAYERS
maxHeight = Max3(heights.r, heights.g, heights.b);
#endif
return maxHeight;
}
// Returns layering blend mask after application of height based blend.
float4 ApplyHeightBlend(float4 heights, float4 blendMask)
{
// Add offsets for all the layers.
heights = heights + float4(_HeightOffset0, _HeightOffset1, _HeightOffset2, _HeightOffset3);
// We need to mask out inactive layers so that their height does not impact the result.
float4 maskedHeights = heights * blendMask.argb;
float maxHeight = GetMaxHeight(maskedHeights);
// Make sure that transition is not zero otherwise the next computation will be wrong.
// The epsilon here also has to be bigger than the epsilon in the next computation.
float transition = max(_HeightTransition, 1e-5);
// The goal here is to have all but the highest layer at negative heights, then we add the transition so that if the next highest layer is near transition it will have a positive value.
// Then we clamp this to zero and normalize everything so that highest layer has a value of 1.
maskedHeights = maskedHeights - maxHeight.xxxx;
// We need to add an epsilon here for active layers (hence the blendMask again) so that at least a layer shows up if everything's too low.
maskedHeights = (max(0, maskedHeights + transition) + 1e-6) * blendMask.argb;
// Normalize
maxHeight = GetMaxHeight(maskedHeights);
maskedHeights = maskedHeights / maxHeight.xxxx;
return maskedHeights.yzwx;
}
// Return the maximun amplitude use by all enabled heightmap

return minUvSize;
}
#if defined(_PIXEL_DISPLACEMENT) && LAYERS_HEIGHTMAP_ENABLE
float weights[_MAX_LAYER];
float4 blendMasks;
float mainHeightInfluence;
float2 uvSpaceScale[_MAX_LAYER];
#if defined(_MAIN_LAYER_INFLUENCE_MODE) && defined(_HEIGHTMAP0)
float heightInfluence[_MAX_LAYER];
#endif
#if defined(_HEIGHTMAP0) || defined(_HEIGHTMAP1) || defined(_HEIGHTMAP2) || defined(_HEIGHTMAP3)
// Note: No multiply by amplitude here, this is bake into the weights and apply in BlendLayeredScalar
// The amplitude is normalize to be able to work with POM algorithm
// Tiling is automatically handled correctly here as we use 4 differents uv even if they come from the same UVSet (they include the tiling)
float height0 = SAMPLE_TEXTURE2D_LOD(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, param.uv[0] + texOffsetCurrent, lod).r;
float height1 = SAMPLE_TEXTURE2D_LOD(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, param.uv[1] + texOffsetCurrent, lod).r;
float height2 = SAMPLE_TEXTURE2D_LOD(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, param.uv[2] + texOffsetCurrent, lod).r;
float height3 = SAMPLE_TEXTURE2D_LOD(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, param.uv[3] + texOffsetCurrent, lod).r;
SetEnabledHeightByLayer(height0, height1, height2, height3); // Not needed as already put in weights but paranoid mode
return BlendLayeredScalar(height0, height1, height2, height3, param.weights) + height0 * param.mainHeightInfluence;
#else
return 0.0;
// See function ComputePerVertexDisplacement() for comment about the weights/influenceMask/BlendMask
// Note: Amplitude is handled in uvSpaceScale, no need to multiply by it here.
float height0 = SAMPLE_TEXTURE2D_LOD(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, param.uv[0] + texOffsetCurrent * param.uvSpaceScale[0], lod).r;
float height1 = SAMPLE_TEXTURE2D_LOD(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, param.uv[1] + texOffsetCurrent * param.uvSpaceScale[1], lod).r;
float height2 = SAMPLE_TEXTURE2D_LOD(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, param.uv[2] + texOffsetCurrent * param.uvSpaceScale[2], lod).r;
float height3 = SAMPLE_TEXTURE2D_LOD(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, param.uv[3] + texOffsetCurrent * param.uvSpaceScale[3], lod).r;
SetEnabledHeightByLayer(height0, height1, height2, height3);
float4 blendMasks = param.blendMasks;
#if defined(_HEIGHT_BASED_BLEND)
// Modify blendMask to take into account the height of the layer. Higher height should be more visible.
blendMasks = ApplyHeightBlend(float4(height0, height1, height2, height3), param.blendMasks);
#endif
float weights[_MAX_LAYER];
ComputeMaskWeights(blendMasks, weights);
#if defined(_MAIN_LAYER_INFLUENCE_MODE) && defined(_HEIGHTMAP0)
float influenceMask = blendMasks.a;
#ifdef _INFLUENCEMASK_MAP
influenceMask *= SAMPLE_TEXTURE2D_LOD(_LayerInfluenceMaskMap, sampler_BaseColorMap0, param.uv[0], lod).r;
#endif
height1 += height0 * _InheritBaseHeight1 * influenceMask;
height2 += height0 * _InheritBaseHeight2 * influenceMask;
height3 += height0 * _InheritBaseHeight3 * influenceMask;
return BlendLayeredScalar(height0, height1, height2, height3, weights);
#endif // defined(_PIXEL_DISPLACEMENT) && LAYERS_HEIGHTMAP_ENABLE
// PPD is affecting only one mapping at the same time, mean we need to execute it for each mapping (UV0, UV1, 3 times for triplanar etc..)
// We chose to not support all this case that are extremely hard to manage (for example mixing different mapping, mean it also require different tangent space that is not supported in Unity)

// - Blend Mask use same mapping as main layer (UVO, Planar, Triplanar)
// From these rules it mean that PPD is enable only if the user 1) ask for it, 2) if there is one heightmap enabled on active layer, 3) if mapping is the same for all layer respecting 2), 4) if mapping is UV0, planar or triplanar mapping
// Most contraint are handled by the inspector (i.e the UI) like the mapping constraint and is assumed in the shader.
float ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord, float influenceMask)
float ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord, float4 blendMasks)
bool ppdEnable = false;
#if defined(_PIXEL_DISPLACEMENT) && LAYERS_HEIGHTMAP_ENABLE
#ifdef _PER_PIXEL_DISPLACEMENT
ppdEnable = true;
ppdEnable = true;
isPlanar = layerTexCoord.base1.mappingType == UV_MAPPING_PLANAR;
isTriplanar = layerTexCoord.base1.mappingType == UV_MAPPING_TRIPLANAR;
#endif

ppdEnable = true;
isPlanar = layerTexCoord.base2.mappingType == UV_MAPPING_PLANAR;
isTriplanar = layerTexCoord.base2.mappingType == UV_MAPPING_TRIPLANAR;
#endif

#if defined(_HEIGHTMAP3)
ppdEnable = true;
#endif // _PER_PIXEL_DISPLACEMENT
// Compute lod as we will sample inside a loop(so can't use regular sampling)
// Note: It appear that CALCULATE_TEXTURE2D_LOD only return interger lod. We want to use float lod to have smoother transition and fading, so do our own calculation.
// Approximation of lod to used. Be conservative here, we will take the highest mip of all layers.
// Remember, we assume that we used the same mapping for all layer, so only size matter.
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
if (ppdEnable)
{
// Even if we use same mapping we can have different tiling. For per pixel displacement we will perform the ray marching with already tiled uv
float maxHeight = GetMaxDisplacement();
// Compute lod as we will sample inside a loop(so can't use regular sampling)
// Note: It appear that CALCULATE_TEXTURE2D_LOD only return interger lod. We want to use float lod to have smoother transition and fading, so do our own calculation.
// Approximation of lod to used. Be conservative here, we will take the highest mip of all layers.
// Remember, we assume that we used the same mapping for all layer, so only size matter.
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
// TODO: Here we calculate the scale transform from world to UV space , which is what we have done in GetLayerTexCoord but without the texBias.
// Mean we must also apply the same "additionalTiling", currently not apply Also precompute all this!
float maxHeight0 = abs(_HeightAmplitude0);
float maxHeight1 = abs(_HeightAmplitude1);
float maxHeight2 = abs(_HeightAmplitude2);
float maxHeight3 = abs(_HeightAmplitude3);
// Calculate blend weights
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
float weights[_MAX_LAYER];
ComputeMaskWeights(blendMasks, weights);
// Be sure we are not considering weight here were there is no heightmap
SetEnabledHeightByLayer(weights[0], weights[1], weights[2], weights[3]);
PerPixelHeightDisplacementParam ppdParam;
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
// For per pixel displacement we need to have normalized height scale to calculate the interesection (required by the algorithm we use)
// mean that we will normalize by the highest amplitude.
// We store this normalization factor with the weights as it will be multiply by the readed height.
ppdParam.weights[0] = weights[0] * (_HeightAmplitude0) / maxHeight;
ppdParam.weights[1] = weights[1] * (_HeightAmplitude1 + _HeightAmplitude0 * _InheritBaseHeight1) / maxHeight;
ppdParam.weights[2] = weights[2] * (_HeightAmplitude2 + _HeightAmplitude0 * _InheritBaseHeight2) / maxHeight;
ppdParam.weights[3] = weights[3] * (_HeightAmplitude3 + _HeightAmplitude0 * _InheritBaseHeight3) / maxHeight;
// Think that inheritbasedheight will be 0 if height0 is fully visible in weights. So there is no double contribution of height0
float mainHeightInfluence = BlendLayeredScalar(0.0, _InheritBaseHeight1, _InheritBaseHeight2, _InheritBaseHeight3, weights) * influenceMask;
ppdParam.mainHeightInfluence = mainHeightInfluence;
#else
[unroll]
for (int i = 0; i < _MAX_LAYER; ++i)
{
ppdParam.weights[i] = weights[i];
}
ppdParam.mainHeightInfluence = 0.0;
ApplyDisplacementTileScale(maxHeight0, maxHeight1, maxHeight2, maxHeight3);
#if defined(_MAIN_LAYER_INFLUENCE_MODE) && defined(_HEIGHTMAP0)
maxHeight1 += abs(_HeightAmplitude0) * _InheritBaseHeight1;
maxHeight2 += abs(_HeightAmplitude0) * _InheritBaseHeight2;
maxHeight3 += abs(_HeightAmplitude0) * _InheritBaseHeight3;
float height; // final height processed
float NdotV;
float weights[_MAX_LAYER];
ComputeMaskWeights(blendMasks, weights);
float maxHeight = BlendLayeredScalar(maxHeight0, maxHeight1, maxHeight2, maxHeight3, weights);
// planar/triplanar
float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(V, uvXZ, uvXY, uvZY);
float2 worldScale0 = (isPlanar || isTriplanar) ? _TexWorldScale0.xx : _InvPrimScale.xy;
float2 worldScale1 = (isPlanar || isTriplanar) ? _TexWorldScale1.xx : _InvPrimScale.xy;
float2 worldScale2 = (isPlanar || isTriplanar) ? _TexWorldScale2.xx : _InvPrimScale.xy;
float2 worldScale3 = (isPlanar || isTriplanar) ? _TexWorldScale3.xx : _InvPrimScale.xy;
// We need to calculate the texture space direction. It depends on the mapping.
if (isTriplanar)
{
// TODO: implement. Require 3 call to POM + dedicated viewDirTS based on triplanar convention
// apply the 3 offset on all layers
/*
ppdParam.uv[0] = layerTexCoord.base0.uvZY;
ppdParam.uv[1] = layerTexCoord.base1.uvYZ;
ppdParam.uv[2] = layerTexCoord.base2.uvYZ;
ppdParam.uv[3] = layerTexCoord.base3.uvYZ;
float3 viewDirTS = ;
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, abs(viewDirTS.z));
ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
// Apply to all uvZY
// Repeat for uvXZ
// Repeat for uvXY
// Apply to all layer that used triplanar
*/
height = 1;
NdotV = 1;
}
else
{
ppdParam.uv[0] = layerTexCoord.base0.uv;
ppdParam.uv[1] = layerTexCoord.base1.uv;
ppdParam.uv[2] = layerTexCoord.base2.uv;
ppdParam.uv[3] = layerTexCoord.base3.uv;
float3x3 worldToTangent = input.worldToTangent;
// Note: The TBN is not normalize as it is based on mikkt. We should normalize it, but POM is always use on simple enough surfarce that mean it is not required (save 2 normalize). Tag: SURFACE_GRADIENT
// For planar the view vector is the world view vector (unless we want to support object triplanar ? and in this case used TransformWorldToObject)
// TODO: do we support object triplanar ? See ComputeLayerTexCoord
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, worldToTangent);
NdotV = viewDirTS.z;
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, height);
// Apply offset to all planar UV if applicable
float4 planarWeight = float4( layerTexCoord.base0.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0,
layerTexCoord.base1.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0,
layerTexCoord.base2.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0,
layerTexCoord.base3.mappingType == UV_MAPPING_PLANAR ? 1.0 : 0.0);
PerPixelHeightDisplacementParam ppdParam;
ppdParam.blendMasks = blendMasks;
ppdParam.uvSpaceScale[0] = _BaseColorMap0_ST.xy * worldScale0;// *maxHeight0;
ppdParam.uvSpaceScale[1] = _BaseColorMap1_ST.xy * worldScale1;// *maxHeight1;
ppdParam.uvSpaceScale[2] = _BaseColorMap2_ST.xy * worldScale2;// *maxHeight2;
ppdParam.uvSpaceScale[3] = _BaseColorMap3_ST.xy * worldScale3;// *maxHeight3;
// _UVMappingMask0.x will be 1.0 is UVSet0 is used;
float4 offsetWeights = isPlanar ? planarWeight : float4(_UVMappingMask0.x, _UVMappingMask1.x, _UVMappingMask2.x, _UVMappingMask3.x);
float uvSpaceScale = BlendLayeredScalar(ppdParam.uvSpaceScale[0], ppdParam.uvSpaceScale[1], ppdParam.uvSpaceScale[2], ppdParam.uvSpaceScale[3], weights);
layerTexCoord.base0.uv += offsetWeights.x * offset;
layerTexCoord.base1.uv += offsetWeights.y * offset;
layerTexCoord.base2.uv += offsetWeights.z * offset;
layerTexCoord.base3.uv += offsetWeights.w * offset;
float2 scaleOffsetDetails0 =_DetailMap0_ST.xy;
float2 scaleOffsetDetails1 =_DetailMap1_ST.xy;
float2 scaleOffsetDetails2 =_DetailMap2_ST.xy;
float2 scaleOffsetDetails3 =_DetailMap3_ST.xy;
offsetWeights = isPlanar ? planarWeight : float4(_UVDetailsMappingMask0.x, _UVDetailsMappingMask1.x, _UVDetailsMappingMask2.x, _UVDetailsMappingMask3.x);
float height; // final height processed
float NdotV;
layerTexCoord.details0.uv += offsetWeights.x * offset;
layerTexCoord.details1.uv += offsetWeights.y * offset;
layerTexCoord.details2.uv += offsetWeights.z * offset;
layerTexCoord.details3.uv += offsetWeights.w * offset;
}
// planar/triplanar
float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(V, uvXZ, uvXY, uvZY);
// Since POM "pushes" geometry inwards (rather than extrude it), { height = height - 1 }.
// Since the result is used as a 'depthOffsetVS', it needs to be positive, so we flip the sign.
float verticalDisplacement = maxHeight - height * maxHeight;
// IDEA: precompute the tiling scale? MOV-MUL vs MOV-MOV-MAX-RCP-MUL.
float tilingScale = rcp(max(_BaseColorMap0_ST.x, _BaseColorMap0_ST.y));
return tilingScale * verticalDisplacement / max(NdotV, 0.001);
// We need to calculate the texture space direction. It depends on the mapping.
if (isTriplanar)
{
// This is not supported currently
height = 1.0;
NdotV = 1.0;
else
{
// For planar it is uv too, not uvXZ
ppdParam.uv[0] = layerTexCoord.base0.uv;
ppdParam.uv[1] = layerTexCoord.base1.uv;
ppdParam.uv[2] = layerTexCoord.base2.uv;
ppdParam.uv[3] = layerTexCoord.base3.uv;
return 0.0;
}
// Note: The TBN is not normalize as it is based on mikkt. We should normalize it, but POM is always use on simple enough surface that mean it is not required (save 2 normalize). Tag: SURFACE_GRADIENT
// Note: worldToTangent is only define for UVSet0, so we expect that layer that use POM have UVSet0
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, input.worldToTangent) * GetDisplacementObjectScale(false).xzy; // Switch from Y-up to Z-up (as we move to tangent space)
NdotV = viewDirTS.z;
float GetMaxHeight(float4 heights)
{
float maxHeight = max(heights.r, heights.g);
#ifdef _LAYEREDLIT_4_LAYERS
maxHeight = max(Max3(heights.r, heights.g, heights.b), heights.a);
#endif
#ifdef _LAYEREDLIT_3_LAYERS
maxHeight = Max3(heights.r, heights.g, heights.b);
#endif
// Transform the view vector into the UV space.
float3 viewDirUV = normalize(float3(viewDirTS.xy * maxHeight, viewDirTS.z));
float unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize
int numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, ppdParam, height);
offset *= uvSpaceScale;
return maxHeight;
}
layerTexCoord.base0.uv += offset;
layerTexCoord.base1.uv += offset;
layerTexCoord.base2.uv += offset;
layerTexCoord.base3.uv += offset;
// Returns layering blend mask after application of height based blend.
float4 ApplyHeightBlend(float4 heights, float4 blendMask)
{
// Add offsets for all the layers.
heights = heights + float4(_HeightOffset0, _HeightOffset1, _HeightOffset2, _HeightOffset3);
layerTexCoord.details0.uv += offset * scaleOffsetDetails0;
layerTexCoord.details1.uv += offset * scaleOffsetDetails1;
layerTexCoord.details2.uv += offset * scaleOffsetDetails2;
layerTexCoord.details3.uv += offset * scaleOffsetDetails3;
}
// We need to mask out inactive layers so that their height does not impact the result.
float4 maskedHeights = heights * blendMask.argb;
float maxHeight = GetMaxHeight(maskedHeights);
// Make sure that transition is not zero otherwise the next computation will be wrong.
// The epsilon here also has to be bigger than the epsilon in the next computation.
float transition = max(_HeightTransition, 1e-5);
// The goal here is to have all but the highest layer at negative heights, then we add the transition so that if the next highest layer is near transition it will have a positive value.
// Then we clamp this to zero and normalize everything so that highest layer has a value of 1.
maskedHeights = maskedHeights - maxHeight.xxxx;
// We need to add an epsilon here for active layers (hence the blendMask again) so that at least a layer shows up if everything's too low.
maskedHeights = (max(0, maskedHeights + transition) + 1e-6) * blendMask.argb;
// Normalize
maxHeight = GetMaxHeight(maskedHeights);
maskedHeights = maskedHeights / maxHeight.xxxx;
// Since POM "pushes" geometry inwards (rather than extrude it), { height = height - 1 }.
// Since the result is used as a 'depthOffsetVS', it needs to be positive, so we flip the sign. { height = -height + 1 }.
return maskedHeights.yzwx;
float verticalDisplacement = maxHeight - height * maxHeight;
return verticalDisplacement / max(NdotV, 0.001);
#else
return 0.0;
#endif
float ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod)
float3 ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod)
float4 inputBlendMasks = GetBlendMask(layerTexCoord, vertexColor, true, lod);
float weights[_MAX_LAYER];
#if defined(_HEIGHTMAP0) || defined(_HEIGHTMAP1) || defined(_HEIGHTMAP2) || defined(_HEIGHTMAP3)
#if LAYERS_HEIGHTMAP_ENABLE
ApplyDisplacementTileScale(height0, height1, height2, height3); // Only apply with per vertex displacement
// Height is affected by tiling property and by object scale (depends on option).
// Apply scaling from tiling properties (TexWorldScale and tiling from BaseColor)
ApplyDisplacementTileScale(height0, height1, height2, height3);
// Nullify height that are not used, so compiler can remove unused case
float4 resultBlendMasks = inputBlendMasks;
#if defined(_HEIGHT_BASED_BLEND)
resultBlendMasks = ApplyHeightBlend(float4(height0, height1, height2, height3), inputBlendMasks);
#endif
float4 blendMasks = GetBlendMask(layerTexCoord, vertexColor, true, lod);
#if defined(_HEIGHT_BASED_BLEND)
// Modify blendMask to take into account the height of the layer. Higher height should be more visible.
blendMasks = ApplyHeightBlend(float4(height0, height1, height2, height3), blendMasks);
#endif
ComputeMaskWeights(resultBlendMasks, weights);
float heightResult = BlendLayeredScalar(height0, height1, height2, height3, weights);
float weights[_MAX_LAYER];
ComputeMaskWeights(blendMasks, weights);
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
// Think that inheritbasedheight will be 0 if height0 is fully visible in weights. So there is no double contribution of height0
float influenceMask = GetInfluenceMask(layerTexCoord, true, lod);
float inheritBaseHeight = BlendLayeredScalar(0.0, _InheritBaseHeight1, _InheritBaseHeight2, _InheritBaseHeight3, weights);
return heightResult + height0 * inheritBaseHeight * inputBlendMasks.a * influenceMask; // We multiply by the input mask for the first layer because if the mask here is black it means that the layer is not actually underneath any visible layer so we don't want to inherit its height.
// _MAIN_LAYER_INFLUENCE_MODE is a pure visual mode that doesn't contribute to the weights of a layer
// The motivation is like this: if a layer is visible, then we will apply influence on top of it (so it is only visual).
// This is what is done for normal and baseColor and we do the same for height.
// Note that if we apply influence before ApplyHeightBlend, then have a different behavior.
#if defined(_MAIN_LAYER_INFLUENCE_MODE) && defined(_HEIGHTMAP0)
// Add main layer influence if any (simply add main layer add on other layer)
// We multiply by the input mask for the first layer (blendMask.a) because if the mask here is black it means that the layer
// is not actually underneath any visible layer so we don't want to inherit its height.
float influenceMask = blendMasks.a;
#ifdef _INFLUENCEMASK_MAP
influenceMask *= GetInfluenceMask(layerTexCoord, true, lod);
#endif
height1 += height0 * _InheritBaseHeight1 * influenceMask;
height2 += height0 * _InheritBaseHeight2 * influenceMask;
height3 += height0 * _InheritBaseHeight3 * influenceMask;
float heightResult = BlendLayeredScalar(height0, height1, height2, height3, weights).xxx;
// Applying scaling of the object if requested
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
float3 objectScale = GetDisplacementObjectScale(true);
// Reminder: mappingType is know statically, so code below is optimize by the compiler
// Planar and Triplanar are in world space thus it is independent of object scale
return heightResult.xxx * BlendLayeredVector3( ((layerTexCoord.base0.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0)),
((layerTexCoord.base1.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0)),
((layerTexCoord.base2.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0)),
((layerTexCoord.base3.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0)), weights);
#else
return heightResult.xxx;
#endif
float heightResult = 0.0;
return float3(0.0, 0.0, 0.0);
return heightResult;
}
// Calculate weights to apply to each layer

outWeights[i] = 0.0f;
}
#if defined(_DENSITY_MODE)
// Note: blendMasks.argb because a is main layer
float4 opacityAsDensity = saturate((inputAlphaMask - (float4(1.0, 1.0, 1.0, 1.0) - blendMasks.argb)) * 20.0); // 20.0 is the number of steps in inputAlphaMask (Density mask. We decided 20 empirically)

#if defined(_HEIGHT_BASED_BLEND)
#if defined(_HEIGHTMAP0) || defined(_HEIGHTMAP1) || defined(_HEIGHTMAP2) || defined(_HEIGHTMAP3)
#if LAYERS_HEIGHTMAP_ENABLE
// Height is affected by tiling property and by object scale (depends on option).
// Apply scaling from tiling properties (TexWorldScale and tiling from BaseColor)
ApplyDisplacementTileScale(height0, height1, height2, height3);
// Nullify height that are not used, so compiler can remove unused case
float4 heights = float4(height0, height1, height2, height3);
// HACK: use height0 to avoid compiler error for unused sampler - To remove when we can have a sampler without a textures
#if !defined(_PER_PIXEL_DISPLACEMENT)
// We don't use height 0 for the height blend based mode
heights.y += (heights.x * 0.0001);
#endif
// Reminder: _MAIN_LAYER_INFLUENCE_MODE is a purely visual mode, it is not take into account for the blendMasks
// As it is purely visual, it is not apply in ComputeLayerWeights
blendMasks = ApplyHeightBlend(heights, blendMasks);
#endif
// If no heightmap is set on any layer, we don't need to try and blend them based on height...
#if defined(_HEIGHT_BASED_BLEND)
// Modify blendMask to take into account the height of the layer. Higher height should be more visible.
blendMasks = ApplyHeightBlend(float4(height0, height1, height2, height3), blendMasks);
#endif
#endif
ComputeMaskWeights(blendMasks, outWeights);

ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
GetLayerTexCoord(input, layerTexCoord);
float influenceMask = 0.0f;
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
influenceMask = GetInfluenceMask(layerTexCoord);
#endif
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord, influenceMask);
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord, blendMasks);
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);

float alpha3 = GetSurfaceData3(input, layerTexCoord, surfaceData3, normalTS3, bentNormalTS3);
// Note: If per pixel displacement is enabled it mean we will fetch again the various heightmaps at the intersection location. Not sure the compiler can optimize.
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
float weights[_MAX_LAYER];
ComputeLayerWeights(input, layerTexCoord, float4(alpha0, alpha1, alpha2, alpha3), blendMasks, weights);

float3 bentNormalTS;
float3 bentNormalWS;
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
#ifdef _INFLUENCEMASK_MAP
float influenceMask = GetInfluenceMask(layerTexCoord);
#else
float influenceMask = 0.0;
#endif
if (influenceMask > 0.0f)
{
surfaceData.baseColor = ComputeMainBaseColorInfluence(influenceMask, surfaceData0.baseColor, surfaceData1.baseColor, surfaceData2.baseColor, surfaceData3.baseColor, layerTexCoord, blendMasks.a, weights);

82
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


void ADD_IDX(ComputeLayerTexCoord)( float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3, float4 uvMappingMask, float4 uvMappingMaskDetail,
float3 positionWS, int mappingType, float worldScale, inout LayerTexCoord layerTexCoord, float additionalTiling = 1.0)
void ADD_IDX(ComputeLayerTexCoord)( // Uv related parameters
float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3, float4 uvMappingMask, float4 uvMappingMaskDetails,
// scale and bias for base and detail + global tiling factor (for layered lit only)
float2 texScale, float2 texBias, float2 texScaleDetails, float2 texBiasDetails, float additionalTiling, float linkDetailsWithBase,
// parameter for planar/triplanar
float3 positionWS, float worldScale,
// mapping type and output
int mappingType, inout LayerTexCoord layerTexCoord)
{
// Handle uv0, uv1, uv2, uv3 based on _UVMappingMask weight (exclusif 0..1)
float2 uvBase = uvMappingMask.x * texCoord0 +

uvBase *= additionalTiling.xx;
float2 uvDetails = uvMappingMaskDetail.x * texCoord0 +
uvMappingMaskDetail.y * texCoord1 +
uvMappingMaskDetail.z * texCoord2 +
uvMappingMaskDetail.w * texCoord3;
float2 uvDetails = uvMappingMaskDetails.x * texCoord0 +
uvMappingMaskDetails.y * texCoord1 +
uvMappingMaskDetails.z * texCoord2 +
uvMappingMaskDetails.w * texCoord3;
uvDetails *= additionalTiling.xx;

}
// Apply tiling options
ADD_IDX(layerTexCoord.base).uv = TRANSFORM_TEX(uvBase, ADD_IDX(_BaseColorMap));
ADD_IDX(layerTexCoord.base).uv = uvBase * texScale + texBias;
ADD_IDX(layerTexCoord.details).uv = TRANSFORM_TEX(TRANSFORM_TEX(uvDetails, ADD_IDX(_BaseColorMap)), ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uv = uvDetails * texScaleDetails + texBiasDetails;
if (linkDetailsWithBase > 0.0)
{
ADD_IDX(layerTexCoord.details).uv = ADD_IDX(layerTexCoord.details).uv * texScale + texBias;
}
ADD_IDX(layerTexCoord.base).uvXZ = TRANSFORM_TEX(uvXZ, ADD_IDX(_BaseColorMap));
ADD_IDX(layerTexCoord.base).uvXY = TRANSFORM_TEX(uvXY, ADD_IDX(_BaseColorMap));
ADD_IDX(layerTexCoord.base).uvZY = TRANSFORM_TEX(uvZY, ADD_IDX(_BaseColorMap));
ADD_IDX(layerTexCoord.details).uvXZ = TRANSFORM_TEX(TRANSFORM_TEX(uvXZ, ADD_IDX(_BaseColorMap)), ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(TRANSFORM_TEX(uvXY, ADD_IDX(_BaseColorMap)), ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvZY = TRANSFORM_TEX(TRANSFORM_TEX(uvZY, ADD_IDX(_BaseColorMap)), ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.base).uvXZ = uvXZ * texScale + texBias;
ADD_IDX(layerTexCoord.base).uvXY = uvXY * texScale + texBias;
ADD_IDX(layerTexCoord.base).uvZY = uvZY * texScale + texBias;
ADD_IDX(layerTexCoord.details).uvXZ = uvXZ * texScaleDetails + texBiasDetails;
ADD_IDX(layerTexCoord.details).uvXY = uvXY * texScaleDetails + texBiasDetails;
ADD_IDX(layerTexCoord.details).uvZY = uvZY * texScaleDetails + texBiasDetails;
if (linkDetailsWithBase > 0.0)
{
ADD_IDX(layerTexCoord.details).uvXZ = ADD_IDX(layerTexCoord.details).uvXZ * texScale + texBias;
ADD_IDX(layerTexCoord.details).uvXY = ADD_IDX(layerTexCoord.details).uvXY * texScale + texBias;
ADD_IDX(layerTexCoord.details).uvZY = ADD_IDX(layerTexCoord.details).uvZY * texScale + texBias;
}
#ifdef SURFACE_GRADIENT
// This part is only relevant for normal mapping with UV_MAPPING_UVSET

uvMappingMask.z * layerTexCoord.vertexBitangentWS2 +
uvMappingMask.w * layerTexCoord.vertexBitangentWS3;
ADD_IDX(layerTexCoord.details).tangentWS = uvMappingMaskDetail.x * layerTexCoord.vertexTangentWS0 +
uvMappingMaskDetail.y * layerTexCoord.vertexTangentWS1 +
uvMappingMaskDetail.z * layerTexCoord.vertexTangentWS2 +
uvMappingMaskDetail.w * layerTexCoord.vertexTangentWS3;
ADD_IDX(layerTexCoord.details).tangentWS = uvMappingMaskDetails.x * layerTexCoord.vertexTangentWS0 +
uvMappingMaskDetails.y * layerTexCoord.vertexTangentWS1 +
uvMappingMaskDetails.z * layerTexCoord.vertexTangentWS2 +
uvMappingMaskDetails.w * layerTexCoord.vertexTangentWS3;
ADD_IDX(layerTexCoord.details).bitangentWS = uvMappingMaskDetail.x * layerTexCoord.vertexBitangentWS0 +
uvMappingMaskDetail.y * layerTexCoord.vertexBitangentWS1 +
uvMappingMaskDetail.z * layerTexCoord.vertexBitangentWS2 +
uvMappingMaskDetail.w * layerTexCoord.vertexBitangentWS3;
ADD_IDX(layerTexCoord.details).bitangentWS = uvMappingMaskDetails.x * layerTexCoord.vertexBitangentWS0 +
uvMappingMaskDetails.y * layerTexCoord.vertexBitangentWS1 +
uvMappingMaskDetails.z * layerTexCoord.vertexBitangentWS2 +
uvMappingMaskDetails.w * layerTexCoord.vertexBitangentWS3;
#endif
}

surfaceData.baseColor = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).rgb * ADD_IDX(_BaseColor).rgb;
#ifdef _DETAIL_MAP_IDX
surfaceData.baseColor *= LerpWhiteTo(2.0 * detailAlbedo, detailMask * ADD_IDX(_DetailAlbedoScale));
// we saturate to avoid to have a smoothness value above 1
surfaceData.baseColor = saturate(surfaceData.baseColor);
// Use overlay blend mode for detail abledo: (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))
float baseColorOverlay = (detailAlbedo < 0.5) ?
surfaceData.baseColor * PositivePow(2.0 * detailAlbedo, ADD_IDX(_DetailAlbedoScale)) :
1.0 - 2.0 * (1.0 - surfaceData.baseColor) * (1.0 - (detailAlbedo * ADD_IDX(_DetailAlbedoScale)));
// Lerp with details mask
surfaceData.baseColor = lerp(surfaceData.baseColor, saturate(baseColorOverlay), detailMask);
#endif
surfaceData.specularOcclusion = 1.0; // Will be setup outside of this function

#endif
#ifdef _DETAIL_MAP_IDX
surfaceData.perceptualSmoothness *= LerpWhiteTo(2.0 * detailSmoothness, detailMask * ADD_IDX(_DetailSmoothnessScale));
// we saturate to avoid to have a smoothness value above 1
surfaceData.perceptualSmoothness = saturate(surfaceData.perceptualSmoothness);
// Use overlay blend mode for detail abledo: (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))
float smoothnessOverlay = (detailSmoothness < 0.5) ?
surfaceData.perceptualSmoothness * PositivePow(2.0 * detailSmoothness, ADD_IDX(_DetailSmoothnessScale)) :
1.0 - 2.0 * (1.0 - surfaceData.baseColor) * (1.0 - (detailSmoothness * ADD_IDX(_DetailSmoothnessScale)));
// Lerp with details mask
surfaceData.perceptualSmoothness = lerp(surfaceData.perceptualSmoothness, saturate(smoothnessOverlay), detailMask);
#endif
// MaskMap is RGBA: Metallic, Ambient Occlusion (Optional), emissive Mask (Optional), Smoothness

21
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl


// Otherwise those parameters are not bound correctly at runtime.
// ===========================================================================
#ifndef LAYERED_LIT_SHADER
TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);
#ifndef LAYERED_LIT_SHADER
TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);
TEXTURE2D(_BaseColorMap);
SAMPLER2D(sampler_BaseColorMap);

PROP_DECL_TEX2D(_DetailMap);
TEXTURE2D(_LayerMaskMap);
SAMPLER2D(sampler_LayerMaskMap);
SAMPLER2D(sampler_LayerMaskMap);
SAMPLER2D(sampler_LayerInfluenceMaskMap);
#endif

// In our case we don't use such a mechanism but need to keep the code quiet. We declare the value and always enable it.
// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
float3 _EmissionColor;
float4 _InvPrimScale; // Only XY are used
// Wind
float _InitialBend;

float4 _SpecularColor;
float _TexWorldScale;
float _InvTilingScale;
float _LinkDetailsWithBase;
#else // LAYERED_LIT_SHADER

float _InheritBaseColor1;
float _InheritBaseColor2;
float _InheritBaseColor3;
float _LayerTilingBlendMask;
float4 _LayerMaskMap_ST;
PROP_DECL(float, _InvTilingScale);
PROP_DECL(float, _LinkDetailsWithBase);
#endif // LAYERED_LIT_SHADER

43
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl


float3 GetVertexDisplacement(float3 positionWS, float3 normalWS, float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3, float4 vertexColor, float3 objectScale)
float3 GetVertexDisplacement(float3 positionWS, float3 normalWS, float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3, float4 vertexColor)
{
// This call will work for both LayeredLit and Lit shader
LayerTexCoord layerTexCoord;

// TODO: do this algorithm for lod fetching as lod not available in vertex/domain shader
// http://www.sebastiansylvan.com/post/the-problem-with-tessellation-in-directx-11/
float lod = 0.0;
float height = ComputePerVertexDisplacement(layerTexCoord, vertexColor, lod);
float3 displ = height * normalWS;
// Applying scaling of the object if requested
displ *= objectScale;
return displ;
return ComputePerVertexDisplacement(layerTexCoord, vertexColor, lod) * normalWS;
void ApplyVertexModification(AttributesMesh input, float3 normalWS, float3 objectScale, inout float3 positionWS)
void ApplyVertexModification(AttributesMesh input, float3 normalWS, inout float3 positionWS)
// If tessellation is enabled we apply displacement map after tessellation
#if defined(_VERTEX_DISPLACEMENT) && !defined(TESSELLATION_ON)
#if defined(_VERTEX_DISPLACEMENT)
positionWS += GetVertexDisplacement(positionWS, normalWS,
#ifdef ATTRIBUTES_NEED_TEXCOORD0
input.uv0,

float2(0.0, 0.0),
#endif
#ifdef ATTRIBUTES_NEED_COLOR
input.color,
input.color
float4(0.0, 0.0, 0.0, 0.0),
float4(0.0, 0.0, 0.0, 0.0)
objectScale);
);
#endif
#ifdef _VERTEX_WIND

bool faceCull = false;
#ifndef _DOUBLESIDED_ON
// TODO: Handle inverse culling (for mirror)!
faceCull = BackFaceCullTriangle(p0, p1, p2, _TessellationBackFaceCullEpsilon, GetCurrentViewPosition()); // Use shadow view
// Handle transform mirroring (like negative scaling)
// Caution: don't change p1/p2 directly as it is use later
float3 backfaceP1 = unity_WorldTransformParams.w < 0.0 ? p2 : p1;
float3 backfaceP2 = unity_WorldTransformParams.w < 0.0 ? p1 : p2;
faceCull = BackFaceCullTriangle(p0, backfaceP1, backfaceP2, _TessellationBackFaceCullEpsilon, GetCurrentViewPosition()); // Use shadow view
}
#endif

// y - 2->0 edge
// z - 0->1 edge
// w - inside tessellation factor
void ApplyTessellationModification(VaryingsMeshToDS input, float3 normalWS, float3 objectScale, inout float3 positionWS)
void ApplyTessellationModification(VaryingsMeshToDS input, float3 normalWS, inout float3 positionWS)
#if defined(_VERTEX_DISPLACEMENT)
#if defined(_TESSELLATION_DISPLACEMENT)
positionWS += GetVertexDisplacement(positionWS, normalWS,
#ifdef VARYINGS_DS_NEED_TEXCOORD0
input.texCoord0,

float2(0.0, 0.0),
#endif
#ifdef VARYINGS_DS_NEED_COLOR
input.color,
input.color
float4(0.0, 0.0, 0.0, 0.0),
float4(0.0, 0.0, 0.0, 0.0)
objectScale);
#endif // _VERTEX_DISPLACEMENT
);
#endif // _TESSELLATION_DISPLACEMENT
}
#endif // #ifdef TESSELLATION_ON

38
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader


_HeightMax("Heightmap Max", Float) = 1
_DetailMap("DetailMap", 2D) = "black" {}
_DetailAlbedoScale("_DetailAlbedoScale", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale("_DetailAlbedoScale", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale("_DetailSmoothnessScale", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale("_DetailSmoothnessScale", Range(0.0, 2.0)) = 1
_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0
_Anisotropy("Anisotropy", Range(-1.0, 1.0)) = 0
_AnisotropyMap("AnisotropyMap", 2D) = "white" {}
_SubsurfaceProfile("Subsurface Profile", Int) = 0

[Enum(UV0, 0, Planar, 4, TriPlanar, 5)] _UVBase("UV Set for base", Float) = 0
_TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _InvTilingScale("Inverse tiling scale = 2 / (abs(_BaseColorMap_ST.x) + abs(_BaseColorMap_ST.y))", Float) = 1
[ToggleOff] _EnablePerPixelDisplacement("Enable per pixel displacement", Float) = 0.0
[Enum(None, 0, Vertex displacement, 1, Pixel displacement, 2, Tessellation displacement, 3)] _DisplacementMode("DisplacementMode", Int) = 0
[ToggleOff] _DisplacementLockObjectScale("displacement lock object scale", Float) = 1.0
[ToggleOff] _DisplacementLockTilingScale("displacement lock tiling scale", Float) = 1.0
[ToggleOff] _PerPixelDisplacementObjectScale("Per pixel displacement object scale", Float) = 1.0
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[HideInInspector] _InvPrimScale("Inverse primitive scale for non-planar POM", Vector) = (1, 1, 0, 0)
[ToggleOff] _LinkDetailsWithBase("LinkDetailsWithBase", Float) = 1.0
// Displacement map
[ToggleOff] _EnableVertexDisplacement("Enable vertex displacement", Float) = 0.0
[ToggleOff] _VertexDisplacementObjectScale("Vertex displacement object scale", Float) = 1.0
[ToggleOff] _VertexDisplacementTilingScale("Vertex displacement tiling height scale", Float) = 1.0
// Wind
[ToggleOff] _EnableWind("Enable Wind", Float) = 0.0
_InitialBend("Initial Bend", float) = 1.0

//-------------------------------------------------------------------------------------
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT _TESSELLATION_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _TESSELLATION_PHONG
#pragma shader_feature _ _TESSELLATION_PHONG
#pragma shader_feature _ _MAPPING_PLANAR _MAPPING_TRIPLANAR
#pragma shader_feature _NORMALMAP_TANGENT_SPACE

Pass
{
Name "ForwardDisplayDebug" // Name is not used
Tags{ "LightMode" = "ForwardDisplayDebug" } // This will be only for transparent object based on the RenderQueue index
Name "ForwardDebugDisplay" // Name is not used
Tags{ "LightMode" = "ForwardDebugDisplay" } // This will be only for transparent object based on the RenderQueue index
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]

6
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitDepthPass.hlsl


#endif
// Attributes
#define REQUIRE_TANGENT_TO_WORLD (defined(_HEIGHTMAP) && defined(_PER_PIXEL_DISPLACEMENT))
#define REQUIRE_TANGENT_TO_WORLD defined(_PIXEL_DISPLACEMENT)
#define REQUIRE_VERTEX_COLOR (defined(_VERTEX_DISPLACEMENT) && defined(LAYERED_LIT_SHADER) && (defined(_LAYER_MASK_VERTEX_COLOR_MUL) || defined(_LAYER_MASK_VERTEX_COLOR_ADD))) || defined(_VERTEX_WIND)
#define REQUIRE_VERTEX_COLOR ((defined(_VERTEX_DISPLACEMENT) || defined(_TESSELLATION_DISPLACEMENT)) && defined(LAYERED_LIT_SHADER) && (defined(_LAYER_MASK_VERTEX_COLOR_MUL) || defined(_LAYER_MASK_VERTEX_COLOR_ADD))) || defined(_VERTEX_WIND)
// This first set of define allow to say which attributes will be use by the mesh in the vertex and domain shader (for tesselation)

// If we have a layered shader, any UV can be use for this. To reduce the number of variant we groupt UV0/UV1 and UV2/UV3 instead of having variant for UV0/UV1/UV2/UV3
// When UVX is present, we assume that UVX - 1 ... UV0 is present
#if defined(_VERTEX_DISPLACEMENT) || REQUIRE_TANGENT_TO_WORLD || defined(_ALPHATEST_ON)
#if defined(_VERTEX_DISPLACEMENT) || REQUIRE_TANGENT_TO_WORLD || defined(_ALPHATEST_ON) || defined(_TESSELLATION_DISPLACEMENT)
#define ATTRIBUTES_NEED_TEXCOORD0
#ifdef LAYERED_LIT_SHADER
#define ATTRIBUTES_NEED_TEXCOORD1

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitDistortionPass.hlsl


#endif
// Attributes
#define REQUIRE_UV_FOR_TESSELATION (defined(TESSELLATION_ON) && (defined(_TESSELLATION_DISPLACEMENT) || defined(_TESSELLATION_DISPLACEMENT_PHONG)))
#define REQUIRE_UV_FOR_TESSELATION (defined(TESSELLATION_ON) && defined(_TESSELLATION_DISPLACEMENT))
#define REQUIRE_TANGENT_TO_WORLD (defined(_HEIGHTMAP) && defined(_PER_PIXEL_DISPLACEMENT))
#define REQUIRE_TANGENT_TO_WORLD (defined(_HEIGHTMAP) && defined(_PIXEL_DISPLACEMENT))
// This first set of define allow to say which attributes will be use by the mesh in the vertex and domain shader (for tesselation)

// If we have a layered shader, any UV can be use for this. To reduce the number of variant we groupt UV0/UV1 and UV2/UV3 instead of having variant for UV0/UV1/UV2/UV3
// When UVX is present, we assume that UVX - 1 ... UV0 is present
#if REQUIRE_UV_FOR_TESSELATION || REQUIRE_TANGENT_TO_WORLD || defined(_ALPHATEST_ON) || defined(_DISTORTION_ON)
#if REQUIRE_UV_FOR_TESSELATION || REQUIRE_TANGENT_TO_WORLD || defined(_ALPHATEST_ON)
#ifdef LAYERED_LIT_SHADER
#define ATTRIBUTES_NEED_TEXCOORD1
#if defined(_REQUIRE_UV2) || defined(_REQUIRE_UV3)

#define VARYINGS_NEED_TANGENT_TO_WORLD
#endif
#if REQUIRE_TANGENT_TO_WORLD || defined(_ALPHATEST_ON) || defined(_DISTORTION_ON)
#if REQUIRE_TANGENT_TO_WORLD || defined(_ALPHATEST_ON)
#ifdef LAYERED_LIT_SHADER
#define VARYINGS_NEED_TEXCOORD1
#if defined(_REQUIRE_UV2) || defined(_REQUIRE_UV3)

6
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitVelocityPass.hlsl


// conflict with the normal in the semantic. This need to be fix! Also no per pixel displacement is possible either.
// Attributes
#define REQUIRE_TANGENT_TO_WORLD 0 /* (defined(_HEIGHTMAP) && defined(_PER_PIXEL_DISPLACEMENT)) */
#define REQUIRE_TANGENT_TO_WORLD 0 /* defined(_PIXEL_DISPLACEMENT) */
#define REQUIRE_VERTEX_COLOR (defined(_VERTEX_DISPLACEMENT) && defined(LAYERED_LIT_SHADER) && (defined(_LAYER_MASK_VERTEX_COLOR_MUL) || defined(_LAYER_MASK_VERTEX_COLOR_ADD))) || defined(_VERTEX_WIND)
#define REQUIRE_VERTEX_COLOR ((defined(_VERTEX_DISPLACEMENT) || defined(_TESSELLATION_DISPLACEMENT)) && defined(LAYERED_LIT_SHADER) && (defined(_LAYER_MASK_VERTEX_COLOR_MUL) || defined(_LAYER_MASK_VERTEX_COLOR_ADD))) || defined(_VERTEX_WIND)
// This first set of define allow to say which attributes will be use by the mesh in the vertex and domain shader (for tesselation)

// If we have a layered shader, any UV can be use for this. To reduce the number of variant we groupt UV0/UV1 and UV2/UV3 instead of having variant for UV0/UV1/UV2/UV3
// When UVX is present, we assume that UVX - 1 ... UV0 is present
#if defined(_VERTEX_DISPLACEMENT) || REQUIRE_TANGENT_TO_WORLD || defined(_ALPHATEST_ON)
#if defined(_VERTEX_DISPLACEMENT) || REQUIRE_TANGENT_TO_WORLD || defined(_ALPHATEST_ON) || defined(_TESSELLATION_DISPLACEMENT)
#define ATTRIBUTES_NEED_TEXCOORD0
#ifdef LAYERED_LIT_SHADER
#define ATTRIBUTES_NEED_TEXCOORD1

107
ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs


using System;
using UnityEngine;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{

public static GUIContent alphaCutoffEnableText = new GUIContent("Alpha Cutoff Enable", "Threshold for alpha cutoff");
public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
public static GUIContent alphaCutoffShadowText = new GUIContent("Alpha Cutoff Shadow", "Threshold for alpha cutoff in case of shadow pass");
public static GUIContent alphaCutoffPrepassText = new GUIContent("Alpha Cutoff Prepass", "Threshold for alpha cutoff in case of depth prepass");
public static GUIContent transparentDepthPrepassEnableText = new GUIContent("Enable transparent depth prepass", "It allow to ");
public static GUIContent doubleSidedEnableText = new GUIContent("Double Sided", "This will render the two face of the objects (disable backface culling) and flip/mirror normal");
public static GUIContent distortionEnableText = new GUIContent("Distortion", "Enable distortion on this shader");
public static GUIContent distortionOnlyText = new GUIContent("Distortion Only", "This shader will only be use to render distortion");

protected const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
protected MaterialProperty alphaCutoff = null;
protected const string kAlphaCutoff = "_AlphaCutoff";
protected MaterialProperty alphaCutoffShadow = null;
protected const string kAlphaCutoffShadow = "_AlphaCutoffShadow";
protected MaterialProperty alphaCutoffPrepass = null;
protected const string kAlphaCutoffPrepass = "_AlphaCutoffPrepass";
protected MaterialProperty transparentDepthPrepassEnable = null;
protected const string kTransparentDepthPrepassEnable = "_TransparentDepthPrepassEnable";
protected MaterialProperty doubleSidedEnable = null;
protected const string kDoubleSidedEnable = "_DoubleSidedEnable";
protected MaterialProperty blendMode = null;

surfaceType = FindProperty(kSurfaceType, props);
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props);
alphaCutoff = FindProperty(kAlphaCutoff, props);
alphaCutoffShadow = FindProperty(kAlphaCutoffShadow, props, false);
alphaCutoffPrepass = FindProperty(kAlphaCutoffPrepass, props, false);
transparentDepthPrepassEnable = FindProperty(kTransparentDepthPrepassEnable, props, false);
doubleSidedEnable = FindProperty(kDoubleSidedEnable, props);
blendMode = FindProperty(kBlendMode, props);
distortionEnable = FindProperty(kDistortionEnable, props, false);

if (distortionEnable.floatValue == 1.0f)
{
EditorGUI.indentLevel++;
EditorGUI.indentLevel--;
}
}
}

EditorGUI.indentLevel++;
// With transparent object and few specific materials like Hair, we need more control on the cutoff to apply
// This allow to get a better sorting (with prepass), better shadow (better silouhette fidelity) etc...
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{
if (alphaCutoffShadow != null)
{
m_MaterialEditor.ShaderProperty(alphaCutoffShadow, StylesBaseUnlit.alphaCutoffShadowText);
}
if (transparentDepthPrepassEnable != null)
{
m_MaterialEditor.ShaderProperty(transparentDepthPrepassEnable, StylesBaseUnlit.transparentDepthPrepassEnableText);
if (transparentDepthPrepassEnable.floatValue == 1.0f)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(alphaCutoffPrepass, StylesBaseUnlit.alphaCutoffPrepassText);
EditorGUI.indentLevel--;
}
}
}
EditorGUI.indentLevel--;
}
// This function must finish with double sided option (see LitUI.cs)
m_MaterialEditor.ShaderProperty(doubleSidedEnable, StylesBaseUnlit.doubleSidedEnableText);

SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
if (material.HasProperty(kDistortionEnable))
{
bool distortionEnable = material.GetFloat(kDistortionEnable) > 0.0f;
if (distortionEnable)
{
material.SetShaderPassEnabled("DistortionVectors", true);
}
else
{
material.SetShaderPassEnabled("DistortionVectors", false);
}
{
bool distortionDepthTest = material.GetFloat(kDistortionDepthTest) > 0.0f;
if (distortionDepthTest)
{

{
material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.Always);
}
SetKeyword(material, "_DISTORTION_ON", distortionEnable);
}
// A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect

if (material.HasProperty(kDistortionEnable))
{
bool distortionEnable = material.GetFloat(kDistortionEnable) > 0.0f;
bool distortionOnly = material.GetFloat(kDistortionOnly) > 0.0f;
bool distortionOnly = false;
if (material.HasProperty(kDistortionOnly))
{
distortionOnly = material.GetFloat(kDistortionOnly) > 0.0f;
}
// If distortion only is enabled, disable all passes (except distortion and debug)
bool enablePass = !(distortionEnable && distortionOnly);
// Disable all passes except distortion
// Distortion is setup in code above
material.SetShaderPassEnabled(HDShaderPassNames.s_ForwardStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_ForwardDebugDisplayStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_DepthOnlyStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_ForwardOnlyOpaqueDepthOnlyStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_ForwardOnlyOpaqueStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_ForwardOnlyOpaqueDebugDisplayStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_GBufferStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_GBufferWithPrepassStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_GBufferDebugDisplayStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MotionVectorsStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_DistortionVectorsStr, distortionEnable); // note: use distortionEnable
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentDepthPrepassStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_MetaStr, enablePass);
material.SetShaderPassEnabled(HDShaderPassNames.s_ShadowCasterStr, enablePass);
}
if (distortionEnable && distortionOnly)
if (material.HasProperty(kTransparentDepthPrepassEnable))
{
bool depthWriteEnable = (material.GetFloat(kTransparentDepthPrepassEnable) > 0.0f) && ((SurfaceType)material.GetFloat(kSurfaceType) == SurfaceType.Transparent);
if (depthWriteEnable)
// Disable all passes except debug material
material.SetShaderPassEnabled("GBuffer", false);
material.SetShaderPassEnabled("DebugViewMaterial", true);
material.SetShaderPassEnabled("Meta", false);
material.SetShaderPassEnabled("ShadowCaster", false);
material.SetShaderPassEnabled("DepthOnly", false);
material.SetShaderPassEnabled("MotionVectors", false);
material.SetShaderPassEnabled("Forward", false);
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentDepthPrepassStr, true);
material.SetShaderPassEnabled("GBuffer", true);
material.SetShaderPassEnabled("DebugViewMaterial", true);
material.SetShaderPassEnabled("Meta", true);
material.SetShaderPassEnabled("ShadowCaster", true);
material.SetShaderPassEnabled("DepthOnly", true);
material.SetShaderPassEnabled("MotionVectors", true);
material.SetShaderPassEnabled("Forward", true);
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentDepthPrepassStr, false);
}
}
}

EditorGUILayout.Space();
EditorGUILayout.LabelField(StylesBaseUnlit.advancedText, EditorStyles.boldLabel);
// NB renderqueue editor is not shown on purpose: we want to override it based on blend mode
// NB RenderQueue editor is not shown on purpose: we want to override it based on blend mode
EditorGUI.indentLevel++;
m_MaterialEditor.EnableInstancingField();
m_MaterialEditor.DoubleSidedGIField();

7
ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader


//-------------------------------------------------------------------------------------
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON
// #pragma shader_feature _DOUBLESIDED_ON - We have no lighting, so no need to have this combination for shader, the option will just disable backface culling
#pragma shader_feature _EMISSIVE_COLOR_MAP

Pass
{
Name "ForwardUnlit"
Tags { "LightMode" = "ForwardDisplayDebug" }
Name "ForwardDebugDisplay"
Tags { "LightMode" = "ForwardDebugDisplay" }
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]

Pass
{
Name "ForwardUnlit"
Tags { "LightMode" = "ForwardOnlyOpaqueDisplayDebug" }
Tags { "LightMode" = "ForwardOnlyOpaqueDebugDisplay" }
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/UnlitData.hlsl


builtinData.velocity = float2(0.0, 0.0);
#ifdef _DISTORTION_ON
#if (SHADERPASS == SHADERPASS_DISTORTION)
float3 distortion = SAMPLE_TEXTURE2D(_DistortionVectorMap, sampler_DistortionVectorMap, input.texCoord0).rgb;
builtinData.distortion = distortion.rg;
builtinData.distortionBlur = distortion.b;

9
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/TessellationShare.hlsl


#endif
#ifdef HAVE_TESSELLATION_MODIFICATION
// TODO: This should be an uniform for the object, this code should be remove (and is specific to Lit.shader) once we have it. - Workaround for now
// Extract scaling from world transform
#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
float3 objectScale = varying.vmesh.objectScale;
#else
float3 objectScale = float3(1.0, 1.0, 1.0);
#endif
ApplyTessellationModification(varying.vmesh, varying.vmesh.normalWS, objectScale, varying.vmesh.positionWS);
ApplyTessellationModification(varying.vmesh, varying.vmesh.normalWS, varying.vmesh.positionWS);
#endif
return VertTesselation(varying);

19
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VaryingMesh.hlsl


#ifdef VARYINGS_DS_NEED_COLOR
float4 color;
#endif
#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
float3 objectScale;
#endif
};
struct PackedVaryingsMeshToDS

#ifdef VARYINGS_DS_NEED_COLOR
float4 interpolators5 : TEXCOORD2;
#endif
#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
float3 interpolators6 : TEXCOORD3;
#endif
};
// Functions to pack data to use as few interpolator as possible, the ShaderGraph should generate these functions

#endif
#ifdef VARYINGS_DS_NEED_COLOR
output.interpolators5 = input.color;
#endif
#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
output.interpolators6 = input.objectScale;
#endif
return output;

#ifdef VARYINGS_DS_NEED_COLOR
output.color = input.interpolators5;
#endif
#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
output.objectScale = input.interpolators6;
#endif
return output;
}

#endif
#ifdef VARYINGS_DS_NEED_COLOR
TESSELLATION_INTERPOLATE_BARY(color, baryCoords);
#endif
#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
// objectScale doesn't change for the whole object.
ouput.objectScale = input0.objectScale;
#endif
return ouput;

20
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VertMesh.hlsl


float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
#endif
// TODO: This should be an uniform for the object, this code should be remove (and is specific to Lit.shader) once we have it. - Workaround for now
// Extract scaling from world transform
#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
float3 objectScale;
float4x4 worldTransform = GetObjectToWorldMatrix();
objectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
objectScale.y = length(float3(worldTransform._m10, worldTransform._m11, worldTransform._m12));
objectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
#else
float3 objectScale = float3(1.0, 1.0, 1.0);
#endif
ApplyVertexModification(input, normalWS, objectScale, positionWS);
ApplyVertexModification(input, normalWS, positionWS);
#endif
positionWS = GetCameraRelativePositionWS(positionWS);

#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
// TODO: This should be an uniform for the object, this code should be remove (and is specific to Lit.shader) once we have it. - Workaround for now
output.objectScale = objectScale;
#endif
#if SHADERPASS == SHADERPASS_VELOCITY
#if (SHADERPASS == SHADERPASS_VELOCITY)
output.normalWS = float3(0.0, 0.0, 1.0);
#else
output.normalWS = normalWS;

9
ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs


public class HDRISkyRenderer : SkyRenderer
{
Material m_SkyHDRIMaterial; // Renders a cubemap into a render texture (can be cube or 2D)
private HDRISkySettings m_HdriSkyParams;
MaterialPropertyBlock m_PropertyBlock;
HDRISkySettings m_HdriSkyParams;
m_PropertyBlock = new MaterialPropertyBlock();
}
public override void Build()

m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(m_HdriSkyParams.exposure, m_HdriSkyParams.multiplier, m_HdriSkyParams.rotation, 0.0f));
// This matrix needs to be updated at the draw call frequency.
MaterialPropertyBlock properties = new MaterialPropertyBlock();
properties.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);
m_PropertyBlock.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);
CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, properties, renderForCubemap ? 0 : 1);
CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, m_PropertyBlock, renderForCubemap ? 0 : 1);
}
public override bool IsSkyValid()

16
ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkySettings.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[DisallowMultipleComponent]
public class HDRISkySettings
: SkySettings
public class HDRISkySettings : SkySettings
}
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
hash = skyHDRI != null ? hash * 23 + skyHDRI.GetHashCode() : hash;
}
return hash;
}
}
}

41
ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkySettings.cs


{
return new ProceduralSkyRenderer(this);
}
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
hash = hash * 23 + worldMieColorIntensity.GetHashCode();
hash = worldMieColorRamp != null ? hash * 23 + worldMieColorRamp.GetHashCode() : hash;
hash = hash * 23 + worldMieDensity.GetHashCode();
hash = hash * 23 + worldMieExtinctionFactor.GetHashCode();
hash = hash * 23 + worldMieNearScatterPush.GetHashCode();
hash = hash * 23 + worldMiePhaseAnisotropy.GetHashCode();
hash = hash * 23 + worldNormalDistance.GetHashCode();
hash = hash * 23 + worldRayleighColorIntensity.GetHashCode();
hash = worldRayleighColorRamp != null ? hash * 23 + worldRayleighColorRamp.GetHashCode() : hash;
hash = hash * 23 + worldRayleighDensity.GetHashCode();
hash = hash * 23 + worldRayleighExtinctionFactor.GetHashCode();
hash = hash * 23 + worldRayleighIndirectScatter.GetHashCode();
hash = hash * 23 + worldRayleighNearScatterPush.GetHashCode();
hash = hash * 23 + heightDistance.GetHashCode();
hash = hash * 23 + heightExtinctionFactor.GetHashCode();
hash = hash * 23 + heightMieDensity.GetHashCode();
hash = hash * 23 + heightMieNearScatterPush.GetHashCode();
hash = hash * 23 + heightNormalDistance.GetHashCode();
hash = hash * 23 + heightPlaneShift.GetHashCode();
hash = hash * 23 + heightRayleighColor.GetHashCode();
hash = hash * 23 + heightRayleighDensity.GetHashCode();
hash = hash * 23 + heightRayleighIntensity.GetHashCode();
hash = hash * 23 + heightRayleighNearScatterPush.GetHashCode();
hash = hash * 23 + heightSeaLevel.GetHashCode();
hash = skyHDRI != null ? hash * 23 + skyHDRI.GetHashCode() : hash;
hash = hash * 23 + worldScaleExponent.GetHashCode();
hash = hash * 23 + maxSkyDistance.GetHashCode();
hash = hash * 23 + debugMode.GetHashCode();
}
return hash;
}
}
}

49
ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs


{
public class IBLFilterGGX
{
RenderTexture m_GgxIblSampleData = null;
int k_GgxIblMaxSampleCount = TextureCache.isMobileBuildTarget ? 34 : 89; // Width
RenderTexture m_GgxIblSampleData;
int m_GgxIblMaxSampleCount = TextureCache.isMobileBuildTarget ? 34 : 89; // Width
ComputeShader m_ComputeGgxIblSampleDataCS = null;
ComputeShader m_ComputeGgxIblSampleDataCS;
ComputeShader m_BuildProbabilityTablesCS = null;
ComputeShader m_BuildProbabilityTablesCS;
Material m_GgxConvolveMaterial = null; // Convolves a cubemap with GGX
Material m_GgxConvolveMaterial; // Convolves a cubemap with GGX
bool m_SupportMIS = !TextureCache.isMobileBuildTarget;
RenderPipelineResources m_RenderPipelinesResources;
RenderPipelineResources m_RenderPipelinesResources;
public bool supportMis
{
get { return !TextureCache.isMobileBuildTarget; }
}
public IBLFilterGGX(RenderPipelineResources renderPipelinesResources)
{

return m_GgxIblSampleData != null;
}
public bool SupportMIS
{
get { return m_SupportMIS; }
}
public void Initialize(CommandBuffer cmd)
{
if (!m_ComputeGgxIblSampleDataCS)

}
if (!m_BuildProbabilityTablesCS && SupportMIS)
if (!m_BuildProbabilityTablesCS && supportMis)
{
m_BuildProbabilityTablesCS = m_RenderPipelinesResources.buildProbabilityTables;
m_ConditionalDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeConditionalDensities");

if (!m_GgxIblSampleData)
{
m_GgxIblSampleData = new RenderTexture(k_GgxIblMaxSampleCount, k_GgxIblMipCountMinusOne, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
m_GgxIblSampleData = new RenderTexture(m_GgxIblMaxSampleCount, k_GgxIblMipCountMinusOne, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
m_GgxIblSampleData.useMipMap = false;
m_GgxIblSampleData.autoGenerateMips = false;
m_GgxIblSampleData.enableRandomWrite = true;

for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
{
string sampleName = String.Format("Filter Cubemap Mip {0}", mip);
cmd.BeginSample(sampleName);
for (int face = 0; face < 6; ++face)
using (new ProfilingSample(cmd, "Filter Cubemap Mip {0}", mip))
Vector4 faceSize = new Vector4(source.width >> mip, source.height >> mip, 1.0f / (source.width >> mip), 1.0f / (source.height >> mip));
Matrix4x4 transform = SkyManager.ComputePixelCoordToWorldSpaceViewDirectionMatrix(0.5f * Mathf.PI, faceSize, worldToViewMatrices[face], true);
for (int face = 0; face < 6; ++face)
{
var faceSize = new Vector4(source.width >> mip, source.height >> mip, 1.0f / (source.width >> mip), 1.0f / (source.height >> mip));
var transform = SkyManager.ComputePixelCoordToWorldSpaceViewDirectionMatrix(0.5f * Mathf.PI, faceSize, worldToViewMatrices[face], true);
MaterialPropertyBlock props = new MaterialPropertyBlock();
props.SetFloat("_Level", mip);
props.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, transform);
var props = new MaterialPropertyBlock();
props.SetFloat("_Level", mip);
props.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, transform);
CoreUtils.SetRenderTarget(cmd, target, ClearFlag.None, mip, (CubemapFace)face);
CoreUtils.DrawFullScreen(cmd, m_GgxConvolveMaterial, props);
CoreUtils.SetRenderTarget(cmd, target, ClearFlag.None, mip, (CubemapFace)face);
CoreUtils.DrawFullScreen(cmd, m_GgxConvolveMaterial, props);
}
cmd.EndSample(sampleName);
}
}

178
ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs


public class SkyManager
{
RenderTexture m_SkyboxCubemapRT = null;
RenderTexture m_SkyboxGGXCubemapRT = null;
RenderTexture m_SkyboxMarginalRowCdfRT = null;
RenderTexture m_SkyboxConditionalCdfRT = null;
RenderTexture m_SkyboxCubemapRT;
RenderTexture m_SkyboxGGXCubemapRT;
RenderTexture m_SkyboxMarginalRowCdfRT;
RenderTexture m_SkyboxConditionalCdfRT;
Material m_StandardSkyboxMaterial = null; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_BlitCubemapMaterial = null;
Material m_StandardSkyboxMaterial; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_BlitCubemapMaterial;
IBLFilterGGX m_iblFilterGgx = null;
IBLFilterGGX m_iblFilterGgx;
Vector4 m_CubemapScreenSize;
Matrix4x4[] m_faceWorldToViewMatrixMatrices = new Matrix4x4[6];

BuiltinSkyParameters m_BuiltinParameters = new BuiltinSkyParameters();
SkyRenderer m_Renderer = null;
SkyRenderer m_Renderer;
bool m_NeedLowLevelUpdateEnvironment = false;
bool m_NeedLowLevelUpdateEnvironment;
float m_CurrentUpdateTime = 0.0f;
float m_CurrentUpdateTime;
// Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/bb204881(v=vs.85).aspx
readonly Vector3[] m_LookAtList =
{
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 0.0f, -1.0f),
};
private SkySettings m_SkySettings;
readonly Vector3[] m_UpVectorList =
{
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
};
SkySettings m_SkySettings;
public SkySettings skySettings
{
set

void RebuildTextures(SkySettings skySettings)
{
int resolution = 256;
// Parameters not set yet. We need them for the resolution.
if (skySettings != null)
resolution = (int)skySettings.resolution;

if (m_SkyboxCubemapRT == null)
{
m_SkyboxCubemapRT = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = false; // We will generate regular mipmap for filtered importance sampling manually
m_SkyboxCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxCubemapRT = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear)
{
dimension = TextureDimension.Cube,
useMipMap = true,
autoGenerateMips = false, // We will generate regular mipmap for filtered importance sampling manually
filterMode = FilterMode.Trilinear
};
m_SkyboxGGXCubemapRT = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_SkyboxGGXCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxGGXCubemapRT.useMipMap = true;
m_SkyboxGGXCubemapRT.autoGenerateMips = false;
m_SkyboxGGXCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxGGXCubemapRT = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear)
{
dimension = TextureDimension.Cube,
useMipMap = true,
autoGenerateMips = false,
filterMode = FilterMode.Trilinear
};
m_SkyboxGGXCubemapRT.Create();
if (m_useMIS)

// + 1 because we store the value of the integral of the cubemap at the end of the texture.
m_SkyboxMarginalRowCdfRT = new RenderTexture(height + 1, 1, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
m_SkyboxMarginalRowCdfRT.useMipMap = false;
m_SkyboxMarginalRowCdfRT.autoGenerateMips = false;
m_SkyboxMarginalRowCdfRT.enableRandomWrite = true;
m_SkyboxMarginalRowCdfRT.filterMode = FilterMode.Point;
m_SkyboxMarginalRowCdfRT = new RenderTexture(height + 1, 1, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear)
{
useMipMap = false,
autoGenerateMips = false,
enableRandomWrite = true,
filterMode = FilterMode.Point
};
m_SkyboxConditionalCdfRT = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
m_SkyboxConditionalCdfRT.useMipMap = false;
m_SkyboxConditionalCdfRT.autoGenerateMips = false;
m_SkyboxConditionalCdfRT.enableRandomWrite = true;
m_SkyboxConditionalCdfRT.filterMode = FilterMode.Point;
m_SkyboxConditionalCdfRT = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear)
{
useMipMap = false,
autoGenerateMips = false,
enableRandomWrite = true,
filterMode = FilterMode.Point
};
m_SkyboxConditionalCdfRT.Create();
}

{
if (!m_SkySettings) return;
Matrix4x4 cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, nearPlane, farPlane);
// Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/bb204881(v=vs.85).aspx
Vector3[] lookAtList =
{
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 0.0f, -1.0f),
};
Vector3[] upVectorList =
{
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
};
var cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, nearPlane, farPlane);
Matrix4x4 lookAt = Matrix4x4.LookAt(Vector3.zero, lookAtList[i], upVectorList[i]);
Matrix4x4 worldToView = lookAt * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API. ...
Vector4 screenSize = new Vector4((int)m_SkySettings.resolution, (int)m_SkySettings.resolution, 1.0f / (int)m_SkySettings.resolution, 1.0f / (int)m_SkySettings.resolution);
var lookAt = Matrix4x4.LookAt(Vector3.zero, m_LookAtList[i], m_UpVectorList[i]);
var worldToView = lookAt * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API. ...
var screenSize = new Vector4((int)m_SkySettings.resolution, (int)m_SkySettings.resolution, 1.0f / (int)m_SkySettings.resolution, 1.0f / (int)m_SkySettings.resolution);
m_faceWorldToViewMatrixMatrices[i] = worldToView;
m_facePixelCoordToViewDirMatrices[i] = ComputePixelCoordToWorldSpaceViewDirectionMatrix(0.5f * Mathf.PI, screenSize, worldToView, true);

float m00 = -2.0f * screenSize.z * m20;
float m11 = -2.0f * screenSize.w * m21;
float m33 = -1.0f;
if (renderToCubemap)
{
// Flip Y.

Matrix4x4 viewSpaceRasterTransform = new Matrix4x4(new Vector4( m00, 0.0f, 0.0f, 0.0f),
new Vector4(0.0f, m11, 0.0f, 0.0f),
new Vector4( m20, m21, m33, 0.0f),
new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
var viewSpaceRasterTransform = new Matrix4x4(new Vector4( m00, 0.0f, 0.0f, 0.0f),
new Vector4(0.0f, m11, 0.0f, 0.0f),
new Vector4( m20, m21, m33, 0.0f),
new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
Vector4 homogeneousZero = new Vector4(0, 0, 0, 1);
var homogeneousZero = new Vector4(0, 0, 0, 1);
worldToViewMatrix.SetColumn(3, homogeneousZero);
// Flip the Z to make the coordinate system left-handed.

return m_Renderer != null && m_Renderer.IsSkyValid();
}
private void RenderSkyToCubemap(BuiltinSkyParameters builtinParams, SkySettings skySettings, RenderTexture target)
void RenderSkyToCubemap(BuiltinSkyParameters builtinParams, SkySettings skySettings, RenderTexture target)
{
for (int i = 0; i < 6; ++i)
{

builtinParams.commandBuffer.GenerateMips(target);
}
private void BlitCubemap(CommandBuffer cmd, Cubemap source, RenderTexture dest)
void BlitCubemap(CommandBuffer cmd, Cubemap source, RenderTexture dest)
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
var propertyBlock = new MaterialPropertyBlock();
for (int i = 0; i < 6; ++i)
{

cmd.GenerateMips(dest);
}
private void RenderCubemapGGXConvolution(CommandBuffer cmd, BuiltinSkyParameters builtinParams, SkySettings skyParams, Texture input, RenderTexture target)
void RenderCubemapGGXConvolution(CommandBuffer cmd, BuiltinSkyParameters builtinParams, SkySettings skyParams, Texture input, RenderTexture target)
{
using (new ProfilingSample(cmd, "Update Env: GGX Convolution"))
{

}
if (!m_iblFilterGgx.IsInitialized())
{
}
// Copy the first mip
using (new ProfilingSample(cmd, "Copy Original Mip"))

using (new ProfilingSample(cmd, "GGX Convolution"))
{
if (m_useMIS && m_iblFilterGgx.SupportMIS)
{
if (m_useMIS && m_iblFilterGgx.supportMis)
}
{
}
}
}
}

m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);
RenderSettings.skybox = IsSkyValid() ? m_StandardSkyboxMaterial : null; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.ambientMode = AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
RenderSettings.customReflection = null;
DynamicGI.UpdateEnvironment();

m_BuiltinParameters.screenSize = m_CubemapScreenSize;
m_BuiltinParameters.cameraPosWS = camera.camera.transform.position;
if (
m_UpdatedFramesRequired > 0 ||
(skySettings.updateMode == EnvironementUpdateMode.OnChanged && skySettings.GetHash() != m_SkyParametersHash) ||
(skySettings.updateMode == EnvironementUpdateMode.Realtime && m_CurrentUpdateTime > skySettings.updatePeriod)
)
if (m_UpdatedFramesRequired > 0 ||
(skySettings.updateMode == EnvironementUpdateMode.OnChanged && skySettings.GetHashCode() != m_SkyParametersHash) ||
(skySettings.updateMode == EnvironementUpdateMode.Realtime && m_CurrentUpdateTime > skySettings.updatePeriod))
{
using (new ProfilingSample(cmd, "Sky Environment Pass"))
{

m_NeedLowLevelUpdateEnvironment = true;
m_UpdatedFramesRequired--;
m_SkyParametersHash = skySettings.GetHash();
m_SkyParametersHash = skySettings.GetHashCode();
m_SkyboxCubemapRT.imageContentsHash = new Hash128((uint)skySettings.GetHash(), 0, 0, 0);
m_SkyboxCubemapRT.imageContentsHash = new Hash128((uint)skySettings.GetHashCode(), 0, 0, 0);
#endif
}
}

int resolution = (int)m_SkySettings.resolution;
RenderTexture tempRT = new RenderTexture(resolution * 6, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
tempRT.dimension = TextureDimension.Tex2D;
tempRT.useMipMap = false;
tempRT.autoGenerateMips = false;
tempRT.filterMode = FilterMode.Trilinear;
var tempRT = new RenderTexture(resolution * 6, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear)
{
dimension = TextureDimension.Tex2D,
useMipMap = false,
autoGenerateMips = false,
filterMode = FilterMode.Trilinear
};
Texture2D temp = new Texture2D(resolution * 6, resolution, TextureFormat.RGBAFloat, false);
Texture2D result = new Texture2D(resolution * 6, resolution, TextureFormat.RGBAFloat, false);
var temp = new Texture2D(resolution * 6, resolution, TextureFormat.RGBAFloat, false);
var result = new Texture2D(resolution * 6, resolution, TextureFormat.RGBAFloat, false);
// Note: We need to invert in Y the cubemap faces because the current sky cubemap is inverted (because it's a RT)
// So to invert it again so that it's a proper cubemap image we need to do it in several steps because ReadPixels does not have scale parameters:

5
ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyRenderer.cs


using System;
abstract public class SkyRenderer
public abstract class SkyRenderer
{
public abstract void Build();
public abstract void Cleanup();

35
ScriptableRenderPipeline/HDRenderPipeline/Sky/SkySettings.cs


using System.Reflection;
using System.Linq;
protected class Unhashed : System.Attribute {}
[Range(0,360)]
public float rotation = 0.0f;
public float exposure = 0.0f;

public float updatePeriod = 0.0f;
public Cubemap lightingOverride = null;
private FieldInfo[] m_Properties;
protected void OnEnable()
{
// Enumerate properties in order to compute the hash more quickly later on.
m_Properties = GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.ToArray();
}
public int GetHash()
public override int GetHashCode()
foreach (var p in m_Properties)
{
bool unhashedAttribute = p.GetCustomAttributes(typeof(Unhashed), true).Length != 0;
object obj = p.GetValue(this);
if (obj != null && !unhashedAttribute) // Sometimes it can be a null reference.
hash = hash * 23 + obj.GetHashCode();
}
hash = hash * 23 + rotation.GetHashCode();
hash = hash * 23 + exposure.GetHashCode();
hash = hash * 23 + multiplier.GetHashCode();
// TODO: Fixme once we switch to .Net 4.6+
//>>>
hash = hash * 23 + ((int)resolution).GetHashCode(); // Enum.GetHashCode generates garbade on .NET 3.5... Wtf !?
hash = hash * 23 + ((int)updateMode).GetHashCode();
//<<<
hash = hash * 23 + updatePeriod.GetHashCode();
hash = lightingOverride != null ? hash * 23 + rotation.GetHashCode() : hash;
return hash;
}
}

6
ScriptableRenderPipeline/HDRenderPipeline/Sky/SkySettingsSingleton.cs


{
public class SkySettingsSingleton : Singleton<SkySettingsSingleton>
{
private SkySettings settings { get; set; }
SkySettings m_Settings { get; set; }
get { return instance.settings; }
set { instance.settings = value; }
get { return instance.m_Settings; }
set { instance.m_Settings = value; }
}
}
}

2
ScriptableRenderPipeline/LightweightPipeline/Editor/ShaderGUI/LightweightStandardGUI.cs


public static readonly string[] specularSmoothnessChannelNames = {"Specular Alpha", "Albedo Alpha"};
}
#pragma warning disable 0414
private MaterialProperty workflowMode = null;
private MaterialProperty blendMode = null;

private ColorPickerHDRConfig m_ColorPickerHDRConfig = new ColorPickerHDRConfig(0f, kMaxfp16, 1 / kMaxfp16, 3f);
private bool m_FirstTimeApply = true;
#pragma warning restore 0414
public void FindProperties(MaterialProperty[] props)
{

27
ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


private Camera m_CurrCamera = null;
private int m_LightIndicesCount = 0;
private ComputeBuffer m_LightIndexListBuffer;
private static readonly int kMaxCascades = 4;

private RenderTargetIdentifier m_CameraColorRT;
private RenderTargetIdentifier m_CameraDepthRT;
private bool m_RenderToIntermediateTarget = false;
private bool m_IntermediateTextureArray = false;
private const int kShadowDepthBufferBits = 16;

{
m_LightIndexListBuffer.Dispose();
m_LightIndexListBuffer = null;
m_LightIndicesCount = 0;
}
}

private void ShadowPass(VisibleLight[] visibleLights, ref ScriptableRenderContext context, ref LightData lightData)
{
if (m_Asset.AreShadowsEnabled() && lightData.mainLightIndex != -1)
if (m_Asset.AreShadowsEnabled() && lightData.mainLightIndex != -1)
{
VisibleLight mainLight = visibleLights[lightData.mainLightIndex];
if (mainLight.light.shadows != LightShadows.None)

// Setup camera matrices
context.SetupCameraProperties(m_CurrCamera, stereoEnabled);
RendererConfiguration rendererSettings = GetRendererSettings(ref lightData);
BeginForwardRendering(ref context, renderingConfig);

// shadow lights types.
// Lightweight pipeline only supports 1 single directional shadow light.
// Any additional pixel lights don't cast shadows.
//
//
// 2) If shadows are disabled or no shadow light is present then main light is the main brighest directional
// 3) If neither a shadow light or main light is first visible light.
private int GetMainLightIndex(VisibleLight[] lights)

int mainShadowLight = -1;
for (int i = 0; i < lights.Length; ++i)
for (int i = 0; i < lights.Length; ++i)
if (shadowsEnabled && LightweightUtils.IsSupportedShadowType (lights[i].lightType) && lights[i].light.shadows != LightShadows.None)
if (shadowsEnabled && LightweightUtils.IsSupportedShadowType (lights[i].lightType) && lights[i].light.shadows != LightShadows.None)
{
// Shadow Type priority: Soft > Hard > None
if (mainShadowLight < 0 || lights[i].light.shadows > lights[mainShadowLight].light.shadows)

if (lights[i].lightType == LightType.Directional)
if (lights[i].lightType == LightType.Directional)
{
if (mainDirectional < 0 || lights[i].light.intensity > lights[mainDirectional].light.intensity)
mainDirectional = i;

if (mainShadowLight >= 0)
if (mainShadowLight >= 0)
}
}
return 0;
}

{
// Main light has an optimized shader path for main light. This will benefit games that only care about a single light.
// Lightweight pipeline also supports only a single shadow light, if available it will be the main light.
if (lightData.mainLightIndex != -1)
if (lightData.mainLightIndex != -1)
{
SetupMainLightConstants (cmd, lights, lightData.mainLightIndex, ref context);
if (lightData.shadowsRendered)

int[] lightIndexMap = m_CullResults.GetLightIndexMap();
int lightIter = 0;
for (int i = 0; i < totalLightCount; ++i)
for (int i = 0; i < totalLightCount; ++i)
if (i == lightData.mainLightIndex || lightIter >= maxLights)
if (i == lightData.mainLightIndex || lightIter >= maxLights)
{
lightIndexMap[i] = -1;
continue;

4
TestbedPipelines/Fptl/FptlLighting.cs


}
else
{
#pragma warning disable CS0162
#pragma warning restore CS0162
}
CommandBuffer cmdShadow = CommandBufferPool.Get();

}
else
{
#pragma warning disable CS0162
#pragma warning restore CS0162
}
// do deferred lighting

2
TestbedPipelines/Fptl/SkyboxHelper.cs


using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Experimental.Rendering
{

2
TestbedPipelines/OnTileDeferredPipeline/OnTileDeferredRenderPipeline.cs


using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.SceneManagement;
namespace UnityEngine.Experimental.Rendering.OnTileDeferredRenderPipeline
{

53
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDBaseEditor.cs


using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
using UnityObject = UnityEngine.Object;
//
// Sample use:
//
// [CustomEditor(typeof(TestComponent)]
// class TestEditor : HDBaseEditor<TestComponent>
// {
// SerializedProperty m_MyFloat;
//
// protected override void OnEnable()
// {
// base.OnEnable();
// m_MyFloat = properties.Find(x => x.myFloat);
// }
//
// public override void OnInspectorGUI()
// {
// EditorGUILayout.PropertyField(m_MyFloat);
// }
// }
//
public class HDBaseEditor<T> : Editor
where T : UnityObject
{
internal PropertyFetcher<T> properties { get; private set; }
protected T m_Target
{
get { return target as T; }
}
protected T[] m_Targets
{
get { return targets as T[]; }
}
protected HDRenderPipeline m_HDPipeline
{
get { return RenderPipelineManager.currentPipeline as HDRenderPipeline; }
}
protected virtual void OnEnable()
{
properties = new PropertyFetcher<T>(serializedObject);
}
}
}

13
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDBaseEditor.cs.meta


fileFormatVersion: 2
guid: 4db007e1d2c155d4a80e2a38f39b39ff
timeCreated: 1507624455
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

56
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.Styles.cs


using UnityEngine;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public sealed partial class HDRenderPipelineInspector
{
// TODO: missing tooltips
sealed class Styles
{
public readonly GUIContent defaults = new GUIContent("Defaults");
public readonly GUIContent defaultDiffuseMaterial = new GUIContent("Default Diffuse Material", "Material to use when creating objects");
public readonly GUIContent defaultShader = new GUIContent("Default Shader", "Shader to use when creating materials");
public readonly GUIContent settingsLabel = new GUIContent("Settings");
// Rendering Settings
public readonly GUIContent renderingSettingsLabel = new GUIContent("Rendering Settings");
public readonly GUIContent useForwardRenderingOnly = new GUIContent("Use Forward Rendering Only");
public readonly GUIContent useDepthPrepassWithDeferredRendering = new GUIContent("Use Depth Prepass with Deferred rendering");
public readonly GUIContent renderAlphaTestOnlyInDeferredPrepass = new GUIContent("Alpha Test Only");
// Texture Settings
public readonly GUIContent textureSettings = new GUIContent("Texture Settings");
public readonly GUIContent spotCookieSize = new GUIContent("Spot Cookie Size");
public readonly GUIContent pointCookieSize = new GUIContent("Point Cookie Size");
public readonly GUIContent reflectionCubemapSize = new GUIContent("Reflection Cubemap Size");
public readonly GUIContent sssSettings = new GUIContent("Subsurface Scattering Settings");
// Shadow Settings
public readonly GUIContent shadowSettings = new GUIContent("Shadow Settings");
public readonly GUIContent shadowsAtlasWidth = new GUIContent("Atlas Width");
public readonly GUIContent shadowsAtlasHeight = new GUIContent("Atlas Height");
// Tile pass Settings
public readonly GUIContent tileLightLoopSettings = new GUIContent("Tile Light Loop Settings");
public readonly GUIContent enableTileAndCluster = new GUIContent("Tile/Clustered");
public readonly GUIContent enableComputeLightEvaluation = new GUIContent("Compute Light Evaluation");
public readonly GUIContent enableComputeLightVariants = new GUIContent("Compute Light Variants");
public readonly GUIContent enableComputeMaterialVariants = new GUIContent("Compute Material Variants");
public readonly GUIContent enableClustered = new GUIContent("Clustered");
public readonly GUIContent enableFptlForOpaqueWhenClustered = new GUIContent("Fptl For Opaque When Clustered");
public readonly GUIContent enableBigTilePrepass = new GUIContent("Big tile prepass");
}
static Styles s_Styles;
// Can't use a static initializer in case we need to create GUIStyle in the Styles class as
// these can only be created with an active GUI rendering context
void CheckStyles()
{
if (s_Styles == null)
s_Styles = new Styles();
}
}
}

13
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.Styles.cs.meta


fileFormatVersion: 2
guid: eaef7e9439aa2fb4093fa259575623d4
timeCreated: 1507717754
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

13
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs.meta


fileFormatVersion: 2
guid: 95517c3b2f4a014468289c3f5eb6d03c
timeCreated: 1507562538
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

258
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.cs


using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
[CustomEditor(typeof(SubsurfaceScatteringSettings))]
public sealed partial class SubsurfaceScatteringSettingsEditor : HDBaseEditor<SubsurfaceScatteringSettings>
{
sealed class Profile
{
internal SerializedProperty self;
internal SubsurfaceScatteringProfile objReference;
internal SerializedProperty name;
internal SerializedProperty scatteringDistance;
internal SerializedProperty transmissionTint;
internal SerializedProperty texturingMode;
internal SerializedProperty transmissionMode;
internal SerializedProperty thicknessRemap;
internal SerializedProperty worldScale;
// Old SSS Model >>>
internal SerializedProperty scatterDistance1;
internal SerializedProperty scatterDistance2;
internal SerializedProperty lerpWeight;
// <<< Old SSS Model
// Render preview
internal RenderTexture profileRT;
internal RenderTexture transmittanceRT;
internal Profile()
{
profileRT = new RenderTexture(256, 256, 0, RenderTextureFormat.DefaultHDR);
transmittanceRT = new RenderTexture( 16, 256, 0, RenderTextureFormat.DefaultHDR);
}
internal void Release()
{
CoreUtils.Destroy(profileRT);
CoreUtils.Destroy(transmittanceRT);
}
}
SerializedProperty m_UseDisneySSS;
List<Profile> m_Profiles;
Material m_ProfileMaterial;
Material m_TransmittanceMaterial;
protected override void OnEnable()
{
base.OnEnable();
// These shaders don't need to be reference by RenderPipelineResource as they are not use at runtime
m_ProfileMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawSssProfile");
m_TransmittanceMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");
int count = SssConstants.SSS_N_PROFILES - 1;
m_Profiles = new List<Profile>();
m_UseDisneySSS = properties.Find(x => x.useDisneySSS);
var serializedProfiles = properties.Find(x => x.profiles);
for (int i = 0; i < count; i++)
{
var serializedProfile = serializedProfiles.GetArrayElementAtIndex(i);
var rp = new RelativePropertyFetcher<SubsurfaceScatteringProfile>(serializedProfile);
var profile = new Profile
{
self = serializedProfile,
objReference = m_Target.profiles[i],
name = rp.Find(x => x.name),
scatteringDistance = rp.Find(x => x.scatteringDistance),
transmissionTint = rp.Find(x => x.transmissionTint),
texturingMode = rp.Find(x => x.texturingMode),
transmissionMode = rp.Find(x => x.transmissionMode),
thicknessRemap = rp.Find(x => x.thicknessRemap),
worldScale = rp.Find(x => x.worldScale),
scatterDistance1 = rp.Find(x => x.scatterDistance1),
scatterDistance2 = rp.Find(x => x.scatterDistance2),
lerpWeight = rp.Find(x => x.lerpWeight)
};
m_Profiles.Add(profile);
}
}
void OnDisable()
{
CoreUtils.Destroy(m_ProfileMaterial);
CoreUtils.Destroy(m_TransmittanceMaterial);
foreach (var profile in m_Profiles)
profile.Release();
m_Profiles = null;
}
public override void OnInspectorGUI()
{
CheckStyles();
// Display a warning if this settings asset is not currently in use
if (m_HDPipeline == null || m_HDPipeline.sssSettings != m_Target)
EditorGUILayout.HelpBox("These profiles aren't currently in use, assign this asset to the HD render pipeline asset to use them.", MessageType.Warning);
serializedObject.Update();
using (var scope = new EditorGUI.ChangeCheckScope())
{
EditorGUILayout.PropertyField(m_UseDisneySSS, s_Styles.useDisneySSS);
if (scope.changed && m_HDPipeline != null)
m_HDPipeline.CreateSssMaterials();
}
EditorGUILayout.Space();
if (m_Profiles == null || m_Profiles.Count == 0)
return;
bool useDisneySSS = m_UseDisneySSS.boolValue;
for (int i = 0; i < m_Profiles.Count; i++)
{
var profile = m_Profiles[i];
CoreEditorUtils.DrawSplitter();
bool state = profile.self.isExpanded;
state = CoreEditorUtils.DrawHeaderFoldout(profile.name.stringValue, state);
if (state)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(profile.name);
using (var scope = new EditorGUI.ChangeCheckScope())
{
if (useDisneySSS)
{
EditorGUILayout.PropertyField(profile.scatteringDistance, s_Styles.profileScatteringDistance);
using (new EditorGUI.DisabledScope(true))
EditorGUILayout.FloatField(s_Styles.profileMaxRadius, profile.objReference.maxRadius);
}
else
{
EditorGUILayout.PropertyField(profile.scatterDistance1, s_Styles.profileScatterDistance1);
EditorGUILayout.PropertyField(profile.scatterDistance2, s_Styles.profileScatterDistance2);
EditorGUILayout.PropertyField(profile.lerpWeight, s_Styles.profileLerpWeight);
}
profile.texturingMode.intValue = EditorGUILayout.Popup(s_Styles.texturingMode, profile.texturingMode.intValue, s_Styles.texturingModeOptions);
profile.transmissionMode.intValue = EditorGUILayout.Popup(s_Styles.profileTransmissionMode, profile.transmissionMode.intValue, s_Styles.transmissionModeOptions);
EditorGUILayout.PropertyField(profile.transmissionTint, s_Styles.profileTransmissionTint);
EditorGUILayout.PropertyField(profile.thicknessRemap, s_Styles.profileMinMaxThickness);
var thicknessRemap = profile.thicknessRemap.vector2Value;
EditorGUILayout.MinMaxSlider(s_Styles.profileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0f, 50f);
profile.thicknessRemap.vector2Value = thicknessRemap;
EditorGUILayout.PropertyField(profile.worldScale, s_Styles.profileWorldScale);
EditorGUILayout.Space();
EditorGUILayout.LabelField(s_Styles.profilePreview0, s_Styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(s_Styles.profilePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(s_Styles.profilePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(s_Styles.profilePreview3, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
serializedObject.ApplyModifiedProperties();
if (scope.changed)
{
// Validate and update the cache for this profile only
profile.objReference.Validate();
m_Target.UpdateCache(i);
}
}
RenderPreview(profile, useDisneySSS);
EditorGUILayout.Space();
EditorGUI.indentLevel--;
}
profile.self.isExpanded = state;
}
CoreEditorUtils.DrawSplitter();
serializedObject.ApplyModifiedProperties();
}
void RenderPreview(Profile profile, bool useDisneySSS)
{
var obj = profile.objReference;
float r = obj.maxRadius;
var S = obj.shapeParam;
var T = (Vector4)profile.transmissionTint.colorValue;
var R = profile.thicknessRemap.vector2Value;
bool transmissionEnabled = profile.transmissionMode.intValue != (int)SubsurfaceScatteringProfile.TransmissionMode.None;
m_ProfileMaterial.SetFloat(HDShaderIDs._MaxRadius, r);
m_ProfileMaterial.SetVector(HDShaderIDs._ShapeParam, S);
// Old SSS Model >>>
CoreUtils.SelectKeyword(m_ProfileMaterial, "SSS_MODEL_DISNEY", "SSS_MODEL_BASIC", useDisneySSS);
// Apply the three-sigma rule, and rescale.
float s = (1f / 3f) * SssConstants.SSS_BASIC_DISTANCE_SCALE;
var scatterDist1 = profile.scatterDistance1.colorValue;
var scatterDist2 = profile.scatterDistance2.colorValue;
float rMax = Mathf.Max(scatterDist1.r, scatterDist1.g, scatterDist1.b,
scatterDist2.r, scatterDist2.g, scatterDist2.b);
var stdDev1 = s * (Vector4)scatterDist1;
var stdDev2 = s * (Vector4)scatterDist2;
m_ProfileMaterial.SetVector(HDShaderIDs._StdDev1, stdDev1);
m_ProfileMaterial.SetVector(HDShaderIDs._StdDev2, stdDev2);
m_ProfileMaterial.SetFloat(HDShaderIDs._LerpWeight, profile.lerpWeight.floatValue);
m_ProfileMaterial.SetFloat(HDShaderIDs._MaxRadius, rMax);
// <<< Old SSS Model
// Draw the profile.
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256f, 256f), profile.profileRT, m_ProfileMaterial, ScaleMode.ScaleToFit, 1f);
EditorGUILayout.Space();
EditorGUILayout.LabelField(s_Styles.transmittancePreview0, s_Styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(s_Styles.transmittancePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(s_Styles.transmittancePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Old SSS Model >>>
// Multiply by 0.1 to convert from millimeters to centimeters. Apply the distance scale.
float a = 0.1f * SssConstants.SSS_BASIC_DISTANCE_SCALE;
var halfRcpVarianceAndWeight1 = new Vector4(a * a * 0.5f / (stdDev1.x * stdDev1.x), a * a * 0.5f / (stdDev1.y * stdDev1.y), a * a * 0.5f / (stdDev1.z * stdDev1.z), 4f * (1f - profile.lerpWeight.floatValue));
var halfRcpVarianceAndWeight2 = new Vector4(a * a * 0.5f / (stdDev2.x * stdDev2.x), a * a * 0.5f / (stdDev2.y * stdDev2.y), a * a * 0.5f / (stdDev2.z * stdDev2.z), 4f * profile.lerpWeight.floatValue);
m_TransmittanceMaterial.SetVector(HDShaderIDs._HalfRcpVarianceAndWeight1, halfRcpVarianceAndWeight1);
m_TransmittanceMaterial.SetVector(HDShaderIDs._HalfRcpVarianceAndWeight2, halfRcpVarianceAndWeight2);
// <<< Old SSS Model
m_TransmittanceMaterial.SetVector(HDShaderIDs._ShapeParam, S);
m_TransmittanceMaterial.SetVector(HDShaderIDs._TransmissionTint, transmissionEnabled ? T : Vector4.zero);
m_TransmittanceMaterial.SetVector(HDShaderIDs._ThicknessRemap, R);
// Draw the transmittance graph.
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16f, 16f), profile.transmittanceRT, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16f);
}
}
}

13
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.cs.meta


fileFormatVersion: 2
guid: a61a2437dcee4e54393f8f65ccf726ab
timeCreated: 1507562486
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

85
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SSS Settings.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3418a08abd15e9a49af3ccbc9e15b5ea, type: 3}
m_Name: SSS Settings
m_EditorClassIdentifier:
useDisneySSS: 1
profiles:
- name: Skin
scatteringDistance: {r: 0.7568628, g: 0.32156864, b: 0.20000002, a: 1}
transmissionTint: {r: 0.7568628, g: 0.32156864, b: 0.20000002, a: 1}
texturingMode: 0
transmissionMode: 2
thicknessRemap: {x: 0, y: 8.152544}
worldScale: 1
scatterDistance1: {r: 0.3019608, g: 0.20000002, b: 0.20000002, a: 0}
scatterDistance2: {r: 0.6, g: 0.20000002, b: 0.20000002, a: 0}
lerpWeight: 0.5
- name: Foliage
scatteringDistance: {r: 0.7568628, g: 0.7019608, b: 0.24313727, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 1
thicknessRemap: {x: 0, y: 0.2873168}
worldScale: 1
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 0.5
- name: Profile 2
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 5}
worldScale: 1
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 3
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 5}
worldScale: 1
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 4
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 5}
worldScale: 1
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 5
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 5}
worldScale: 1
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1
- name: Profile 6
scatteringDistance: {r: 0.5, g: 0.5, b: 0.5, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 0
thicknessRemap: {x: 0, y: 5}
worldScale: 1
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.5, g: 0.5, b: 0.5, a: 0}
lerpWeight: 1

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SSS Settings.asset.meta


fileFormatVersion: 2
guid: 873499ce7a6f749408981f512a9683f7
timeCreated: 1507649491
licenseType: Pro
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

508
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs


using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[GenerateHLSL]
public class SssConstants
{
public const int SSS_N_PROFILES = 8; // Max. number of profiles, including the slot taken by the neutral profile
public const int SSS_NEUTRAL_PROFILE_ID = SSS_N_PROFILES - 1; // Does not result in blurring
public const int SSS_N_SAMPLES_NEAR_FIELD = 55; // Used for extreme close ups; must be a Fibonacci number
public const int SSS_N_SAMPLES_FAR_FIELD = 21; // Used at a regular distance; must be a Fibonacci number
public const int SSS_LOD_THRESHOLD = 4; // The LoD threshold of the near-field kernel (in pixels)
public const int SSS_TRSM_MODE_NONE = 0;
public const int SSS_TRSM_MODE_THIN = 1;
// Old SSS Model >>>
public const int SSS_BASIC_N_SAMPLES = 11; // Must be an odd number
public const int SSS_BASIC_DISTANCE_SCALE = 3; // SSS distance units per centimeter
// <<< Old SSS Model
}
[Serializable]
public sealed class SubsurfaceScatteringProfile
{
public enum TexturingMode : uint
{
PreAndPostScatter = 0,
PostScatter = 1
}
public enum TransmissionMode : uint
{
None = SssConstants.SSS_TRSM_MODE_NONE,
ThinObject = SssConstants.SSS_TRSM_MODE_THIN,
Regular
}
public string name;
[ColorUsage(false, true, 0f, 8f, 0.125f, 3f)]
public Color scatteringDistance; // Per color channel (no meaningful units)
[ColorUsage(false)]
public Color transmissionTint; // Color, 0 to 1
public TexturingMode texturingMode;
public TransmissionMode transmissionMode;
public Vector2 thicknessRemap; // X = min, Y = max (in millimeters)
public float worldScale; // Size of the world unit in meters
// Old SSS Model >>>
[ColorUsage(false, true, 0f, 8f, 0.125f, 3f)]
public Color scatterDistance1;
[ColorUsage(false, true, 0f, 8f, 0.125f, 3f)]
public Color scatterDistance2;
[Range(0f, 1f)]
public float lerpWeight;
// <<< Old SSS Model
public Vector3 shapeParam { get; private set; } // RGB = shape parameter: S = 1 / D
public float maxRadius { get; private set; } // In millimeters
public Vector2[] filterKernelNearField { get; private set; } // X = radius, Y = reciprocal of the PDF
public Vector2[] filterKernelFarField { get; private set; } // X = radius, Y = reciprocal of the PDF
public Vector4 halfRcpWeightedVariances { get; private set; }
public Vector4[] filterKernelBasic { get; private set; }
public SubsurfaceScatteringProfile(string name)
{
this.name = name;
scatteringDistance = Color.grey;
transmissionTint = Color.white;
texturingMode = TexturingMode.PreAndPostScatter;
transmissionMode = TransmissionMode.None;
thicknessRemap = new Vector2(0f, 5f);
worldScale = 1f;
// Old SSS Model >>>
scatterDistance1 = new Color(0.3f, 0.3f, 0.3f, 0f);
scatterDistance2 = new Color(0.5f, 0.5f, 0.5f, 0f);
lerpWeight = 1f;
// <<< Old SSS Model
}
public void Validate()
{
thicknessRemap.y = Mathf.Max(thicknessRemap.y, 0f);
thicknessRemap.x = Mathf.Clamp(thicknessRemap.x, 0f, thicknessRemap.y);
worldScale = Mathf.Max(worldScale, 0.001f);
// Old SSS Model >>>
scatterDistance1 = new Color
{
r = Mathf.Max(0.05f, scatterDistance1.r),
g = Mathf.Max(0.05f, scatterDistance1.g),
b = Mathf.Max(0.05f, scatterDistance1.b),
a = 0.0f
};
scatterDistance2 = new Color
{
r = Mathf.Max(0.05f, scatterDistance2.r),
g = Mathf.Max(0.05f, scatterDistance2.g),
b = Mathf.Max(0.05f, scatterDistance2.b),
a = 0f
};
// <<< Old SSS Model
UpdateKernel();
}
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar.
public void UpdateKernel()
{
if (filterKernelNearField == null || filterKernelNearField.Length != SssConstants.SSS_N_SAMPLES_NEAR_FIELD)
filterKernelNearField = new Vector2[SssConstants.SSS_N_SAMPLES_NEAR_FIELD];
if (filterKernelFarField == null || filterKernelFarField.Length != SssConstants.SSS_N_SAMPLES_FAR_FIELD)
filterKernelFarField = new Vector2[SssConstants.SSS_N_SAMPLES_FAR_FIELD];
// Clamp to avoid artifacts.
shapeParam = new Vector3(
1f / Mathf.Max(0.001f, scatteringDistance.r),
1f / Mathf.Max(0.001f, scatteringDistance.g),
1f / Mathf.Max(0.001f, scatteringDistance.b)
);
// We importance sample the color channel with the widest scattering distance.
float s = Mathf.Min(shapeParam.x, shapeParam.y, shapeParam.z);
// Importance sample the normalized diffusion profile for the computed value of 's'.
// ------------------------------------------------------------------------------------
// R(r, s) = s * (Exp[-r * s] + Exp[-r * s / 3]) / (8 * Pi * r)
// PDF(r, s) = s * (Exp[-r * s] + Exp[-r * s / 3]) / 4
// CDF(r, s) = 1 - 1/4 * Exp[-r * s] - 3/4 * Exp[-r * s / 3]
// ------------------------------------------------------------------------------------
// Importance sample the near field kernel.
for (int i = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; i < n; i++)
{
float p = (i + 0.5f) * (1f / n);
float r = KernelCdfInverse(p, s);
// N.b.: computation of normalized weights, and multiplication by the surface albedo
// of the actual geometry is performed at runtime (in the shader).
filterKernelNearField[i].x = r;
filterKernelNearField[i].y = 1f / KernelPdf(r, s);
}
// Importance sample the far field kernel.
for (int i = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; i < n; i++)
{
float p = (i + 0.5f) * (1f / n);
float r = KernelCdfInverse(p, s);
// N.b.: computation of normalized weights, and multiplication by the surface albedo
// of the actual geometry is performed at runtime (in the shader).
filterKernelFarField[i].x = r;
filterKernelFarField[i].y = 1f / KernelPdf(r, s);
}
maxRadius = filterKernelFarField[SssConstants.SSS_N_SAMPLES_FAR_FIELD - 1].x;
// Old SSS Model >>>
UpdateKernelAndVarianceData();
// <<< Old SSS Model
}
// Old SSS Model >>>
public void UpdateKernelAndVarianceData()
{
const int kNumSamples = SssConstants.SSS_BASIC_N_SAMPLES;
const int kDistanceScale = SssConstants.SSS_BASIC_DISTANCE_SCALE;
if (filterKernelBasic == null || filterKernelBasic.Length != kNumSamples)
filterKernelBasic = new Vector4[kNumSamples];
// Apply the three-sigma rule, and rescale.
var stdDev1 = ((1f / 3f) * kDistanceScale) * scatterDistance1;
var stdDev2 = ((1f / 3f) * kDistanceScale) * scatterDistance2;
// Our goal is to blur the image using a filter which is represented
// as a product of a linear combination of two normalized 1D Gaussians
// as suggested by Jimenez et al. in "Separable Subsurface Scattering".
// A normalized (i.e. energy-preserving) 1D Gaussian with the mean of 0
// is defined as follows: G1(x, v) = exp(-x * x / (2 * v)) / sqrt(2 * Pi * v),
// where 'v' is variance and 'x' is the radial distance from the origin.
// Using the weight 'w', our 1D and the resulting 2D filters are given as:
// A1(v1, v2, w, x) = G1(x, v1) * (1 - w) + G1(r, v2) * w,
// A2(v1, v2, w, x, y) = A1(v1, v2, w, x) * A1(v1, v2, w, y).
// The resulting filter function is a non-Gaussian PDF.
// It is separable by design, but generally not radially symmetric.
// N.b.: our scattering distance is rather limited. Therefore, in order to allow
// for a greater range of standard deviation values for flatter profiles,
// we rescale the world using 'distanceScale', effectively reducing the SSS
// distance units from centimeters to (1 / distanceScale).
// Find the widest Gaussian across 3 color channels.
float maxStdDev1 = Mathf.Max(stdDev1.r, stdDev1.g, stdDev1.b);
float maxStdDev2 = Mathf.Max(stdDev2.r, stdDev2.g, stdDev2.b);
var weightSum = Vector3.zero;
float step = 1f / (kNumSamples - 1);
// Importance sample the linear combination of two Gaussians.
for (int i = 0; i < kNumSamples; i++)
{
// Generate 'u' on (0, 0.5] and (0.5, 1).
float u = (i <= kNumSamples / 2) ? 0.5f - i * step // The center and to the left
: i * step; // From the center to the right
u = Mathf.Clamp(u, 0.001f, 0.999f);
float pos = GaussianCombinationCdfInverse(u, maxStdDev1, maxStdDev2, lerpWeight);
float pdf = GaussianCombination(pos, maxStdDev1, maxStdDev2, lerpWeight);
Vector3 val;
val.x = GaussianCombination(pos, stdDev1.r, stdDev2.r, lerpWeight);
val.y = GaussianCombination(pos, stdDev1.g, stdDev2.g, lerpWeight);
val.z = GaussianCombination(pos, stdDev1.b, stdDev2.b, lerpWeight);
// We do not divide by 'numSamples' since we will renormalize, anyway.
filterKernelBasic[i].x = val.x * (1 / pdf);
filterKernelBasic[i].y = val.y * (1 / pdf);
filterKernelBasic[i].z = val.z * (1 / pdf);
filterKernelBasic[i].w = pos;
weightSum.x += filterKernelBasic[i].x;
weightSum.y += filterKernelBasic[i].y;
weightSum.z += filterKernelBasic[i].z;
}
// Renormalize the weights to conserve energy.
for (int i = 0; i < kNumSamples; i++)
{
filterKernelBasic[i].x *= 1 / weightSum.x;
filterKernelBasic[i].y *= 1 / weightSum.y;
filterKernelBasic[i].z *= 1 / weightSum.z;
}
Vector4 weightedStdDev;
weightedStdDev.x = Mathf.Lerp(stdDev1.r, stdDev2.r, lerpWeight);
weightedStdDev.y = Mathf.Lerp(stdDev1.g, stdDev2.g, lerpWeight);
weightedStdDev.z = Mathf.Lerp(stdDev1.b, stdDev2.b, lerpWeight);
weightedStdDev.w = Mathf.Lerp(maxStdDev1, maxStdDev2, lerpWeight);
// Store (1 / (2 * WeightedVariance)) per color channel.
halfRcpWeightedVariances.Set(
0.5f / (weightedStdDev.x * weightedStdDev.x),
0.5f / (weightedStdDev.y * weightedStdDev.y),
0.5f / (weightedStdDev.z * weightedStdDev.z),
0.5f / (weightedStdDev.w * weightedStdDev.w)
);
}
// <<< Old SSS Model
static float KernelVal(float r, float s)
{
return s * (Mathf.Exp(-r * s) + Mathf.Exp(-r * s * (1.0f / 3.0f))) / (8.0f * Mathf.PI * r);
}
// Computes the value of the integrand over a disk: (2 * PI * r) * KernelVal().
static float KernelValCircle(float r, float s)
{
return 0.25f * s * (Mathf.Exp(-r * s) + Mathf.Exp(-r * s * (1.0f / 3.0f)));
}
static float KernelPdf(float r, float s)
{
return KernelValCircle(r, s);
}
static float KernelCdf(float r, float s)
{
return 1.0f - 0.25f * Mathf.Exp(-r * s) - 0.75f * Mathf.Exp(-r * s * (1.0f / 3.0f));
}
static float KernelCdfDerivative1(float r, float s)
{
return 0.25f * s * Mathf.Exp(-r * s) * (1.0f + Mathf.Exp(r * s * (2.0f / 3.0f)));
}
static float KernelCdfDerivative2(float r, float s)
{
return (-1.0f / 12.0f) * s * s * Mathf.Exp(-r * s) * (3.0f + Mathf.Exp(r * s * (2.0f / 3.0f)));
}
// The CDF is not analytically invertible, so we use Halley's Method of root finding.
// { f(r, s, p) = CDF(r, s) - p = 0 } with the initial guess { r = (10^p - 1) / s }.
static float KernelCdfInverse(float p, float s)
{
// Supply the initial guess.
float r = (Mathf.Pow(10f, p) - 1f) / s;
float t = float.MaxValue;
while (true)
{
float f0 = KernelCdf(r, s) - p;
float f1 = KernelCdfDerivative1(r, s);
float f2 = KernelCdfDerivative2(r, s);
float dr = f0 / (f1 * (1f - f0 * f2 / (2f * f1 * f1)));
if (Mathf.Abs(dr) < t)
{
r = r - dr;
t = Mathf.Abs(dr);
}
else
{
// Converged to the best result.
break;
}
}
return r;
}
// Old SSS Model >>>
static float Gaussian(float x, float stdDev)
{
float variance = stdDev * stdDev;
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance);
}
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight);
}
static float RationalApproximation(float t)
{
// Abramowitz and Stegun formula 26.2.23.
// The absolute value of the error should be less than 4.5 e-4.
float[] c = { 2.515517f, 0.802853f, 0.010328f };
float[] d = { 1.432788f, 0.189269f, 0.001308f };
return t - ((c[2] * t + c[1]) * t + c[0]) / (((d[2] * t + d[1]) * t + d[0]) * t + 1.0f);
}
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
static float NormalCdfInverse(float p, float stdDev)
{
float x;
if (p < 0.5)
{
// F^-1(p) = - G^-1(p)
x = -RationalApproximation(Mathf.Sqrt(-2f * Mathf.Log(p)));
}
else
{
// F^-1(p) = G^-1(1-p)
x = RationalApproximation(Mathf.Sqrt(-2f * Mathf.Log(1f - p)));
}
return x * stdDev;
}
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight);
}
// <<< Old SSS Model
}
public sealed class SubsurfaceScatteringSettings : ScriptableObject
{
public bool useDisneySSS = true;
public SubsurfaceScatteringProfile[] profiles;
[NonSerialized] public int texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
[NonSerialized] public int transmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
[NonSerialized] public Vector4[] thicknessRemaps; // Remap: 0 = start, 1 = end - start
[NonSerialized] public Vector4[] worldScales; // Size of the world unit in meters (only the X component is used)
[NonSerialized] public Vector4[] shapeParams; // RGB = S = 1 / D, A = filter radius
[NonSerialized] public Vector4[] transmissionTints; // RGB = color, A = unused
[NonSerialized] public Vector4[] filterKernels; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF
// Old SSS Model >>>
[NonSerialized] public Vector4[] halfRcpWeightedVariances;
[NonSerialized] public Vector4[] halfRcpVariancesAndWeights;
[NonSerialized] public Vector4[] filterKernelsBasic;
// <<< Old SSS Model
public SubsurfaceScatteringProfile this[int index]
{
get
{
if (index >= SssConstants.SSS_N_PROFILES - 1)
throw new IndexOutOfRangeException("index");
return profiles[index];
}
}
void OnEnable()
{
if (profiles != null && profiles.Length != SssConstants.SSS_NEUTRAL_PROFILE_ID)
Array.Resize(ref profiles, SssConstants.SSS_NEUTRAL_PROFILE_ID);
if (profiles == null)
profiles = new SubsurfaceScatteringProfile[SssConstants.SSS_NEUTRAL_PROFILE_ID];
for (int i = 0; i < SssConstants.SSS_NEUTRAL_PROFILE_ID; i++)
{
if (profiles[i] == null)
profiles[i] = new SubsurfaceScatteringProfile("Profile " + i);
profiles[i].Validate();
}
ValidateArray(ref thicknessRemaps, SssConstants.SSS_N_PROFILES);
ValidateArray(ref worldScales, SssConstants.SSS_N_PROFILES);
ValidateArray(ref shapeParams, SssConstants.SSS_N_PROFILES);
ValidateArray(ref transmissionTints, SssConstants.SSS_N_PROFILES);
ValidateArray(ref filterKernels, SssConstants.SSS_N_PROFILES * SssConstants.SSS_N_SAMPLES_NEAR_FIELD);
// Old SSS Model >>>
ValidateArray(ref halfRcpWeightedVariances, SssConstants.SSS_N_PROFILES);
ValidateArray(ref halfRcpVariancesAndWeights, SssConstants.SSS_N_PROFILES * 2);
ValidateArray(ref filterKernelsBasic, SssConstants.SSS_N_PROFILES * SssConstants.SSS_BASIC_N_SAMPLES);
Debug.Assert(SssConstants.SSS_NEUTRAL_PROFILE_ID < 16, "Transmission flags (32-bit integer) cannot support more than 16 profiles.");
UpdateCache();
}
static void ValidateArray<T>(ref T[] array, int len)
{
if (array == null || array.Length != len)
array = new T[len];
}
public void UpdateCache()
{
texturingModeFlags = transmissionFlags = 0;
for (int i = 0; i < SssConstants.SSS_N_PROFILES - 1; i++)
{
UpdateCache(i);
}
// Fill the neutral profile.
int neutralId = SssConstants.SSS_NEUTRAL_PROFILE_ID;
worldScales[neutralId] = Vector4.one;
shapeParams[neutralId] = Vector4.zero;
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
{
filterKernels[n * neutralId + j].x = 0f;
filterKernels[n * neutralId + j].y = 1f;
filterKernels[n * neutralId + j].z = 0f;
filterKernels[n * neutralId + j].w = 1f;
}
// Old SSS Model >>>
halfRcpWeightedVariances[neutralId] = Vector4.one;
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{
filterKernelsBasic[n * neutralId + j] = Vector4.one;
filterKernelsBasic[n * neutralId + j].w = 0f;
}
// <<< Old SSS Model
}
public void UpdateCache(int i)
{
texturingModeFlags |= (int)profiles[i].texturingMode << i;
transmissionFlags |= (int)profiles[i].transmissionMode << i * 2;
thicknessRemaps[i] = new Vector4(profiles[i].thicknessRemap.x, profiles[i].thicknessRemap.y - profiles[i].thicknessRemap.x, 0f, 0f);
worldScales[i] = new Vector4(profiles[i].worldScale, 0f, 0f, 0f);
shapeParams[i] = profiles[i].shapeParam;
shapeParams[i].w = profiles[i].maxRadius;
transmissionTints[i] = profiles[i].transmissionTint * 0.25f; // Premultiplied
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
{
filterKernels[n * i + j].x = profiles[i].filterKernelNearField[j].x;
filterKernels[n * i + j].y = profiles[i].filterKernelNearField[j].y;
if (j < SssConstants.SSS_N_SAMPLES_FAR_FIELD)
{
filterKernels[n * i + j].z = profiles[i].filterKernelFarField[j].x;
filterKernels[n * i + j].w = profiles[i].filterKernelFarField[j].y;
}
}
// Old SSS Model >>>
halfRcpWeightedVariances[i] = profiles[i].halfRcpWeightedVariances;
var stdDev1 = ((1f / 3f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * (Vector4)profiles[i].scatterDistance1;
var stdDev2 = ((1f / 3f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * (Vector4)profiles[i].scatterDistance2;
// Multiply by 0.1 to convert from millimeters to centimeters. Apply the distance scale.
// Rescale by 4 to counter rescaling of transmission tints.
float a = 0.1f * SssConstants.SSS_BASIC_DISTANCE_SCALE;
halfRcpVariancesAndWeights[2 * i + 0] = new Vector4(a * a * 0.5f / (stdDev1.x * stdDev1.x), a * a * 0.5f / (stdDev1.y * stdDev1.y), a * a * 0.5f / (stdDev1.z * stdDev1.z), 4f * (1f - profiles[i].lerpWeight));
halfRcpVariancesAndWeights[2 * i + 1] = new Vector4(a * a * 0.5f / (stdDev2.x * stdDev2.x), a * a * 0.5f / (stdDev2.y * stdDev2.y), a * a * 0.5f / (stdDev2.z * stdDev2.z), 4f * profiles[i].lerpWeight);
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{
filterKernelsBasic[n * i + j] = profiles[i].filterKernelBasic[j];
}
// <<< Old SSS Model
}
}
}

13
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs.meta


fileFormatVersion: 2
guid: 3418a08abd15e9a49af3ccbc9e15b5ea
timeCreated: 1507538042
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

13
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringProfileEditor.Styles.cs.meta


fileFormatVersion: 2
guid: fcb1bb4049093ff41855e3951f22e9cf
timeCreated: 1507119569
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

170
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringProfileEditor.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
[CustomEditor(typeof(SubsurfaceScatteringProfile))]
public partial class SubsurfaceScatteringProfileEditor : Editor
{
RenderTexture m_ProfileImage;
RenderTexture m_TransmittanceImage;
Material m_ProfileMaterial;
Material m_TransmittanceMaterial;
SerializedProperty m_ScatteringDistance;
SerializedProperty m_MaxRadius;
SerializedProperty m_ShapeParam;
SerializedProperty m_TransmissionTint;
SerializedProperty m_TexturingMode;
SerializedProperty m_TransmissionMode;
SerializedProperty m_ThicknessRemap;
SerializedProperty m_WorldScale;
// Old SSS Model >>>
SerializedProperty m_ScatterDistance1;
SerializedProperty m_ScatterDistance2;
SerializedProperty m_LerpWeight;
// <<< Old SSS Model
void OnEnable()
{
using (var o = new PropertyFetcher<SubsurfaceScatteringProfile>(serializedObject))
{
m_ScatteringDistance = o.FindProperty(x => x.scatteringDistance);
m_MaxRadius = o.FindProperty("m_MaxRadius");
m_ShapeParam = o.FindProperty("m_ShapeParam");
m_TransmissionTint = o.FindProperty(x => x.transmissionTint);
m_TexturingMode = o.FindProperty(x => x.texturingMode);
m_TransmissionMode = o.FindProperty(x => x.transmissionMode);
m_ThicknessRemap = o.FindProperty(x => x.thicknessRemap);
m_WorldScale = o.FindProperty(x => x.worldScale);
// Old SSS Model >>>
m_ScatterDistance1 = o.FindProperty(x => x.scatterDistance1);
m_ScatterDistance2 = o.FindProperty(x => x.scatterDistance2);
m_LerpWeight = o.FindProperty(x => x.lerpWeight);
// <<< Old SSS Model
}
// These shaders don't need to be reference by RenderPipelineResource as they are not use at runtime
m_ProfileMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawSssProfile");
m_TransmittanceMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");
m_ProfileImage = new RenderTexture(256, 256, 0, RenderTextureFormat.DefaultHDR);
m_TransmittanceImage = new RenderTexture( 16, 256, 0, RenderTextureFormat.DefaultHDR);
}
void OnDisable()
{
CoreUtils.Destroy(m_ProfileMaterial);
CoreUtils.Destroy(m_TransmittanceMaterial);
CoreUtils.Destroy(m_ProfileImage);
CoreUtils.Destroy(m_TransmittanceImage);
}
public override void OnInspectorGUI()
{
var hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
if (hdPipeline == null)
return;
serializedObject.Update();
CheckStyles();
// Old SSS Model >>>
bool useDisneySSS = hdPipeline.sssSettings.useDisneySSS;
// <<< Old SSS Model
using (var scope = new EditorGUI.ChangeCheckScope())
{
if (useDisneySSS)
{
EditorGUILayout.PropertyField(m_ScatteringDistance, s_Styles.profileScatteringDistance);
using (new EditorGUI.DisabledScope(true))
EditorGUILayout.PropertyField(m_MaxRadius, s_Styles.profileMaxRadius);
}
else
{
EditorGUILayout.PropertyField(m_ScatterDistance1, s_Styles.profileScatterDistance1);
EditorGUILayout.PropertyField(m_ScatterDistance2, s_Styles.profileScatterDistance2);
EditorGUILayout.PropertyField(m_LerpWeight, s_Styles.profileLerpWeight);
}
m_TexturingMode.intValue = EditorGUILayout.Popup(s_Styles.texturingMode, m_TexturingMode.intValue, s_Styles.texturingModeOptions);
m_TransmissionMode.intValue = EditorGUILayout.Popup(s_Styles.profileTransmissionMode, m_TransmissionMode.intValue, s_Styles.transmissionModeOptions);
EditorGUILayout.PropertyField(m_TransmissionTint, s_Styles.profileTransmissionTint);
EditorGUILayout.PropertyField(m_ThicknessRemap, s_Styles.profileMinMaxThickness);
Vector2 thicknessRemap = m_ThicknessRemap.vector2Value;
EditorGUILayout.MinMaxSlider(s_Styles.profileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0.0f, 50.0f);
m_ThicknessRemap.vector2Value = thicknessRemap;
EditorGUILayout.PropertyField(m_WorldScale, s_Styles.profileWorldScale);
EditorGUILayout.Space();
EditorGUILayout.LabelField(s_Styles.profilePreview0, s_Styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(s_Styles.profilePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(s_Styles.profilePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(s_Styles.profilePreview3, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
serializedObject.ApplyModifiedProperties();
if (scope.changed)
{
// Validate each individual asset and update caches.
((SubsurfaceScatteringProfile)target).Validate();
}
}
float r = m_MaxRadius.floatValue;
Vector3 S = m_ShapeParam.vector3Value;
Vector4 T = m_TransmissionTint.colorValue;
Vector2 R = m_ThicknessRemap.vector2Value;
bool transmissionEnabled = m_TransmissionMode.intValue != (int)SubsurfaceScatteringProfile.TransmissionMode.None;
m_ProfileMaterial.SetFloat(HDShaderIDs._MaxRadius, r);
m_ProfileMaterial.SetVector(HDShaderIDs._ShapeParam, S);
// Old SSS Model >>>
CoreUtils.SelectKeyword(m_ProfileMaterial, "SSS_MODEL_DISNEY", "SSS_MODEL_BASIC", useDisneySSS);
// Apply the three-sigma rule, and rescale.
float s = (1.0f / 3.0f) * SssConstants.SSS_BASIC_DISTANCE_SCALE;
float rMax = Mathf.Max(m_ScatterDistance1.colorValue.r, m_ScatterDistance1.colorValue.g, m_ScatterDistance1.colorValue.b,
m_ScatterDistance2.colorValue.r, m_ScatterDistance2.colorValue.g, m_ScatterDistance2.colorValue.b);
Vector4 stdDev1 = s * m_ScatterDistance1.colorValue;
Vector4 stdDev2 = s * m_ScatterDistance2.colorValue;
m_ProfileMaterial.SetVector(HDShaderIDs._StdDev1, stdDev1);
m_ProfileMaterial.SetVector(HDShaderIDs._StdDev2, stdDev2);
m_ProfileMaterial.SetFloat(HDShaderIDs._LerpWeight, m_LerpWeight.floatValue);
m_ProfileMaterial.SetFloat(HDShaderIDs._MaxRadius, rMax);
// <<< Old SSS Model
// Draw the profile.
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImage, m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
EditorGUILayout.Space();
EditorGUILayout.LabelField(s_Styles.transmittancePreview0, s_Styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(s_Styles.transmittancePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(s_Styles.transmittancePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Old SSS Model >>>
// Multiply by 0.1 to convert from millimeters to centimeters. Apply the distance scale.
float a = 0.1f * SssConstants.SSS_BASIC_DISTANCE_SCALE;
Vector4 halfRcpVarianceAndWeight1 = new Vector4(a * a * 0.5f / (stdDev1.x * stdDev1.x), a * a * 0.5f / (stdDev1.y * stdDev1.y), a * a * 0.5f / (stdDev1.z * stdDev1.z), 4 * (1.0f - m_LerpWeight.floatValue));
Vector4 halfRcpVarianceAndWeight2 = new Vector4(a * a * 0.5f / (stdDev2.x * stdDev2.x), a * a * 0.5f / (stdDev2.y * stdDev2.y), a * a * 0.5f / (stdDev2.z * stdDev2.z), 4 * m_LerpWeight.floatValue);
m_TransmittanceMaterial.SetVector(HDShaderIDs._HalfRcpVarianceAndWeight1, halfRcpVarianceAndWeight1);
m_TransmittanceMaterial.SetVector(HDShaderIDs._HalfRcpVarianceAndWeight2, halfRcpVarianceAndWeight2);
// <<< Old SSS Model
m_TransmittanceMaterial.SetVector(HDShaderIDs._ShapeParam, S);
m_TransmittanceMaterial.SetVector(HDShaderIDs._TransmissionTint, transmissionEnabled ? T : Vector4.zero);
m_TransmittanceMaterial.SetVector(HDShaderIDs._ThicknessRemap, R);
// Draw the transmittance graph.
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImage, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
}
}
}

13
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringProfileEditor.cs.meta


fileFormatVersion: 2
guid: 4e87e719e85a91846ad1d5aa15793685
timeCreated: 1507118957
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/FoliageSSSProfile.asset.meta


fileFormatVersion: 2
guid: d6ee4403015766f4093158d69216c0bf
timeCreated: 1493161911
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

9
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset.meta


fileFormatVersion: 2
guid: 906339bac2066fc4aa22a3652e1283ef
timeCreated: 1493291209
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

116
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/FoliageSSSProfile.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a6e7465350bf0d248b4799d98e18cd24, type: 3}
m_Name: FoliageSSSProfile
m_EditorClassIdentifier:
scatteringDistance: {r: 0.75735295, g: 0.7008203, b: 0.24502596, a: 1}
transmissionTint: {r: 1, g: 1, b: 1, a: 1}
texturingMode: 0
transmissionMode: 1
thicknessRemap: {x: 0, y: 0.2873168}
worldScale: 1
settingsIndex: 1
m_ShapeParam: {x: 1.3203883, y: 1.4268992, z: 4.0812}
m_MaxRadius: 7.839332
m_FilterKernelNearField:
- {x: 0.013854082, y: 1.5332626}
- {x: 0.04207757, y: 1.5715919}
- {x: 0.07101321, y: 1.611625}
- {x: 0.10069309, y: 1.653469}
- {x: 0.13115102, y: 1.6972395}
- {x: 0.16242325, y: 1.743061}
- {x: 0.19454831, y: 1.791069}
- {x: 0.22756726, y: 1.8414105}
- {x: 0.2615238, y: 1.8942443}
- {x: 0.29646498, y: 1.9497447}
- {x: 0.33244094, y: 2.0081}
- {x: 0.36950532, y: 2.069517}
- {x: 0.40771604, y: 2.1342213}
- {x: 0.44713485, y: 2.2024598}
- {x: 0.48782852, y: 2.274504}
- {x: 0.5298689, y: 2.3506513}
- {x: 0.5733336, y: 2.4312308}
- {x: 0.6183063, y: 2.5166042}
- {x: 0.66487795, y: 2.6071734}
- {x: 0.71314675, y: 2.703383}
- {x: 0.76321995, y: 2.805728}
- {x: 0.81521386, y: 2.9147599}
- {x: 0.86925554, y: 3.031096}
- {x: 0.92548406, y: 3.1554284}
- {x: 0.9840515, y: 3.288537}
- {x: 1.0451256, y: 3.431302}
- {x: 1.1088905, y: 3.5847225}
- {x: 1.1755506, y: 3.749937}
- {x: 1.2453312, y: 3.9282467}
- {x: 1.3184844, y: 4.1211514}
- {x: 1.3952904, y: 4.3303804}
- {x: 1.4760638, y: 4.5579505}
- {x: 1.5611593, y: 4.8062224}
- {x: 1.650978, y: 5.0779796}
- {x: 1.7459753, y: 5.3765287}
- {x: 1.8466738, y: 5.7058387}
- {x: 1.9536757, y: 6.070716}
- {x: 2.0676782, y: 6.4770336}
- {x: 2.189499, y: 6.9320674}
- {x: 2.3201032, y: 7.4449396}
- {x: 2.4606442, y: 8.027264}
- {x: 2.612515, y: 8.694056}
- {x: 2.777422, y: 9.465107}
- {x: 2.9574924, y: 10.367077}
- {x: 3.1554203, y: 11.436736}
- {x: 3.3747015, y: 12.726331}
- {x: 3.6199868, y: 14.312694}
- {x: 3.897662, y: 16.313623}
- {x: 4.2168484, y: 18.919455}
- {x: 4.5912457, y: 22.459015}
- {x: 5.042839, y: 27.553566}
- {x: 5.610336, y: 35.534466}
- {x: 6.3721733, y: 49.863647}
- {x: 7.53103, y: 83.235695}
- {x: 10.026244, y: 249.90146}
m_FilterKernelFarField:
- {x: 0.036647703, y: 1.5641627}
- {x: 0.113649175, y: 1.671985}
- {x: 0.19610003, y: 1.7934121}
- {x: 0.28470552, y: 1.9309369}
- {x: 0.38030306, y: 2.0876582}
- {x: 0.48389605, y: 2.2674706}
- {x: 0.5966971, y: 2.4753277}
- {x: 0.72018707, y: 2.717616}
- {x: 0.85619545, y: 3.0026984}
- {x: 1.0070126, y: 3.3417335}
- {x: 1.1755506, y: 3.749937}
- {x: 1.3655809, y: 4.248627}
- {x: 1.5821002, y: 4.868682}
- {x: 1.8319175, y: 5.6567397}
- {x: 2.1246579, y: 6.6871305}
- {x: 2.4745958, y: 8.086858}
- {x: 2.9043517, y: 10.094101}
- {x: 3.4533012, y: 13.217383}
- {x: 4.20053, y: 18.777578}
- {x: 5.349281, y: 31.61934}
- {x: 7.839332, y: 95.36225}
scatterDistance1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
scatterDistance2: {r: 0.6, g: 0.6, b: 0.6, a: 0}
lerpWeight: 0.5
m_HalfRcpWeightedVariances: {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
m_FilterKernelBasic:
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.11381993}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.23580086}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.37865555}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.57677805}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -1.3907351}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.11382001}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.23580086}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.37865555}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.57677805}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 1.3907368}

116
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SSSProfile/SkinSSSProfile.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a6e7465350bf0d248b4799d98e18cd24, type: 3}
m_Name: SkinSSSProfile
m_EditorClassIdentifier:
scatteringDistance: {r: 0.758, g: 0.321, b: 0.201, a: 1}
transmissionTint: {r: 0.7568628, g: 0.32156864, b: 0.20000002, a: 1}
texturingMode: 0
transmissionMode: 2
thicknessRemap: {x: 0, y: 8.152544}
worldScale: 1
settingsIndex: 0
m_ShapeParam: {x: 1.3192612, y: 3.1152647, z: 4.9751244}
m_MaxRadius: 7.84603
m_FilterKernelNearField:
- {x: 0.013865918, y: 1.5345725}
- {x: 0.04211352, y: 1.5729346}
- {x: 0.07107388, y: 1.6130018}
- {x: 0.100779116, y: 1.6548817}
- {x: 0.13126306, y: 1.6986896}
- {x: 0.16256203, y: 1.7445502}
- {x: 0.1947145, y: 1.7925992}
- {x: 0.22776169, y: 1.8429838}
- {x: 0.26174724, y: 1.8958628}
- {x: 0.29671827, y: 1.9514104}
- {x: 0.33272493, y: 2.0098157}
- {x: 0.369821, y: 2.0712852}
- {x: 0.40806437, y: 2.1360447}
- {x: 0.44751683, y: 2.2043417}
- {x: 0.48824534, y: 2.276447}
- {x: 0.5303216, y: 2.3526597}
- {x: 0.5738235, y: 2.433308}
- {x: 0.61883456, y: 2.5187542}
- {x: 0.665446, y: 2.609401}
- {x: 0.713756, y: 2.7056925}
- {x: 0.763872, y: 2.808125}
- {x: 0.8159103, y: 2.91725}
- {x: 0.8699981, y: 3.0336854}
- {x: 0.9262747, y: 3.1581244}
- {x: 0.98489225, y: 3.2913465}
- {x: 1.0460185, y: 3.434234}
- {x: 1.1098381, y: 3.5877857}
- {x: 1.1765549, y: 3.7531407}
- {x: 1.2463952, y: 3.9316032}
- {x: 1.319611, y: 4.124672}
- {x: 1.3964823, y: 4.3340797}
- {x: 1.4773248, y: 4.561845}
- {x: 1.5624928, y: 4.810328}
- {x: 1.6523882, y: 5.082317}
- {x: 1.747467, y: 5.381122}
- {x: 1.8482518, y: 5.710715}
- {x: 1.9553448, y: 6.0759025}
- {x: 2.069445, y: 6.482568}
- {x: 2.1913698, y: 6.9379897}
- {x: 2.3220856, y: 7.4513016}
- {x: 2.4627466, y: 8.0341215}
- {x: 2.614747, y: 8.701484}
- {x: 2.7797952, y: 9.473195}
- {x: 2.9600194, y: 10.375936}
- {x: 3.1581159, y: 11.446505}
- {x: 3.3775842, y: 12.737201}
- {x: 3.6230793, y: 14.324919}
- {x: 3.9009922, y: 16.327562}
- {x: 4.220452, y: 18.935623}
- {x: 4.5951686, y: 22.478209}
- {x: 5.047148, y: 27.57712}
- {x: 5.615129, y: 35.564823}
- {x: 6.3776174, y: 49.90625}
- {x: 7.5374603, y: 83.30668}
- {x: 10.03481, y: 250.11497}
m_FilterKernelFarField:
- {x: 0.03667902, y: 1.5654991}
- {x: 0.11374626, y: 1.6734134}
- {x: 0.19626758, y: 1.7949444}
- {x: 0.28494877, y: 1.9325867}
- {x: 0.38062802, y: 2.0894418}
- {x: 0.48430943, y: 2.2694077}
- {x: 0.59720695, y: 2.4774427}
- {x: 0.72080237, y: 2.7199378}
- {x: 0.8569269, y: 3.005264}
- {x: 1.007873, y: 3.3445888}
- {x: 1.1765549, y: 3.7531407}
- {x: 1.3667475, y: 4.252257}
- {x: 1.5834517, y: 4.872841}
- {x: 1.8334827, y: 5.6615734}
- {x: 2.126473, y: 6.692844}
- {x: 2.4767098, y: 8.093767}
- {x: 2.9068332, y: 10.102725}
- {x: 3.4562516, y: 13.228675}
- {x: 4.2041187, y: 18.793621}
- {x: 5.3538504, y: 31.646347}
- {x: 7.84603, y: 95.44374}
scatterDistance1: {r: 0.3, g: 0.2, b: 0.2, a: 0}
scatterDistance2: {r: 0.6, g: 0.2, b: 0.2, a: 0}
lerpWeight: 0.5
m_HalfRcpWeightedVariances: {x: 2.4691355, y: 12.5, z: 12.5, w: 2.4691355}
m_FilterKernelBasic:
- {x: 0.09090909, y: 0.21162307, z: 0.21162307, w: -0.000000048879357}
- {x: 0.09090909, y: 0.18990478, z: 0.18990478, w: -0.11381993}
- {x: 0.09090909, y: 0.13233659, z: 0.13233659, w: -0.23580086}
- {x: 0.09090909, y: 0.061445467, z: 0.061445467, w: -0.37865555}
- {x: 0.09090909, y: 0.010501689, z: 0.010501689, w: -0.57677805}
- {x: 0.09090909, y: 2.9458339e-10, z: 2.9458339e-10, w: -1.3907351}
- {x: 0.09090909, y: 0.18990476, z: 0.18990476, w: 0.11382001}
- {x: 0.09090909, y: 0.13233659, z: 0.13233659, w: 0.23580086}
- {x: 0.09090909, y: 0.061445467, z: 0.061445467, w: 0.37865555}
- {x: 0.09090909, y: 0.010501689, z: 0.010501689, w: 0.57677805}
- {x: 0.09090909, y: 2.9456845e-10, z: 2.9456845e-10, w: 1.3907368}

12
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.meta


fileFormatVersion: 2
guid: a6e7465350bf0d248b4799d98e18cd24
timeCreated: 1490016484
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

637
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs


using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[GenerateHLSL]
public class SssConstants
{
public const int SSS_N_PROFILES = 8; // Max. number of profiles, including the slot taken by the neutral profile
public const int SSS_NEUTRAL_PROFILE_ID = SSS_N_PROFILES - 1; // Does not result in blurring
public const int SSS_N_SAMPLES_NEAR_FIELD = 55; // Used for extreme close ups; must be a Fibonacci number
public const int SSS_N_SAMPLES_FAR_FIELD = 21; // Used at a regular distance; must be a Fibonacci number
public const int SSS_LOD_THRESHOLD = 4; // The LoD threshold of the near-field kernel (in pixels)
public const int SSS_TRSM_MODE_NONE = 0;
public const int SSS_TRSM_MODE_THIN = 1;
// Old SSS Model >>>
public const int SSS_BASIC_N_SAMPLES = 11; // Must be an odd number
public const int SSS_BASIC_DISTANCE_SCALE = 3; // SSS distance units per centimeter
// <<< Old SSS Model
}
[Serializable]
public class SubsurfaceScatteringProfile : ScriptableObject
{
public enum TexturingMode : uint { PreAndPostScatter = 0, PostScatter = 1 };
public enum TransmissionMode : uint { None = SssConstants.SSS_TRSM_MODE_NONE, ThinObject = SssConstants.SSS_TRSM_MODE_THIN, Regular };
[ColorUsage(false, true, 0f, 8f, 0.125f, 3f)]
public Color scatteringDistance; // Per color channel (no meaningful units)
[ColorUsage(false)]
public Color transmissionTint; // Color, 0 to 1
public TexturingMode texturingMode;
public TransmissionMode transmissionMode;
public Vector2 thicknessRemap; // X = min, Y = max (in millimeters)
public float worldScale; // Size of the world unit in meters
[HideInInspector]
public int settingsIndex; // SubsurfaceScatteringSettings.profiles[i]
[SerializeField]
Vector3 m_ShapeParam; // RGB = shape parameter: S = 1 / D
[SerializeField]
float m_MaxRadius; // In millimeters
[SerializeField]
Vector2[] m_FilterKernelNearField; // X = radius, Y = reciprocal of the PDF
[SerializeField]
Vector2[] m_FilterKernelFarField; // X = radius, Y = reciprocal of the PDF
// Old SSS Model >>>
[ColorUsage(false, true, 0f, 8f, 0.125f, 3f)]
public Color scatterDistance1;
[ColorUsage(false, true, 0f, 8f, 0.125f, 3f)]
public Color scatterDistance2;
[Range(0f, 1f)]
public float lerpWeight;
[SerializeField]
Vector4 m_HalfRcpWeightedVariances;
[SerializeField]
Vector4[] m_FilterKernelBasic;
// <<< Old SSS Model
// --- Public Methods ---
public SubsurfaceScatteringProfile()
{
scatteringDistance = Color.grey;
transmissionTint = Color.white;
texturingMode = TexturingMode.PreAndPostScatter;
transmissionMode = TransmissionMode.None;
thicknessRemap = new Vector2(0.0f, 5.0f);
worldScale = 1.0f;
settingsIndex = SssConstants.SSS_NEUTRAL_PROFILE_ID; // Updated by SubsurfaceScatteringSettings.OnValidate() once assigned
// Old SSS Model >>>
scatterDistance1 = new Color(0.3f, 0.3f, 0.3f, 0.0f);
scatterDistance2 = new Color(0.5f, 0.5f, 0.5f, 0.0f);
lerpWeight = 1.0f;
// <<< Old SSS Model
BuildKernel();
}
public void Validate()
{
thicknessRemap.y = Mathf.Max(thicknessRemap.y, 0f);
thicknessRemap.x = Mathf.Clamp(thicknessRemap.x, 0f, thicknessRemap.y);
worldScale = Mathf.Max(worldScale, 0.001f);
// Old SSS Model >>>
var c = new Color();
c.r = Mathf.Max(0.05f, scatterDistance1.r);
c.g = Mathf.Max(0.05f, scatterDistance1.g);
c.b = Mathf.Max(0.05f, scatterDistance1.b);
c.a = 0.0f;
scatterDistance1 = c;
c.r = Mathf.Max(0.05f, scatterDistance2.r);
c.g = Mathf.Max(0.05f, scatterDistance2.g);
c.b = Mathf.Max(0.05f, scatterDistance2.b);
c.a = 0.0f;
scatterDistance2 = c;
// <<< Old SSS Model
BuildKernel();
}
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar.
public void BuildKernel()
{
if (m_FilterKernelNearField == null || m_FilterKernelNearField.Length != SssConstants.SSS_N_SAMPLES_NEAR_FIELD)
{
m_FilterKernelNearField = new Vector2[SssConstants.SSS_N_SAMPLES_NEAR_FIELD];
}
if (m_FilterKernelFarField == null || m_FilterKernelFarField.Length != SssConstants.SSS_N_SAMPLES_FAR_FIELD)
{
m_FilterKernelFarField = new Vector2[SssConstants.SSS_N_SAMPLES_FAR_FIELD];
}
// Clamp to avoid artifacts.
m_ShapeParam.x = 1.0f / Mathf.Max(0.001f, scatteringDistance.r);
m_ShapeParam.y = 1.0f / Mathf.Max(0.001f, scatteringDistance.g);
m_ShapeParam.z = 1.0f / Mathf.Max(0.001f, scatteringDistance.b);
// We importance sample the color channel with the widest scattering distance.
float s = Mathf.Min(m_ShapeParam.x, m_ShapeParam.y, m_ShapeParam.z);
// Importance sample the normalized diffusion profile for the computed value of 's'.
// ------------------------------------------------------------------------------------
// R(r, s) = s * (Exp[-r * s] + Exp[-r * s / 3]) / (8 * Pi * r)
// PDF(r, s) = s * (Exp[-r * s] + Exp[-r * s / 3]) / 4
// CDF(r, s) = 1 - 1/4 * Exp[-r * s] - 3/4 * Exp[-r * s / 3]
// ------------------------------------------------------------------------------------
// Importance sample the near field kernel.
for (int i = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; i < n; i++)
{
float p = (i + 0.5f) * (1.0f / n);
float r = KernelCdfInverse(p, s);
// N.b.: computation of normalized weights, and multiplication by the surface albedo
// of the actual geometry is performed at runtime (in the shader).
m_FilterKernelNearField[i].x = r;
m_FilterKernelNearField[i].y = 1.0f / KernelPdf(r, s);
}
// Importance sample the far field kernel.
for (int i = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; i < n; i++)
{
float p = (i + 0.5f) * (1.0f / n);
float r = KernelCdfInverse(p, s);
// N.b.: computation of normalized weights, and multiplication by the surface albedo
// of the actual geometry is performed at runtime (in the shader).
m_FilterKernelFarField[i].x = r;
m_FilterKernelFarField[i].y = 1.0f / KernelPdf(r, s);
}
m_MaxRadius = m_FilterKernelFarField[SssConstants.SSS_N_SAMPLES_FAR_FIELD - 1].x;
// Old SSS Model >>>
UpdateKernelAndVarianceData();
// <<< Old SSS Model
}
// Old SSS Model >>>
public void UpdateKernelAndVarianceData()
{
const int numSamples = SssConstants.SSS_BASIC_N_SAMPLES;
const int distanceScale = SssConstants.SSS_BASIC_DISTANCE_SCALE;
if (m_FilterKernelBasic == null || m_FilterKernelBasic.Length != numSamples)
{
m_FilterKernelBasic = new Vector4[numSamples];
}
// Apply the three-sigma rule, and rescale.
Color stdDev1 = ((1.0f / 3.0f) * distanceScale) * scatterDistance1;
Color stdDev2 = ((1.0f / 3.0f) * distanceScale) * scatterDistance2;
// Our goal is to blur the image using a filter which is represented
// as a product of a linear combination of two normalized 1D Gaussians
// as suggested by Jimenez et al. in "Separable Subsurface Scattering".
// A normalized (i.e. energy-preserving) 1D Gaussian with the mean of 0
// is defined as follows: G1(x, v) = exp(-x * x / (2 * v)) / sqrt(2 * Pi * v),
// where 'v' is variance and 'x' is the radial distance from the origin.
// Using the weight 'w', our 1D and the resulting 2D filters are given as:
// A1(v1, v2, w, x) = G1(x, v1) * (1 - w) + G1(r, v2) * w,
// A2(v1, v2, w, x, y) = A1(v1, v2, w, x) * A1(v1, v2, w, y).
// The resulting filter function is a non-Gaussian PDF.
// It is separable by design, but generally not radially symmetric.
// N.b.: our scattering distance is rather limited. Therefore, in order to allow
// for a greater range of standard deviation values for flatter profiles,
// we rescale the world using 'distanceScale', effectively reducing the SSS
// distance units from centimeters to (1 / distanceScale).
// Find the widest Gaussian across 3 color channels.
float maxStdDev1 = Mathf.Max(stdDev1.r, stdDev1.g, stdDev1.b);
float maxStdDev2 = Mathf.Max(stdDev2.r, stdDev2.g, stdDev2.b);
Vector3 weightSum = new Vector3(0, 0, 0);
float step = 1.0f / (numSamples - 1);
// Importance sample the linear combination of two Gaussians.
for (int i = 0; i < numSamples; i++)
{
// Generate 'u' on (0, 0.5] and (0.5, 1).
float u = (i <= numSamples / 2) ? 0.5f - i * step // The center and to the left
: i * step; // From the center to the right
u = Mathf.Clamp(u, 0.001f, 0.999f);
float pos = GaussianCombinationCdfInverse(u, maxStdDev1, maxStdDev2, lerpWeight);
float pdf = GaussianCombination(pos, maxStdDev1, maxStdDev2, lerpWeight);
Vector3 val;
val.x = GaussianCombination(pos, stdDev1.r, stdDev2.r, lerpWeight);
val.y = GaussianCombination(pos, stdDev1.g, stdDev2.g, lerpWeight);
val.z = GaussianCombination(pos, stdDev1.b, stdDev2.b, lerpWeight);
// We do not divide by 'numSamples' since we will renormalize, anyway.
m_FilterKernelBasic[i].x = val.x * (1 / pdf);
m_FilterKernelBasic[i].y = val.y * (1 / pdf);
m_FilterKernelBasic[i].z = val.z * (1 / pdf);
m_FilterKernelBasic[i].w = pos;
weightSum.x += m_FilterKernelBasic[i].x;
weightSum.y += m_FilterKernelBasic[i].y;
weightSum.z += m_FilterKernelBasic[i].z;
}
// Renormalize the weights to conserve energy.
for (int i = 0; i < numSamples; i++)
{
m_FilterKernelBasic[i].x *= 1 / weightSum.x;
m_FilterKernelBasic[i].y *= 1 / weightSum.y;
m_FilterKernelBasic[i].z *= 1 / weightSum.z;
}
Vector4 weightedStdDev;
weightedStdDev.x = Mathf.Lerp(stdDev1.r, stdDev2.r, lerpWeight);
weightedStdDev.y = Mathf.Lerp(stdDev1.g, stdDev2.g, lerpWeight);
weightedStdDev.z = Mathf.Lerp(stdDev1.b, stdDev2.b, lerpWeight);
weightedStdDev.w = Mathf.Lerp(maxStdDev1, maxStdDev2, lerpWeight);
// Store (1 / (2 * WeightedVariance)) per color channel.
m_HalfRcpWeightedVariances.x = 0.5f / (weightedStdDev.x * weightedStdDev.x);
m_HalfRcpWeightedVariances.y = 0.5f / (weightedStdDev.y * weightedStdDev.y);
m_HalfRcpWeightedVariances.z = 0.5f / (weightedStdDev.z * weightedStdDev.z);
m_HalfRcpWeightedVariances.w = 0.5f / (weightedStdDev.w * weightedStdDev.w);
}
// <<< Old SSS Model
public Vector3 shapeParameter
{
// Set in BuildKernel().
get { return m_ShapeParam; }
}
public float maxRadius
{
// Set in BuildKernel().
get { return m_MaxRadius; }
}
public Vector2[] filterKernelNearField
{
// Set in BuildKernel().
get { return m_FilterKernelNearField; }
}
public Vector2[] filterKernelFarField
{
// Set in BuildKernel().
get { return m_FilterKernelFarField; }
}
// Old SSS Model >>>
public Vector4[] filterKernelBasic
{
// Set via UpdateKernelAndVarianceData().
get { return m_FilterKernelBasic; }
}
public Vector4 halfRcpWeightedVariances
{
// Set via UpdateKernelAndVarianceData().
get { return m_HalfRcpWeightedVariances; }
}
// <<< Old SSS Model
// --- Private Methods ---
static float KernelVal(float r, float s)
{
return s * (Mathf.Exp(-r * s) + Mathf.Exp(-r * s * (1.0f / 3.0f))) / (8.0f * Mathf.PI * r);
}
// Computes the value of the integrand over a disk: (2 * PI * r) * KernelVal().
static float KernelValCircle(float r, float s)
{
return 0.25f * s * (Mathf.Exp(-r * s) + Mathf.Exp(-r * s * (1.0f / 3.0f)));
}
static float KernelPdf(float r, float s)
{
return KernelValCircle(r, s);
}
static float KernelCdf(float r, float s)
{
return 1.0f - 0.25f * Mathf.Exp(-r * s) - 0.75f * Mathf.Exp(-r * s * (1.0f / 3.0f));
}
static float KernelCdfDerivative1(float r, float s)
{
return 0.25f * s * Mathf.Exp(-r * s) * (1.0f + Mathf.Exp(r * s * (2.0f / 3.0f)));
}
static float KernelCdfDerivative2(float r, float s)
{
return (-1.0f / 12.0f) * s * s * Mathf.Exp(-r * s) * (3.0f + Mathf.Exp(r * s * (2.0f / 3.0f)));
}
// The CDF is not analytically invertible, so we use Halley's Method of root finding.
// { f(r, s, p) = CDF(r, s) - p = 0 } with the initial guess { r = (10^p - 1) / s }.
static float KernelCdfInverse(float p, float s)
{
// Supply the initial guess.
float r = (Mathf.Pow(10.0f, p) - 1.0f) / s;
float t = float.MaxValue;
while (true)
{
float f0 = KernelCdf(r, s) - p;
float f1 = KernelCdfDerivative1(r, s);
float f2 = KernelCdfDerivative2(r, s);
float dr = f0 / (f1 * (1.0f - f0 * f2 / (2.0f * f1 * f1)));
if (Mathf.Abs(dr) < t)
{
r = r - dr;
t = Mathf.Abs(dr);
}
else
{
// Converged to the best result.
break;
}
}
return r;
}
// Old SSS Model >>>
static float Gaussian(float x, float stdDev)
{
float variance = stdDev * stdDev;
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance);
}
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight);
}
static float RationalApproximation(float t)
{
// Abramowitz and Stegun formula 26.2.23.
// The absolute value of the error should be less than 4.5 e-4.
float[] c = {2.515517f, 0.802853f, 0.010328f};
float[] d = {1.432788f, 0.189269f, 0.001308f};
return t - ((c[2] * t + c[1]) * t + c[0]) / (((d[2] * t + d[1]) * t + d[0]) * t + 1.0f);
}
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
static float NormalCdfInverse(float p, float stdDev)
{
float x;
if (p < 0.5)
{
// F^-1(p) = - G^-1(p)
x = -RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(p)));
}
else
{
// F^-1(p) = G^-1(1-p)
x = RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(1.0f - p)));
}
return x * stdDev;
}
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight);
}
// <<< Old SSS Model
}
[Serializable]
public class SubsurfaceScatteringSettings : ISerializationCallbackReceiver
{
public int numProfiles; // Excluding the neutral profile
public SubsurfaceScatteringProfile[] profiles;
// Below are the cached values. TODO: uncomment when SSS profile asset serialization is fixed.
/*[NonSerialized]*/ public int texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
/*[NonSerialized]*/ public int transmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
/*[NonSerialized]*/ public Vector4[] thicknessRemaps; // Remap: 0 = start, 1 = end - start
/*[NonSerialized]*/ public Vector4[] worldScales; // Size of the world unit in meters (only the X component is used)
/*[NonSerialized]*/ public Vector4[] shapeParams; // RGB = S = 1 / D, A = filter radius
/*[NonSerialized]*/ public Vector4[] transmissionTints; // RGB = color, A = unused
/*[NonSerialized]*/ public Vector4[] filterKernels; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF
// Old SSS Model >>>
public bool useDisneySSS;
/*[NonSerialized]*/ public Vector4[] halfRcpWeightedVariances;
/*[NonSerialized]*/ public Vector4[] halfRcpVariancesAndWeights;
/*[NonSerialized]*/ public Vector4[] filterKernelsBasic;
// <<< Old SSS Model
// --- Public Methods ---
public SubsurfaceScatteringSettings()
{
numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
texturingModeFlags = 0;
transmissionFlags = 0;
thicknessRemaps = null;
worldScales = null;
shapeParams = null;
transmissionTints = null;
filterKernels = null;
// Old SSS Model >>>
useDisneySSS = true;
halfRcpWeightedVariances = null;
halfRcpVariancesAndWeights = null;
filterKernelsBasic = null;
// <<< Old SSS Model
UpdateCache();
}
public void OnValidate()
{
// Reserve one slot for the neutral profile.
numProfiles = Math.Min(profiles.Length, SssConstants.SSS_N_PROFILES - 1);
if (profiles.Length != numProfiles)
{
Array.Resize(ref profiles, numProfiles);
}
for (int i = 0; i < numProfiles; i++)
{
if (profiles[i] != null)
{
// Assign the profile IDs.
profiles[i].settingsIndex = i;
}
}
foreach (var profile in profiles)
{
if (profile != null)
profile.Validate();
}
UpdateCache();
}
public void UpdateCache()
{
texturingModeFlags = transmissionFlags = 0;
if (thicknessRemaps == null || thicknessRemaps.Length != SssConstants.SSS_N_PROFILES)
{
thicknessRemaps = new Vector4[SssConstants.SSS_N_PROFILES];
}
if (worldScales == null || worldScales.Length != SssConstants.SSS_N_PROFILES)
{
worldScales = new Vector4[SssConstants.SSS_N_PROFILES];
}
if (shapeParams == null || shapeParams.Length != SssConstants.SSS_N_PROFILES)
{
shapeParams = new Vector4[SssConstants.SSS_N_PROFILES];
}
if (transmissionTints == null || transmissionTints.Length != SssConstants.SSS_N_PROFILES)
{
transmissionTints = new Vector4[SssConstants.SSS_N_PROFILES];
}
const int filterKernelsNearFieldLen = SssConstants.SSS_N_PROFILES * SssConstants.SSS_N_SAMPLES_NEAR_FIELD;
if (filterKernels == null || filterKernels.Length != filterKernelsNearFieldLen)
{
filterKernels = new Vector4[filterKernelsNearFieldLen];
}
// Old SSS Model >>>
if (halfRcpWeightedVariances == null || halfRcpWeightedVariances.Length != SssConstants.SSS_N_PROFILES)
{
halfRcpWeightedVariances = new Vector4[SssConstants.SSS_N_PROFILES];
}
if (halfRcpVariancesAndWeights == null || halfRcpVariancesAndWeights.Length != 2 * SssConstants.SSS_N_PROFILES)
{
halfRcpVariancesAndWeights = new Vector4[2 * SssConstants.SSS_N_PROFILES];
}
const int filterKernelsLen = SssConstants.SSS_N_PROFILES * SssConstants.SSS_BASIC_N_SAMPLES;
if (filterKernelsBasic == null || filterKernelsBasic.Length != filterKernelsLen)
{
filterKernelsBasic = new Vector4[filterKernelsLen];
}
// <<< Old SSS Model
for (int i = 0; i < SssConstants.SSS_N_PROFILES - 1; i++)
{
// If a profile is null, it means that it was never set in the HDRenderPipeline Asset or that the profile asset has been deleted.
// In this case we want the users to be warned if a material uses one of those. This is why we fill the profile with pink transmission values.
if (i >= numProfiles || profiles[i] == null)
{
// Pink transmission
transmissionFlags |= 1 << i * 2;
transmissionTints[i] = new Vector4(100.0f, 0.0f, 100.0f, 1.0f);
// Default neutral values for the rest
worldScales[i] = Vector4.one;
shapeParams[i] = Vector4.zero;
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
{
filterKernels[n * i + j].x = 0.0f;
filterKernels[n * i + j].y = 1.0f;
filterKernels[n * i + j].z = 0.0f;
filterKernels[n * i + j].w = 1.0f;
}
// Old SSS Model >>>
halfRcpWeightedVariances[i] = Vector4.one;
halfRcpVariancesAndWeights[2 * i + 0] = Vector4.one;
halfRcpVariancesAndWeights[2 * i + 1] = Vector4.one;
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{
filterKernelsBasic[n * i + j] = Vector4.one;
filterKernelsBasic[n * i + j].w = 0.0f;
}
continue;
}
Debug.Assert(numProfiles < 16, "Transmission flags (32-bit integer) cannot support more than 16 profiles.");
texturingModeFlags |= (int)profiles[i].texturingMode << i;
transmissionFlags |= (int)profiles[i].transmissionMode << i * 2;
thicknessRemaps[i] = new Vector4(profiles[i].thicknessRemap.x, profiles[i].thicknessRemap.y - profiles[i].thicknessRemap.x, 0.0f, 0.0f);
worldScales[i] = new Vector4(profiles[i].worldScale, 0, 0, 0);
shapeParams[i] = profiles[i].shapeParameter;
shapeParams[i].w = profiles[i].maxRadius;
transmissionTints[i] = profiles[i].transmissionTint * 0.25f; // Premultiplied
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
{
filterKernels[n * i + j].x = profiles[i].filterKernelNearField[j].x;
filterKernels[n * i + j].y = profiles[i].filterKernelNearField[j].y;
if (j < SssConstants.SSS_N_SAMPLES_FAR_FIELD)
{
filterKernels[n * i + j].z = profiles[i].filterKernelFarField[j].x;
filterKernels[n * i + j].w = profiles[i].filterKernelFarField[j].y;
}
}
// Old SSS Model >>>
halfRcpWeightedVariances[i] = profiles[i].halfRcpWeightedVariances;
Vector4 stdDev1 = ((1.0f / 3.0f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * profiles[i].scatterDistance1;
Vector4 stdDev2 = ((1.0f / 3.0f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * profiles[i].scatterDistance2;
// Multiply by 0.1 to convert from millimeters to centimeters. Apply the distance scale.
// Rescale by 4 to counter rescaling of transmission tints.
float a = 0.1f * SssConstants.SSS_BASIC_DISTANCE_SCALE;
halfRcpVariancesAndWeights[2 * i + 0] = new Vector4(a * a * 0.5f / (stdDev1.x * stdDev1.x), a * a * 0.5f / (stdDev1.y * stdDev1.y), a * a * 0.5f / (stdDev1.z * stdDev1.z), 4 * (1.0f - profiles[i].lerpWeight));
halfRcpVariancesAndWeights[2 * i + 1] = new Vector4(a * a * 0.5f / (stdDev2.x * stdDev2.x), a * a * 0.5f / (stdDev2.y * stdDev2.y), a * a * 0.5f / (stdDev2.z * stdDev2.z), 4 * profiles[i].lerpWeight);
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{
filterKernelsBasic[n * i + j] = profiles[i].filterKernelBasic[j];
}
// <<< Old SSS Model
}
// Fill the neutral profile.
{
int i = SssConstants.SSS_NEUTRAL_PROFILE_ID;
worldScales[i] = Vector4.one;
shapeParams[i] = Vector4.zero;
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
{
filterKernels[n * i + j].x = 0.0f;
filterKernels[n * i + j].y = 1.0f;
filterKernels[n * i + j].z = 0.0f;
filterKernels[n * i + j].w = 1.0f;
}
// Old SSS Model >>>
halfRcpWeightedVariances[i] = Vector4.one;
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{
filterKernelsBasic[n * i + j] = Vector4.one;
filterKernelsBasic[n * i + j].w = 0.0f;
}
// <<< Old SSS Model
}
}
public void OnBeforeSerialize()
{
// No special action required.
}
public void OnAfterDeserialize()
{
// TODO: uncomment when SSS profile asset serialization is fixed.
// UpdateCache();
}
}
}

/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringProfileEditor.Styles.cs → /ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs

正在加载...
取消
保存