浏览代码

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

Unity 2017.3
/main
GitHub 7 年前
当前提交
06f28ec2
共有 650 个文件被更改,包括 3989 次插入3234 次删除
  1. 8
      SampleScenes/HDTest/DistortionTest.unity
  2. 22
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Distorsion_Lit_Reject.mat
  3. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_plane_Clear_ior101.mat
  4. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_plane_Clear_ior15.mat
  5. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_plane_Dragon.mat
  6. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_plane_EarthMap.mat
  7. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_Clear_ior101.mat
  8. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_Clear_ior15.mat
  9. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_Dragon.mat
  10. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_EarthMap.mat
  11. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_EarthMap_RefractionMask.mat
  12. 2
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_EarthMap_pretransparent.mat
  13. 32
      SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Distorsion_Unlit_Voronoi.mat
  14. 986
      SampleScenes/HDTest/GraphicTest/Common/Textures/EarthColorandMask.png
  15. 56
      SampleScenes/HDTest/GraphicTest/LayeredTessellation/Material/Layer-2-woord-rock.mat
  16. 1
      SampleScenes/HDTest/GraphicTest/LayeredTessellation/Material/Layer-2-woord-rock.mat.meta
  17. 12
      ScriptableRenderPipeline/Core/ShaderLibrary/Fibonacci.hlsl
  18. 31
      ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl
  19. 256
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  20. 2
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowMoments.hlsl
  21. 25
      ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  22. 6
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  23. 4
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl
  24. 2
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs
  25. 6
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.shader
  26. 3
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.Styles.cs
  27. 6
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs
  28. 24
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs
  29. 8
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  30. 6
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  31. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Deferred.compute
  32. 4
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl
  33. 53
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  34. 19
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl
  35. 18
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  36. 151
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  37. 30
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  38. 30
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  39. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  40. 28
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  41. 6
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs
  42. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  43. 21
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl
  44. 614
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  45. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  46. 967
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  47. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  48. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl
  49. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  50. 998
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LtcData.DisneyDiffuse.cs
  51. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute
  52. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader
  53. 58
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs
  54. 14
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataIndividualLayer.hlsl
  55. 32
      ScriptableRenderPipeline/HDRenderPipeline/Material/Material.hlsl
  56. 34
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs
  57. 7
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader
  58. 9
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/UnlitData.hlsl
  59. 6
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl
  60. 2
      ScriptableRenderPipeline/HDRenderPipeline/Sky/AtmosphericScattering/AtmosphericScattering.cs.hlsl
  61. 2
      ScriptableRenderPipeline/HDRenderPipeline/Sky/BlacksmithlSky/BlacksmithSkyRenderer.cs
  62. 28
      ScriptableRenderPipeline/LightweightPipeline/Editor/LegacyShadersToLightweightPipelineUpgrader.cs
  63. 22
      ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightAssetInspector.cs
  64. 4
      ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightPipelineUpgraders.cs
  65. 8
      ScriptableRenderPipeline/LightweightPipeline/Editor/StandardToLightweightMaterialUpgrader.cs
  66. 124
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  67. 5
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.asset
  68. 25
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.cs
  69. 5
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineUtils.cs
  70. 2
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightBlit.shader
  71. 2
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightCopyDepth.shader
  72. 203
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightCore.cginc
  73. 239
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc
  74. 244
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPassLit.cginc
  75. 14
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightShadows.cginc
  76. 21
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandard.shader
  77. 9
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardSimpleLighting.shader
  78. 2
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightUnlit.shader
  79. 5
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/Scenes.meta
  80. 3
      Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/021_Lighting_BasicPoint.unity
  81. 304
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/_OldToCleanup_/Scenes/0007_LitShaderMaps/007_LitShaderMaps_05_Emission.mat
  82. 4
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/_OldToCleanup_/HDRPAsset/HDRenderPipelineResourcesTest.asset
  83. 17
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/BlackRGBA64x64.tga.meta
  84. 17
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/MidGreyRGBA64x64.tga.meta
  85. 17
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/WhiteRGBA64x64.tga.meta
  86. 17
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/Black-WhiteRGBA64x64.tga.meta
  87. 1
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/_OldToCleanup_/HDRP_Default_Scene_Settings.prefab
  88. 20
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Materials/HDRP_Default_Material.mat
  89. 8
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/HDRI/KirbyCoveWhiteBalancedNoSun.exr.meta
  90. 14
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/uvGrid.tga.meta
  91. 20
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/HDRP_Test_Camera.prefab
  92. 10
      ImageTemplates/HDRenderPipeline/Scenes/1xxx_Materials.meta
  93. 70
      ScriptableRenderPipeline/Core/ShaderLibrary/Refraction.hlsl
  94. 10
      ScriptableRenderPipeline/Core/ShaderLibrary/Refraction.hlsl.meta
  95. 259
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDLightEditorUtilities.cs
  96. 13
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDLightEditorUtilities.cs.meta
  97. 763
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitData.hlsl
  98. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitData.hlsl.meta

8
SampleScenes/HDTest/DistortionTest.unity


m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 12b78618760f1ed418b720ef565ac193, type: 2}
- {fileID: 2100000, guid: f7ab0c70df8099e48a29dac7439299a8, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 12b78618760f1ed418b720ef565ac193, type: 2}
- {fileID: 2100000, guid: f7ab0c70df8099e48a29dac7439299a8, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_ShowToolkit: 0
m_ShowCustomSorter: 0
breakBeforeColorGrading: 0
m_BeforeTransparentBundles: []
m_BeforeTransparentBundles:
- assemblyQualifiedName: InvertOpaque, Assembly-CSharp, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null
m_BeforeStackBundles:
- assemblyQualifiedName: HalfToneOpaque, Assembly-CSharp, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null

22
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Distorsion_Lit_Reject.mat


m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Mat_Distorsion_Lit_Reject
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _BLENDMODE_ALPHA _BLENDMODE_PRESERVE_SPECULAR_LIGHTING _ENABLE_FOG_ON_TRANSPARENT
_NORMALMAP_TANGENT_SPACE _SURFACE_TYPE_TRANSPARENT
m_Shader: {fileID: 4800000, guid: c4edd00ff2db5b24391a4fcb1762e459, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _BLENDMODE_ALPHA _DISTORTIONDEPTHTEST_OFF
_DOUBLESIDEDENABLE_OFF _ENABLE_FOG_ON_TRANSPARENT _NORMALMAP_TANGENT_SPACE _PREREFRACTIONPASS_OFF
_SURFACE_TYPE_TRANSPARENT
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

disabledShaderPasses:
- ForwardOnlyOpaqueDepthOnly
- ForwardOnlyOpaque
- Forward
- DepthOnly
- DepthForwardOnly
- ForwardOnly
- GBuffer
- GBufferWithPrepass
- MOTIONVECTORS
- TransparentDepthPrepass
- META
- SHADOWCASTER
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

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}
- _ColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}

- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_plane_Clear_ior101.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_plane_Clear_ior15.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_plane_Dragon.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_plane_EarthMap.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_Clear_ior101.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_Clear_ior15.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_Dragon.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_EarthMap.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_EarthMap_RefractionMask.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

2
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_refraction_sphere_EarthMap_pretransparent.mat


- _ZTestMode: 8
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 0.078431375}
- _BaseColor: {r: 1, g: 1, b: 1, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

32
SampleScenes/HDTest/GraphicTest/Common/Material/Mat_Distorsion_Unlit_Voronoi.mat


m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Mat_Distorsion_Lit_Only_2DNoise
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _BLENDMODE_ALPHA _BLENDMODE_PRESERVE_SPECULAR_LIGHTING _ENABLE_FOG_ON_TRANSPARENT
_NORMALMAP_TANGENT_SPACE _SURFACE_TYPE_TRANSPARENT
m_Name: Mat_Distorsion_Unlit_Voronoi
m_Shader: {fileID: 4800000, guid: c4edd00ff2db5b24391a4fcb1762e459, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _BLENDMODE_ALPHA _DISTORTIONDEPTHTEST_OFF
_DOUBLESIDEDENABLE_OFF _ENABLE_FOG_ON_TRANSPARENT _NORMALMAP_TANGENT_SPACE _PREREFRACTIONPASS_OFF
_SURFACE_TYPE_TRANSPARENT
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

disabledShaderPasses:
- ForwardOnlyOpaque
- ForwardOnlyOpaqueDepthOnly
- Forward
- DepthOnly
- DepthForwardOnly
- ForwardOnly
- GBuffer
- GBufferWithPrepass
- MOTIONVECTORS
- TransparentDepthPrepass
- META
- SHADOWCASTER
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Texture: {fileID: 8600000, guid: 99d420ed53cf5bc449b014653d05770d, type: 2}
m_Texture: {fileID: 8600000, guid: 857ebf2cca737d54194a3a1077fec4cc, type: 2}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissiveColorMap:

- _DistortionBlurBlendMode: 0
- _DistortionBlurDstBlend: 1
- _DistortionBlurRemapMax: 1
- _DistortionBlurRemapMin: 0
- _DistortionBlurScale: 1
- _DistortionBlurRemapMin: 0.097841725
- _DistortionBlurScale: 1.5
- _DistortionBlurSrcBlend: 1
- _DistortionDepthTest: 0
- _DistortionDstBlend: 1

- _DistortionScale: 1
- _DistortionScale: 200000
- _DistortionSrcBlend: 1
- _DistortionStencilRef: 4
- _DoubleSidedEnable: 0

- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}

986
SampleScenes/HDTest/GraphicTest/Common/Textures/EarthColorandMask.png
文件差异内容过多而无法显示
查看文件

56
SampleScenes/HDTest/GraphicTest/LayeredTessellation/Material/Layer-2-woord-rock.mat


m_PrefabInternal: {fileID: 0}
m_Name: Layer-2-woord-rock
m_Shader: {fileID: 4800000, guid: eab0538d9d5746246806a9611c04ac4d, type: 3}
m_ShaderKeywords: _BLENDMODE_PRESERVE_SPECULAR_LIGHTING _HEIGHTMAP0 _HEIGHTMAP1
_NORMALMAP0 _NORMALMAP1 _NORMALMAP_TANGENT_SPACE0 _NORMALMAP_TANGENT_SPACE1 _NORMALMAP_TANGENT_SPACE2
_NORMALMAP_TANGENT_SPACE3 _TESSELLATION_PHONG
m_ShaderKeywords: _BLENDMODE_PRESERVE_SPECULAR_LIGHTING _DISPLACEMENT_LOCK_TILING_SCALE
_HEIGHTMAP0 _HEIGHTMAP1 _NORMALMAP0 _NORMALMAP1 _NORMALMAP_TANGENT_SPACE0 _NORMALMAP_TANGENT_SPACE1
_NORMALMAP_TANGENT_SPACE2 _NORMALMAP_TANGENT_SPACE3 _TESSELLATION_DISPLACEMENT
_TESSELLATION_PHONG _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlbedoAffectEmissive: 0
- _AlphaCutoff: 0.5

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

- _LinkDetailsWithBase1: 1
- _LinkDetailsWithBase2: 1
- _LinkDetailsWithBase3: 1
- _MaterialID: 1
- _Metallic: 0
- _Metallic0: 0
- _Metallic1: 0

- _PreRefractionPass: 0
- _ShiverDirectionality: 0.5
- _ShiverDrag: 0.2
- _ShowLayer0: 0
- _ShowLayer0: 1
- _ShowLayer1: 0
- _ShowLayer2: 0
- _ShowLayer3: 0

- _SrcBlend: 1
- _StencilRef: 2
- _Stiffness: 1
- _SubsurfaceProfile0: 0
- _SubsurfaceProfile1: 0
- _SubsurfaceProfile2: 0
- _SubsurfaceProfile3: 0
- _SubsurfaceRadius0: 1
- _SubsurfaceRadius1: 1
- _SubsurfaceRadius2: 1
- _SubsurfaceRadius3: 1
- _SurfaceType: 0
- _TessellationBackFaceCullEpsilon: -0.25
- _TessellationFactor: 4

- _TexWorldScale2: 1
- _TexWorldScale3: 1
- _TexWorldScaleBlendMask: 1
- _Thickness0: 1
- _Thickness1: 1
- _Thickness2: 1
- _Thickness3: 1
- _UVBase0: 0
- _UVBase1: 0
- _UVBase2: 0

1
SampleScenes/HDTest/GraphicTest/LayeredTessellation/Material/Layer-2-woord-rock.mat.meta


timeCreated: 1487270827
licenseType: Pro
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData: '{"GUIDArray":["e6f68673cc8e7c347a989ffe33cb21b4","f6dfdaa6d241dc94bb8816edbe111721","",""]}'
assetBundleName:

12
ScriptableRenderPipeline/Core/ShaderLibrary/Fibonacci.hlsl


// Computes a point using the Fibonacci sequence of length N.
// Input: Fib[N - 1], Fib[N - 2], and the index 'i' of the point.
// Ref: Efficient Quadrature Rules for Illumination Integrals
float2 Fibonacci2dSeq(float fibN1, float fibN2, int i)
float2 Fibonacci2dSeq(float fibN1, float fibN2, uint i)
{
// 3 cycles on GCN if 'fibN1' and 'fibN2' are known at compile time.
// N.b.: According to Swinbank and Pusser [SP06], the uniformity of the distribution

#define GOLDEN_RATIO 1.6180339887498948482
// Replaces the Fibonacci sequence in Fibonacci2dSeq() with the Golden ratio.
float2 Golden2dSeq(int i, float n)
float2 Golden2dSeq(uint i, float n)
static const int k_FibonacciSeq[] = {
static const uint k_FibonacciSeq[] = {
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181
};

case 89: return k_Fibonacci2dSeq89[i];
default:
{
int fibN1 = sampleCount;
int fibN2 = sampleCount;
uint fibN1 = sampleCount;
uint fibN2 = sampleCount;
for (int j = 1; j < 20; j++)
for (uint j = 1; j < 20; j++)
{
if (k_FibonacciSeq[j] == fibN1)
{

31
ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl


// ----------------------------------------------------------------------------
// Ref: Listing 18 in "Moving Frostbite to PBR" + https://knarkowicz.wordpress.com/2014/12/27/analytical-dfg-term-for-ibl/
float4 IntegrateGGXAndDisneyFGD(float3 V, float3 N, float roughness, uint sampleCount = 4096)
float4 IntegrateGGXAndDisneyFGD(float3 V, float3 N, float roughness, uint sampleCount = 8192)
{
float NdotV = saturate(dot(N, V));
float4 acc = float4(0.0, 0.0, 0.0, 0.0);

if (NdotL > 0.0)
{
// Integral is
// 1 / NumSample * \int[ L * fr * (N.L) / pdf ] with pdf = D(H) * (N.H) / (4 * (L.H)) and fr = F(H) * G(V, L) * D(H) / (4 * (N.L) * (N.V))
// This is split in two part:
// A) \int[ L * (N.L) ]
// B) \int[ F(H) * 4 * (N.L) * V(V, L) * (L.H) / (N.H) ] with V(V, L) = G(V, L) / (4 * (N.L) * (N.V))
// = \int[ F(H) * weightOverPdf ]
// Integral{BSDF * <N,L> dw} =
// Integral{(F0 + (1 - F0) * (1 - <V,H>)^5) * (BSDF / F) * <N,L> dw} =
// F0 * Integral{(BSDF / F) * <N,L> dw} +
// (1 - F0) * Integral{(1 - <V,H>)^5 * (BSDF / F) * <N,L> dw} =
// (1 - F0) * x + F0 * y = lerp(x, y, F0)
// Recombine at runtime with: ( f0 * weightOverPdf * (1 - Fc) + f90 * weightOverPdf * Fc ) with Fc =(1 - V.H)^5
float Fc = pow(1.0 - VdotH, 5.0);
acc.x += (1.0 - Fc) * weightOverPdf;
acc.y += Fc * weightOverPdf;
acc.x += weightOverPdf * pow(1 - VdotH, 5);
acc.y += weightOverPdf;
}
// for Disney we still use a Cosine importance sampling, true Disney importance sampling imply a look up table

{
float3 H = normalize(L + V);
float LdotH = dot(L, H);
float disneyDiffuse = DisneyDiffuseNoPI(NdotV, NdotL, LdotH, RoughnessToPerceptualRoughness(roughness));
float LdotV = dot(L, V);
float disneyDiffuse = DisneyDiffuseNoPI(NdotV, NdotL, LdotV, RoughnessToPerceptualRoughness(roughness));
return acc / sampleCount;
acc /= sampleCount;
// Remap from the [0.5, 1.5] to the [0, 1] range.
acc.z -= 0.5;
return acc;
}
uint GetIBLRuntimeFilterSampleCount(uint mipLevel)

256
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute


#define EVSM_4 2
#define MSM 3
#define THREADS 16
#define MAX_BLUR_SIZE 17
#define MAX_BLUR_SIZE (THREADS+1)
#pragma kernel main_VSM_3 KERNEL_MAIN=main_VSM_3 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=3
#pragma kernel main_VSM_5 KERNEL_MAIN=main_VSM_5 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=5

#pragma kernel main_MSM_15 KERNEL_MAIN=main_MSM_15 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=15
#pragma kernel main_MSM_17 KERNEL_MAIN=main_MSM_17 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=17
#pragma kernel main_MSAA_VSM_3 KERNEL_MAIN=main_MSAA_VSM_3 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=3
#pragma kernel main_MSAA_VSM_5 KERNEL_MAIN=main_MSAA_VSM_5 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=5
#pragma kernel main_MSAA_VSM_7 KERNEL_MAIN=main_MSAA_VSM_7 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=7
#pragma kernel main_MSAA_VSM_9 KERNEL_MAIN=main_MSAA_VSM_9 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=9
#pragma kernel main_MSAA_VSM_11 KERNEL_MAIN=main_MSAA_VSM_11 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=11
#pragma kernel main_MSAA_VSM_13 KERNEL_MAIN=main_MSAA_VSM_13 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=13
#pragma kernel main_MSAA_VSM_15 KERNEL_MAIN=main_MSAA_VSM_15 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=15
#pragma kernel main_MSAA_VSM_17 KERNEL_MAIN=main_MSAA_VSM_17 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=8 BLUR_SIZE=17
#pragma kernel main_MSAA_EVSM_2_3 KERNEL_MAIN=main_MSAA_EVSM_2_3 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=3
#pragma kernel main_MSAA_EVSM_2_5 KERNEL_MAIN=main_MSAA_EVSM_2_5 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=5
#pragma kernel main_MSAA_EVSM_2_7 KERNEL_MAIN=main_MSAA_EVSM_2_7 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=7
#pragma kernel main_MSAA_EVSM_2_9 KERNEL_MAIN=main_MSAA_EVSM_2_9 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=9
#pragma kernel main_MSAA_EVSM_2_11 KERNEL_MAIN=main_MSAA_EVSM_2_11 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=11
#pragma kernel main_MSAA_EVSM_2_13 KERNEL_MAIN=main_MSAA_EVSM_2_13 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=13
#pragma kernel main_MSAA_EVSM_2_15 KERNEL_MAIN=main_MSAA_EVSM_2_15 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=15
#pragma kernel main_MSAA_EVSM_2_17 KERNEL_MAIN=main_MSAA_EVSM_2_17 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=8 BLUR_SIZE=17
#pragma kernel main_MSAA_EVSM_4_3 KERNEL_MAIN=main_MSAA_EVSM_4_3 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=3
#pragma kernel main_MSAA_EVSM_4_5 KERNEL_MAIN=main_MSAA_EVSM_4_5 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=5
#pragma kernel main_MSAA_EVSM_4_7 KERNEL_MAIN=main_MSAA_EVSM_4_7 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=7
#pragma kernel main_MSAA_EVSM_4_9 KERNEL_MAIN=main_MSAA_EVSM_4_9 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=9
#pragma kernel main_MSAA_EVSM_4_11 KERNEL_MAIN=main_MSAA_EVSM_4_11 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=11
#pragma kernel main_MSAA_EVSM_4_13 KERNEL_MAIN=main_MSAA_EVSM_4_13 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=13
#pragma kernel main_MSAA_EVSM_4_15 KERNEL_MAIN=main_MSAA_EVSM_4_15 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=15
#pragma kernel main_MSAA_EVSM_4_17 KERNEL_MAIN=main_MSAA_EVSM_4_17 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=8 BLUR_SIZE=17
#pragma kernel main_MSAA_MSM_3 KERNEL_MAIN=main_MSAA_MSM_3 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=3
#pragma kernel main_MSAA_MSM_5 KERNEL_MAIN=main_MSAA_MSM_5 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=5
#pragma kernel main_MSAA_MSM_7 KERNEL_MAIN=main_MSAA_MSM_7 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=7
#pragma kernel main_MSAA_MSM_9 KERNEL_MAIN=main_MSAA_MSM_9 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=9
#pragma kernel main_MSAA_MSM_11 KERNEL_MAIN=main_MSAA_MSM_11 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=11
#pragma kernel main_MSAA_MSM_13 KERNEL_MAIN=main_MSAA_MSM_13 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=13
#pragma kernel main_MSAA_MSM_15 KERNEL_MAIN=main_MSAA_MSM_15 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=15
#pragma kernel main_MSAA_MSM_17 KERNEL_MAIN=main_MSAA_MSM_17 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=8 BLUR_SIZE=17
#define BLUR_BORDER (BLUR_SIZE / 2)
#define LDS_SIZE (THREADS + BLUR_BORDER + BLUR_BORDER)
#if MAX_MSAA == 1
Texture2D<float> depthTex;
#if MAX_MSAA > 1
Texture2DMS<float> depthTex;
Texture2DMS<float> depthTex;
Texture2D<float> depthTex;
uniform uint4 srcRect; // .xy = offset, .zw = width/height
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp, 4:= reversed z
uniform uint4 srcRect; // .xy = offset, .zw = width/height
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp, 4:= reversed z
uniform float4 blurWeightsStorage[3]; // Unity expects float arrays to be tightly packed
static float blurWeights[12] = (float[12])blurWeightsStorage;
uniform float4 blurWeightsStorage[3]; // Unity expects float arrays to be tightly packed
static float blurWeights[12] = (float[12])blurWeightsStorage;
static const int kBits_16 = 1; // 16 bits per channel
static const int kChannels_2 = 2; // 2 channels per pixel

# define SHADOW_MOMENTS 2
float2 DepthToMoments( float depth )
{
return float2( depth, depth * depth );

float2 moments = ShadowMoments_WarpDepth( depth, evsmExponents );
return float4( moments.xy, moments.xy * moments.xy );
}
[branch]
return ShadowMoments_Encode16MSM( depth );
return ShadowMoments_Encode16MSM( depth );
else
{
float dsq = depth * depth;

#endif
#define moment_t MERGE_NAME( float, SHADOW_MOMENTS )
#define BLUR_BORDER (BLUR_SIZE / 2)
#define LDS_STRIDE (THREADS + BLUR_BORDER + BLUR_BORDER)
#define moment_t MERGE_NAME( float, SHADOW_MOMENTS )
groupshared moment_t moments[LDS_SIZE][LDS_SIZE];
groupshared float moments1[THREADS * LDS_STRIDE]; // contains the blurred first moment
groupshared float moments2[THREADS * LDS_STRIDE]; // contains the blurred second moment
groupshared float moments3[THREADS * LDS_STRIDE]; // contains the blurred third moment
groupshared float moments4[THREADS * LDS_STRIDE]; // contains the blurred fourth moment
groupshared float sampleWeights[MAX_MSAA];
groupshared float sumWeights;
[numthreads( THREADS, THREADS, 1 )]
void KERNEL_MAIN(uint3 dispatchId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID)
int getLDSIdx( int2 pos, int stride )
uint i, j; // because the compiler scopes like its 1999.
// interleave two consecutive rows to avoid bank conflicts
return (pos.y >> 1) * (stride << 1) + (pos.x << 1) + (pos.y & 1);
}
void writeToShared( moment_t val, int2 pos, int stride )
{
int idx = getLDSIdx( pos, stride );
moments1[idx] = val.x;
moments2[idx] = val.y;
#if SHADOW_MOMENTS == 4
moments3[idx] = val.z;
moments4[idx] = val.w;
#endif
}
moment_t readFromShared( int2 pos, int stride )
{
int idx = getLDSIdx( pos, stride );
moment_t res;
res.x = moments1[idx];
res.y = moments2[idx];
#if SHADOW_MOMENTS == 4
res.z = moments3[idx];
res.w = moments4[idx];
#endif
return res;
}
[numthreads( THREADS, THREADS, 1 )]
void KERNEL_MAIN( uint3 dispatchId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID )
{
depthTex.GetDimensions(width, height, sampleCnt);
sampleCnt = Clamp(0, MAX_MSAA, sampleCnt);
depthTex.GetDimensions( width, height, sampleCnt );
sampleCnt = Clamp( sampleCnt, 2, MAX_MSAA );
float sumWeights = 0;
float sampleWeights[MAX_MSAA];
for (i = 0; i < sampleCnt; i++)
if( groupThreadId.x < sampleCnt )
float2 spos = depthTex.GetSamplePosition( i );
sampleWeights[i] = sampleCntRcp; // TODO: find a better weight filter
sumWeights += sampleWeights[i];
float2 spos = depthTex.GetSamplePosition( groupThreadId.x );
sampleWeights[groupThreadId.x] = sampleCntRcp;
sumWeights = 1.0 / sumWeights;
if( groupThreadId.x == 0 )
{
float sum = 0.0;
for( uint i = 0; i < sampleCnt; i++ )
sum += sampleWeights[i];
sumWeights = 1.0 / sum;
}
#endif
// load moments into LDS

// the data in 4 blocks.
const bool reverse_z = (dstRect.w & kReversed_z) != 0;
const int2 ldsSize = int2( LDS_SIZE, LDS_SIZE );
const int2 threadsCnt = int2( THREADS, THREADS );
const int4 validSrc = int4( srcRect.xy, srcRect.xy + srcRect.zw - 1 );
int2 srcIdx = ((int2) dispatchId.xy) - blurBorder.xx + srcRect.xy;
int2 ldsIdx = groupThreadId.xy;
const bool reverse_z = (dstRect.w & kReversed_z) != 0;
const int2 validSrc = (int2) (srcRect.xy + srcRect.zw - 1);
// calculate an average moment over all samples for a given pixel and load the result into LDS
uint iw, ih, is;
int2 srcIdx = ((int2) dispatchId.xy) - blurBorder.xx + (int2) srcRect.xy;
int2 ldsIdx = (int2) groupThreadId.xy;
moment_t hblurredMoments[2];
for( ih = 0; ih < 2; ih++ )
for( int ih = 0; ih < 2; ih++ )
[branch]
if (ldsIdx.y >= ldsSize.y)
continue;
for( iw = 0; iw < 2; iw++ )
for( int iw = 0; iw < 2; iw++ )
[branch]
if (ldsIdx.x >= ldsSize.x)
continue;
moment_t avgMoments = 0.0;
#if MAX_MSAA > 1
for( is = 0; is < sampleCnt; is++ )
if( ldsIdx.x < LDS_STRIDE )
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ) ).x;
depth = reverse_z ? (1.0 - depth) : depth;
moment_t moments = DepthToMoments( depth );
avgMoments += sampleWeights[is] * moments;
}
avgMoments *= sumWeights;
#if MAX_MSAA > 1
moment_t avgMoments = 0.0;
[loop]
for( uint is = 0; is < sampleCnt; is++ )
{
float depth = depthTex.Load( min( srcIdx, validSrc ), is ).x;
depth = reverse_z ? (1.0 - depth) : depth;
# if SHADOW_MOMENT_ALGORITHM == MSM
// We're pancaking triangles to znear in the depth pass so depth and subsequently all moments can end up being zero.
// The solver ShadowMoments_SolveMSM then ends up calculating infinities and nands, which produces different results
// on different vendors' GPUs. So we're adding a small safety margin here.
depth = Clamp( depth, 0.001, 0.999 );
# endif
avgMoments += sampleWeights[is] * DepthToMoments( depth );
}
avgMoments *= sumWeights;
writeToShared( avgMoments, int2( ldsIdx.x, groupThreadId.y ), LDS_STRIDE );
float depth = depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x;
avgMoments = DepthToMoments( reverse_z ? (1.0-depth) : depth );
float depth = depthTex.Load( int3( min( srcIdx, validSrc ), 0 ) ).x;
depth = reverse_z ? (1.0 - depth) : depth;
# if SHADOW_MOMENT_ALGORITHM == MSM
// We're pancaking triangles to znear in the depth pass so depth and subsequently all moments can end up being zero.
// The solver ShadowMoments_SolveMSM then ends up calculating infinities and nands, which produces different results
// on different vendors' GPUs. So we're adding a small safety margin here.
depth = Clamp( depth, 0.001, 0.999 );
# endif
writeToShared( DepthToMoments( depth ), int2( ldsIdx.x, groupThreadId.y ), LDS_STRIDE );
moments[ldsIdx.y][ldsIdx.x] = avgMoments;
ldsIdx.x += threadsCnt.x;
srcIdx.x += threadsCnt.x;
ldsIdx.x += THREADS;
srcIdx.x += THREADS;
}
ldsIdx.x = groupThreadId.x;
srcIdx.x = (int) dispatchId.x - blurBorder + srcRect.x;
ldsIdx.y += threadsCnt.y;
srcIdx.y += threadsCnt.y;
}
// sync across all threads so LDS contains the moments for each pixel that we need for the blur
GroupMemoryBarrierWithGroupSync();
GroupMemoryBarrierWithGroupSync();
// first pass blurs horizontally
ldsIdx = groupThreadId.xy + int2( blurBorder, 0 );
moment_t hblurredMoment = 0.0, hblurredMoment2 = 0.0;
int blurOffset;
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
{
hblurredMoment += moments[ldsIdx.y][ldsIdx.x + blurOffset] * blurWeights[abs( blurOffset )];
}
ldsIdx.y += threadsCnt.y;
[branch]
if( ldsIdx.y < ldsSize.y )
{
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
hblurredMoments[ih] = 0;
int2 idx = { groupThreadId.x + blurBorder, groupThreadId.y };
[loop]
for( int blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
hblurredMoment2 += moments[ldsIdx.y][ldsIdx.x + blurOffset] * blurWeights[abs(blurOffset)];
hblurredMoments[ih] += readFromShared( int2( idx.x + blurOffset, idx.y ), LDS_STRIDE ) * blurWeights[abs( blurOffset )];
GroupMemoryBarrierWithGroupSync();
ldsIdx.x = groupThreadId.x;
srcIdx.x = (int) dispatchId.x - blurBorder + srcRect.x;
srcIdx.y += THREADS;
// make sure all reads/writes are done
GroupMemoryBarrierWithGroupSync();
// replace LDS values with the horizontally blurred values
moments[groupThreadId.y][ldsIdx.x] = hblurredMoment;
[branch]
if( ldsIdx.y < ldsSize.y )
moments[ldsIdx.y][ldsIdx.x] = hblurredMoment2;
GroupMemoryBarrierWithGroupSync();
// update LDS with horizontally blurred values
writeToShared( hblurredMoments[0], (int2) groupThreadId.xy, THREADS );
if( (groupThreadId.y + THREADS) < LDS_STRIDE )
writeToShared( hblurredMoments[1], int2( groupThreadId.x, groupThreadId.y + THREADS ), THREADS );
// sync threads
GroupMemoryBarrierWithGroupSync();
ldsIdx = groupThreadId.xy + blurBorder.xx;
ldsIdx = (int2) groupThreadId.xy + int2( 0, blurBorder );
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
[unroll]
for( int blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
vblurredMoment += moments[ldsIdx.y + blurOffset][ldsIdx.x] * blurWeights[abs( blurOffset )];
vblurredMoment += readFromShared( int2( ldsIdx.x, ldsIdx.y + blurOffset ), THREADS ) * blurWeights[abs(blurOffset)];
dispatchId.z = dstRect.z;
dispatchId.z = dstRect.z;
outputTex[dispatchId] = vblurredMoment;
}
}

2
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowMoments.hlsl


return mul( moments, mat );
}
// Note: Don't call this with all moments being equal or 0.0, otherwise this code degenerates into lots of +/-inf calculations
// which don't behave quite the same on all hardware.
void ShadowMoments_SolveMSM( float4 moments, float depth, float momentBias, out float3 z, out float4 b )
{
// Bias input data to avoid artifacts

25
ScriptableRenderPipeline/Core/Shadow/Shadow.cs


protected const int k_BlurKernelDefSize = (7 - k_BlurKernelMinSize) / 2;
protected const int k_BlurKernelMaxSize = 17;
protected const int k_BlurKernelCount = k_BlurKernelMaxSize / 2;
protected const int k_MaxSampleCount = 8;
protected ComputeShader m_MomentBlurCS;
protected int[] m_KernelVSM = new int[k_BlurKernelCount];
protected int[] m_KernelEVSM_2 = new int[k_BlurKernelCount];

return use_2_Channels ? RenderTextureFormat.RGFloat : RenderTextureFormat.ARGBFloat;
}
}
public ShadowVariance( ref AtlasInit init ) : base( ref init )
public ShadowVariance( ref AtlasInit init, int sampleCount ) : base( ref init )
m_SampleCount = 1; // TODO: Unity can't bind msaa rts as textures, yet, so this has to remain 1 for now
m_SampleCount = sampleCount <= 0 ? 1 : (sampleCount > k_MaxSampleCount ? k_MaxSampleCount : sampleCount);
m_MomentBlurCS = Resources.Load<ComputeShader>( "ShadowBlurMoments" );
if( m_MomentBlurCS )

m_KernelVSM[i] = m_MomentBlurCS.FindKernel( "main_VSM_" + blurSize );
m_KernelEVSM_2[i] = m_MomentBlurCS.FindKernel( "main_EVSM_2_" + blurSize );
m_KernelEVSM_4[i] = m_MomentBlurCS.FindKernel( "main_EVSM_4_" + blurSize );
m_KernelMSM[i] = m_MomentBlurCS.FindKernel( "main_MSM_" + blurSize );
m_KernelVSM[i] = m_MomentBlurCS.FindKernel( "main" + (m_SampleCount > 1 ? "_MSAA_" : "_") + "VSM_" + blurSize );
m_KernelEVSM_2[i] = m_MomentBlurCS.FindKernel( "main" + (m_SampleCount > 1 ? "_MSAA_" : "_") + "EVSM_2_" + blurSize );
m_KernelEVSM_4[i] = m_MomentBlurCS.FindKernel( "main" + (m_SampleCount > 1 ? "_MSAA_" : "_") + "EVSM_4_" + blurSize );
m_KernelMSM[i] = m_MomentBlurCS.FindKernel( "main" + (m_SampleCount > 1 ? "_MSAA_" : "_") + "MSM_" + blurSize );
m_BlurWeights[i] = new float[2+i];
FillBlurWeights( i );

m_BlurWeights[i][j] *= weightSum;
}
}
public ShadowVariance( ref AtlasInit init ) : this( ref init, 1 ) {}
override protected void CreateShadowmap( RenderTexture shadowmap )
{

override protected void PreUpdate( FrameId frameId, CommandBuffer cb, uint rendertargetSlice )
{
cb.SetRenderTarget( m_ShadowmapId, 0, (CubemapFace) 0, (int) rendertargetSlice );
cb.GetTemporaryRT( m_TempDepthId, (int) m_Width, (int) m_Height, (int) m_ShadowmapBits, FilterMode.Bilinear, RenderTextureFormat.Shadowmap, RenderTextureReadWrite.Default, m_SampleCount );
RenderTextureDescriptor desc = new RenderTextureDescriptor( (int) m_Width, (int) m_Height, RenderTextureFormat.Shadowmap, (int) m_ShadowmapBits );
desc.autoGenerateMips = false;
desc.enableRandomWrite = false;
desc.msaaSamples = m_SampleCount;
desc.shadowSamplingMode = ShadowSamplingMode.RawDepth;
desc.useMipMap = false;
desc.bindMS = true;
cb.GetTemporaryRT( m_TempDepthId, desc );
cb.SetRenderTarget( new RenderTargetIdentifier( m_TempDepthId ) );
cb.ClearRenderTarget( true, true, m_ClearColor );
}

6
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs


None,
DiffuseLighting,
SpecularLighting,
VisualizeCascade
VisualizeCascade,
IndirectDiffuseOcclusionFromSsao,
IndirectDiffuseGtaoFromSsao,
IndirectSpecularOcclusionFromSsao,
IndirectSpecularGtaoFromSsao
}
public class DebugDisplaySettings

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


#define DEBUGLIGHTINGMODE_DIFFUSE_LIGHTING (1)
#define DEBUGLIGHTINGMODE_SPECULAR_LIGHTING (2)
#define DEBUGLIGHTINGMODE_VISUALIZE_CASCADE (3)
#define DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO (4)
#define DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO (5)
#define DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO (6)
#define DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO (7)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Attributes.DebugViewVarying: static fields

2
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs


static void MenuCreateSubsurfaceScatteringProfile()
{
var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon");
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<DoCreateNewAssetSubsurfaceScatteringSettings>(), "New SSS Profile.asset", icon, null);
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<DoCreateNewAssetSubsurfaceScatteringSettings>(), "New SSS Settings.asset", icon, null);
}
[MenuItem("Assets/Create/HDRenderPipeline/HDRISky Settings", priority = 750)]

6
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.shader


UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
uint featureFlags = 0xFFFFFFFF;
DECODE_FROM_GBUFFER(gbuffer, featureFlags, bsdfData, bakeDiffuseLighting);
DECODE_FROM_GBUFFER(gbuffer, MATERIAL_FEATURE_MASK_FLAGS, bsdfData, bakeDiffuseLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, LIGHT_FEATURE_MASK_FLAGS_OPAQUE, diffuseLighting, specularLighting);
Outputs outputs;
#ifdef OUTPUT_SPLIT_LIGHTING

3
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.Styles.cs


public readonly GUIContent shapeLengthLine = new GUIContent("Length", "Length of the line light");
public readonly GUIContent shapeLengthRect = new GUIContent("Size X", "SizeX of the rectangle light");
public readonly GUIContent shapeWidthRect = new GUIContent("Size Y", "SizeY of the rectangle light");
public readonly GUIContent shapeLengthPyramid = new GUIContent("Size X", "");
public readonly GUIContent shapeWidthPyramid = new GUIContent("Size Y", "");
public readonly GUIContent aspectRatioPyramid = new GUIContent("Aspect ratio", "");
public readonly GUIContent shapeLengthBox = new GUIContent("Size X", "");
public readonly GUIContent shapeWidthBox = new GUIContent("Size Y", "");
public readonly GUIContent applyRangeAttenuation = new GUIContent("Apply Range Attenuation", "Allows disabling range attenuation. This is useful indoor (like a room) to avoid having to setup a large range for a light to get correct inverse square attenuation that may leak out of the indoor");

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


public SerializedProperty spotLightShape;
public SerializedProperty shapeLength;
public SerializedProperty shapeWidth;
public SerializedProperty aspectRatio;
public SerializedProperty shapeRadius;
public SerializedProperty maxSmoothness;
public SerializedProperty applyRangeAttenuation;

spotLightShape = o.Find(x => x.spotLightShape),
shapeLength = o.Find(x => x.shapeLength),
shapeWidth = o.Find(x => x.shapeWidth),
aspectRatio = o.Find(x => x.aspectRatio),
shapeRadius = o.Find(x => x.shapeRadius),
maxSmoothness = o.Find(x => x.maxSmoothness),
applyRangeAttenuation = o.Find(x => x.applyRangeAttenuation),

// TODO : replace with angle and ratio
else if (spotLightShape == SpotLightShape.Pyramid)
{
EditorGUILayout.Slider(m_AdditionalLightData.shapeLength, 0.01f, 10f, s_Styles.shapeLengthPyramid);
EditorGUILayout.Slider(m_AdditionalLightData.shapeWidth, 0.01f, 10f, s_Styles.shapeWidthPyramid);
EditorGUILayout.Slider(m_BaseData.spotAngle, 0f, 179.9f, s_Styles.spotAngle);
EditorGUILayout.Slider(m_AdditionalLightData.aspectRatio, 0.05f, 20.0f, s_Styles.aspectRatioPyramid);
}
else if (spotLightShape == SpotLightShape.Box)
{

24
ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDAdditionalLightData.cs


#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Experimental.Rendering.HDPipeline;
#endif
using UnityEngine.Serialization;

// Only for Spotlight, should be hide for other light
public SpotLightShape spotLightShape = SpotLightShape.Cone;
// Only for Rectangle/Line/projector lights
// Only for Rectangle/Line/box projector lights
// Only for Rectangle/projector lights
// Only for Rectangle/box projector lights
// Only for pyramid projector
public float aspectRatio = 1.0f;
// Only for Sphere/Disc
public float shapeRadius = 0.0f;

switch (light.type)
{
case LightType.Directional:
EditorLightUtilities.DrawDirectionalLightGizmo(light);
HDLightEditorUtilities.DrawDirectionalLightGizmo(light);
EditorLightUtilities.DrawPointlightGizmo(light, selected);
HDLightEditorUtilities.DrawPointlightGizmo(light, selected);
EditorLightUtilities.DrawSpotlightGizmo(light, selected);
HDLightEditorUtilities.DrawSpotlightGizmo(light, selected);
EditorLightUtilities.DrawFrustumlightGizmo(light);
else if (spotLightShape == SpotLightShape.Box) // TODO
EditorLightUtilities.DrawFrustumlightGizmo(light);
HDLightEditorUtilities.DrawFrustumlightGizmo(light);
else if (spotLightShape == SpotLightShape.Box)
HDLightEditorUtilities.DrawFrustumlightGizmo(light);
break;
}
}

{
case LightTypeExtent.Rectangle:
EditorLightUtilities.DrawArealightGizmo(light);
HDLightEditorUtilities.DrawArealightGizmo(light);
EditorLightUtilities.DrawArealightGizmo(light);
HDLightEditorUtilities.DrawArealightGizmo(light);
break;
}
}

8
ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


// Disk,
};
// This is use to distinguish between reflection and refraction probe in LightLoop
[GenerateHLSL]
public enum GPUImageBasedLightingType
{
Reflection,
Refraction
};
// These structures share between C# and hlsl need to be align on float4, so we pad them.
[GenerateHLSL]
public struct DirectionalLightData

6
ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


#define GPULIGHTTYPE_RECTANGLE (6)
//
// UnityEngine.Experimental.Rendering.HDPipeline.GPUImageBasedLightingType: static fields
//
#define GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION (0)
#define GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION (1)
//
// UnityEngine.Experimental.Rendering.HDPipeline.EnvShapeType: static fields
//
#define ENVSHAPETYPE_NONE (0)

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


{
uint2 tileCoord = (16 * groupId) / GetTileSize();
uint2 pixelCoord = dispatchThreadId;
uint featureFlags = 0xFFFFFFFF;
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIAL_FEATURE_MASK_FLAGS;
#endif

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


//#define SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS // enables separate resources and algorithms for spot and point lights
// directional
#define SHADOW_DISPATCH_DIR_TEX 3
#define SHADOW_DISPATCH_DIR_SMP 0
#define SHADOW_DISPATCH_DIR_TEX 3
#define SHADOW_DISPATCH_DIR_SMP 0
#define SHADOW_DISPATCH_DIR_ALG GPUSHADOWALGORITHM_PCF_TENT_5X5 // all cascades
#define SHADOW_DISPATCH_DIR_ALG_0 GPUSHADOWALGORITHM_PCF_TENT_7X7 // 1st cascade
#define SHADOW_DISPATCH_DIR_ALG_1 GPUSHADOWALGORITHM_PCF_TENT_5X5 // 2nd cascade

53
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


bool useGlobalOverrides = true;
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Spot , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Directional , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Directional , ShadowAlgorithm.PCF, ShadowVariant.V3, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetShadowLightTypeDelegate(HDShadowLightType);

public enum LightFeatureFlags
{
// Light bit mask must match LightDefinitions.s_LightFeatureMaskFlags value
Punctual = 1 << 8,
Area = 1 << 9,
Directional = 1 << 10,
Env = 1 << 11,
Sky = 1 << 12,
SSL = 1 << 13 // If adding more light be sure to not overflow LightDefinitions.s_LightFeatureMaskFlags
Punctual = 1 << 12,
Area = 1 << 13,
Directional = 1 << 14,
Env = 1 << 15,
Sky = 1 << 16,
SSRefraction = 1 << 17,
SSReflection = 1 << 18,
// If adding more light be sure to not overflow LightDefinitions.s_LightFeatureMaskFlags
}
[GenerateHLSL]

public static int s_NumFeatureVariants = 27;
// Following define the maximum number of bits use in each feature category.
public static uint s_LightFeatureMaskFlags = 0xFF00;
public static uint s_MaterialFeatureMaskFlags = 0x00FF; // don't use all bits just to be safe from signed and/or float conversions :/
public static uint s_LightFeatureMaskFlags = 0xFFF000;
public static uint s_LightFeatureMaskFlagsOpaque = 0xFFF000 & ~((uint)LightFeatureFlags.SSRefraction); // Opaque don't support screen space refraction
public static uint s_LightFeatureMaskFlagsTransparent = 0xFFF000 & ~((uint)LightFeatureFlags.SSReflection); // Transparent don't support screen space reflection
public static uint s_MaterialFeatureMaskFlags = 0x000FFF; // don't use all bits just to be safe from signed and/or float conversions :/
}
[GenerateHLSL]

lightData.size = new Vector2(additionalLightData.shapeLength, additionalLightData.shapeWidth);
if (lightData.lightType == GPULightType.ProjectorBox || lightData.lightType == GPULightType.ProjectorPyramid)
if (lightData.lightType == GPULightType.ProjectorBox)
lightData.right *= 2 / additionalLightData.shapeLength;
lightData.up *= 2 / additionalLightData.shapeWidth;
lightData.right *= 2.0f / additionalLightData.shapeLength;
lightData.up *= 2.0f / additionalLightData.shapeWidth;
}
else if (lightData.lightType == GPULightType.ProjectorPyramid)
{
// Get width and height for the current frustum
var spotAngle = light.spotAngle;
float frustumHeight;
float frustumWidth;
if (additionalLightData.aspectRatio >= 1.0f)
{
frustumHeight = 2.0f * Mathf.Tan(spotAngle * 0.5f * Mathf.Deg2Rad);
frustumWidth = frustumHeight * additionalLightData.aspectRatio;
}
else
{
frustumWidth = 2.0f * Mathf.Tan(spotAngle * 0.5f * Mathf.Deg2Rad);
frustumHeight = frustumWidth / additionalLightData.aspectRatio;
}
lightData.size = new Vector2(frustumWidth, frustumHeight);
// Rescale for cookies and windowing.
lightData.right *= 2.0f / frustumWidth;
lightData.up *= 2.0f / frustumHeight;
}
if (lightData.lightType == GPULightType.Spot)

Vector3 camPosWS = camera.transform.position;
// Note: Light with null intensity/Color are culled by the C++, no need to test it here
if (cullResults.visibleLights.Count != 0 || cullResults.visibleReflectionProbes.Count != 0)
{
// 0. deal with shadows

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


//
// UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightFeatureFlags: static fields
//
#define LIGHTFEATUREFLAGS_PUNCTUAL (256)
#define LIGHTFEATUREFLAGS_AREA (512)
#define LIGHTFEATUREFLAGS_DIRECTIONAL (1024)
#define LIGHTFEATUREFLAGS_ENV (2048)
#define LIGHTFEATUREFLAGS_SKY (4096)
#define LIGHTFEATUREFLAGS_SSL (8192)
#define LIGHTFEATUREFLAGS_PUNCTUAL (4096)
#define LIGHTFEATUREFLAGS_AREA (8192)
#define LIGHTFEATUREFLAGS_DIRECTIONAL (16384)
#define LIGHTFEATUREFLAGS_ENV (32768)
#define LIGHTFEATUREFLAGS_SKY (65536)
#define LIGHTFEATUREFLAGS_SSREFRACTION (131072)
#define LIGHTFEATUREFLAGS_SSREFLECTION (262144)
//
// UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightDefinitions: static fields

#define TILE_SIZE_FPTL (16)
#define TILE_SIZE_CLUSTERED (32)
#define NUM_FEATURE_VARIANTS (27)
#define LIGHT_FEATURE_MASK_FLAGS (65280)
#define MATERIAL_FEATURE_MASK_FLAGS (255)
#define LIGHT_FEATURE_MASK_FLAGS (16773120)
#define LIGHT_FEATURE_MASK_FLAGS_OPAQUE (16642048)
#define LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT (16510976)
#define MATERIAL_FEATURE_MASK_FLAGS (4095)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.TilePass.SFiniteLightBound
// PackingRules = Exact

18
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


ShadowContext shadowContext;
};
// Store all the accumulated lighting produce by the light loop
struct LightLoopAccumulatedLighting
{
float3 dirDiffuseLighting;
float3 dirSpecularLighting;
float3 punctualDiffuseLighting;
float3 punctualSpecularLighting;
float3 areaDiffuseLighting;
float3 areaSpecularLighting;
float3 envDiffuseLighting;
float3 envSpecularLighting;
float envDiffuseLightingWeight;
};
//-----------------------------------------------------------------------------
// Cookie sampling functions
// ----------------------------------------------------------------------------

151
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


#endif // LIGHTLOOP_TILE_PASS
void applyWeigthedIblLighting(float3 localDiffuseLighting, float3 localSpecularLighting, float2 weight, inout float3 iblDiffuseLighting, inout float3 iblSpecularLighting, inout float totalIblWeight)
{
// IBL weights should not exceed 1.
float accumulatedWeight = totalIblWeight + weight.y;
totalIblWeight = saturate(accumulatedWeight);
weight.y -= saturate(accumulatedWeight - totalIblWeight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x);
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, float3 bakeDiffuseLighting, uint featureFlags,
out float3 diffuseLighting,

context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
// This struct is use to store accumulated lighting, summation is done in PostEvaluateBSDF
LightLoopAccumulatedLighting accLighting;
ZERO_INITIALIZE(LightLoopAccumulatedLighting, accLighting);
// This struct is define in the material. the Lightloop must not access it
// PostEvaluateBSDF call at the end will convert Lighting to diffuse and specular lighting
AggregateLighting aggregateLighting;
ZERO_INITIALIZE(AggregateLighting, aggregateLighting); // LightLoop is in charge of initializing the struct
uint i = 0; // Declare once to avoid the D3D11 compiler warning.

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional(context, V, posInput, preLightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
accLighting.dirDiffuseLighting += localDiffuseLighting;
accLighting.dirSpecularLighting += localSpecularLighting;
DirectLighting lighting = EvaluateBSDF_Directional(context, V, posInput, preLightData, _DirectionalLightDatas[i], bsdfData);
AccumulateDirectLighting(lighting, aggregateLighting);
}
}

for (i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, preLightData, _LightDatas[punctualIndex], bsdfData, _LightDatas[punctualIndex].lightType,
localDiffuseLighting, localSpecularLighting);
accLighting.punctualDiffuseLighting += localDiffuseLighting;
accLighting.punctualSpecularLighting += localSpecularLighting;
DirectLighting lighting = EvaluateBSDF_Punctual(context, V, posInput, preLightData, _LightDatas[punctualIndex], bsdfData, _LightDatas[punctualIndex].lightType);
AccumulateDirectLighting(lighting, aggregateLighting);
}
#else

float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, preLightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType,
localDiffuseLighting, localSpecularLighting);
accLighting.punctualDiffuseLighting += localDiffuseLighting;
accLighting.punctualSpecularLighting += localSpecularLighting;
DirectLighting lighting = EvaluateBSDF_Punctual(context, V, posInput, preLightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType);
AccumulateDirectLighting(lighting, aggregateLighting);
}
#endif

while (i < areaLightCount && lightType == GPULIGHTTYPE_LINE)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Area( context, V, posInput, preLightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_LINE,
localDiffuseLighting, localSpecularLighting);
accLighting.areaDiffuseLighting += localDiffuseLighting;
accLighting.areaSpecularLighting += localSpecularLighting;
DirectLighting lighting = EvaluateBSDF_Area(context, V, posInput, preLightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_LINE);
AccumulateDirectLighting(lighting, aggregateLighting);
i++;
areaIndex = i < areaLightCount ? FetchIndex(areaLightStart, i) : 0;
lightType = i < areaLightCount ? _LightDatas[areaIndex].lightType : 0xFF;

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Area( context, V, posInput, preLightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_RECTANGLE,
localDiffuseLighting, localSpecularLighting);
accLighting.areaDiffuseLighting += localDiffuseLighting;
accLighting.areaSpecularLighting += localSpecularLighting;
DirectLighting lighting = EvaluateBSDF_Area(context, V, posInput, preLightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_RECTANGLE);
AccumulateDirectLighting(lighting, aggregateLighting);
i++;
areaIndex = i < areaLightCount ? FetchIndex(areaLightStart, i) : 0;

#else
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Area( context, V, posInput, preLightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType,
localDiffuseLighting, localSpecularLighting);
accLighting.areaDiffuseLighting += localDiffuseLighting;
accLighting.areaSpecularLighting += localSpecularLighting;
DirectLighting lighting = EvaluateBSDF_Area(context, V, posInput, preLightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType);
AccumulateDirectLighting(lighting, aggregateLighting);
float totalIblWeight = 0.0; // Max: 1
float reflectionHierarchyWeight = 0.0; // Max: 1.0
float refractionHierarchyWeight = 0.0; // Max: 1.0
if (featureFlags & LIGHTFEATUREFLAGS_SSL)
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION)
{
IndirectLighting lighting = EvaluateBSDF_SSRefraction(context, V, posInput, preLightData, bsdfData, refractionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
if (featureFlags & LIGHTFEATUREFLAGS_SSREFLECTION)
// SSR and rough refraction
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
EvaluateBSDF_SSL(V, posInput, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
applyWeigthedIblLighting(localDiffuseLighting, localSpecularLighting, weight, accLighting.envDiffuseLighting, accLighting.envSpecularLighting, totalIblWeight);
accLighting.envDiffuseLightingWeight = weight.x;
IndirectLighting lighting = EvaluateBSDF_SSReflection(context, V, posInput, preLightData, bsdfData, reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
if (featureFlags & LIGHTFEATUREFLAGS_ENV || featureFlags & LIGHTFEATUREFLAGS_SKY)

{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
#ifdef LIGHTLOOP_TILE_PASS

#endif
// Note: In case of IBL we are sorted from smaller to bigger projected solid angle bounds. We are not sorted by type so we can't do a 'while' approach like for area light.
for (i = 0; i < envLightCount && totalIblWeight < 1.0; ++i)
for (i = 0; i < envLightCount && reflectionHierarchyWeight < 1.0; ++i)
{
#ifdef LIGHTLOOP_TILE_PASS
uint envLightIndex = FetchIndex(envLightStart, i);

EvaluateBSDF_Env(context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType, localDiffuseLighting, localSpecularLighting, weight);
applyWeigthedIblLighting(localDiffuseLighting, localSpecularLighting, weight, accLighting.envDiffuseLighting, accLighting.envSpecularLighting, totalIblWeight);
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType,
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
// Refraction probe and reflection probe will process exactly the same weight. It will be good for performance to be able to share this computation
// However it is hard to deal with the fact that reflectionHierarchyWeight and refractionHierarchyWeight have not the same values, they are independent
// The refraction probe is rarely used and happen only with sphere shape and high IOR. So we accept the slow path that use more simple code and
// doesn't affect the performance of the reflection which is more important.
// We reuse LIGHTFEATUREFLAGS_SSREFRACTION flag as refraction is mainly base on the screen. Would be aa waste to not use screen and only cubemap.
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION)
{
for (i = 0; i < envLightCount && refractionHierarchyWeight < 1.0; ++i)
{
#ifdef LIGHTLOOP_TILE_PASS
uint envLightIndex = FetchIndex(envLightStart, i);
#else
uint envLightIndex = i;
#endif
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType,
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
if (featureFlags & LIGHTFEATUREFLAGS_SKY)
// Only apply the sky IBL if the sky texture is available
if (featureFlags & LIGHTFEATUREFLAGS_SKY && _EnvLightSkyEnabled)
// Only apply the sky IBL if the sky texture is available, and if we haven't yet accumulated enough IBL lighting.
if (_EnvLightSkyEnabled && totalIblWeight < 1.0)
// Only apply the sky if we haven't yet accumulated enough IBL lighting.
if (reflectionHierarchyWeight < 1.0)
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, bsdfData, ENVSHAPETYPE_SKY, localDiffuseLighting, localSpecularLighting, weight);
applyWeigthedIblLighting(localDiffuseLighting, localSpecularLighting, weight, accLighting.envDiffuseLighting, accLighting.envSpecularLighting, totalIblWeight);
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, bsdfData, ENVSHAPETYPE_SKY, GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION)
{
if (refractionHierarchyWeight < 1.0)
{
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, bsdfData, ENVSHAPETYPE_SKY, GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
}
}
}

PostEvaluateBSDF( context, V, posInput, preLightData, accLighting, bsdfData, bakeDiffuseLighting,
PostEvaluateBSDF( context, V, posInput, preLightData, bsdfData, bakeDiffuseLighting, aggregateLighting,
diffuseLighting, specularLighting);
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);

30
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


_ThicknessMap2("Thickness Map", 2D) = "white" {}
_ThicknessMap3("Thickness Map", 2D) = "white" {}
_ThicknessRemap0("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessRemap1("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessRemap2("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessRemap3("Thickness Remap", Vector) = (0, 1, 0, 0)
// All the following properties exist only in layered lit material
// Layer blending options

// Transparency
[ToggleOff] _PreRefractionPass("PreRefractionPass", Float) = 0.0
// HACK: GI Baking system relies on some properties existing in the shader ("_MainTex", "_Cutoff" and "_Color") for opacity handling, so we need to store our version of those parameters in the hard-coded name the GI baking system recognizes.
_MainTex("Albedo", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
}
HLSLINCLUDE

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL

HLSLPROGRAM
#define SHADERPASS SHADERPASS_GBUFFER
#define _BYPASS_ALPHA_TEST
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL

#include "../../Debug/DebugDisplay.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitMetaPass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassLightTransport.hlsl"
ENDHLSL

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitVelocityPass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassVelocity.hlsl"
ENDHLSL

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDepthPass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"
ENDHLSL

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDepthPass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"
ENDHLSL

#include "../../Lighting/Lighting.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassForward.hlsl"
ENDHLSL

#include "../../Lighting/Lighting.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassForward.hlsl"
ENDHLSL

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


_ThicknessMap2("Thickness Map", 2D) = "white" {}
_ThicknessMap3("Thickness Map", 2D) = "white" {}
_ThicknessRemap0("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessRemap1("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessRemap2("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessRemap3("Thickness Remap", Vector) = (0, 1, 0, 0)
// All the following properties exist only in layered lit material
// Layer blending options

// Transparency
[ToggleOff] _PreRefractionPass("PreRefractionPass", Float) = 0.0
// HACK: GI Baking system relies on some properties existing in the shader ("_MainTex", "_Cutoff" and "_Color") for opacity handling, so we need to store our version of those parameters in the hard-coded name the GI baking system recognizes.
_MainTex("Albedo", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
}
HLSLINCLUDE

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL

#pragma domain Domain
#define SHADERPASS SHADERPASS_GBUFFER
#define _BYPASS_ALPHA_TEST
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL

#include "../../Debug/DebugDisplay.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitMetaPass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassLightTransport.hlsl"
ENDHLSL

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitVelocityPass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassVelocity.hlsl"
ENDHLSL

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDepthPass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"
ENDHLSL

#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "../Lit/ShaderPass/LitDepthPass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassDepthOnly.hlsl"
ENDHLSL

#include "../../Lighting/Lighting.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassForward.hlsl"
ENDHLSL

#include "../../Lighting/Lighting.hlsl"
#include "../Lit/ShaderPass/LitSharePass.hlsl"
#include "../Lit/LitData.hlsl"
#include "LayeredLitData.hlsl"
#include "../../ShaderPass/ShaderPassForward.hlsl"
ENDHLSL

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


TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode);
SetKeyword(material, "_TESSELLATION_PHONG", tessMode == TessellationMode.Phong);
}
SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor", material);
}
static public void SetupBaseLitMaterialPass(Material material)

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


public static string InputsText = "Inputs";
public static GUIContent baseColorText = new GUIContent("Base Color + Opacity", "Albedo (RGB) and Opacity (A)");
public static GUIContent baseColorRefractionMaskText = new GUIContent("Base Color + RefractionMask", "Albedo (RGB) and Refraction mask (A)");
public static GUIContent smoothnessMapChannelText = new GUIContent("Smoothness Source", "Smoothness texture and channel");
public static GUIContent metallicText = new GUIContent("Metallic", "Metallic scale factor");

public static GUIContent subsurfaceRadiusMapText = new GUIContent("Subsurface radius map (R)", "Determines the range of the blur.");
public static GUIContent thicknessText = new GUIContent("Thickness", "If subsurface scattering is enabled, low values allow some light to be transmitted through the object.");
public static GUIContent thicknessMapText = new GUIContent("Thickness map (R)", "If subsurface scattering is enabled, low values allow some light to be transmitted through the object.");
public static GUIContent thicknessRemapText = new GUIContent("Thickness Remap", "Remaps values of the thickness map from [0, 1] to the specified range.");
// Clear Coat
public static GUIContent coatCoverageText = new GUIContent("Coat Coverage", "Percentage of clear coat coverage");

protected const string kThickness = "_Thickness";
protected MaterialProperty[] thicknessMap = new MaterialProperty[kMaxLayerCount];
protected const string kThicknessMap = "_ThicknessMap";
protected MaterialProperty[] thicknessRemap = new MaterialProperty[kMaxLayerCount];
protected const string kThicknessRemap = "_ThicknessRemap";
protected MaterialProperty[] UVDetail = new MaterialProperty[kMaxLayerCount];
protected const string kUVDetail = "_UVDetail";

subsurfaceRadiusMap[i] = FindProperty(string.Format("{0}{1}", kSubsurfaceRadiusMap, m_PropertySuffixes[i]), props);
thickness[i] = FindProperty(string.Format("{0}{1}", kThickness, m_PropertySuffixes[i]), props);
thicknessMap[i] = FindProperty(string.Format("{0}{1}", kThicknessMap, m_PropertySuffixes[i]), props);
thicknessRemap[i] = FindProperty(string.Format("{0}{1}", kThicknessRemap, m_PropertySuffixes[i]), props);
// Details
UVDetail[i] = FindProperty(string.Format("{0}{1}", kUVDetail, m_PropertySuffixes[i]), props);

for (int i = 0; i < profiles.Length; i++)
{
names[i + 1] = new GUIContent(profiles[i].name);
values[i + 1] = i;
values[i + 1] = i + 1;
}
using (var scope = new EditorGUI.ChangeCheckScope())

m_MaterialEditor.ShaderProperty(subsurfaceRadius[layerIndex], Styles.subsurfaceRadiusText);
m_MaterialEditor.TexturePropertySingleLine(Styles.subsurfaceRadiusMapText, subsurfaceRadiusMap[layerIndex]);
m_MaterialEditor.ShaderProperty(thickness[layerIndex], Styles.thicknessText);
if (thicknessMap[layerIndex].textureValue != null)
{
// Display the remap of texture values.
Vector2 remap = thicknessRemap[layerIndex].vectorValue;
EditorGUI.BeginChangeCheck();
EditorGUILayout.MinMaxSlider(Styles.thicknessRemapText, ref remap.x, ref remap.y, 0.0f, 1.0f);
if (EditorGUI.EndChangeCheck())
{
thicknessRemap[layerIndex].vectorValue = remap;
}
}
else
{
// Allow the user to set the constant value of thickness if no thickness map is provided.
m_MaterialEditor.ShaderProperty(thickness[layerIndex], Styles.thicknessText);
}
}
protected void ShaderClearCoatInputGUI()

EditorGUI.indentLevel++;
bool refractionEnable = (material.HasProperty(kRefractionMode) && refractionMode.floatValue > 0.0f) && (material.HasProperty(kPreRefractionPass) && preRefractionPass.floatValue == 0.0f);
m_MaterialEditor.TexturePropertySingleLine(refractionEnable ? Styles.baseColorRefractionMaskText : Styles.baseColorText, baseColorMap[layerIndex], baseColor[layerIndex]);
m_MaterialEditor.TexturePropertySingleLine(Styles.baseColorText, baseColorMap[layerIndex], baseColor[layerIndex]);
if ((Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitStandard || (Lit.MaterialId)materialID.floatValue == Lit.MaterialId.LitAniso)
{

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


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

new GUIContent("Thin Object", "Choose this mode for thin objects, such as paper or leaves. Transmitted light reuses the shadowing state of the surface."),
new GUIContent("Regular", "Choose this mode for moderately thick objects. For performance reasons, transmitted light ignores occlusion (shadows).")
};
public readonly GUIContent profileMinMaxThickness = new GUIContent("Min-Max Thickness", "Shows the values of the thickness remap below (in millimeters).");
public readonly GUIContent profileThicknessRemap = new GUIContent("Thickness Remap", "Remaps the thickness parameter from [0, 1] to the desired range (in millimeters).");
public readonly GUIContent profileMinMaxThickness = new GUIContent("Min-Max Thickness (mm)", "Shows the values of the thickness remap below (in millimeters).");
public readonly GUIContent profileThicknessRemap = new GUIContent("Thickness Remap (mm)", "Remaps the thickness parameter from [0, 1] to the desired range (in millimeters).");
public readonly GUIContent profileWorldScale = new GUIContent("World Scale", "Size of the world unit in meters.");
// Old SSS Model >>>
public readonly GUIContent profileScatterDistance1 = new GUIContent("Scattering Distance #1", "The radius (in centimeters) of the 1st Gaussian filter, one per color channel. Alpha is ignored. The blur is energy-preserving, so a wide filter results in a large area with small contributions of individual samples. Smaller values increase the sharpness.");

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs


public Vector3 transmittanceColor;
[SurfaceDataAttributes("Transmittance Absorption Distance")]
public float atDistance;
[SurfaceDataAttributes("Refraction mask")]
public float refractionMask;
[SurfaceDataAttributes("Transmittance mask")]
public float transmittanceMask;
};
//-----------------------------------------------------------------------------

public float ior;
// Reuse thickness from SSS
public Vector3 absorptionCoefficient;
public float refractionMask;
public float transmittanceMask;
};
//-----------------------------------------------------------------------------

{
m_InitPreFGD = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/PreIntegratedFGD");
// For DisneyDiffuse integration values goes from (0.5 to 1.53125). GGX need 0 to 1. Use float format.
m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear);
m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGB2101010, RenderTextureReadWrite.Linear);
m_PreIntegratedFGD.filterMode = FilterMode.Bilinear;
m_PreIntegratedFGD.wrapMode = TextureWrapMode.Clamp;
m_PreIntegratedFGD.hideFlags = HideFlags.DontSave;

{
CoreUtils.DrawFullScreen(cmd, m_InitPreFGD, new RenderTargetIdentifier(m_PreIntegratedFGD));
}
m_isInit = true;
}

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


// UnityEngine.Experimental.Rendering.HDPipeline.Lit+RefractionMode: static fields
//
#define REFRACTIONMODE_NONE (0)
#define REFRACTIONMODE_THICK_PLANE (1)
#define REFRACTIONMODE_THICK_SPHERE (2)
#define REFRACTIONMODE_THIN_PLANE (3)
#define REFRACTIONMODE_PLANE (1)
#define REFRACTIONMODE_SPHERE (2)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+SurfaceData: static fields

#define DEBUGVIEW_LIT_SURFACEDATA_IOR (1016)
#define DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_COLOR (1017)
#define DEBUGVIEW_LIT_SURFACEDATA_AT_DISTANCE (1018)
#define DEBUGVIEW_LIT_SURFACEDATA_REFRACTION_MASK (1019)
#define DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_MASK (1019)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+BSDFData: static fields

#define DEBUGVIEW_LIT_BSDFDATA_COAT_IOR (1050)
#define DEBUGVIEW_LIT_BSDFDATA_IOR (1051)
#define DEBUGVIEW_LIT_BSDFDATA_ABSORPTION_COEFFICIENT (1052)
#define DEBUGVIEW_LIT_BSDFDATA_REFRACTION_MASK (1053)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE_MASK (1053)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+GBufferMaterial: static fields

float ior;
float3 transmittanceColor;
float atDistance;
float refractionMask;
float transmittanceMask;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Lit+BSDFData

float coatIOR;
float ior;
float3 absorptionCoefficient;
float refractionMask;
float transmittanceMask;
};
//

case DEBUGVIEW_LIT_SURFACEDATA_AT_DISTANCE:
result = surfacedata.atDistance.xxx;
break;
case DEBUGVIEW_LIT_SURFACEDATA_REFRACTION_MASK:
result = surfacedata.refractionMask.xxx;
case DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_MASK:
result = surfacedata.transmittanceMask.xxx;
break;
}
}

case DEBUGVIEW_LIT_BSDFDATA_ABSORPTION_COEFFICIENT:
result = bsdfdata.absorptionCoefficient;
break;
case DEBUGVIEW_LIT_BSDFDATA_REFRACTION_MASK:
result = bsdfdata.refractionMask.xxx;
case DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE_MASK:
result = bsdfdata.transmittanceMask.xxx;
break;
}
}

614
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


// Define refraction keyword helpers
#define HAS_REFRACTION (defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE))
#if HAS_REFRACTION
# include "../../../Core/ShaderLibrary/Refraction.hlsl"
# if defined(_REFRACTION_PLANE)
# define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModel_Plane(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
# elif defined(_REFRACTION_SPHERE)
# define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModel_Sphere(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
# endif
#endif
// In case we pack data uint16 buffer we need to change the output render target format to uint16
// TODO: Is there a way to automate these output type based on the format declare in lit.cs ?

// Reference Lambert diffuse / GGX Specular for IBL and area lights
#ifdef HAS_LIGHTLOOP // Both reference define below need to be define only if LightLoop is present, else we get a compile error
//#define LIT_DISPLAY_REFERENCE_AREA
//#define LIT_DISPLAY_REFERENCE_IBL
// #define LIT_DISPLAY_REFERENCE_AREA
// #define LIT_DISPLAY_REFERENCE_IBL
#endif
// Use Lambert diffuse instead of Disney diffuse
// #define LIT_DIFFUSE_LAMBERT_BRDF

#define LIT_USE_GGX_ENERGY_COMPENSATION
// Sampler use by area light, gaussian pyramid, ambient occlusion etc...
SamplerState s_linear_clamp_sampler;

#define MIN_N_DOT_V 0.0001 // The minimum value of 'NdotV'
//-----------------------------------------------------------------------------
// Helper for cheap screen space raycasting
//-----------------------------------------------------------------------------
float3 EstimateRaycast(float3 V, PositionInputs posInputs, float3 positionWS, float3 rayWS)
{
// For all refraction approximation, to calculate the refracted point in world space,
// we approximate the scene as a plane (back plane) with normal -V at the depth hit point.
// (We avoid to raymarch the depth texture to get the refracted point.)
uint2 depthSize = uint2(_PyramidDepthMipSize.xy);
// Get the depth of the approximated back plane
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInputs.positionSS * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane
float depthFromPositionInput = depth - posInputs.depthVS;
float offset = dot(-V, positionWS - posInputs.positionWS);
float depthFromPosition = depthFromPositionInput - offset;
float hitDistanceFromPosition = depthFromPosition / dot(-V, rayWS);
return positionWS + rayWS * hitDistanceFromPosition;
}
//-----------------------------------------------------------------------------
// Ligth and material classification for the deferred rendering path
// Configure what kind of combination is supported
//-----------------------------------------------------------------------------

/* 2 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 3 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 4 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 5 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 5 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_STANDARD,
// SSS
/* 6 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS,

/* 10 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_SSS,
/* 10 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_SSS,
// Aniso
/* 11 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_ANISO,

/* 15 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 15 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_ANISO,
// With foliage or crowd with SSS and standard can overlap a lot, better to have a dedicated combination
/* 16 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,

/* 20 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 20 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
// ClearCoat
/* 21 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,

/* 25 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 25 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 26 */ LIGHT_FEATURE_MASK_FLAGS | MATERIAL_FEATURE_MASK_FLAGS, // Catch all case with MATERIAL_FEATURE_MASK_FLAGS is needed in case we disable material classification
/* 26 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIAL_FEATURE_MASK_FLAGS, // Catch all case with MATERIAL_FEATURE_MASK_FLAGS is needed in case we disable material classification
};
uint FeatureFlagsToTileVariant(uint featureFlags)

uint transmissionMode = BitFieldExtract(_TransmissionFlags, 2u, 2u * subsurfaceProfile);
bsdfData.enableTransmission = transmissionMode != SSS_TRSM_MODE_NONE && (_EnableSSSAndTransmission > 0);
bsdfData.useThinObjectMode = transmissionMode == SSS_TRSM_MODE_THIN;
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, subsurfaceProfile);
#if defined(SHADERPASS) && (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT) // In case of GI pass don't modify the diffuseColor
bool enableSssAndTransmission = false;
#elif defined(SHADERPASS) && (SHADERPASS == SHADERPASS_SUBSURFACE_SCATTERING)
bool enableSssAndTransmission = true;
#else
bool enableSssAndTransmission = _EnableSSSAndTransmission != 0;
#endif
if (enableSssAndTransmission) // If we globally disable SSS effect, don't modify diffuseColor
{
// We modify the albedo here as this code is used by all lighting (including light maps and GI).
if (performPostScatterTexturing)
{
#if !defined(SHADERPASS) || (SHADERPASS != SHADERPASS_SUBSURFACE_SCATTERING)
bsdfData.diffuseColor = float3(1.0, 1.0, 1.0);
#endif
}
else
{
bsdfData.diffuseColor = sqrt(bsdfData.diffuseColor);
}
}
bsdfData.useThinObjectMode = transmissionMode == SSS_TRSM_MODE_THIN;
if (_UseDisneySSS)
{
bsdfData.transmittance = ComputeTransmittance(_ShapeParams[subsurfaceProfile].rgb,

_TransmissionTints[subsurfaceProfile].rgb,
bsdfData.thickness, bsdfData.subsurfaceRadius);
}
}
}
bsdfData.transmittance *= bsdfData.diffuseColor; // Premultiply
// Returns the modified albedo (diffuse color) for materials with subsurface scattering.
// Ref: Advanced Techniques for Realistic Real-Time Skin Rendering.
float3 ApplyDiffuseTexturingMode(BSDFData bsdfData)
{
float3 albedo = bsdfData.diffuseColor;
if (bsdfData.materialId == MATERIALID_LIT_SSS)
{
#if defined(SHADERPASS) && (SHADERPASS == SHADERPASS_SUBSURFACE_SCATTERING)
// If the SSS pass is executed, we know we have SSS enabled.
bool enableSssAndTransmission = true;
#else
bool enableSssAndTransmission = _EnableSSSAndTransmission != 0;
#endif
if (enableSssAndTransmission)
{
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, bsdfData.subsurfaceProfile);
if (performPostScatterTexturing)
{
// Post-scatter texturing mode: the albedo is only applied during the SSS pass.
#if !defined(SHADERPASS) || (SHADERPASS != SHADERPASS_SUBSURFACE_SCATTERING)
albedo = float3(1, 1, 1);
#endif
}
else
{
// Pre- and pos- scatter texturing mode.
albedo = sqrt(albedo);
}
}
return albedo;
}
void FillMaterialIdClearCoatData(float3 coatNormalWS, float coatCoverage, float coatIOR, inout BSDFData bsdfData)

bsdfData.coatCoverage = coatCoverage;
}
void FillMaterialIdTransparencyData(float ior, float3 transmittanceColor, float atDistance, float thickness, float refractionMask, inout BSDFData bsdfData)
void FillMaterialIdTransparencyData(float ior, float3 transmittanceColor, float atDistance, float thickness, float transmittanceMask, inout BSDFData bsdfData)
bsdfData.refractionMask = refractionMask;
bsdfData.transmittanceMask = transmittanceMask;
void GetPreIntegratedFGD(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 specularFGD, out float diffuseFGD)
void GetPreIntegratedFGD(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 specularFGD, out float diffuseFGD, out float reflectivity)
// _PreIntegratedFGD.x = Gv * (1 - Fc) with Fc = (1 - H.L)^5
// _PreIntegratedFGD.y = Gv * Fc
// Integral{BSDF * <N,L> dw} =
// Integral{(F0 + (1 - F0) * (1 - <V,H>)^5) * (BSDF / F) * <N,L> dw} =
// F0 * Integral{(BSDF / F) * <N,L> dw} +
// (1 - F0) * Integral{(1 - <V,H>)^5 * (BSDF / F) * <N,L> dw} =
// (1 - F0) * x + F0 * y = lerp(x, y, F0)
// _PreIntegratedFGD.z = DisneyDiffuse
// z = DisneyDiffuse
// f0 * Gv * (1 - Fc) + Gv * Fc
specularFGD = fresnel0 * preFGD.x + preFGD.y;
specularFGD = lerp(preFGD.xxx, preFGD.yyy, fresnel0);
diffuseFGD = preFGD.z;
// Remap from the [0, 1] to the [0.5, 1.5] range.
diffuseFGD = preFGD.z + 0.5;
reflectivity = preFGD.y;
}
void ApplyDebugToSurfaceData(inout SurfaceData surfaceData)

#if HAS_REFRACTION
// Note: Will override thickness of SSS's property set
FillMaterialIdTransparencyData(
surfaceData.ior, surfaceData.transmittanceColor, surfaceData.atDistance, surfaceData.thickness, surfaceData.refractionMask,
surfaceData.ior, surfaceData.transmittanceColor, surfaceData.atDistance, surfaceData.thickness, surfaceData.transmittanceMask,
bsdfData);
#endif

// GGX
float partLambdaV;
float energyCompensation;
float TdotV;
float BdotV;

float3x3 ltcXformClearCoat; // TODO: make sure the compiler not wasting VGPRs on constants
float ltcClearCoatFresnelTerm;
float3x3 ltcCoatT;
// Refraction
float3 transmissionRefractV; // refracted view vector after exiting the shape
float3 transmissionPositionWS; // start of the refracted ray after exiting the shape
float transmissionOpticalDepth; // length of the transmission during refraction through the shape
float3 transmissionTransmittance; // transmittance due to absorption
float transmissionSSMipLevel; // mip level of the screen space gaussian pyramid for rough refraction
#ifdef VOLUMETRIC_SHADOWING_ENABLED
float globalFogExtinction;

iblR = reflect(-V, iblNormalWS);
}
float reflectivity;
GetPreIntegratedFGD(NdotV, bsdfData.perceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD);
GetPreIntegratedFGD(NdotV, bsdfData.perceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD, reflectivity);
if (bsdfData.materialId == MATERIALID_LIT_CLEAR_COAT && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{

preLightData.iblDirWS = GetSpecularDominantDir(iblNormalWS, iblR, iblRoughness, NdotV);
preLightData.iblMipLevel = PerceptualRoughnessToMipmapLevel(iblPerceptualRoughness);
}
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
// Ref: Practical multiple scattering compensation for microfacet models.
// We only apply the formulation for metals.
// For dielectrics, the change of reflectance is negligible.
// We deem the intensity difference of a couple of percent for high values of roughness
// to not be worth the cost of another precomputed table.
// Note: this formulation bakes the BSDF non-symmetric!
preLightData.energyCompensation = 1.0 / reflectivity - 1.0;
#else
preLightData.energyCompensation = 0.0;
#endif // LIT_USE_GGX_ENERGY_COMPENSATION
// Area light
// UVs for sampling the LUTs

preLightData.globalFogExtinction = _GlobalFog_Extinction;
#endif
#ifdef REFRACTION_MODEL
RefractionModelResult refraction = REFRACTION_MODEL(V, posInput, bsdfData);
preLightData.transmissionRefractV = refraction.rayWS;
preLightData.transmissionPositionWS = refraction.positionWS;
preLightData.transmissionOpticalDepth = refraction.opticalDepth;
preLightData.transmissionTransmittance = exp(-bsdfData.absorptionCoefficient * refraction.opticalDepth);
preLightData.transmissionSSMipLevel = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness, uint(_GaussianPyramidColorMipSize.z));
#else
preLightData.transmissionRefractV = -V;
preLightData.transmissionPositionWS = posInput.positionWS;
preLightData.transmissionOpticalDepth = 0;
preLightData.transmissionTransmittance = float3(1.0, 1.0, 1.0);
preLightData.transmissionSSMipLevel = 0;
#endif
return preLightData;
}

// This function require the 3 structure surfaceData, builtinData, bsdfData because it may require both the engine side data, and data that will not be store inside the gbuffer.
float3 GetBakedDiffuseLigthing(SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData, PreLightData preLightData)
{
bsdfData.diffuseColor = ApplyDiffuseTexturingMode(bsdfData);
// Premultiply bake diffuse lighting information with DisneyDiffuse pre-integration
return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor;
}

#ifdef HAS_LIGHTLOOP
//-----------------------------------------------------------------------------
// Lighting structure for light accumulation
//-----------------------------------------------------------------------------
// These structure allow to accumulate lighting accross the Lit material
// AggregateLighting is init to zero and transfer to EvaluateBSDF, but the LightLoop can't access its content.
struct DirectLighting
{
float3 diffuse;
float3 specular;
};
struct IndirectLighting
{
float3 specularReflected;
float3 specularTransmitted;
};
struct AggregateLighting
{
DirectLighting direct;
IndirectLighting indirect;
};
void AccumulateDirectLighting(DirectLighting src, inout AggregateLighting dst)
{
dst.direct.diffuse += src.diffuse;
dst.direct.specular += src.specular;
}
void AccumulateIndirectLighting(IndirectLighting src, inout AggregateLighting dst)
{
dst.indirect.specularReflected += src.specularReflected;
dst.indirect.specularTransmitted += src.specularTransmitted;
}
//-----------------------------------------------------------------------------
// BSDF share between directional light, punctual light and area light (reference)
//-----------------------------------------------------------------------------

float diffuseTerm = DisneyDiffuse(NdotV, NdotL, LdotV, bsdfData.perceptualRoughness);
#endif
diffuseLighting = bsdfData.diffuseColor * diffuseTerm;
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
diffuseLighting = diffuseTerm;
}
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.

}
else
{
isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1 - positionLS.z) <= 1;
isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1.0 - positionLS.z) <= 1.0;
}
// We let the sampler handle tiling or clamping to border.

cookie.a = isInBounds ? cookie.a : 0;
cookie.a = isInBounds ? cookie.a : 0.0;
void EvaluateBSDF_Directional(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput, PreLightData preLightData,
DirectionalLightData lightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
DirectLighting EvaluateBSDF_Directional( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput, PreLightData preLightData,
DirectionalLightData lightData, BSDFData bsdfData)
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 positionWS = posInput.positionWS;
float3 L = -lightData.forward; // Lights are pointing backward in Unity

diffuseLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
specularLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
float shadow = 1;
float shadow = 1.0;
[branch] if (lightData.shadowIndex >= 0)
{

[branch] if (illuminance > 0.0)
{
BSDF(V, L, positionWS, preLightData, bsdfData, diffuseLighting, specularLighting);
BSDF(V, L, positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
diffuseLighting *= illuminance * lightData.diffuseScale;
specularLighting *= illuminance * lightData.specularScale;
lighting.diffuse *= illuminance * lightData.diffuseScale;
lighting.specular *= illuminance * lightData.specularScale;
}
[branch] if (bsdfData.enableTransmission)

float illuminance = Lambert() * ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
diffuseLighting += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
lighting.diffuse *= lightData.color;
lighting.specular *= lightData.color;
return lighting;
}
//-----------------------------------------------------------------------------

return attenuation * GetAngleAttenuation(L, -lightData.forward, lightData.angleScale, lightData.angleOffset);
}
void EvaluateBSDF_Punctual( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData, int GPULightType,
out float3 diffuseLighting,
out float3 specularLighting)
DirectLighting EvaluateBSDF_Punctual( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData, int GPULightType)
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 positionWS = posInput.positionWS;
int lightType = GPULightType;

lightData.diffuseScale *= attenuation;
lightData.specularScale *= attenuation;
diffuseLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
specularLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
float shadow = 1;
float shadow = 1.0;
[branch] if (lightData.shadowIndex >= 0)
{

[branch] if (illuminance > 0.0)
{
bsdfData.roughness = max(bsdfData.roughness, lightData.minRoughness); // Simulate that a punctual ligth have a radius with this hack
BSDF(V, L, positionWS, preLightData, bsdfData, diffuseLighting, specularLighting);
bsdfData.roughness = max(bsdfData.roughness, lightData.minRoughness); // Simulate that a punctual light have a radius with this hack
BSDF(V, L, positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
diffuseLighting *= illuminance * lightData.diffuseScale;
specularLighting *= illuminance * lightData.specularScale;
lighting.diffuse *= illuminance * lightData.diffuseScale;
lighting.specular *= illuminance * lightData.specularScale;
}
[branch] if (bsdfData.enableTransmission)

float illuminance = Lambert() * ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
diffuseLighting += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
lighting.diffuse *= lightData.color;
lighting.specular *= lightData.color;
return lighting;
}
#include "LitReference.hlsl"

//-----------------------------------------------------------------------------
void EvaluateBSDF_Line(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData,
out float3 diffuseLighting, out float3 specularLighting)
DirectLighting EvaluateBSDF_Line( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData)
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
diffuseLighting, specularLighting);
lighting.diffuse, lighting.specular);
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float len = lightData.size.x;
float3 T = lightData.right;

axis, invAspectRatio);
// Terminate if the shaded point is too far away.
if (intensity == 0.0) return;
if (intensity == 0.0)
return lighting;
lightData.diffuseScale *= intensity;
lightData.specularScale *= intensity;

{
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse);
ltcValue *= lightData.diffuseScale;
diffuseLighting = bsdfData.diffuseColor * (preLightData.ltcMagnitudeDiffuse * ltcValue);
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
}
[branch] if (bsdfData.enableTransmission)

ltcValue *= lightData.diffuseScale;
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
diffuseLighting += EvaluateTransmission(bsdfData, ltcValue, 1);
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse += EvaluateTransmission(bsdfData, ltcValue, 1);
}
// Evaluate the coat part

{
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular);
ltcValue *= lightData.specularScale;
specularLighting += preLightData.ltcMagnitudeFresnel * ltcValue;
lighting.specular += preLightData.ltcMagnitudeFresnel * ltcValue;
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
lighting.diffuse *= lightData.color;
lighting.specular *= lightData.color;
return lighting;
}
//-----------------------------------------------------------------------------

// #define ELLIPSOIDAL_ATTENUATION
void EvaluateBSDF_Rect( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData,
out float3 diffuseLighting, out float3 specularLighting)
DirectLighting EvaluateBSDF_Rect( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData)
DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
diffuseLighting, specularLighting);
lighting.diffuse, lighting.specular);
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float3 unL = lightData.positionWS - positionWS;
[branch]

return;
return lighting;
}
// Rotate the light direction into the light space.

#endif
// Terminate if the shaded point is too far away.
if (intensity == 0.0) return;
if (intensity == 0.0)
return lighting;
lightData.diffuseScale *= intensity;
lightData.specularScale *= intensity;

// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformDiffuse));
ltcValue *= lightData.diffuseScale;
diffuseLighting = bsdfData.diffuseColor * (preLightData.ltcMagnitudeDiffuse * ltcValue);
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
}
[branch] if (bsdfData.enableTransmission)

ltcValue *= lightData.diffuseScale;
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
diffuseLighting += EvaluateTransmission(bsdfData, ltcValue, 1);
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse += EvaluateTransmission(bsdfData, ltcValue, 1);
}
// Evaluate the coat part

// ltcValue = LTCEvaluate(lightVerts, V, bsdfData.coatNormalWS, preLightData.coatNdotV, preLightData.ltcXformClearCoat);
// specularLighting = preLightData.ltcClearCoatFresnelTerm * (ltcValue * bsdfData.coatCoverage);
// lighting.specular = preLightData.ltcClearCoatFresnelTerm * (ltcValue * bsdfData.coatCoverage);
// modify matL value based on Fresnel transmission
// matL = mul(matL, preLightData.ltcCoatT);

// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformSpecular));
ltcValue *= lightData.specularScale;
specularLighting += preLightData.ltcMagnitudeFresnel * ltcValue;
lighting.specular += preLightData.ltcMagnitudeFresnel * ltcValue;
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
lighting.diffuse *= lightData.color;
lighting.specular *= lightData.color;
return lighting;
void EvaluateBSDF_Area( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData, int GPULightType,
out float3 diffuseLighting, out float3 specularLighting)
DirectLighting EvaluateBSDF_Area( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData, int GPULightType)
EvaluateBSDF_Line(lightLoopContext, V, posInput, preLightData, lightData, bsdfData, diffuseLighting, specularLighting);
return EvaluateBSDF_Line(lightLoopContext, V, posInput, preLightData, lightData, bsdfData);
EvaluateBSDF_Rect(lightLoopContext, V, posInput, preLightData, lightData, bsdfData, diffuseLighting, specularLighting);
return EvaluateBSDF_Rect(lightLoopContext, V, posInput, preLightData, lightData, bsdfData);
// EvaluateBSDF_SSL
// EvaluateBSDF_SSLighting for screen space lighting
void EvaluateBSDF_SSL(float3 V, PositionInputs posInput, BSDFData bsdfData, out float3 diffuseLighting, out float3 specularLighting, out float2 weight)
IndirectLighting EvaluateBSDF_SSReflection(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, BSDFData bsdfData,
inout float hierarchyWeight)
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
weight = float2(0.0, 0.0);
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
// TODO
return lighting;
}
IndirectLighting EvaluateBSDF_SSRefraction(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, BSDFData bsdfData,
inout float hierarchyWeight)
{
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
// 3. If this point is available (ie: in color GBuffer and point is not in front of the object)
// 3. If this point is available (ie: in color buffer and point is not in front of the object)
weight.x = bsdfData.refractionMask;
float3 refractedBackPointWS = float3(0.0, 0.0, 0.0);
float opticalDepth = 0.0;
uint2 depthSize = uint2(_PyramidDepthMipSize.xy);
// For all refraction approximation, to calculate the refracted point in world space,
// we approximate the scene as a plane (back plane) with normal -V at the depth hit point.
// (We avoid to raymarch the depth texture to get the refracted point.)
#if defined(_REFRACTION_PLANE)
// Plane shape model:
// We approximate locally the shape of the object as a plane with normal {bsdfData.normalWS} at {bsdfData.positionWS}
// with a thickness {bsdfData.thickness}
// Refracted ray
float3 R = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
// Get the depth of the approximated back plane
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane
float distFromP = depth - posInput.depthVS;
// Optical depth within the thin plane
opticalDepth = bsdfData.thickness / dot(R, -bsdfData.normalWS);
// The refracted ray exiting the thin plane is the same as the incident ray (parallel interfaces and same ior)
float VoR = dot(-V, R);
float VoN = dot(V, bsdfData.normalWS);
refractedBackPointWS = posInput.positionWS + R * opticalDepth - V * (distFromP - VoR * opticalDepth);
#elif defined(_REFRACTION_SPHERE)
// Sphere shape model:
// We approximate locally the shape of the object as sphere, that is tangent to the shape.
// The sphere has a diameter of {bsdfData.thickness}
// The center of the sphere is at {bsdfData.positionWS} - {bsdfData.normalWS} * {bsdfData.thickness}
//
// So the light is refracted twice: in and out of the tangent sphere
// Get the depth of the approximated back plane
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInput.positionSS * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane
float depthFromPosition = depth - posInput.depthVS;
// First refraction (tangent sphere in)
// Refracted ray
float3 R1 = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
// Center of the tangent sphere
float3 C = posInput.positionWS - bsdfData.normalWS * bsdfData.thickness * 0.5;
// Second refraction (tangent sphere out)
float NoR1 = dot(bsdfData.normalWS, R1);
// Optical depth within the sphere
opticalDepth = -NoR1 * bsdfData.thickness;
// Out hit point in the tangent sphere
float3 P1 = posInput.positionWS + R1 * opticalDepth;
// Out normal
float3 N1 = normalize(C - P1);
// Out refracted ray
float3 R2 = refract(R1, N1, bsdfData.ior);
float N1oR2 = dot(N1, R2);
float VoR1 = dot(V, R1);
// Refracted source point
refractedBackPointWS = P1 - R2 * (depthFromPosition - NoR1 * VoR1 * bsdfData.thickness) / N1oR2;
#endif
float3 refractedBackPointWS = EstimateRaycast(V, posInput, preLightData.transmissionPositionWS, preLightData.transmissionRefractV);
uint2 depthSize = uint2(_PyramidDepthMipSize.xy);
float refractedBackPointDepth = LinearEyeDepth(LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, refractedBackPointSS * depthSize, 0).r, _ZBufferParams);
// Exit if texel is out of color buffer

|| any(refractedBackPointSS > 1.0))
{
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
return;
// Do nothing and don't update the hierarchy weight so we can fall back on refraction probe
return lighting;
float mipLevel = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness, uint(_GaussianPyramidColorMipSize.z));
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, refractedBackPointSS, mipLevel).rgb;
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, refractedBackPointSS, preLightData.transmissionSSMipLevel).rgb;
float3 transmittance = exp(-bsdfData.absorptionCoefficient * opticalDepth);
diffuseLighting *= transmittance;
#endif // HAS_REFRACTION
lighting.specularTransmitted *= preLightData.transmissionTransmittance;
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight); // Shouldn't be needed, but safer in case we decide to change hiearchy priority
lighting.specularTransmitted *= weight;
#else
// No refraction, no need to go further
hierarchyWeight = 1.0;
#endif
return lighting;
}
//-----------------------------------------------------------------------------

// _preIntegratedFGD and _CubemapLD are unique for each BRDF
void EvaluateBSDF_Env( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int envShapeType,
out float3 diffuseLighting, out float3 specularLighting, out float2 weight)
IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int envShapeType, int GPUImageBasedLightingType,
inout float hierarchyWeight)
weight = float2(0.0, 1.0);
IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
#if !HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
return lighting;
#endif
float3 envLighting = float3(0.0, 0.0, 0.0);
float weight = 1.0;
specularLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
envLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
// TODO: Do refraction reference (is it even possible ?)
/*
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
diffuseLighting = IntegrateLambertIBLRef(lightData, V, bsdfData);
#else
diffuseLighting = IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
#endif
*/
diffuseLighting = float3(0.0, 0.0, 0.0);
// #ifdef LIT_DIFFUSE_LAMBERT_BRDF
// envLighting += IntegrateLambertIBLRef(lightData, V, bsdfData);
// #else
// envLighting += IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
// #endif
weight = 1.0;
#else

float3 R = preLightData.iblDirWS;
float3 coatR = preLightData.coatIblDirWS;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{
positionWS = preLightData.transmissionPositionWS;
R = preLightData.transmissionRefractV;
}
// In Unity the cubemaps are capture with the localToWorld transform of the component.
// This mean that location and orientation matter. So after intersection of proxy volume we need to convert back to world.

// 2. Process the influence
float distFade = max(length(positionLS) - lightData.innerDistance.x, 0.0);
weight.y = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
weight = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
}
else if (envShapeType == ENVSHAPETYPE_BOX)
{

// Influence volume
// Calculate falloff value, so reflections on the edges of the volume would gradually blend to previous reflection.
float distFade = DistancePointBox(positionLS, -lightData.innerDistance, lightData.innerDistance);
weight.y = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
weight = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
weight.y = Smoothstep01(weight.y);
weight = Smoothstep01(weight);
specularLighting = float3(0.0, 0.0, 0.0);
// Evaluate the Clear Coat component if needed and change the BSDF roughness to match Fresnel transmission
if (bsdfData.materialId == MATERIALID_LIT_CLEAR_COAT && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))

// Evaluate the Clear Coat color
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, coatR, 0.0);
specularLighting += F * preLD.rgb * bsdfData.coatCoverage;
envLighting += F * preLD.rgb * bsdfData.coatCoverage;
// Change the Fresnel term to account for transmission through Clear Coat and reflection on the base layer.
F = Sqr(-F * bsdfData.coatCoverage + 1.0);

specularLighting += F * preLD.rgb * preLightData.specularFGD;
envLighting += F * preLD.rgb;
#endif
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
diffuseLighting = float3(0.0, 0.0, 0.0);
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
lighting.specularReflected = envLighting * preLightData.specularFGD * weight;
else
lighting.specularTransmitted = envLighting * preLightData.transmissionTransmittance * weight;
#endif
return lighting;
}
//-----------------------------------------------------------------------------

void PostEvaluateBSDF( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightLoopAccumulatedLighting accLighting, BSDFData bsdfData, float3 bakeDiffuseLighting,
PreLightData preLightData, BSDFData bsdfData, float3 bakeDiffuseLighting, AggregateLighting lighting,
out float3 diffuseLighting, out float3 specularLighting)
{
// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the baseColor)

// Try to mimic multibounce with specular color. Not the point of the original formula but ok result.
// Take the min of screenspace specular occlusion and visibility cone specular occlusion
#if GTAO_MULTIBOUNCE_APPROX
accLighting.envSpecularLighting *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0);
lighting.indirect.specularReflected *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0);
accLighting.envSpecularLighting *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion));
lighting.indirect.specularReflected *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion));
// TODO: we could call a function like PostBSDF that will apply albedo and divide by PI once for the loop
float3 directDiffuseLighting = (accLighting.dirDiffuseLighting + accLighting.punctualDiffuseLighting + accLighting.areaDiffuseLighting)
lighting.direct.diffuse *=
* GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);
GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);
* lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
// envDiffuseLighting is used for refraction in this Lit material. Use the weight to balance between transmission and reflection
diffuseLighting = lerp(directDiffuseLighting + bakeDiffuseLighting, accLighting.envDiffuseLighting, accLighting.envDiffuseLightingWeight);
specularLighting = accLighting.dirSpecularLighting + accLighting.punctualSpecularLighting + accLighting.areaSpecularLighting + accLighting.envSpecularLighting;
}
float3 modifiedDiffuseColor = ApplyDiffuseTexturingMode(bsdfData);
// Apply the albedo to the direct diffuse lighting (only once). The indirect (baked)
// diffuse lighting has already had the albedo applied in GetBakedDiffuseLigthing().
diffuseLighting = modifiedDiffuseColor * lighting.direct.diffuse + bakeDiffuseLighting;
// If refraction is enable we use the transmittanceMask to lerp between current diffuse lighting and refraction value
// Physically speaking, it should be transmittanceMask should be 1, but for artistic reasons, we let the value vary
#if HAS_REFRACTION
diffuseLighting = lerp(diffuseLighting, lighting.indirect.specularTransmitted, bsdfData.transmittanceMask);
#endif
specularLighting = lighting.direct.specular + lighting.indirect.specularReflected;
// Rescale the GGX to account for the multiple scattering.
specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation;
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO)
{
diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO)
{
diffuseLighting = GetSpecularOcclusionFromAmbientOcclusion(preLightData.NdotV, indirectAmbientOcclusion, bsdfData.roughness);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
#if GTAO_MULTIBOUNCE_APPROX
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO)
{
diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO)
{
diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
#endif
#endif
}
#endif // #ifdef HAS_LIGHTLOOP

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader


_SubsurfaceRadiusMap("Subsurface Radius Map", 2D) = "white" {}
_Thickness("Thickness", Range(0.0, 1.0)) = 1.0
_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
_CoatCoverage("Coat Coverage", Range(0.0, 1.0)) = 1.0
_CoatIOR("Coat IOR", Range(0.0, 1.0)) = 0.5

_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
[ToggleOff] _DistortionEnable("Enable Distortion", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 1.0
[Enum(Add, 0, Multiply, 1)] _DistortionBlendMode("Distortion Blend Mode", Int) = 0
[HideInInspector] _DistortionSrcBlend("Distortion Blend Src", Int) = 0
[HideInInspector] _DistortionDstBlend("Distortion Blend Dst", Int) = 0

// 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
_EmissionColor("Color", Color) = (1, 1, 1)
// HACK: GI Baking system relies on some properties existing in the shader ("_MainTex", "_Cutoff" and "_Color") for opacity handling, so we need to store our version of those parameters in the hard-coded name the GI baking system recognizes.
_MainTex("Albedo", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
}
HLSLINCLUDE

HLSLPROGRAM
#define SHADERPASS SHADERPASS_GBUFFER
#define _BYPASS_ALPHA_TEST
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitSharePass.hlsl"

967
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
文件差异内容过多而无法显示
查看文件

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


int _SubsurfaceProfile;
float _SubsurfaceRadius;
float _Thickness;
float4 _ThicknessRemap;
float _CoatCoverage;
float _CoatIOR;

PROP_DECL(int, _SubsurfaceProfile);
PROP_DECL(float, _SubsurfaceRadius);
PROP_DECL(float, _Thickness);
PROP_DECL(float4, _ThicknessRemap);
PROP_DECL(float, _OpacityAsDensity);
float _InheritBaseNormal1;

13
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl


{
float4 val = SampleEnv(lightLoopContext, lightData.envIndex, L, 0);
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function
acc += bsdfData.diffuseColor * LambertNoPI() * weightOverPdf * val.rgb;
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
acc += LambertNoPI() * weightOverPdf * val.rgb;
}
}

if (NdotL > 0.0)
{
float3 H = normalize(L + V);
float LdotH = dot(L, H);
float LdotV = dot(L, V);
float disneyDiffuse = DisneyDiffuse(NdotV, NdotL, LdotH, bsdfData.perceptualRoughness);
float disneyDiffuse = DisneyDiffuse(NdotV, NdotL, LdotV, bsdfData.perceptualRoughness);
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function
acc += bsdfData.diffuseColor * disneyDiffuse * weightOverPdf * val.rgb;
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
acc += disneyDiffuse * weightOverPdf * val.rgb;
}
}

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


_SubsurfaceRadiusMap("Subsurface Radius Map", 2D) = "white" {}
_Thickness("Thickness", Range(0.0, 1.0)) = 1.0
_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
_CoatCoverage("Coat Coverage", Range(0.0, 1.0)) = 1.0
_CoatIOR("Coat IOR", Range(0.0, 1.0)) = 0.5

_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
[ToggleOff] _DistortionEnable("Enable Distortion", Float) = 0.0
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 1.0
[Enum(Add, 0, Multiply, 1)] _DistortionBlendMode("Distortion Blend Mode", Int) = 0
[HideInInspector] _DistortionSrcBlend("Distortion Blend Src", Int) = 0
[HideInInspector] _DistortionDstBlend("Distortion Blend Dst", Int) = 0

_TessellationShapeFactor("Tessellation shape factor", Range(0.0, 1.0)) = 0.75 // Only use with Phong
_TessellationBackFaceCullEpsilon("Tessellation back face epsilon", Range(-1.0, 0.0)) = -0.25
// TODO: Handle culling mode for backface culling
// HACK: GI Baking system relies on some properties existing in the shader ("_MainTex", "_Cutoff" and "_Color") for opacity handling, so we need to store our version of those parameters in the hard-coded name the GI baking system recognizes.
_MainTex("Albedo", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
}
HLSLINCLUDE

#pragma domain Domain
#define SHADERPASS SHADERPASS_GBUFFER
#define _BYPASS_ALPHA_TEST
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/LitSharePass.hlsl"

998
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LtcData.DisneyDiffuse.cs
文件差异内容过多而无法显示
查看文件

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute


// divergence of execution across the warp.
float maxDistInPixels = maxDistance * max(pixelsPerMm.x, pixelsPerMm.y);
float3 albedo = ApplyDiffuseTexturingMode(bsdfData);
_CameraFilteringTexture[pixelCoord] = float4(bsdfData.diffuseColor * centerIrradiance, 1);
_CameraFilteringTexture[pixelCoord] = float4(albedo * centerIrradiance, 1);
#endif
return;
}

[branch] if (!useNearFieldKernel)
{
_CameraFilteringTexture[pixelCoord] = float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
_CameraFilteringTexture[pixelCoord] = float4(albedo * totalIrradiance / totalWeight, 1);
return;
}

totalIrradiance, totalWeight);
}
_CameraFilteringTexture[pixelCoord] = float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
_CameraFilteringTexture[pixelCoord] = float4(albedo * totalIrradiance / totalWeight, 1);
}

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader


float halfRcpVariance = _HalfRcpWeightedVariances[profileID].a;
#endif
float3 albedo = ApplyDiffuseTexturingMode(bsdfData);
bsdfData.diffuseColor = float3(1, 1, 1);
albedo = float3(1, 1, 1);
#endif
// Take the first (central) sample.

#if SSS_DEBUG_LOD
return float4(0, 0, 1, 1);
#else
return float4(bsdfData.diffuseColor * sampleIrradiance, 1);
return float4(albedo * sampleIrradiance, 1);
#endif
}

}
}
return float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
return float4(albedo * totalIrradiance / totalWeight, 1);
}
ENDHLSL
}

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


[GenerateHLSL]
public class SssConstants
{
public const int SSS_N_PROFILES = 16; // 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_PROFILES = 16; // Max. number of profiles, including the slot taken by the neutral profile
public const int SSS_NEUTRAL_PROFILE_ID = 0; // 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)

void OnEnable()
{
if (profiles != null && profiles.Length != SssConstants.SSS_NEUTRAL_PROFILE_ID)
Array.Resize(ref profiles, SssConstants.SSS_NEUTRAL_PROFILE_ID);
// The neutral profile is not a part of the array.
int profileArraySize = SssConstants.SSS_N_PROFILES - 1;
if (profiles != null && profiles.Length != profileArraySize)
Array.Resize(ref profiles, profileArraySize);
profiles = new SubsurfaceScatteringProfile[SssConstants.SSS_NEUTRAL_PROFILE_ID];
profiles = new SubsurfaceScatteringProfile[profileArraySize];
for (int i = 0; i < SssConstants.SSS_NEUTRAL_PROFILE_ID; i++)
for (int i = 0; i < profileArraySize; i++)
profiles[i] = new SubsurfaceScatteringProfile("Profile " + i);
profiles[i] = new SubsurfaceScatteringProfile("Profile " + (i + 1));
profiles[i].Validate();
}

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.");
Debug.Assert(SssConstants.SSS_NEUTRAL_PROFILE_ID < 16, "Transmission flags (32-bit integer) cannot support more than 16 profiles (2 bits per profile).");
UpdateCache();
}

// <<< Old SSS Model
}
public void UpdateCache(int i)
public void UpdateCache(int p)
// 'p' is the profile array index. 'i' is the index in the shader (accounting for the neutral profile).
int i = p + 1;
// Erase previous value (This need to be done here individually as in the SSS editor we edit individual component)
int mask = 1 << i;
texturingModeFlags &= ~mask;

texturingModeFlags |= (int)profiles[i].texturingMode << i;
transmissionFlags |= (int)profiles[i].transmissionMode << i * 2;
texturingModeFlags |= (int)profiles[p].texturingMode << i;
transmissionFlags |= (int)profiles[p].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
thicknessRemaps[i] = new Vector4(profiles[p].thicknessRemap.x, profiles[p].thicknessRemap.y - profiles[p].thicknessRemap.x, 0f, 0f);
worldScales[i] = new Vector4(profiles[p].worldScale, 0f, 0f, 0f);
shapeParams[i] = profiles[p].shapeParam;
shapeParams[i].w = profiles[p].maxRadius;
transmissionTints[i] = profiles[p].transmissionTint * 0.25f; // Premultiplied
filterKernels[n * i + j].x = profiles[i].filterKernelNearField[j].x;
filterKernels[n * i + j].y = profiles[i].filterKernelNearField[j].y;
filterKernels[n * i + j].x = profiles[p].filterKernelNearField[j].x;
filterKernels[n * i + j].y = profiles[p].filterKernelNearField[j].y;
filterKernels[n * i + j].z = profiles[i].filterKernelFarField[j].x;
filterKernels[n * i + j].w = profiles[i].filterKernelFarField[j].y;
filterKernels[n * i + j].z = profiles[p].filterKernelFarField[j].x;
filterKernels[n * i + j].w = profiles[p].filterKernelFarField[j].y;
halfRcpWeightedVariances[i] = profiles[i].halfRcpWeightedVariances;
halfRcpWeightedVariances[i] = profiles[p].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;
var stdDev1 = ((1f / 3f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * (Vector4)profiles[p].scatterDistance1;
var stdDev2 = ((1f / 3f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * (Vector4)profiles[p].scatterDistance2;
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);
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[p].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[p].lerpWeight);
filterKernelsBasic[n * i + j] = profiles[i].filterKernelBasic[j];
filterKernelsBasic[n * i + j] = profiles[p].filterKernelBasic[j];
}
// <<< Old SSS Model
}

14
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataIndividualLayer.hlsl


surfaceData.subsurfaceProfile = ADD_IDX(_SubsurfaceProfile);
surfaceData.subsurfaceRadius = ADD_IDX(_SubsurfaceRadius);
surfaceData.thickness = ADD_IDX(_Thickness);
#ifdef _SUBSURFACE_RADIUS_MAP_IDX
surfaceData.subsurfaceRadius *= SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_SubsurfaceRadiusMap), SAMPLER_SUBSURFACE_RADIUSMAP_IDX, ADD_IDX(layerTexCoord.base)).r;

surfaceData.thickness *= SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_ThicknessMap), SAMPLER_THICKNESSMAP_IDX, ADD_IDX(layerTexCoord.base)).r;
surfaceData.thickness = SAMPLE_UVMAPPING_TEXTURE2D(ADD_IDX(_ThicknessMap), SAMPLER_THICKNESSMAP_IDX, ADD_IDX(layerTexCoord.base)).r;
surfaceData.thickness = ADD_IDX(_ThicknessRemap).x + ADD_IDX(_ThicknessRemap).y * surfaceData.thickness;
#else
surfaceData.thickness = ADD_IDX(_Thickness);
#endif
// This part of the code is not used in case of layered shader but we keep the same macro system for simplicity

surfaceData.atDistance = _ATDistance;
// Thickness already defined with SSS (from both thickness and thicknessMap)
surfaceData.thickness *= _ThicknessMultiplier;
// Rough refraction don't use opacity. Instead we use opacity as a refraction mask.
surfaceData.refractionMask = alpha;
// Rough refraction don't use opacity. Instead we use opacity as a transmittance mask.
surfaceData.transmittanceMask = 1.0 - alpha;
surfaceData.refractionMask = 1.0;
surfaceData.transmittanceMask = 0.0;
#endif
surfaceData.coatNormalWS = input.worldToTangent[2].xyz; // Assign vertex normal

surfaceData.ior = 1.0;
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
surfaceData.atDistance = 1000000.0;
surfaceData.refractionMask = 0.0;
surfaceData.transmittanceMask = 0.0;
#endif // #if !defined(LAYERED_LIT_SHADER)

32
ScriptableRenderPipeline/HDRenderPipeline/Material/Material.hlsl


return result;
}
//-----------------------------------------------------------------------------
// Alpha test replacement
//-----------------------------------------------------------------------------
// This function must be use instead of clip instruction. It allow to manage in which case the clip is perform
void DoAlphaTest(float alpha, float alphaCutoff)
{
// For Deferred:
// If we have a prepass, we need to remove the clip from the GBuffer pass (otherwise HiZ does not work on PS4) - SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
// For Forward (Lit or Unlit)
// Opaque geometry always has a depth pre-pass so we never want to do the clip here. For transparent we perform the clip as usual.
// Also no alpha test for light transport
#if !(SHADERPASS == SHADERPASS_FORWARD && !defined(_SURFACE_TYPE_TRANSPARENT)) && !(SHADERPASS == SHADERPASS_FORWARD_UNLIT && !defined(_SURFACE_TYPE_TRANSPARENT)) && !defined(SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST) && !(SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)
clip(alpha - alphaCutoff);
#endif
}
//-----------------------------------------------------------------------------
// Reflection / Refraction hierarchy handling
//-----------------------------------------------------------------------------
// This function is use with reflection and refraction hierarchy of LightLoop
// It will add weight to hierarchyWeight but ensure that hierarchyWeight is not more than one
// by updating the weight value. Returned weight value must be apply on current lighting
// Example: Total hierarchyWeight is 0.8 and weight is 0.4. Function return hierarchyWeight of 1.0 and weight of 0.2
// hierarchyWeight and weight must be positive and between 0 and 1
void UpdateLightingHierarchyWeights(inout float hierarchyWeight, inout float weight)
{
float accumulatedWeight = hierarchyWeight + weight;
hierarchyWeight = saturate(accumulatedWeight);
weight -= saturate(accumulatedWeight - hierarchyWeight);
}
//-----------------------------------------------------------------------------
// BuiltinData

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


// or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color.
// The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color.
MaterialEditor.FixupEmissiveFlag(material);
// Commented out for now because unfortunately we used the hard coded property names used by the GI system for our own parameters
// So we need a way to work around that before we activate this.
//SetupMainTexForAlphaTestGI("_EmissiveColorMap", "_EmissiveColor", material);
// DoubleSidedGI has to be synced with our double sided toggle
var serializedObject = new SerializedObject(material);
var doubleSidedGIppt = serializedObject.FindProperty("m_DoubleSidedGI");
doubleSidedGIppt.boolValue = doubleSidedEnable;
serializedObject.ApplyModifiedProperties();
}
// This is a hack for GI. PVR looks in the shader for a texture named "_MainTex" to extract the opacity of the material for baking. In the same manner, "_Cutoff" and "_Color" are also necessary.
// Since we don't have those parameters in our shaders we need to provide a "fake" useless version of them with the right values for the GI to work.
protected static void SetupMainTexForAlphaTestGI(string colorMapPropertyName, string colorPropertyName, Material material)
{
if(material.HasProperty(colorMapPropertyName))
{
var mainTex = material.GetTexture(colorMapPropertyName);
material.SetTexture("_MainTex", mainTex);
}
if(material.HasProperty(colorPropertyName))
{
var color = material.GetColor(colorPropertyName);
material.SetColor("_Color", color);
}
if(material.HasProperty("_AlphaCutoff")) // Same for all our materials
{
var cutoff = material.GetFloat("_AlphaCutoff");
material.SetFloat("_Cutoff", cutoff);
}
}
static public void SetupBaseUnlitMaterialPass(Material material)

// 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();
EditorGUI.indentLevel--;
}

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


_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
[ToggleOff] _DistortionEnable("Enable Distortion", Float) = 0.0
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Depth Test Enable", Float) = 1.0
[Enum(Add, 0, Multiply, 1)] _DistortionBlendMode("Distortion Blend Mode", Int) = 0
[HideInInspector] _DistortionSrcBlend("Distortion Blend Src", Int) = 0
[HideInInspector] _DistortionDstBlend("Distortion Blend Dst", Int) = 0

// 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
_EmissionColor("Color", Color) = (1, 1, 1)
// HACK: GI Baking system relies on some properties existing in the shader ("_MainTex", "_Cutoff" and "_Color") for opacity handling, so we need to store our version of those parameters in the hard-coded name the GI baking system recognizes.
_MainTex("Albedo", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
}
HLSLINCLUDE

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


void DoAlphaTest(float alpha, float alphaCutoff)
{
// Don't do the clip when rendering forward opaque (unlit). Forward opaque always have a prepass (with depth test on)
#if !(SHADERPASS == SHADERPASS_FORWARD_UNLIT && !defined(_SURFACE_TYPE_TRANSPARENT))
clip(alpha - alphaCutoff);
#endif
}
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{

6
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl


if (_DebugLightingMode != DEBUGLIGHTINGMODE_NONE)
#endif
{
uint featureFlags = 0xFFFFFFFF;
#ifdef _SURFACE_TYPE_TRANSPARENT
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
#else
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
#endif
float3 diffuseLighting;
float3 specularLighting;
float3 bakeDiffuseLighting = GetBakedDiffuseLigthing(surfaceData, builtinData, bsdfData, preLightData);

2
ScriptableRenderPipeline/HDRenderPipeline/Sky/AtmosphericScattering/AtmosphericScattering.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderLoop/ScriptableRenderPipeline/HDRenderPipeline/Sky/AtmosphericScattering/AtmosphericScattering.cs. Please don't edit by hand.
// This file was automatically generated. Please don't edit by hand.
//
#ifndef ATMOSPHERICSCATTERING_CS_HLSL

2
ScriptableRenderPipeline/HDRenderPipeline/Sky/BlacksmithlSky/BlacksmithSkyRenderer.cs


public override void Build()
{
m_ProceduralSkyMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/Sky/SkyProcedural");
m_ProceduralSkyMaterial = CoreUtils.CreateEngineMaterial("Hidden/HDRenderPipeline/Sky/SkyBlacksmith");
}
public override void Cleanup()

28
ScriptableRenderPipeline/LightweightPipeline/Editor/LegacyShadersToLightweightPipelineUpgrader.cs


{
public class LegacyShadersToLightweightPipelineUpgrader
{
[MenuItem("RenderPipeline/LightweightPipeline/Material Upgraders/Upgrade Legacy Materials to LightweightPipeline - Project", false, 3)]
public static void UpgradeMaterialsToLDProject()
{
List<MaterialUpgrader> materialUpgraders = new List<MaterialUpgrader>();
GetUpgraders(ref materialUpgraders);
//[MenuItem("RenderPipeline/Lightweight Pipeline/Material Upgraders/Upgrade Legacy Materials to LightweightPipeline - Project", false, 3)]
//public static void UpgradeMaterialsToLDProject()
//{
// List<MaterialUpgrader> materialUpgraders = new List<MaterialUpgrader>();
// GetUpgraders(ref materialUpgraders);
MaterialUpgrader.UpgradeProjectFolder(materialUpgraders, "Upgrade to LD Materials");
}
// MaterialUpgrader.UpgradeProjectFolder(materialUpgraders, "Upgrade to LD Materials");
//}
[MenuItem("RenderPipeline/LightweightPipeline/Material Upgraders/Upgrade Legacy Materials to LightweightPipeline - Selection", false, 4)]
public static void UpgradeMaterialsToLDSelection()
{
List<MaterialUpgrader> materialUpgraders = new List<MaterialUpgrader>();
GetUpgraders(ref materialUpgraders);
//[MenuItem("RenderPipeline/Lightweight Pipeline/Material Upgraders/Upgrade Legacy Materials to LightweightPipeline - Selection", false, 4)]
//public static void UpgradeMaterialsToLDSelection()
//{
// List<MaterialUpgrader> materialUpgraders = new List<MaterialUpgrader>();
// GetUpgraders(ref materialUpgraders);
MaterialUpgrader.UpgradeSelection(materialUpgraders, "Upgrade to Lightweight Materials");
}
// MaterialUpgrader.UpgradeSelection(materialUpgraders, "Upgrade to Lightweight Materials");
//}
private static void GetUpgraders(ref List<MaterialUpgrader> materialUpgraders)
{

22
ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightAssetInspector.cs


public static GUIContent renderingLabel = new GUIContent("Rendering");
public static GUIContent shadowLabel = new GUIContent("Shadows");
public static GUIContent defaults = new GUIContent("Defaults");
public static GUIContent linearRenderingLabel = new GUIContent("Force Linear Colorspace", "When enabled Lightweight shader will perform gamma to linear conversion in the shader when linear rendering is not supported or disabled");
public static GUIContent maxPixelLights = new GUIContent("Per-Object Pixel Lights",
"Max amount of pixel lights.");
public static GUIContent maxAdditionalPixelLightsLabel = new GUIContent("Max Additional Pixel Lights",
"Controls the additional per-pixel lights that run in fragment light loop.");
"Lightweight pipeline support at most 4 vertex lights.");
"If enabled, shades additional lights exceeding maxAdditionalPixelLights per-vertex up to the maximum of 8 lights.");
public static GUIContent enableSoftParticles = new GUIContent("Enable Soft Particles", "By enabled this the pipeline will generate depth texture necessary for SoftParticles");

"Material to use when creating 3D objects");
public static GUIContent defaultParticleMaterial = new GUIContent("Default Particle Material",
"Material to use when creating Paticle Systems");
"Material to use when creating Particle Systems");
public static GUIContent defaultLineMaterial = new GUIContent("Default Line Material",
"Material to use when creating Line Renderers");

public static GUIContent attenuationTextureLabel = new GUIContent("Attenuation Texture", "Light attenuation falloff texture");
}
private int kMaxSupportedPixelLights = 9;
private SerializedProperty m_LinearRenderingProperty;
private int kMaxSupportedAdditionalPixelLights = 8;
private SerializedProperty m_MaxPixelLights;
private SerializedProperty m_MaxAdditionalPixelLights;
private SerializedProperty m_SupportsVertexLightProp;
private SerializedProperty m_SupportSoftParticlesProp;
private SerializedProperty m_ShadowTypeProp;

void OnEnable()
{
m_LinearRenderingProperty = serializedObject.FindProperty("m_LinearRendering");
m_MaxPixelLights = serializedObject.FindProperty("m_MaxPixelLights");
m_MaxAdditionalPixelLights = serializedObject.FindProperty("m_MaxAdditionalPixelLights");
m_SupportsVertexLightProp = serializedObject.FindProperty("m_SupportsVertexLight");
m_SupportSoftParticlesProp = serializedObject.FindProperty("m_SupportSoftParticles");
m_ShadowTypeProp = serializedObject.FindProperty("m_ShadowType");

EditorGUILayout.Space();
EditorGUILayout.LabelField(Styles.renderingLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_LinearRenderingProperty, Styles.linearRenderingLabel);
EditorGUILayout.LabelField(Styles.maxPixelLights);
m_MaxPixelLights.intValue = EditorGUILayout.IntSlider(m_MaxPixelLights.intValue, 0, kMaxSupportedPixelLights);
EditorGUILayout.LabelField(Styles.maxAdditionalPixelLightsLabel);
m_MaxAdditionalPixelLights.intValue = EditorGUILayout.IntSlider(m_MaxAdditionalPixelLights.intValue, 0, kMaxSupportedAdditionalPixelLights);
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(m_SupportsVertexLightProp, Styles.enableVertexLightLabel);
EditorGUILayout.PropertyField(m_SupportSoftParticlesProp, Styles.enableSoftParticles);

4
ScriptableRenderPipeline/LightweightPipeline/Editor/LightweightPipelineUpgraders.cs


{
public StandardUpgrader(string oldShaderName)
{
RenameShader(oldShaderName, LightweightPipelineAsset.m_PBSShaderPath);
RenameShader(oldShaderName, LightweightPipelineAsset.m_StandardShaderPath);
}
}

{
RenameShader(oldShaderName, LightweightPipelineAsset.m_PBSShaderPath);
RenameShader(oldShaderName, LightweightPipelineAsset.m_StandardShaderPath);
SetFloat("_Shininess", 1.0f);
}
}

8
ScriptableRenderPipeline/LightweightPipeline/Editor/StandardToLightweightMaterialUpgrader.cs


{
public class StandardToLightweightMaterialUpgrader
{
[MenuItem("RenderPipeline/LightweightPipeline/Material Upgraders/Upgrade Standard Materials to Lightweight Mobile - Project Folder", false, 1)]
[MenuItem("RenderPipeline/Lightweight Pipeline/Material Upgraders/Upgrade Project Materials", false, 1)]
MaterialUpgrader.UpgradeProjectFolder(upgraders, "Upgrade to LD Materials");
MaterialUpgrader.UpgradeProjectFolder(upgraders, "Upgrade to Lightweight Pipeline Materials");
[MenuItem("RenderPipeline/LightweightPipeline/Material Upgraders/Upgrade Standard Materials to Lightweight Mobile - Selection", false, 2)]
[MenuItem("RenderPipeline/Lightweight Pipeline/Material Upgraders/Upgrade Selected Materials", false, 2)]
MaterialUpgrader.UpgradeSelection(upgraders, "Upgrade to LD Materials");
MaterialUpgrader.UpgradeSelection(upgraders, "Upgrade to Lightweight Pipeline Materials");
}
private static void GetUpgraders(ref List<MaterialUpgrader> upgraders)

124
ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


public struct LightData
{
public int additionalPixelLightsCount;
public int vertexLightsCount;
public int pixelAdditionalLightsCount;
public int totalAdditionalLightsCount;
public bool hasAdditionalLights;
public bool shadowsRendered;
}

// Max amount of visible lights. This controls the lights constant buffers in shader but not the max shaded lights.
// Lights are set per-object and the max shaded lights for each object are controlled by the max pixel lights in pipeline asset and kMaxVertexLights.
// Maximum amount of visible lights the shader can process. This controls the constant global light buffer size.
// It must match the MAX_VISIBLE_LIGHTS in LightweightCore.cginc
private static readonly int kMaxPerObjectLights = 8;
// Lights are culled per-object. This holds the maximum amount of additional lights that can shade each object.
// The engine fills in the lights indices per-object in unity4_LightIndices0 and unity_4LightIndices1
private static readonly int kMaxPerObjectAdditionalLights = 8;
private Vector4[] m_LightPositions = new Vector4[kMaxVisibleAdditionalLights];
private Vector4[] m_LightColors = new Vector4[kMaxVisibleAdditionalLights];

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

public override void Dispose()
{
base.Dispose();
if (m_LightIndexListBuffer != null)
{
m_LightIndexListBuffer.Dispose();
m_LightIndexListBuffer = null;
}
}
CullResults m_CullResults;

if (m_Asset.AreShadowsEnabled() && lightData.mainLightIndex != -1)
{
VisibleLight mainLight = visibleLights[lightData.mainLightIndex];
if (!LightweightUtils.IsSupportedShadowType(mainLight.lightType))
{
Debug.LogWarning("Only directional and spot shadows are supported by LightweightPipeline.");
return;
}
int shadowOriginalIndex = (lightData.hasAdditionalLights) ? GetLightUnsortedIndex(lightData.mainLightIndex) : lightData.mainLightIndex;
int shadowOriginalIndex = (lightData.totalAdditionalLightsCount > 0) ? GetLightUnsortedIndex(lightData.mainLightIndex) : lightData.mainLightIndex;
lightData.shadowsRendered = RenderShadows(ref m_CullResults, ref mainLight,
shadowOriginalIndex, ref context);
}

int visibleLightsCount = visibleLights.Length;
m_SortedLightIndexMap.Clear();
// kMaxPerObjectLights + 1 main light
int maxSupportedPixelLights = Math.Min(m_Asset.MaxSupportedPixelLights, kMaxPerObjectLights + 1);
int maxPixelLights = Math.Min(maxSupportedPixelLights, visibleLightsCount);
if (maxPixelLights <= 1)
lightData.shadowsRendered = false;
if (visibleLightsCount <= 1)
lightData.mainLightIndex = maxPixelLights - 1;
lightData.additionalPixelLightsCount = 0;
// If there's exactly one visible light that will be picked as main light.
// Otherwise we disable main light by setting its index to -1.
lightData.mainLightIndex = visibleLightsCount - 1;
lightData.pixelAdditionalLightsCount = 0;
lightData.totalAdditionalLightsCount = 0;
return;
else
{
lightData.mainLightIndex = SortLights(visibleLights);
lightData.additionalPixelLightsCount = maxPixelLights - 1;
}
// We always support at least one per-pixel light, which is main light. Shade objects up to a limit of per-object
// pixel lights defined in the pipeline settings.
int maxSupportedPixelLights = Math.Min(m_Asset.MaxAdditionalPixelLights, kMaxPerObjectAdditionalLights) + 1;
int maxPixelLights = Math.Min(maxSupportedPixelLights, visibleLightsCount);
lightData.vertexLightsCount = (m_Asset.SupportsVertexLight) ? Math.Min(4, Math.Min(visibleLightsCount - maxPixelLights, kMaxPerObjectLights)) : 0;
lightData.hasAdditionalLights = (lightData.additionalPixelLightsCount + lightData.vertexLightsCount) > 0;
lightData.shadowsRendered = false;
// If vertex lighting is enabled in the pipeline settings, then we shade the remaining visible lights per-vertex
// up to the maximum amount of per-object lights.
int vertexLights = (m_Asset.SupportsVertexLight) ? kMaxPerObjectAdditionalLights - maxPixelLights - 1: 0;
lightData.mainLightIndex = SortLights(visibleLights);
lightData.pixelAdditionalLightsCount = maxPixelLights - 1;
lightData.totalAdditionalLightsCount = lightData.pixelAdditionalLightsCount + vertexLights;
}
private int SortLights(VisibleLight[] visibleLights)

Dictionary<int, int> visibleLightsIDMap = new Dictionary<int, int>();
for (int i = 0; i < totalVisibleLights; ++i)
visibleLightsIDMap.Add(visibleLights[i].light.GetInstanceID(), i);
visibleLightsIDMap.Add(visibleLights[i].GetHashCode(), i);
// Sorts light so we have all directionals first, then local lights.
// Directionals are sorted further by shadow, cookie and intensity

for (int i = 0; i < totalVisibleLights; ++i)
m_SortedLightIndexMap.Add(visibleLightsIDMap[visibleLights[i].light.GetInstanceID()]);
m_SortedLightIndexMap.Add(visibleLightsIDMap[visibleLights[i].GetHashCode()]);
return GetMainLight(visibleLights);
}

private void InitializeLightConstants(VisibleLight[] lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightSpotDir,
out Vector4 lightAttenuationParams)
{
lightPos = Vector4.zero;
lightPos = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
// When no lights are available in the pipeline or maxPixelLights is set to 0
// In this case we want to initialize the lightData to default values and return
// When no lights are visible, main light will be set to -1.
// In this case we initialize it to default values and return
if (lightIndex < 0)
return;

Vector4 dir = light.localToWorld.GetColumn(2);
lightSpotDir = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f);
// Spot Attenuation with a linear falloff can be defined as
// (SdotL - cosOuterAngle) / (cosInnerAngle - cosOuterAngle)
// This can be rewritten as
// invAngleRange = 1.0 / (cosInnerAngle - cosOuterAngle)
// SdotL * invAngleRange + (-cosOuterAngle * invAngleRange)
// If we precompute the terms in a MAD instruction
float angleRange = cosInneAngle - cosOuterAngle;
lightAttenuationParams = new Vector4(cosOuterAngle,
Mathf.Approximately(angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq);
float smoothAngleRange = cosInneAngle - cosOuterAngle;
if (Mathf.Approximately(smoothAngleRange, 0.0f))
smoothAngleRange = 1.0f;
float invAngleRange = 1.0f / smoothAngleRange;
float add = -cosOuterAngle * invAngleRange;
lightAttenuationParams = new Vector4(invAngleRange, add, quadAtten, rangeSq);
lightAttenuationParams = new Vector4(-1.0f, 1.0f, quadAtten, rangeSq);
lightAttenuationParams = new Vector4(0.0f, 1.0f, quadAtten, rangeSq);
}
}

{
// 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)
{
SetupMainLightConstants (cmd, lights, lightData.mainLightIndex, ref context);
if (lightData.shadowsRendered)
SetupShadowShaderConstants (cmd, ref context, ref lights[lightData.mainLightIndex], m_ShadowCasterCascadesCount);
}
SetupMainLightConstants(cmd, lights, lightData.mainLightIndex, ref context);
if (lightData.shadowsRendered)
SetupShadowShaderConstants(cmd, ref context, ref lights[lightData.mainLightIndex], m_ShadowCasterCascadesCount);
if (lightData.hasAdditionalLights)
if (lightData.totalAdditionalLightsCount > 0)
SetupAdditionalListConstants(cmd, lights, ref lightData, ref context);
}

}
m_CullResults.SetLightIndexMap(perObjectLightIndexMap);
cmd.SetGlobalVector(PerCameraBuffer._AdditionalLightCount, new Vector4 (lightData.additionalPixelLightsCount, lightData.vertexLightsCount, 0.0f, 0.0f));
cmd.SetGlobalVector(PerCameraBuffer._AdditionalLightCount, new Vector4 (lightData.pixelAdditionalLightsCount,
lightData.totalAdditionalLightsCount, 0.0f, 0.0f));
cmd.SetGlobalVectorArray (PerCameraBuffer._AdditionalLightPosition, m_LightPositions);
cmd.SetGlobalVectorArray (PerCameraBuffer._AdditionalLightColor, m_LightColors);
cmd.SetGlobalVectorArray (PerCameraBuffer._AdditionalLightAttenuationParams, m_LightAttenuations);

{
Vector3 shadowLightDir = Vector3.Normalize(shadowLight.localToWorld.GetColumn(2));
float bias = shadowLight.light.shadowBias * 0.1f;
float normalBias = shadowLight.light.shadowNormalBias;
Light light = shadowLight.light;
float bias = light.shadowBias * 0.1f;
float normalBias = light.shadowNormalBias;
float shadowResolution = m_ShadowSlices[0].shadowResolution;
const int maxShadowCascades = 4;

private void SetShaderKeywords(CommandBuffer cmd, ref LightData lightData, VisibleLight[] visibleLights)
{
LightweightUtils.SetKeyword(cmd, "_LIGHTWEIGHT_FORCE_LINEAR", m_Asset.ForceLinearRendering);
LightweightUtils.SetKeyword(cmd, "_VERTEX_LIGHTS", lightData.vertexLightsCount > 0);
LightweightUtils.SetKeyword(cmd, "_ATTENUATION_TEXTURE", m_Asset.AttenuationTexture != null);
int vertexLightsCount = lightData.totalAdditionalLightsCount - lightData.pixelAdditionalLightsCount;
LightweightUtils.SetKeyword(cmd, "_VERTEX_LIGHTS", vertexLightsCount > 0);
LightweightUtils.SetKeyword (cmd, "_MAIN_DIRECTIONAL_LIGHT", mainLightIndex != -1 && visibleLights[mainLightIndex].lightType == LightType.Directional);
LightweightUtils.SetKeyword (cmd, "_MAIN_DIRECTIONAL_LIGHT", mainLightIndex == -1 || visibleLights[mainLightIndex].lightType == LightType.Directional);
LightweightUtils.SetKeyword(cmd, "_ADDITIONAL_PIXEL_LIGHTS", lightData.additionalPixelLightsCount > 0);
LightweightUtils.SetKeyword(cmd, "_ADDITIONAL_LIGHTS", lightData.totalAdditionalLightsCount > 0);
string[] shadowKeywords = new string[] { "_HARD_SHADOWS", "_SOFT_SHADOWS", "_HARD_SHADOWS_CASCADES", "_SOFT_SHADOWS_CASCADES" };
for (int i = 0; i < shadowKeywords.Length; ++i)

RendererConfiguration GetRendererSettings(ref LightData lightData)
{
RendererConfiguration settings = RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe;
if (lightData.hasAdditionalLights)
if (lightData.totalAdditionalLightsCount > 0)
settings |= RendererConfiguration.PerObjectLightIndices8;
return settings;
}

5
ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.asset


m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3}
m_Name: LightweightPipelineAsset
m_EditorClassIdentifier:
m_MaxPixelLights: 5
m_SupportsVertexLight: 1
m_MaxAdditionalPixelLights: 4
m_SupportsVertexLight: 0
m_SupportSoftParticles: 1
m_MSAA: 4
m_RenderScale: 1

m_ShadowCascades: 1
m_Cascade2Split: 0.25
m_Cascade4Split: {x: 0.067, y: 0.2, z: 0.467}
m_LinearRendering: 1
m_AttenuationTexture: {fileID: 2800000, guid: ee420ad43ff580149a07f10ad66c49ff,
type: 3}
m_DefaultDiffuseMaterial: {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d,

25
ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.cs


public class LightweightPipelineAsset : RenderPipelineAsset
{
public static readonly string m_SimpleLightShaderPath = "ScriptableRenderPipeline/LightweightPipeline/Standard (Simple Lighting)";
public static readonly string m_PBSShaderPath = "ScriptableRenderPipeline/LightweightPipeline/Standard (Simple Lighting)";
public static readonly string m_BlitShaderPath = "Hidden/ScriptableRenderPipeline/LightweightPipeline/Blit";
public static readonly string m_CopyDephPath = "Hidden/ScriptableRenderPipeline/LightweightPipeline/CopyDepth";
private static readonly string m_PipelineFolder = "Assets/ScriptableRenderPipeline/LightweightPipeline";
public static readonly string m_SimpleLightShaderPath = "LightweightPipeline/Standard (Simple Lighting)";
public static readonly string m_StandardShaderPath = "LightweightPipeline/Standard (Physically Based)";
public static readonly string m_BlitShaderPath = "Hidden/LightweightPipeline/Blit";
public static readonly string m_CopyDephPath = "Hidden/LightweightPipeline/CopyDepth";
private static readonly string m_PipelineFolder = "Assets/LightweightPipeline";
[SerializeField] private int m_MaxPixelLights = 1;
[SerializeField] private int m_MaxAdditionalPixelLights = 1;
[SerializeField] private bool m_SupportsVertexLight = true;
[SerializeField] private bool m_SupportSoftParticles = false;
[SerializeField] private MSAAQuality m_MSAA = MSAAQuality.Disabled;

[SerializeField] private ShadowCascades m_ShadowCascades = ShadowCascades.NO_CASCADES;
[SerializeField] private float m_Cascade2Split = 0.25f;
[SerializeField] private Vector3 m_Cascade4Split = new Vector3(0.067f, 0.2f, 0.467f);
[SerializeField] private bool m_LinearRendering = true;
[SerializeField] private Texture2D m_AttenuationTexture;
[SerializeField] private Material m_DefaultDiffuseMaterial;

[SerializeField] private Shader m_DefaultShader;
#if UNITY_EDITOR
[UnityEditor.MenuItem("RenderPipeline/LightweightPipeline/Create Pipeline Asset", false, 15)]
[UnityEditor.MenuItem("RenderPipeline/Lightweight Pipeline/Create Pipeline Asset", false, 15)]
static void CreateLightweightPipeline()
{
var instance = ScriptableObject.CreateInstance<LightweightPipelineAsset>();

return ShadowSetting != ShadowType.NO_SHADOW;
}
public int MaxSupportedPixelLights
public int MaxAdditionalPixelLights
get { return m_MaxPixelLights; }
get { return m_MaxAdditionalPixelLights; }
}
public bool SupportsVertexLight

{
get { return m_Cascade4Split; }
private set { m_Cascade4Split = value; }
}
public bool ForceLinearRendering
{
get { return m_LinearRendering; }
set { m_LinearRendering = value; }
}
public Texture2D AttenuationTexture

5
ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineUtils.cs


if (rhs.lightType == LightType.Directional) return 1;
}
// Particle Lights have the Light reference set to null
// They are at the end of the priority
if (lhsLight == null) return 1;
if (rhsLight == null) return -1;
// In the following priority: Soft, Hard, None
if (lhsLight.shadows != rhsLight.shadows)
return (int)rhsLight.shadows - (int)lhsLight.shadows;

2
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightBlit.shader


Shader "Hidden/ScriptableRenderPipeline/LightweightPipeline/Blit"
Shader "Hidden/LightweightPipeline/Blit"
{
SubShader
{

2
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightCopyDepth.shader


Shader "Hidden/ScriptableRenderPipeline/LightweightPipeline/CopyDepth"
Shader "Hidden/LightweightPipeline/CopyDepth"
{
SubShader
{

203
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightCore.cginc


#ifndef LIGHTWEIGHT_PIPELINE_CORE_INCLUDED
#define LIGHTWEIGHT_PIPELINE_CORE_INCLUDED
#include "LightweightInput.cginc"
#include "LightweightLighting.cginc"
#include "LightweightShadows.cginc"
#include "UnityCG.cginc"
#define MAX_VISIBLE_LIGHTS 16
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
#define LIGHTWEIGHT_SPECULAR_HIGHLIGHTS
#if defined(UNITY_COLORSPACE_GAMMA)
#define LIGHTWEIGHT_GAMMA_TO_LINEAR(gammaColor) gammaColor * gammaColor
#define LIGHTWEIGHT_LINEAR_TO_GAMMA(linColor) sqrt(color)
#else
#define LIGHTWEIGHT_GAMMA_TO_LINEAR(color) color
#define LIGHTWEIGHT_LINEAR_TO_GAMMA(color) color
#define kDieletricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) // standard dielectric reflectivity coef at incident angle (= 4%)
#ifdef _SPECULAR_SETUP
#define SAMPLE_METALLICSPECULAR(uv) tex2D(_SpecGlossMap, uv)
#else
#define SAMPLE_METALLICSPECULAR(uv) tex2D(_MetallicGlossMap, uv)
#endif
CBUFFER_START(_PerObject)
half4 unity_LightIndicesOffsetAndCount;
half4 unity_4LightIndices0;
half4 unity_4LightIndices1;
half _Shininess;
CBUFFER_END
CBUFFER_START(_PerCamera)
float4 _MainLightPosition;
half4 _MainLightColor;
float4 _MainLightAttenuationParams;
half4 _MainLightSpotDir;
half4 _AdditionalLightCount;
float4 _AdditionalLightPosition[MAX_VISIBLE_LIGHTS];
half4 _AdditionalLightColor[MAX_VISIBLE_LIGHTS];
float4 _AdditionalLightAttenuationParams[MAX_VISIBLE_LIGHTS];
half4 _AdditionalLightSpotDir[MAX_VISIBLE_LIGHTS];
CBUFFER_END
half SpecularReflectivity(half3 specular)
CBUFFER_START(_PerFrame)
half4 _GlossyEnvironmentColor;
sampler2D _AttenuationTexture;
CBUFFER_END
half3 TangentToWorldNormal(half3 normalTangent, half3 tangent, half3 binormal, half3 normal)
#if (SHADER_TARGET < 30)
// SM2.0: instruction count limitation
// SM2.0: simplified SpecularStrength
return specular.r; // Red channel - because most metals are either monocrhome or with redish/yellowish tint
half3x3 tangentToWorld = half3x3(tangent, binormal, normal);
return normalize(mul(normalTangent, tangentToWorld));
}
float ComputeFogFactor(float z)
{
float clipZ_01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(z);
#if defined(FOG_LINEAR)
// factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
float fogFactor = saturate(clipZ_01 * unity_FogParams.z + unity_FogParams.w);
return half(fogFactor);
#elif defined(FOG_EXP)
// factor = exp(-density*z)
float unityFogFactor = unity_FogParams.y * clipZ_01;
return half(saturate(exp2(-unityFogFactor)));
#elif defined(FOG_EXP2)
// factor = exp(-(density*z)^2)
float unityFogFactor = unity_FogParams.x * clipZ_01;
return half(saturate(exp2(-unityFogFactor*unityFogFactor)));
return max(max(specular.r, specular.g), specular.b);
return 0.0h;
#endif
}
void ApplyFog(inout half3 color, half fogFactor)
{
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
color = lerp(unity_FogColor, color, fogFactor);
#endif
}
half4 OutputColor(half3 color, half alpha)
{
#if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON)
return half4(LIGHTWEIGHT_LINEAR_TO_GAMMA(color), alpha);
#else
return half4(LIGHTWEIGHT_LINEAR_TO_GAMMA(color), 1);
inline void InitializeSurfaceData(LightweightVertexOutput i, out SurfaceData outSurfaceData)
inline half Alpha(half albedoAlpha)
float2 uv = i.uv01.xy;
half4 albedoAlpha = tex2D(_MainTex, uv);
#if defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A)
half alpha = _Color.a;
#else
half alpha = albedoAlpha * _Color.a;
#endif
#if defined(_ALPHATEST_ON)
clip(alpha - _Cutoff);
#endif
return alpha;
}
outSurfaceData.albedo = LIGHTWEIGHT_GAMMA_TO_LINEAR(albedoAlpha.rgb) * _Color.rgb;
outSurfaceData.alpha = Alpha(albedoAlpha.a);
outSurfaceData.metallicSpecGloss = MetallicSpecGloss(uv, albedoAlpha);
outSurfaceData.normalWorld = Normal(i);
outSurfaceData.ao = OcclusionLW(uv);
outSurfaceData.emission = EmissionLW(uv);
half3 Normal(float2 uv)
{
#if _NORMALMAP
return UnpackNormal(tex2D(_BumpMap, uv));
#else
return half3(0.0h, 0.0h, 1.0h);
#endif
inline void InitializeBRDFData(SurfaceData surfaceData, out BRDFData outBRDFData)
inline void SpecularGloss(half2 uv, half alpha, out half4 specularGloss)
// BRDF SETUP
#ifdef _METALLIC_SETUP
half2 metallicGloss = surfaceData.metallicSpecGloss.ra;
half metallic = metallicGloss.r;
half smoothness = metallicGloss.g;
specularGloss = half4(0, 0, 0, 1);
#ifdef _SPECGLOSSMAP
specularGloss = tex2D(_SpecGlossMap, uv);
specularGloss.rgb = LIGHTWEIGHT_GAMMA_TO_LINEAR(specularGloss.rgb);
#elif defined(_SPECULAR_COLOR)
specularGloss = _SpecColor;
#endif
#ifdef _GLOSSINESS_FROM_BASE_ALPHA
specularGloss.a = alpha;
#endif
}
// We'll need oneMinusReflectivity, so
// 1-reflectivity = 1-lerp(dielectricSpec, 1, metallic) = lerp(1-dielectricSpec, 0, metallic)
// store (1-dielectricSpec) in kDieletricSpec.a, then
// 1-reflectivity = lerp(alpha, 0, metallic) = alpha + metallic*(0 - alpha) =
// = alpha - metallic * alpha
half oneMinusDielectricSpec = kDieletricSpec.a;
half oneMinusReflectivity = oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
half reflectivity = 1.0 - oneMinusReflectivity;
half4 MetallicSpecGloss(float2 uv, half albedoAlpha)
{
half4 specGloss;
outBRDFData.diffuse = surfaceData.albedo * oneMinusReflectivity;
outBRDFData.specular = lerp(kDieletricSpec.rgb, surfaceData.albedo, metallic);
#ifdef _METALLICSPECGLOSSMAP
specGloss = specGloss = SAMPLE_METALLICSPECULAR(uv);
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
specGloss.a = albedoAlpha * _GlossMapScale;
#else
specGloss.a *= _GlossMapScale;
#endif
#else // _METALLICSPECGLOSSMAP
#if _METALLIC_SETUP
specGloss.rgb = _Metallic.rrr;
half3 specular = surfaceData.metallicSpecGloss.rgb;
half smoothness = surfaceData.metallicSpecGloss.a;
half reflectivity = SpecularReflectivity(specular);
specGloss.rgb = _SpecColor.rgb;
#endif
outBRDFData.diffuse = surfaceData.albedo * (half3(1.0h, 1.0h, 1.0h) - specular);
outBRDFData.specular = specular;
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
specGloss.a = albedoAlpha * _GlossMapScale;
#else
specGloss.a = _Glossiness;
#endif
outBRDFData.grazingTerm = saturate(smoothness + reflectivity);
outBRDFData.perceptualRoughness = 1.0h - smoothness;
outBRDFData.roughness = outBRDFData.perceptualRoughness * outBRDFData.perceptualRoughness;
return specGloss;
}
#ifdef _ALPHAPREMULTIPLY_ON
half alpha = surfaceData.alpha;
outBRDFData.diffuse *= alpha;
surfaceData.alpha = reflectivity + alpha * (1.0 - reflectivity);
half OcclusionLW(float2 uv)
{
#ifdef _OCCLUSIONMAP
#if (SHADER_TARGET < 30)
// SM20: instruction count limitation
// SM20: simpler occlusion
return tex2D(_OcclusionMap, uv).g;
#else
half occ = tex2D(_OcclusionMap, uv).g;
return LerpOneTo(occ, _OcclusionStrength);
#endif
#else
return 1.0;
half4 OutputColor(half3 color, half alpha)
half3 EmissionLW(float2 uv)
#if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON)
return LIGHTWEIGHT_LINEAR_TO_GAMMA(half4(color, alpha));
#ifndef _EMISSION
return 0;
return half4(LIGHTWEIGHT_LINEAR_TO_GAMMA(color), 1);
return LIGHTWEIGHT_GAMMA_TO_LINEAR(tex2D(_EmissionMap, uv).rgb) * _EmissionColor.rgb;
#endif

239
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc


#ifndef LIGHTWEIGHT_LIGHTING_INCLUDED
#define LIGHTWEIGHT_LIGHTING_INCLUDED
#include "LightweightCore.cginc"
#include "LightweightShadows.cginc"
#define kDieletricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) // standard dielectric reflectivity coef at incident angle (= 4%)
// Main light initialized without indexing
#define INITIALIZE_MAIN_LIGHT(light) \
light.pos = _MainLightPosition; \
light.color = _MainLightColor; \
light.atten = _MainLightAttenuationParams; \
light.spotDir = _MainLightSpotDir;
// Indexing might have a performance hit for old mobile hardware
#define INITIALIZE_LIGHT(light, i) \
half4 indices = (i < 4) ? unity_4LightIndices0 : unity_4LightIndices1; \
int index = (i < 4) ? i : i - 4; \
int lightIndex = indices[index]; \
light.pos = _AdditionalLightPosition[lightIndex]; \
light.color = _AdditionalLightColor[lightIndex]; \
light.atten = _AdditionalLightAttenuationParams[lightIndex]; \
light.spotDir = _AdditionalLightSpotDir[lightIndex]
struct LightInput
{
float4 pos;
half4 color;
float4 atten;
half4 spotDir;
};
struct SurfaceData
{
half3 albedo;
half3 specular;
half metallic;
half smoothness;
half3 normal;
half3 emission;
half occlusion;
half alpha;
};
struct SurfaceInput
{
float4 lightmapUV;
half3 normalWS;
half3 tangentWS;
half3 bitangentWS;
float3 positionWS;
half3 viewDirectionWS;
half fogFactor;
};
struct BRDFData
{
half3 diffuse;
half3 specular;
half perceptualRoughness;
half roughness;
half grazingTerm;
};
inline void InitializeSurfaceData(out SurfaceData outSurfaceData)
{
outSurfaceData.albedo = half3(1.0h, 1.0h, 1.0h);
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
outSurfaceData.metallic = 1.0h;
outSurfaceData.smoothness = 0.5h;
outSurfaceData.normal = half3(0.0h, 0.0h, 1.0h);
outSurfaceData.occlusion = 1.0h;
outSurfaceData.emission = half3(0.0h, 0.0h, 0.0h);
outSurfaceData.alpha = 1.0h;
}
half SpecularReflectivity(half3 specular)
{
#if (SHADER_TARGET < 30)
// SM2.0: instruction count limitation
// SM2.0: simplified SpecularStrength
return specular.r; // Red channel - because most metals are either monocrhome or with redish/yellowish tint
#else
return max(max(specular.r, specular.g), specular.b);
#endif
}
inline void InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, half alpha, out BRDFData outBRDFData)
{
// BRDF SETUP
#ifdef _METALLIC_SETUP
// We'll need oneMinusReflectivity, so
// 1-reflectivity = 1-lerp(dielectricSpec, 1, metallic) = lerp(1-dielectricSpec, 0, metallic)
// store (1-dielectricSpec) in kDieletricSpec.a, then
// 1-reflectivity = lerp(alpha, 0, metallic) = alpha + metallic*(0 - alpha) =
// = alpha - metallic * alpha
half oneMinusDielectricSpec = kDieletricSpec.a;
half oneMinusReflectivity = oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
half reflectivity = 1.0 - oneMinusReflectivity;
outBRDFData.diffuse = albedo * oneMinusReflectivity;
outBRDFData.specular = lerp(kDieletricSpec.rgb, albedo, metallic);
#else
half reflectivity = SpecularReflectivity(specular);
outBRDFData.diffuse = albedo * (half3(1.0h, 1.0h, 1.0h) - specular);
outBRDFData.specular = specular;
#endif
outBRDFData.grazingTerm = saturate(smoothness + reflectivity);
outBRDFData.perceptualRoughness = 1.0h - smoothness;
outBRDFData.roughness = outBRDFData.perceptualRoughness * outBRDFData.perceptualRoughness;
#ifdef _ALPHAPREMULTIPLY_ON
outBRDFData.diffuse *= alpha;
alpha = reflectivity + alpha * (1.0 - reflectivity);
#endif
}
// Based on Minimalist CookTorrance BRDF
// Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255

return c;
}
UnityIndirect LightweightGI(float2 lightmapUV, half3 ambientColor, half3 normalWorld, half3 reflectVec, half occlusion, half perceptualRoughness)
UnityIndirect LightweightGI(float4 lightmapUV, half3 normalWorld, half3 reflectVec, half occlusion, half perceptualRoughness)
ambientColor = (DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, lightmapUV)));
o.diffuse += (DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, lightmapUV.xy))) * occlusion;
ambientColor += SHEvalLinearL0L1(half4(normalWorld, 1.0));
ambientColor = max(half3(0.0, 0.0, 0.0), ambientColor);
o.diffuse = ShadeSH9(half4(normalWorld, 1.0)) * occlusion;
o.diffuse = ambientColor * occlusion;
#ifndef _GLOSSYREFLECTIONS_OFF
Unity_GlossyEnvironmentData g;

return o;
}
inline half ComputeLightAttenuationVertex(LightInput lightInput, half3 normal, float3 worldPos, out half3 lightDirection)
half SpotAttenuation(half3 spotDirection, half3 lightDirection, float4 attenuationParams)
{
// Spot Attenuation with a linear falloff can be defined as
// (SdotL - cosOuterAngle) / (cosInnerAngle - cosOuterAngle)
// This can be rewritten as
// invAngleRange = 1.0 / (cosInnerAngle - cosOuterAngle)
// SdotL * invAngleRange + (-cosOuterAngle * invAngleRange)
// If we precompute the terms in a MAD instruction
half SdotL = dot(spotDirection, lightDirection);
// attenuationParams.x = invAngleRange
// attenuationParams.y = (-cosOuterAngle invAngleRange)
return saturate(SdotL * attenuationParams.x + attenuationParams.y);
}
// In per-vertex falloff there's no smooth falloff to light range. A hard cut will be noticed
inline half ComputeVertexLightAttenuation(LightInput lightInput, half3 normal, float3 worldPos, out half3 lightDirection)
float3 posToLightVec = lightInput.pos - worldPos;
float3 posToLightVec = lightInput.pos - worldPos * lightInput.pos.w;
//// attenuationParams.z = kQuadFallOff = (25.0) / (lightRange * lightRange)
//// attenuationParams.w = lightRange * lightRange
//// TODO: we can precompute 1.0 / (attenuationParams.w * 0.64 - attenuationParams.w)
//// falloff is computed from 80% light range squared
float lightAtten = half(1.0 / (1.0 + distanceSqr * attenuationParams.z));
half SdotL = saturate(dot(lightInput.spotDir.xyz, lightDirection));
lightAtten *= saturate((SdotL - attenuationParams.x) / attenuationParams.y);
return half(lightAtten);
// attenuationParams.z = kQuadFallOff = (25.0) / (lightRange * lightRange)
// attenuationParams.w = lightRange * lightRange
half lightAtten = half(1.0 / (1.0 + distanceSqr * attenuationParams.z));
lightAtten *= SpotAttenuation(lightInput.spotDir.xyz, lightDirection, attenuationParams);
return lightAtten;
inline half ComputeLightAttenuation(LightInput lightInput, half3 normal, float3 worldPos, out half3 lightDirection)
// In per-pixel falloff attenuation smoothly decreases to light range.
inline half ComputePixelLightAttenuation(LightInput lightInput, half3 normal, float3 worldPos, out half3 lightDirection)
#ifdef _ATTENUATION_TEXTURE
float u = (distanceSqr * attenuationParams.z) / attenuationParams.w;
float lightAtten = tex2D(_AttenuationTexture, float2(u, 0.0)).a;
#else
//// attenuationParams.z = kQuadFallOff = (25.0) / (lightRange * lightRange)
//// attenuationParams.w = lightRange * lightRange
//// TODO: we can precompute 1.0 / (attenuationParams.w * 0.64 - attenuationParams.w)
//// falloff is computed from 80% light range squared
float lightAtten = half(1.0 / (1.0 + distanceSqr * attenuationParams.z));
float falloff = saturate((distanceSqr - attenuationParams.w) / (attenuationParams.w * 0.64 - attenuationParams.w));
lightAtten *= half(falloff);
#endif
half SdotL = saturate(dot(lightInput.spotDir.xyz, lightDirection));
lightAtten *= saturate((SdotL - attenuationParams.x) / attenuationParams.y);
return half(lightAtten);
float u = (distanceSqr * attenuationParams.z) / attenuationParams.w;
half lightAtten = tex2D(_AttenuationTexture, float2(u, 0.0)).a;
lightAtten *= SpotAttenuation(lightInput.spotDir.xyz, lightDirection, attenuationParams);
return lightAtten;
}
inline half ComputeMainLightAttenuation(LightInput lightInput, half3 normal, float3 worldPos, out half3 lightDirection)

lightDirection = lightInput.pos;
return 1.0;
#else
return ComputeLightAttenuation(lightInput, normal, worldPos, lightDirection);
return ComputePixelLightAttenuation(lightInput, normal, worldPos, lightDirection);
#endif
}

return (diffuse + specular) * atten;
}
half4 LightweightFragmentPBR(half4 lightmapUV, float3 positionWS, half3 normalWS, half3 tangentWS, half3 bitangentWS,
half3 viewDirectionWS, half fogFactor, half3 albedo, half metallic, half3 specular, half smoothness,
half3 normalTS, half ambientOcclusion, half3 emission, half alpha)
{
BRDFData brdfData;
InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
half3 vertexNormal = normalWS;
#if _NORMALMAP
normalWS = TangentToWorldNormal(normalTS, tangentWS, bitangentWS, normalWS);
#else
normalWS = normalize(normalWS);
#endif
half3 reflectVec = reflect(-viewDirectionWS, normalWS);
half roughness2 = brdfData.roughness * brdfData.roughness;
UnityIndirect indirectLight = LightweightGI(lightmapUV, normalWS, reflectVec, ambientOcclusion, brdfData.perceptualRoughness);
// PBS
half fresnelTerm = Pow4(1.0 - saturate(dot(normalWS, viewDirectionWS)));
half3 color = LightweightBRDFIndirect(brdfData, indirectLight, roughness2, fresnelTerm);
half3 lightDirectionWS;
LightInput light;
INITIALIZE_MAIN_LIGHT(light);
half lightAtten = ComputeMainLightAttenuation(light, normalWS, positionWS, lightDirectionWS);
lightAtten *= LIGHTWEIGHT_SHADOW_ATTENUATION(positionWS, normalize(vertexNormal), _ShadowLightDirection.xyz);
half NdotL = saturate(dot(normalWS, lightDirectionWS));
half3 radiance = light.color * (lightAtten * NdotL);
color += LightweightBDRF(brdfData, roughness2, normalWS, lightDirectionWS, viewDirectionWS) * radiance;
#ifdef _ADDITIONAL_LIGHTS
int pixelLightCount = min(_AdditionalLightCount.x, unity_LightIndicesOffsetAndCount.y);
for (int lightIter = 0; lightIter < pixelLightCount; ++lightIter)
{
LightInput light;
INITIALIZE_LIGHT(light, lightIter);
half lightAtten = ComputePixelLightAttenuation(light, normalWS, positionWS, lightDirectionWS);
half NdotL = saturate(dot(normalWS, lightDirectionWS));
half3 radiance = light.color * (lightAtten * NdotL);
color += LightweightBDRF(brdfData, roughness2, normalWS, lightDirectionWS, viewDirectionWS) * radiance;
}
#endif
color += emission;
// Computes fog factor per-vertex
ApplyFog(color, fogFactor);
return OutputColor(color, alpha);
}
#endif

244
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPassLit.cginc


#ifndef LIGHTWEIGHT_PASS_LIT_INCLUDED
#define LIGHTWEIGHT_PASS_LIT_INCLUDED
#include "LightweightCore.cginc"
#include "LightweightLighting.cginc"
struct LightweightVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct LightweightVertexOutput
{
float2 uv : TEXCOORD0;
float4 ambientOrLightmapUV : TEXCOORD1; // xy: lightmapUV, zw: dynamicLightmapUV OR color from SH
float4 posWS : TEXCOORD2;
#if _NORMALMAP
half3 tangent : TEXCOORD3;
half3 binormal : TEXCOORD4;
half3 normal : TEXCOORD5;
#else
half3 normal : TEXCOORD3;
#endif
half4 viewDir : TEXCOORD6; // xyz: viewDir
half4 fogFactorAndVertexLight : TEXCOORD7; // x: fogFactor, yzw: vertex light
float4 clipPos : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
inline void InitializeStandardLitSurfaceData(LightweightVertexOutput IN, out SurfaceData outSurfaceData)
{
float2 uv = IN.uv;
half4 albedoAlpha = tex2D(_MainTex, uv);
half4 specGloss = MetallicSpecGloss(uv, albedoAlpha);
outSurfaceData.albedo = LIGHTWEIGHT_GAMMA_TO_LINEAR(albedoAlpha.rgb) * _Color.rgb;
#if _METALLIC_SETUP
outSurfaceData.metallic = specGloss.r;
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
#else
outSurfaceData.metallic = 1.0h;
outSurfaceData.specular = specGloss.rgb;
#endif
outSurfaceData.smoothness = specGloss.a;
outSurfaceData.normal = Normal(uv);
outSurfaceData.occlusion = OcclusionLW(uv);
outSurfaceData.emission = EmissionLW(uv);
outSurfaceData.emission += IN.fogFactorAndVertexLight.yzw;
outSurfaceData.alpha = Alpha(albedoAlpha.a);
}
void InitializeSurfaceInput(LightweightVertexOutput IN, out SurfaceInput outSurfaceInput)
{
#if LIGHTMAP_ON
outSurfaceInput.lightmapUV = float4(IN.ambientOrLightmapUV.xy, 0.0, 0.0);
#else
outSurfaceInput.lightmapUV = float4(0.0, 0.0, 0.0, 0.0);
#endif
#if _NORMALMAP
outSurfaceInput.tangentWS = IN.tangent;
outSurfaceInput.bitangentWS = IN.binormal;
#else
outSurfaceInput.tangentWS = half3(1.0h, 0.0h, 0.0h);
outSurfaceInput.bitangentWS = half3(0.0h, 1.0h, 0.0h);
#endif
outSurfaceInput.normalWS = IN.normal;
outSurfaceInput.positionWS = IN.posWS;
outSurfaceInput.viewDirectionWS = IN.viewDir;
outSurfaceInput.fogFactor = IN.fogFactorAndVertexLight.x;
}
LightweightVertexOutput LitPassVertex(LightweightVertexInput v)
{

UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.uv01.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
#ifdef LIGHTMAP_ON
o.uv01.zw = v.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
o.hpos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.posWS.xyz = worldPos;

#if _NORMALMAP
half sign = v.tangent.w * unity_WorldTransformParams.w;
half3 tangent = UnityObjectToWorldDir(v.tangent);
half3 binormal = cross(normal, tangent) * sign;
// Initialize tangetToWorld in column-major to benefit from better glsl matrix multiplication code
o.tangentToWorld0 = half3(tangent.x, binormal.x, normal.x);
o.tangentToWorld1 = half3(tangent.y, binormal.y, normal.y);
o.tangentToWorld2 = half3(tangent.z, binormal.z, normal.z);
o.tangent = normalize(mul((half3x3)unity_ObjectToWorld, v.tangent.xyz));
o.binormal = cross(normal, o.tangent) * sign;
o.normal = normal;
// TODO: change to only support point lights per vertex. This will greatly simplify shader ALU
//#if defined(_VERTEX_LIGHTS) && defined(_MULTIPLE_LIGHTS)
// half3 diffuse = half3(1.0, 1.0, 1.0);
// // pixel lights shaded = min(pixelLights, perObjectLights)
// // vertex lights shaded = min(vertexLights, perObjectLights) - pixel lights shaded
// // Therefore vertexStartIndex = pixelLightCount; vertexEndIndex = min(vertexLights, perObjectLights)
// int vertexLightStart = min(globalLightCount.x, unity_LightIndicesOffsetAndCount.y);
// int vertexLightEnd = min(globalLightCount.y, unity_LightIndicesOffsetAndCount.y);
// for (int lightIter = vertexLightStart; lightIter < vertexLightEnd; ++lightIter)
// {
// int lightIndex = unity_4LightIndices0[lightIter];
// LightInput lightInput;
// INITIALIZE_LIGHT(lightInput, lightIndex);
//
// half3 lightDirection;
// half atten = ComputeLightAttenuationVertex(lightInput, normal, worldPos, lightDirection);
// o.fogCoord.yzw += LightingLambert(diffuse, lightDirection, normal, atten);
// }
//#endif
#ifdef LIGHTMAP_ON
o.ambientOrLightmapUV.xy = v.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
// TODO: Dynamic Lightmap
o.ambientOrLightmapUV.zw = float2(0.0, 0.0);
#if !defined(LIGHTMAP_ON)
o.fogCoord.yzw = SHEvalLinearL2(half4(normal, 1.0));
// TODO: Currently there's no way to pass in ambient contribution to fragmentPBR.
// We should allow to create custom ambient computation for things like SH evaluation, lightmap, ambient color etc.
//#else
// o.ambientOrLightmapUV = half4(SHEvalLinearL2(half4(normal, 1.0)), 0.0h);
UNITY_TRANSFER_FOG(o, o.hpos);
o.fogFactorAndVertexLight.yzw = half3(0.0h, 0.0h, 0.0h);
#if defined(_VERTEX_LIGHTS)
half3 diffuse = half3(1.0, 1.0, 1.0);
int vertexLightStart = _AdditionalLightCount.x;
int vertexLightEnd = min(_AdditionalLightCount.y, unity_LightIndicesOffsetAndCount.y);
for (int lightIter = vertexLightStart; lightIter < vertexLightEnd; ++lightIter)
{
LightInput lightData;
INITIALIZE_LIGHT(lightData, lightIter);
half3 lightDirection;
half atten = ComputeVertexLightAttenuation(lightData, normal, worldPos, lightDirection);
o.fogFactorAndVertexLight.yzw += LightingLambert(diffuse, lightDirection, normal, atten) * lightData.color;
}
#endif
float4 clipPos = UnityObjectToClipPos(v.vertex);
o.fogFactorAndVertexLight.x = ComputeFogFactor(clipPos.z);
o.clipPos = clipPos;
half4 LitPassFragment(LightweightVertexOutput i) : SV_Target
half4 LitPassFragment(LightweightVertexOutput IN) : SV_Target
InitializeSurfaceData(i, surfaceData);
InitializeStandardLitSurfaceData(IN, surfaceData);
BRDFData brdfData;
InitializeBRDFData(surfaceData, brdfData);
float2 lightmapUV = i.uv01.zw;
half3 normal = surfaceData.normalWorld;
half3 reflectVec = reflect(-i.viewDir.xyz, normal);
half roughness2 = brdfData.roughness * brdfData.roughness;
UnityIndirect indirectLight = LightweightGI(lightmapUV, i.fogCoord.yzw, normal, reflectVec, surfaceData.ao, brdfData.perceptualRoughness);
// PBS
half fresnelTerm = Pow4(1.0 - saturate(dot(normal, i.viewDir.xyz)));
half3 color = LightweightBRDFIndirect(brdfData, indirectLight, roughness2, fresnelTerm);
half3 lightDirection;
#ifdef _MAIN_LIGHT
LightInput light;
INITIALIZE_MAIN_LIGHT(light);
half lightAtten = ComputeMainLightAttenuation(light, normal, i.posWS.xyz, lightDirection);
lightAtten *= LIGHTWEIGHT_SHADOW_ATTENUATION(i, _ShadowLightDirection.xyz);
half NdotL = saturate(dot(normal, lightDirection));
half3 radiance = light.color * (lightAtten * NdotL);
color += LightweightBDRF(brdfData, roughness2, normal, lightDirection, i.viewDir.xyz) * radiance;
#endif
#ifdef _ADDITIONAL_PIXEL_LIGHTS
int pixelLightCount = min(_AdditionalLightCount.x, unity_LightIndicesOffsetAndCount.y);
for (int lightIter = 0; lightIter < pixelLightCount; ++lightIter)
{
LightInput light;
INITIALIZE_LIGHT(light, lightIter);
half lightAtten = ComputeLightAttenuation(light, normal, i.posWS.xyz, lightDirection);
half NdotL = saturate(dot(normal, lightDirection));
half3 radiance = light.color * (lightAtten * NdotL);
color += LightweightBDRF(brdfData, roughness2, normal, lightDirection, i.viewDir.xyz) * radiance;
}
#endif
SurfaceInput surfaceInput;
InitializeSurfaceInput(IN, surfaceInput);
color += surfaceData.emission;
UNITY_APPLY_FOG(i.fogCoord, color);
return OutputColor(color, surfaceData.alpha);
return LightweightFragmentPBR(surfaceInput.lightmapUV, surfaceInput.positionWS, surfaceInput.normalWS, surfaceInput.tangentWS, surfaceInput.bitangentWS, surfaceInput.viewDirectionWS, surfaceInput.fogFactor, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.normal, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha);
half4 LitPassFragmentSimple(LightweightVertexOutput i) : SV_Target
half4 LitPassFragmentSimple(LightweightVertexOutput IN) : SV_Target
half4 diffuseAlpha = tex2D(_MainTex, i.uv01.xy);
float2 uv = IN.uv;
half4 diffuseAlpha = tex2D(_MainTex, uv);
half3 diffuse = LIGHTWEIGHT_GAMMA_TO_LINEAR(diffuseAlpha.rgb) * _Color.rgb;
#ifdef _GLOSSINESS_FROM_BASE_ALPHA

clip(alpha - _Cutoff);
#endif
half3 normal = Normal(i);
#if _NORMALMAP
half3 normalTangent = Normal(uv);
half3 normalWorld = TangentToWorldNormal(normalTangent, IN.tangent, IN.binormal, IN.normal);
#else
half3 normalWorld = normalize(IN.normal);
#endif
SpecularGloss(i.uv01.xy, alpha, specularGloss);
SpecularGloss(uv, alpha, specularGloss);
half3 viewDir = i.viewDir.xyz;
float3 worldPos = i.posWS.xyz;
half3 viewDir = IN.viewDir.xyz;
float3 worldPos = IN.posWS.xyz;
half3 color = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv01.zw)) * diffuse;
half3 color = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.ambientOrLightmapUV.xy)) * diffuse;
half3 color = (SHEvalLinearL0L1(half4(normal, 1.0)) + i.fogCoord.yzw) * diffuse;
half3 color = (ShadeSH9(half4(normalWorld, 1.0)) + IN.ambientOrLightmapUV.xyz) * diffuse;
#ifdef _MAIN_LIGHT
half lightAtten = ComputeMainLightAttenuation(lightInput, normal, worldPos, lightDirection);
lightAtten *= LIGHTWEIGHT_SHADOW_ATTENUATION(i, _ShadowLightDirection.xyz);
half lightAtten = ComputeMainLightAttenuation(lightInput, normalWorld, worldPos, lightDirection);
lightAtten *= LIGHTWEIGHT_SHADOW_ATTENUATION(worldPos, normalize(IN.normal), _ShadowLightDirection.xyz);
#ifdef LIGHTWEIGHT_SPECULAR_HIGHLIGHTS
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normal, viewDir, lightAtten) * lightInput.color;
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normalWorld, viewDir, lightAtten) * lightInput.color;
color += LightingLambert(diffuse, lightDirection, normal, lightAtten) * lightInput.color;
color += LightingLambert(diffuse, lightDirection, normalWorld, lightAtten) * lightInput.color;
#endif
#ifdef _ADDITIONAL_PIXEL_LIGHTS
#ifdef _ADDITIONAL_LIGHTS
half lightAtten = ComputeLightAttenuation(lightData, normal, worldPos, lightDirection);
half lightAtten = ComputePixelLightAttenuation(lightData, normalWorld, worldPos, lightDirection);
#ifdef LIGHTWEIGHT_SPECULAR_HIGHLIGHTS
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normal, viewDir, lightAtten) * lightData.color;
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normalWorld, viewDir, lightAtten) * lightData.color;
color += LightingLambert(diffuse, lightDirection, normal, lightAtten) * lightData.color;
color += LightingLambert(diffuse, lightDirection, normalWorld, lightAtten) * lightData.color;
#endif // _ADDITIONAL_PIXEL_LIGHTS
#endif // _ADDITIONAL_LIGHTS
color += EmissionLW(uv);
color += IN.fogFactorAndVertexLight.yzw;
color += EmissionLW(i.uv01.xy);
UNITY_APPLY_FOG(i.fogCoord, color);
// Computes Fog Factor per vextex
ApplyFog(color, IN.fogFactorAndVertexLight.x);
return OutputColor(color, alpha);
};

14
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightShadows.cginc


#endif
#ifdef _SHADOWS
#define LIGHTWEIGHT_SHADOW_ATTENUATION(vertexOutput, shadowDir) ComputeShadowAttenuation(vertexOutput, shadowDir)
#define LIGHTWEIGHT_SHADOW_ATTENUATION(posWorld, vertexNormal, shadowDir) ComputeShadowAttenuation(posWorld, vertexNormal, shadowDir)
#define LIGHTWEIGHT_SHADOW_ATTENUATION(vertexOutput, shadowDir) 1.0h
#define LIGHTWEIGHT_SHADOW_ATTENUATION(posWorld, vertexNormal, shadowDir) 1.0h
#endif
sampler2D_float _ShadowMap;

return attenuation * 0.25;
}
inline half ComputeShadowAttenuation(LightweightVertexOutput i, half3 shadowDir)
inline half ComputeShadowAttenuation(float3 posWorld, half3 vertexNormal, half3 shadowDir)
#if _NORMALMAP
half3 vertexNormal = half3(i.tangentToWorld0.z, i.tangentToWorld1.z, i.tangentToWorld2.z);
#else
half3 vertexNormal = i.normal;
#endif
float3 posWorldOffsetNormal = i.posWS + vertexNormal * bias;
float3 posWorldOffsetNormal = posWorld + vertexNormal * bias;
int cascadeIndex = 0;
#ifdef _SHADOW_CASCADES

21
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandard.shader


Shader "ScriptableRenderPipeline/LightweightPipeline/Standard (PBS)"
Shader "LightweightPipeline/Standard (Physically Based)"
{
Properties
{

#pragma shader_feature _NORMALMAP
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _EMISSION
#pragma shader_feature _ _METALLICSPECGLOSSMAP
#pragma shader_feature ___ _DETAIL_MULX2
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature _ _GLOSSYREFLECTIONS_OFF
#pragma shader_feature _ _OCCLUSIONMAP
#pragma shader_feature _PARALLAXMAP
#pragma shader_feature _METALLICSPECGLOSSMAP
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature _GLOSSYREFLECTIONS_OFF
#pragma shader_feature _OCCLUSIONMAP
#pragma multi_compile _ _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_PIXEL_LIGHTS
#pragma multi_compile _ _LIGHTWEIGHT_FORCE_LINEAR
#pragma multi_compile _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ATTENUATION_TEXTURE
#pragma multi_compile_fog
#pragma multi_compile_instancing

#include "UnityCG.cginc"
#include "UnityStandardInput.cginc"
#include "LightweightPassLit.cginc"
ENDCG

9
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardSimpleLighting.shader


// Shader targeted for low end devices. Single Pass Forward Rendering. Shader Model 2
Shader "ScriptableRenderPipeline/LightweightPipeline/Standard (Simple Lighting)"
Shader "LightweightPipeline/Standard (Simple Lighting)"
{
// Keep properties of StandardSpecular shader for upgrade reasons.
Properties

#pragma shader_feature _NORMALMAP
#pragma shader_feature _EMISSION
#pragma multi_compile _ _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_PIXEL_LIGHTS
#pragma multi_compile _ _LIGHTWEIGHT_FORCE_LINEAR
#pragma multi_compile _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ATTENUATION_TEXTURE
#include "UnityCG.cginc"
#include "UnityStandardInput.cginc"
#include "LightweightPassLit.cginc"
ENDCG

2
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightUnlit.shader


Shader "ScriptableRenderPipeline/LightweightPipeline/Unlit"
Shader "LightweightPipeline/Unlit"
{
Properties
{

5
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/Scenes.meta


fileFormatVersion: 2
guid: 642eb9f65f77a9d47b5cfb977aaee96f
guid: da5a3f10e37fea74c8fb43737fbb9100
timeCreated: 1495194790
timeCreated: 1508423723
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/021_Lighting_BasicPoint.unity


m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 1
m_Type: 0
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1

maxSmoothness: 1
applyRangeAttenuation: 1
useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 1
--- !u!1 &1266012094
GameObject:

304
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/_OldToCleanup_/Scenes/0007_LitShaderMaps/007_LitShaderMaps_05_Emission.mat


m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: 007_LitShaderMaps_05_Emission
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _BLENDMODE_PRESERVE_SPECULAR_LIGHTING _EMISSIVE_COLOR_MAP _NORMALMAP_TANGENT_SPACE
m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALBEDOAFFECTEMISSIVE_OFF _ALPHACUTOFFENABLE_OFF _BLENDMODE_PRESERVE_SPECULAR_LIGHTING
_DEPTHOFFSETENABLE_OFF _DOUBLESIDEDENABLE_OFF _EMISSIVE_COLOR_MAP _ENABLESPECULAROCCLUSION_OFF
_ENABLEWIND_OFF _NORMALMAP_TANGENT_SPACE _OBJECTSCALEAFFECTTILE_OFF _OPACITYASDENSITY0_OFF
_OPACITYASDENSITY1_OFF _OPACITYASDENSITY2_OFF _OPACITYASDENSITY3_OFF _PREREFRACTIONPASS_OFF
_USEDENSITYMODE_OFF _USEHEIGHTBASEDBLEND_OFF _USEMAINLAYERINFLUENCE_OFF
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Texture: {fileID: 0}
m_Scale: {x: 3, y: 2}
m_Offset: {x: 0, y: 0}
- _BaseColorMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseColorMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseColorMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseColorMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS3:
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_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LayerInfluenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LayerMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: ae15313a7f54946eaa9e4be92ab62112, type: 3}
m_Scale: {x: 3, y: 2}

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMapOS0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMapOS1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMapOS2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMapOS3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}

m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap0:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap1:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap2:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap3:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _ATDistance: 1
- _AlbedoAffectEmissive: 0

- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAlbedoScale: 1
- _DetailAlbedoScale0: 1
- _DetailAlbedoScale1: 1
- _DetailAlbedoScale2: 1
- _DetailAlbedoScale3: 1
- _DetailNormalScale0: 1
- _DetailNormalScale1: 1
- _DetailNormalScale2: 1
- _DetailNormalScale3: 1
- _DetailSmoothnessScale0: 1
- _DetailSmoothnessScale1: 1
- _DetailSmoothnessScale2: 1
- _DetailSmoothnessScale3: 1
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 0

- _GlossinessSource: 0
- _GlossyReflections: 1
- _HeightAmplitude: 0.01
- _HeightAmplitude0: 0.02
- _HeightAmplitude1: 0.02
- _HeightAmplitude2: 0.02
- _HeightAmplitude3: 0.02
- _HeightCenter0: 0.5
- _HeightCenter1: 0.5
- _HeightCenter2: 0.5
- _HeightCenter3: 0.5
- _HeightMax0: 1
- _HeightMax1: 1
- _HeightMax2: 1
- _HeightMax3: 1
- _HeightMin0: -1
- _HeightMin1: -1
- _HeightMin2: -1
- _HeightMin3: -1
- _HeightOffset0: 0
- _HeightOffset1: 0
- _HeightOffset2: 0
- _HeightOffset3: 0
- _HeightTransition: 0
- _InheritBaseColor1: 0
- _InheritBaseColor2: 0
- _InheritBaseColor3: 0
- _InheritBaseHeight1: 0
- _InheritBaseHeight2: 0
- _InheritBaseHeight3: 0
- _InheritBaseNormal1: 0
- _InheritBaseNormal2: 0
- _InheritBaseNormal3: 0
- _InvTilingScale0: 1
- _InvTilingScale1: 1
- _InvTilingScale2: 1
- _InvTilingScale3: 1
- _LayerCount: 2
- _LinkDetailsWithBase0: 1
- _LinkDetailsWithBase1: 1
- _LinkDetailsWithBase2: 1
- _LinkDetailsWithBase3: 1
- _Metallic0: 0
- _Metallic1: 0
- _Metallic2: 0
- _Metallic3: 0
- _NormalMapSpace0: 0
- _NormalMapSpace1: 0
- _NormalMapSpace2: 0
- _NormalMapSpace3: 0
- _NormalScale0: 1
- _NormalScale1: 1
- _NormalScale2: 1
- _NormalScale3: 1
- _ObjectScaleAffectTile: 0
- _OpacityAsDensity0: 0
- _OpacityAsDensity1: 0
- _OpacityAsDensity2: 0
- _OpacityAsDensity3: 0
- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMinSamples: 5

- _Shininess: 1
- _ShiverDirectionality: 0.5
- _ShiverDrag: 0.2
- _ShowLayer0: 0
- _ShowLayer1: 0
- _ShowLayer2: 0
- _ShowLayer3: 0
- _ShowMaterialReferences: 0
- _Smoothness0: 1
- _Smoothness1: 1
- _Smoothness2: 1
- _Smoothness3: 1
- _SmoothnessRemapMax0: 1
- _SmoothnessRemapMax1: 1
- _SmoothnessRemapMax2: 1
- _SmoothnessRemapMax3: 1
- _SmoothnessRemapMin0: 0
- _SmoothnessRemapMin1: 0
- _SmoothnessRemapMin2: 0
- _SmoothnessRemapMin3: 0
- _SmoothnessTextureChannel: 0
- _SpecSource: 0
- _SpecularHighlights: 1

- _SubsurfaceProfile: 0
- _SubsurfaceProfile0: 0
- _SubsurfaceProfile1: 0
- _SubsurfaceProfile2: 0
- _SubsurfaceProfile3: 0
- _SubsurfaceRadius0: 1
- _SubsurfaceRadius1: 1
- _SubsurfaceRadius2: 1
- _SubsurfaceRadius3: 1
- _TexWorldScale0: 1
- _TexWorldScale1: 1
- _TexWorldScale2: 1
- _TexWorldScale3: 1
- _TexWorldScaleBlendMask: 1
- _Thickness0: 1
- _Thickness1: 1
- _Thickness2: 1
- _Thickness3: 1
- _UVBase0: 0
- _UVBase1: 0
- _UVBase2: 0
- _UVBase3: 0
- _UVBlendMask: 0
- _UVDetail0: 0
- _UVDetail1: 0
- _UVDetail2: 0
- _UVDetail3: 0
- _UseDensityMode: 0
- _UseHeightBasedBlend: 0
- _UseMainLayerInfluence: 0
- _VertexColorMode: 0
- _BaseColor0: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor1: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor2: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor3: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVDetailsMappingMask3: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask0: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask1: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask2: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask3: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMaskBlendMask: {r: 1, g: 0, b: 0, a: 0}

4
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/_OldToCleanup_/HDRPAsset/HDRenderPipelineResourcesTest.asset


debugFullScreenShader: {fileID: 4800000, guid: e874aca2df8300a488258738c31f85cf,
type: 3}
deferredShader: {fileID: 4800000, guid: 00dd221e34a6ab349a1196b0f2fab693, type: 3}
screenSpaceAmbientOcclusionShader: {fileID: 4800000, guid: cf0db7f5267ad944dbf4326b7102c9ca,
type: 3}
subsurfaceScatteringCS: {fileID: 7200000, guid: b06a7993621def248addd55d0fe931b1,
type: 3}
volumetricLightingCS: {fileID: 7200000, guid: 799166e2ee6a4b041bba9e74f6942097,

computeGgxIblSampleData: {fileID: 7200000, guid: 764a24bb47ef5ba4781d9ae82ca07445,
type: 3}
GGXConvolve: {fileID: 4800000, guid: 123ed592ad5c2494b8aed301fd609e7b, type: 3}
opaqueAtmosphericScattering: {fileID: 4800000, guid: 326059e48e5735e46a98047eff4f0295,
type: 3}
skyboxCubemap: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}

17
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/BlackRGBA64x64.tga.meta


fileFormatVersion: 2
guid: 524019d263762af4caa9ace94c74c38e
timeCreated: 1497039348
licenseType: Pro
timeCreated: 18446744011573954816
externalObjects: {}
sRGBTexture: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0

crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

17
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/MidGreyRGBA64x64.tga.meta


fileFormatVersion: 2
guid: bf7ad3b25a0b12d4ebe4f64c2054b38b
timeCreated: 1497039348
licenseType: Pro
timeCreated: 18446744011573954816
externalObjects: {}
sRGBTexture: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0

crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

17
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/WhiteRGBA64x64.tga.meta


fileFormatVersion: 2
guid: ddccffa3f2572ce408af53c7f903f841
timeCreated: 1497039348
licenseType: Pro
timeCreated: 18446744011573954816
externalObjects: {}
sRGBTexture: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0

crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

17
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/Black-WhiteRGBA64x64.tga.meta


fileFormatVersion: 2
guid: 3bc698316c6d71040a8a5be738601d45
timeCreated: 1497043838
licenseType: Pro
timeCreated: 18446744011573954816
externalObjects: {}
sRGBTexture: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0

crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []

1
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/_OldToCleanup_/HDRP_Default_Scene_Settings.prefab


m_EditorClassIdentifier:
m_CommonSettings: {fileID: 0}
m_SkySettings: {fileID: 11400000, guid: 55214718938e62442b0f5673994ee7b7, type: 2}
m_SsaoSettings: {fileID: 0}

20
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Materials/HDRP_Default_Material.mat


m_PrefabInternal: {fileID: 0}
m_Name: HDRP_Default_Material
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _BLENDMODE_PRESERVE_SPECULAR_LIGHTING _NORMALMAP_TANGENT_SPACE
m_ShaderKeywords: _BLENDMODE_ALPHA _BLENDMODE_PRESERVE_SPECULAR_LIGHTING _ENABLE_FOG_ON_TRANSPARENT
_MAPPING_PLANAR _NORMALMAP_TANGENT_SPACE _SURFACE_TYPE_TRANSPARENT
m_CustomRenderQueue: -1
stringTagMap: {}
m_CustomRenderQueue: 3000
stringTagMap:
RenderType: Transparent
disabledShaderPasses:
- DistortionVectors
m_SavedProperties:

- _DoubleSidedEnable: 0
- _DoubleSidedNormalMode: 1
- _Drag: 1
- _DstBlend: 0
- _DstBlend: 10
- _EmissiveColorMode: 1
- _EmissiveIntensity: 0
- _EnableBlendModePreserveSpecularLighting: 1

- _Stiffness: 1
- _SubsurfaceProfile: 0
- _SubsurfaceRadius: 1
- _SurfaceType: 0
- _SurfaceType: 1
- _UVBase: 0
- _UVBase: 4
- _ZWrite: 1
- _ZWrite: 0
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 0.7294118, g: 0.7294118, b: 0.7294118, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}

- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 0, g: 0, b: 0, a: 0}

8
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/HDRI/KirbyCoveWhiteBalancedNoSun.exr.meta


fileFormatVersion: 2
guid: 5613e937b42b0294c8bcf543109dfe11
guid: 5fb993a599e7e9b4b825e1a28e6d2c07
timeCreated: 1508426924
licenseType: Pro
TextureImporter:
fileIDToRecycleName:
8900000: generatedCubemap

mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0

14
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Textures/uvGrid.tga.meta


fileFormatVersion: 2
guid: 0361211e0d3ff044f80391eb793ead6b
guid: b23bea53bdbdb5a4aaacf12522910599
timeCreated: 1508430343
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}

textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1

20
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/HDRP_Test_Camera.prefab


- component: {fileID: 4209882255362944}
- component: {fileID: 20109210616973140}
- component: {fileID: 114270329781043846}
- component: {fileID: 114110876577682668}
m_Layer: 0
m_Name: HDRP_Test_Camera
m_TagString: MainCamera

m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1132393308280272}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}

m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!114 &114110876577682668
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1132393308280272}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0e34c98127e05d340ba44a1d4a734454, type: 3}
m_Name:
m_EditorClassIdentifier:
m_CommonSettings: {fileID: 0}
m_SkySettings: {fileID: 11400000, guid: 55214718938e62442b0f5673994ee7b7, type: 2}
--- !u!114 &114270329781043846
MonoBehaviour:
m_ObjectHideFlags: 1

cameraToUse: {fileID: 20109210616973140}
hdr: 1
msaaSamples: 1
width: 1280
height: 720
width: 1920
height: 1080

10
ImageTemplates/HDRenderPipeline/Scenes/1xxx_Materials.meta


fileFormatVersion: 2
guid: 423cb1bfe2cc81e43879ddfa7458a9de
folderAsset: yes
timeCreated: 1509010375
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

70
ScriptableRenderPipeline/Core/ShaderLibrary/Refraction.hlsl


#ifndef UNITY_REFRACTION_INCLUDED
#define UNITY_REFRACTION_INCLUDED
//-----------------------------------------------------------------------------
// Util refraction
//-----------------------------------------------------------------------------
struct RefractionModelResult
{
float opticalDepth;
float3 positionWS; // out ray position
float3 rayWS; // out ray direction
};
RefractionModelResult RefractionModel_Sphere(float3 V, float3 positionWS, float3 normalWS, float ior, float thickness)
{
// Sphere shape model:
// We approximate locally the shape of the object as sphere, that is tangent to the shape.
// The sphere has a diameter of {thickness}
// The center of the sphere is at {positionWS} - {normalWS} * {thickness}
//
// So the light is refracted twice: in and out of the tangent sphere
// First refraction (tangent sphere in)
// Refracted ray
float3 R1 = refract(-V, normalWS, 1.0 / ior);
// Center of the tangent sphere
float3 C = positionWS - normalWS * thickness * 0.5;
// Second refraction (tangent sphere out)
float NoR1 = dot(normalWS, R1);
// Optical depth within the sphere
float opticalDepth = -NoR1 * thickness;
// Out hit point in the tangent sphere
float3 P1 = positionWS + R1 * opticalDepth;
// Out normal
float3 N1 = normalize(C - P1);
// Out refracted ray
float3 R2 = refract(R1, N1, ior);
float N1oR2 = dot(N1, R2);
float VoR1 = dot(V, R1);
RefractionModelResult result;
result.opticalDepth = opticalDepth;
result.positionWS = P1;
result.rayWS = R2;
return result;
}
RefractionModelResult RefractionModel_Plane(float3 V, float3 positionWS, float3 normalWS, float ior, float thickness)
{
// Plane shape model:
// We approximate locally the shape of the object as a plane with normal {normalWS} at {positionWS}
// with a thickness {thickness}
// Refracted ray
float3 R = refract(-V, normalWS, 1.0 / ior);
// Optical depth within the thin plane
float opticalDepth = thickness / dot(R, -normalWS);
RefractionModelResult result;
result.opticalDepth = opticalDepth;
result.positionWS = positionWS + R * opticalDepth;
result.rayWS = -V;
return result;
}
#endif

10
ScriptableRenderPipeline/Core/ShaderLibrary/Refraction.hlsl.meta


fileFormatVersion: 2
guid: 61125f624d229884d8cff04fc0fceab7
timeCreated: 1509090550
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

259
ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDLightEditorUtilities.cs


#if UNITY_EDITOR
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.Experimental.Rendering.HDPipeline;
#endif
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
#if UNITY_EDITOR
public static class HDLightEditorUtilities
{
public static void DrawSpotlightGizmo(Light spotlight, bool selected)
{
var flatRadiusAtRange = spotlight.range * Mathf.Tan(spotlight.spotAngle * Mathf.Deg2Rad * 0.5f);
var vectorLineUp = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.up * flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineDown = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.up * -flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineRight = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.right * flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineLeft = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.right * -flatRadiusAtRange - spotlight.gameObject.transform.position);
var rangeDiscDistance = Mathf.Cos(Mathf.Deg2Rad * spotlight.spotAngle / 2) * spotlight.range;
var rangeDiscRadius = spotlight.range * Mathf.Sin(spotlight.spotAngle * Mathf.Deg2Rad * 0.5f);
var nearDiscDistance = Mathf.Cos(Mathf.Deg2Rad * spotlight.spotAngle / 2) * spotlight.shadowNearPlane;
var nearDiscRadius = spotlight.shadowNearPlane * Mathf.Sin(spotlight.spotAngle * Mathf.Deg2Rad * 0.5f);
//Draw Range disc
Handles.Disc(spotlight.gameObject.transform.rotation, spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * rangeDiscDistance, spotlight.gameObject.transform.forward, rangeDiscRadius, false, 1);
//Draw Lines
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineUp * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineDown * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineRight * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineLeft * spotlight.range);
if (selected)
{
//Draw Range Arcs
Handles.DrawWireArc(spotlight.gameObject.transform.position, spotlight.gameObject.transform.right, vectorLineUp, spotlight.spotAngle, spotlight.range);
Handles.DrawWireArc(spotlight.gameObject.transform.position, spotlight.gameObject.transform.up, vectorLineLeft, spotlight.spotAngle, spotlight.range);
//Draw Near Plane Disc
if (spotlight.shadows != LightShadows.None) Handles.Disc(spotlight.gameObject.transform.rotation, spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * nearDiscDistance, spotlight.gameObject.transform.forward, nearDiscRadius, false, 1);
//Inner Cone
var additionalLightData = spotlight.GetComponent<HDAdditionalLightData>();
DrawInnerCone(spotlight,additionalLightData);
}
}
public static void DrawInnerCone(Light spotlight, HDAdditionalLightData additionalLightData)
{
if (additionalLightData == null) return;
var flatRadiusAtRange = spotlight.range * Mathf.Tan(spotlight.spotAngle * additionalLightData.m_InnerSpotPercent * 0.01f * Mathf.Deg2Rad * 0.5f);
var vectorLineUp = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.up * flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineDown = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.up * -flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineRight = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.right * flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineLeft = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.right * -flatRadiusAtRange - spotlight.gameObject.transform.position);
//Draw Lines
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineUp * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineDown * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineRight * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineLeft * spotlight.range);
var innerAngle = spotlight.spotAngle * additionalLightData.GetInnerSpotPercent01();
if (innerAngle > 0)
{
var innerDiscDistance = Mathf.Cos(Mathf.Deg2Rad * innerAngle * 0.5f) * spotlight.range;
var innerDiscRadius = spotlight.range * Mathf.Sin(innerAngle * Mathf.Deg2Rad * 0.5f);
//Draw Range disc
Handles.Disc(spotlight.gameObject.transform.rotation, spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * innerDiscDistance, spotlight.gameObject.transform.forward, innerDiscRadius, false, 1);
}
}
public static void DrawArealightGizmo(Light arealight)
{
var RectangleSize = new Vector3(arealight.areaSize.x, arealight.areaSize.y, 0);
Gizmos.matrix = arealight.transform.localToWorldMatrix;
Gizmos.DrawWireCube(Vector3.zero, RectangleSize);
Gizmos.matrix = Matrix4x4.identity;
Gizmos.DrawWireSphere(arealight.transform.position, arealight.range);
}
public static void DrawPointlightGizmo(Light pointlight, bool selected)
{
if (pointlight.shadows != LightShadows.None && selected) Gizmos.DrawWireSphere(pointlight.transform.position, pointlight.shadowNearPlane);
Gizmos.DrawWireSphere(pointlight.transform.position, pointlight.range);
}
public static void DrawSpherelightGizmo(Light spherelight)
{
var additionalLightData = spherelight.GetComponent<HDAdditionalLightData>();
if (additionalLightData == null) return;
Gizmos.DrawSphere(spherelight.transform.position, additionalLightData.shapeLength);
if (spherelight.shadows != LightShadows.None) Gizmos.DrawWireSphere(spherelight.transform.position, spherelight.shadowNearPlane);
Gizmos.DrawWireSphere(spherelight.transform.position, spherelight.range);
}
// Same as Gizmo.DrawFrustum except that when aspect is below one, fov represent fovX instead of fovY
// Use to match our light frustum pyramid behavior
public static void DrawLightPyramidFrustum(Vector3 center, float fov, float maxRange, float minRange, float aspect)
{
fov = Mathf.Deg2Rad * fov * 0.5f;
float tanfov = Mathf.Tan(fov);
Vector3 farEnd = new Vector3(0, 0, maxRange);
Vector3 endSizeX;
Vector3 endSizeY;
if (aspect >= 1.0f)
{
endSizeX = new Vector3(maxRange * tanfov * aspect, 0, 0);
endSizeY = new Vector3(0, maxRange * tanfov, 0);
}
else
{
endSizeX = new Vector3(maxRange * tanfov, 0, 0);
endSizeY = new Vector3(0, maxRange * tanfov / aspect, 0);
}
Vector3 s1, s2, s3, s4;
Vector3 e1 = farEnd + endSizeX + endSizeY;
Vector3 e2 = farEnd - endSizeX + endSizeY;
Vector3 e3 = farEnd - endSizeX - endSizeY;
Vector3 e4 = farEnd + endSizeX - endSizeY;
if (minRange <= 0.0f)
{
s1 = s2 = s3 = s4 = center;
}
else
{
Vector3 startSizeX;
Vector3 startSizeY;
if (aspect >= 1.0f)
{
startSizeX = new Vector3(minRange * tanfov * aspect, 0, 0);
startSizeY = new Vector3(0, minRange * tanfov, 0);
}
else
{
startSizeY = new Vector3(minRange * tanfov / aspect, 0, 0);
startSizeX = new Vector3(0, minRange * tanfov, 0);
}
Vector3 startPoint = center;
s1 = startPoint + startSizeX + startSizeY;
s2 = startPoint - startSizeX + startSizeY;
s3 = startPoint - startSizeX - startSizeY;
s4 = startPoint + startSizeX - startSizeY;
Gizmos.DrawLine(s1, s2);
Gizmos.DrawLine(s2, s3);
Gizmos.DrawLine(s3, s4);
Gizmos.DrawLine(s4, s1);
}
Gizmos.DrawLine(e1, e2);
Gizmos.DrawLine(e2, e3);
Gizmos.DrawLine(e3, e4);
Gizmos.DrawLine(e4, e1);
Gizmos.DrawLine(s1, e1);
Gizmos.DrawLine(s2, e2);
Gizmos.DrawLine(s3, e3);
Gizmos.DrawLine(s4, e4);
}
public static void DrawLightOrthoFrustum(Vector3 center, float width, float height, float maxRange, float minRange)
{
Vector3 farEnd = new Vector3(0, 0, maxRange);
Vector3 endSizeX = new Vector3(width, 0, 0);
Vector3 endSizeY = new Vector3(0, height, 0);
Vector3 s1, s2, s3, s4;
Vector3 e1 = farEnd + endSizeX + endSizeY;
Vector3 e2 = farEnd - endSizeX + endSizeY;
Vector3 e3 = farEnd - endSizeX - endSizeY;
Vector3 e4 = farEnd + endSizeX - endSizeY;
if (minRange <= 0.0f)
{
s1 = s2 = s3 = s4 = center;
}
else
{
Vector3 startSizeX = new Vector3(width, 0, 0);
Vector3 startSizeY = new Vector3(0, height, 0);
Vector3 startPoint = center;
s1 = startPoint + startSizeX + startSizeY;
s2 = startPoint - startSizeX + startSizeY;
s3 = startPoint - startSizeX - startSizeY;
s4 = startPoint + startSizeX - startSizeY;
Gizmos.DrawLine(s1, s2);
Gizmos.DrawLine(s2, s3);
Gizmos.DrawLine(s3, s4);
Gizmos.DrawLine(s4, s1);
}
Gizmos.DrawLine(e1, e2);
Gizmos.DrawLine(e2, e3);
Gizmos.DrawLine(e3, e4);
Gizmos.DrawLine(e4, e1);
Gizmos.DrawLine(s1, e1);
Gizmos.DrawLine(s2, e2);
Gizmos.DrawLine(s3, e3);
Gizmos.DrawLine(s4, e4);
}
public static void DrawFrustumlightGizmo(Light frustumlight)
{
var additionalLightData = frustumlight.GetComponent<HDAdditionalLightData>();
if (additionalLightData == null) return;
Matrix4x4 matrix = new Matrix4x4(frustumlight.transform.right, frustumlight.transform.up, frustumlight.transform.forward, frustumlight.transform.position);
Gizmos.matrix = matrix;
if (additionalLightData.spotLightShape == SpotLightShape.Pyramid)
{
DrawLightPyramidFrustum(Vector3.zero, frustumlight.spotAngle, frustumlight.range, 0.0f, additionalLightData.aspectRatio);
}
else // Ortho frustum
{
//DrawLightOrthoFrustum(Vector3.zero, additionalLightData.shapeLength, additionalLightData.shapeWidth, frustumlight.range, 0.0f);
Vector3 frustumCenter = new Vector3(0.0f, 0.0f, 0.5f * frustumlight.range);
Vector3 frustumsize = new Vector3(additionalLightData.shapeLength, additionalLightData.shapeWidth, frustumlight.range);
Gizmos.DrawWireCube(frustumCenter, frustumsize);
}
Gizmos.matrix = Matrix4x4.identity;
}
public static void DrawDirectionalLightGizmo(Light directionalLight)
{
var gizmoSize = 0.2f;
Handles.Disc(directionalLight.transform.rotation, directionalLight.transform.position, directionalLight.gameObject.transform.forward, gizmoSize, false, 1);
Gizmos.DrawLine(directionalLight.transform.position, directionalLight.transform.position + directionalLight.transform.forward);
Gizmos.DrawLine(directionalLight.transform.position + directionalLight.transform.up * gizmoSize, directionalLight.transform.position + directionalLight.transform.up * gizmoSize + directionalLight.transform.forward);
Gizmos.DrawLine(directionalLight.transform.position + directionalLight.transform.up * -gizmoSize, directionalLight.transform.position + directionalLight.transform.up * -gizmoSize + directionalLight.transform.forward);
Gizmos.DrawLine(directionalLight.transform.position + directionalLight.transform.right * gizmoSize, directionalLight.transform.position + directionalLight.transform.right * gizmoSize + directionalLight.transform.forward);
Gizmos.DrawLine(directionalLight.transform.position + directionalLight.transform.right * -gizmoSize, directionalLight.transform.position + directionalLight.transform.right * -gizmoSize + directionalLight.transform.forward);
}
public static void DrawCross(Transform m_transform)
{
var gizmoSize = 0.25f;
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.forward * gizmoSize / m_transform.localScale.z));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.forward * -gizmoSize / m_transform.localScale.z));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.up * gizmoSize / m_transform.localScale.y));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.up * -gizmoSize / m_transform.localScale.y));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.right * gizmoSize / m_transform.localScale.x));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.right * -gizmoSize / m_transform.localScale.x));
}
}
#endif
}

13
ScriptableRenderPipeline/HDRenderPipeline/Lighting/HDLightEditorUtilities.cs.meta


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

763
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitData.hlsl


//-------------------------------------------------------------------------------------
// Fill SurfaceData/Builtin data function
//-------------------------------------------------------------------------------------
#include "../Lit/LitData.hlsl"
#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
// then we take the sampler matching the first textures use of this type
#if defined(_NORMALMAP0)
#if defined(_NORMALMAP_TANGENT_SPACE0)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap0
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS0
#endif
#elif defined(_NORMALMAP1)
#if defined(_NORMALMAP_TANGENT_SPACE1)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap1
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS1
#endif
#elif defined(_NORMALMAP2)
#if defined(_NORMALMAP_TANGENT_SPACE2)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap2
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS2
#endif
#elif defined(_NORMALMAP3)
#if defined(_NORMALMAP_TANGENT_SPACE3)
#define SAMPLER_NORMALMAP_IDX sampler_NormalMap3
#else
#define SAMPLER_NORMALMAP_IDX sampler_NormalMapOS3
#endif
#elif defined(_BENTNORMALMAP0)
#if defined(_NORMALMAP_TANGENT_SPACE0)
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMap0
#else
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMapOS0
#endif
#elif defined(_BENTNORMALMAP1)
#if defined(_NORMALMAP_TANGENT_SPACE1)
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMap1
#else
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMapOS1
#endif
#elif defined(_BENTNORMALMAP2)
#if defined(_NORMALMAP_TANGENT_SPACE2)
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMap2
#else
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMapOS2
#endif
#else
#if defined(_NORMALMAP_TANGENT_SPACE3)
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMap3
#else
#define SAMPLER_NORMALMAP_IDX sampler_BentNormalMapOS3
#endif
#endif
#if defined(_DETAIL_MAP0)
#define SAMPLER_DETAILMAP_IDX sampler_DetailMap0
#elif defined(_DETAIL_MAP1)
#define SAMPLER_DETAILMAP_IDX sampler_DetailMap1
#elif defined(_DETAIL_MAP2)
#define SAMPLER_DETAILMAP_IDX sampler_DetailMap2
#else
#define SAMPLER_DETAILMAP_IDX sampler_DetailMap3
#endif
#if defined(_MASKMAP0)
#define SAMPLER_MASKMAP_IDX sampler_MaskMap0
#elif defined(_MASKMAP1)
#define SAMPLER_MASKMAP_IDX sampler_MaskMap1
#elif defined(_MASKMAP2)
#define SAMPLER_MASKMAP_IDX sampler_MaskMap2
#else
#define SAMPLER_MASKMAP_IDX sampler_MaskMap3
#endif
#if defined(_HEIGHTMAP0)
#define SAMPLER_HEIGHTMAP_IDX sampler_HeightMap0
#elif defined(_HEIGHTMAP1)
#define SAMPLER_HEIGHTMAP_IDX sampler_HeightMap1
#elif defined(_HEIGHTMAP2)
#define SAMPLER_HEIGHTMAP_IDX sampler_HeightMap2
#elif defined(_HEIGHTMAP3)
#define SAMPLER_HEIGHTMAP_IDX sampler_HeightMap3
#endif
#if defined(_SUBSURFACE_RADIUS_MAP0)
#define _SUBSURFACE_RADIUS_MAP_IDX sampler_SubsurfaceRadiusMap0
#elif defined(_SUBSURFACE_RADIUS_MAP1)
#define _SUBSURFACE_RADIUS_MAP_IDX sampler_SubsurfaceRadiusMap1
#elif defined(_SUBSURFACE_RADIUS_MAP2)
#define _SUBSURFACE_RADIUS_MAP_IDX sampler_SubsurfaceRadiusMap2
#elif defined(_SUBSURFACE_RADIUS_MAP3)
#define _SUBSURFACE_RADIUS_MAP_IDX sampler_SubsurfaceRadiusMap3
#endif
#if defined(_THICKNESSMAP0)
#define SAMPLER_THICKNESSMAP_IDX sampler_ThicknessMap0
#elif defined(_THICKNESSMAP1)
#define SAMPLER_THICKNESSMAP_IDX sampler_ThicknessMap1
#elif defined(_THICKNESSMAP2)
#define SAMPLER_THICKNESSMAP_IDX sampler_ThicknessMap2
#elif defined(_THICKNESSMAP3)
#define SAMPLER_THICKNESSMAP_IDX sampler_ThicknessMap3
#endif
// Define a helper macro
#define ADD_ZERO_IDX(Name) Name##0
// include LitDataInternal multiple time to define the variation of GetSurfaceData for each layer
#define LAYER_INDEX 0
#define ADD_IDX(Name) Name##0
#ifdef _NORMALMAP0
#define _NORMALMAP_IDX
#endif
#ifdef _NORMALMAP_TANGENT_SPACE0
#define _NORMALMAP_TANGENT_SPACE_IDX
#endif
#ifdef _DETAIL_MAP0
#define _DETAIL_MAP_IDX
#endif
#ifdef _SUBSURFACE_RADIUS_MAP0
#define _SUBSURFACE_RADIUS_MAP_IDX
#endif
#ifdef _THICKNESSMAP0
#define _THICKNESSMAP_IDX
#endif
#ifdef _MASKMAP0
#define _MASKMAP_IDX
#endif
#ifdef _BENTNORMALMAP0
#define _BENTNORMALMAP_IDX
#endif
#include "../Lit/LitDataIndividualLayer.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#undef _NORMALMAP_IDX
#undef _NORMALMAP_TANGENT_SPACE_IDX
#undef _DETAIL_MAP_IDX
#undef _SUBSURFACE_RADIUS_MAP_IDX
#undef _THICKNESSMAP_IDX
#undef _MASKMAP_IDX
#undef _BENTNORMALMAP_IDX
#define LAYER_INDEX 1
#define ADD_IDX(Name) Name##1
#ifdef _NORMALMAP1
#define _NORMALMAP_IDX
#endif
#ifdef _NORMALMAP_TANGENT_SPACE1
#define _NORMALMAP_TANGENT_SPACE_IDX
#endif
#ifdef _DETAIL_MAP1
#define _DETAIL_MAP_IDX
#endif
#ifdef _SUBSURFACE_RADIUS_MAP1
#define _SUBSURFACE_RADIUS_MAP_IDX
#endif
#ifdef _THICKNESSMAP1
#define _THICKNESSMAP_IDX
#endif
#ifdef _MASKMAP1
#define _MASKMAP_IDX
#endif
#ifdef _BENTNORMALMAP1
#define _BENTNORMALMAP_IDX
#endif
#include "../Lit/LitDataIndividualLayer.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#undef _NORMALMAP_IDX
#undef _NORMALMAP_TANGENT_SPACE_IDX
#undef _DETAIL_MAP_IDX
#undef _SUBSURFACE_RADIUS_MAP_IDX
#undef _THICKNESSMAP_IDX
#undef _MASKMAP_IDX
#undef _BENTNORMALMAP_IDX
#define LAYER_INDEX 2
#define ADD_IDX(Name) Name##2
#ifdef _NORMALMAP2
#define _NORMALMAP_IDX
#endif
#ifdef _NORMALMAP_TANGENT_SPACE2
#define _NORMALMAP_TANGENT_SPACE_IDX
#endif
#ifdef _DETAIL_MAP2
#define _DETAIL_MAP_IDX
#endif
#ifdef _SUBSURFACE_RADIUS_MAP2
#define _SUBSURFACE_RADIUS_MAP_IDX
#endif
#ifdef _THICKNESSMAP2
#define _THICKNESSMAP_IDX
#endif
#ifdef _MASKMAP2
#define _MASKMAP_IDX
#endif
#ifdef _BENTNORMALMAP2
#define _BENTNORMALMAP_IDX
#endif
#include "../Lit/LitDataIndividualLayer.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#undef _NORMALMAP_IDX
#undef _NORMALMAP_TANGENT_SPACE_IDX
#undef _DETAIL_MAP_IDX
#undef _SUBSURFACE_RADIUS_MAP_IDX
#undef _THICKNESSMAP_IDX
#undef _MASKMAP_IDX
#undef _BENTNORMALMAP_IDX
#define LAYER_INDEX 3
#define ADD_IDX(Name) Name##3
#ifdef _NORMALMAP3
#define _NORMALMAP_IDX
#endif
#ifdef _NORMALMAP_TANGENT_SPACE3
#define _NORMALMAP_TANGENT_SPACE_IDX
#endif
#ifdef _DETAIL_MAP3
#define _DETAIL_MAP_IDX
#endif
#ifdef _SUBSURFACE_RADIUS_MAP3
#define _SUBSURFACE_RADIUS_MAP_IDX
#endif
#ifdef _THICKNESSMAP3
#define _THICKNESSMAP_IDX
#endif
#ifdef _MASKMAP3
#define _MASKMAP_IDX
#endif
#ifdef _BENTNORMALMAP3
#define _BENTNORMALMAP_IDX
#endif
#include "../Lit/LitDataIndividualLayer.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#undef _NORMALMAP_IDX
#undef _NORMALMAP_TANGENT_SPACE_IDX
#undef _DETAIL_MAP_IDX
#undef _SUBSURFACE_RADIUS_MAP_IDX
#undef _THICKNESSMAP_IDX
#undef _MASKMAP_IDX
#undef _BENTNORMALMAP_IDX
float3 BlendLayeredVector3(float3 x0, float3 x1, float3 x2, float3 x3, float weight[4])
{
float3 result = float3(0.0, 0.0, 0.0);
result = x0 * weight[0] + x1 * weight[1];
#if _LAYER_COUNT >= 3
result += (x2 * weight[2]);
#endif
#if _LAYER_COUNT >= 4
result += x3 * weight[3];
#endif
return result;
}
float BlendLayeredScalar(float x0, float x1, float x2, float x3, float weight[4])
{
float result = 0.0;
result = x0 * weight[0] + x1 * weight[1];
#if _LAYER_COUNT >= 3
result += x2 * weight[2];
#endif
#if _LAYER_COUNT >= 4
result += x3 * weight[3];
#endif
return result;
}
// In the case of subsurface profile index, the goal is to take the index with the hights weights.
// Or the last found in case of equality.
float BlendLayeredSSSprofile(float x0, float x1, float x2, float x3, float weight[4])
{
int sssProfileIndex = x0;
float currentMax = weight[0];
sssProfileIndex = currentMax < weight[1] ? x1 : sssProfileIndex;
currentMax = max(currentMax, weight[1]);
#if _LAYER_COUNT >= 3
sssProfileIndex = currentMax < weight[2] ? x2 : sssProfileIndex;
currentMax = max(currentMax, weight[2]);
#endif
#if _LAYER_COUNT >= 4
sssProfileIndex = currentMax < weight[3] ? x3 : sssProfileIndex;
#endif
return sssProfileIndex;
}
#define SURFACEDATA_BLEND_VECTOR3(surfaceData, name, mask) BlendLayeredVector3(MERGE_NAME(surfaceData, 0) MERGE_NAME(., name), MERGE_NAME(surfaceData, 1) MERGE_NAME(., name), MERGE_NAME(surfaceData, 2) MERGE_NAME(., name), MERGE_NAME(surfaceData, 3) MERGE_NAME(., name), mask);
#define SURFACEDATA_BLEND_SCALAR(surfaceData, name, mask) BlendLayeredScalar(MERGE_NAME(surfaceData, 0) MERGE_NAME(., name), MERGE_NAME(surfaceData, 1) MERGE_NAME(., name), MERGE_NAME(surfaceData, 2) MERGE_NAME(., name), MERGE_NAME(surfaceData, 3) MERGE_NAME(., name), mask);
#define SURFACEDATA_BLEND_SSS_PROFILE(surfaceData, name, mask) BlendLayeredSSSprofile(MERGE_NAME(surfaceData, 0) MERGE_NAME(., name), MERGE_NAME(surfaceData, 1) MERGE_NAME(., name), MERGE_NAME(surfaceData, 2) MERGE_NAME(., name), MERGE_NAME(surfaceData, 3) MERGE_NAME(., name), mask);
#define PROP_BLEND_SCALAR(name, mask) BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);
void GetLayerTexCoord(float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3,
float3 positionWS, float3 vertexNormalWS, inout LayerTexCoord layerTexCoord)
{
layerTexCoord.vertexNormalWS = vertexNormalWS;
layerTexCoord.triplanarWeights = ComputeTriplanarWeights(vertexNormalWS);
int mappingType = UV_MAPPING_UVSET;
#if defined(_LAYER_MAPPING_PLANAR_BLENDMASK)
mappingType = UV_MAPPING_PLANAR;
#elif defined(_LAYER_MAPPING_TRIPLANAR_BLENDMASK)
mappingType = UV_MAPPING_TRIPLANAR;
#endif
// 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,
_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;
// On all layers (but not on blend mask) we can scale the tiling with object scale (only uniform supported)
// Note: the object scale doesn't affect planar/triplanar mapping as they already handle the object scale.
float tileObjectScale = 1.0;
#ifdef _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE
// Extract scaling from world transform
float4x4 worldTransform = GetObjectToWorldMatrix();
// assuming uniform scaling, take only the first column
tileObjectScale = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
#endif
mappingType = UV_MAPPING_UVSET;
#if defined(_LAYER_MAPPING_PLANAR0)
mappingType = UV_MAPPING_PLANAR;
#elif defined(_LAYER_MAPPING_TRIPLANAR0)
mappingType = UV_MAPPING_TRIPLANAR;
#endif
ComputeLayerTexCoord0( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask0, _UVDetailsMappingMask0,
_BaseColorMap0_ST.xy, _BaseColorMap0_ST.zw, _DetailMap0_ST.xy, _DetailMap0_ST.zw, 1.0
#if !defined(_MAIN_LAYER_INFLUENCE_MODE)
* tileObjectScale // We only affect layer0 in case we are not in influence mode (i.e we should not change the base object)
#endif
, _LinkDetailsWithBase0
, positionWS, _TexWorldScale0,
mappingType, layerTexCoord);
mappingType = UV_MAPPING_UVSET;
#if defined(_LAYER_MAPPING_PLANAR1)
mappingType = UV_MAPPING_PLANAR;
#elif defined(_LAYER_MAPPING_TRIPLANAR1)
mappingType = UV_MAPPING_TRIPLANAR;
#endif
ComputeLayerTexCoord1( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask1, _UVDetailsMappingMask1,
_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)
mappingType = UV_MAPPING_PLANAR;
#elif defined(_LAYER_MAPPING_TRIPLANAR2)
mappingType = UV_MAPPING_TRIPLANAR;
#endif
ComputeLayerTexCoord2( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask2, _UVDetailsMappingMask2,
_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)
mappingType = UV_MAPPING_PLANAR;
#elif defined(_LAYER_MAPPING_TRIPLANAR3)
mappingType = UV_MAPPING_TRIPLANAR;
#endif
ComputeLayerTexCoord3( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask3, _UVDetailsMappingMask3,
_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
// layerTexCoord must have been initialize to 0 outside of this function
void GetLayerTexCoord(FragInputs input, inout LayerTexCoord layerTexCoord)
{
#ifdef SURFACE_GRADIENT
GenerateLayerTexCoordBasisTB(input, layerTexCoord);
#endif
GetLayerTexCoord( input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
input.positionWS, input.worldToTangent[2].xyz, layerTexCoord);
}
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 _DISPLACEMENT_LOCK_TILING_SCALE
float tileObjectScale = 1.0;
#ifdef _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE
// Extract scaling from world transform
float4x4 worldTransform = GetObjectToWorldMatrix();
// assuming uniform scaling, take only the first column
tileObjectScale = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
#endif
// TODO: precompute all these scaling factors!
height0 *= _InvTilingScale0;
#if !defined(_MAIN_LAYER_INFLUENCE_MODE)
height0 /= tileObjectScale; // We only affect layer0 in case we are not in influence mode (i.e we should not change the base object)
#endif
height1 = (height1 / tileObjectScale) * _InvTilingScale1;
height2 = (height2 / tileObjectScale) * _InvTilingScale2;
height3 = (height3 / tileObjectScale) * _InvTilingScale3;
#endif
}
// This function is just syntaxic sugar to nullify height not used based on heightmap avaibility and layer
void SetEnabledHeightByLayer(inout float height0, inout float height1, inout float height2, inout float height3)
{
#ifndef _HEIGHTMAP0
height0 = 0.0;
#endif
#ifndef _HEIGHTMAP1
height1 = 0.0;
#endif
#ifndef _HEIGHTMAP2
height2 = 0.0;
#endif
#ifndef _HEIGHTMAP3
height3 = 0.0;
#endif
#if _LAYER_COUNT < 4
height3 = 0.0;
#endif
#if _LAYER_COUNT < 3
height2 = 0.0;
#endif
}
void ComputeMaskWeights(float4 inputMasks, out float outWeights[_MAX_LAYER])
{
float masks[_MAX_LAYER];
masks[0] = inputMasks.a;
masks[1] = inputMasks.r;
#if _LAYER_COUNT > 2
masks[2] = inputMasks.g;
#else
masks[2] = 0.0;
#endif
#if _LAYER_COUNT > 3
masks[3] = inputMasks.b;
#else
masks[3] = 0.0;
#endif
// calculate weight of each layers
// Algorithm is like this:
// Top layer have priority on others layers
// If a top layer doesn't use the full weight, the remaining can be use by the following layer.
float weightsSum = 0.0;
[unroll]
for (int i = _LAYER_COUNT - 1; i >= 0; --i)
{
outWeights[i] = min(masks[i], (1.0 - weightsSum));
weightsSum = saturate(weightsSum + masks[i]);
}
}
// Caution: Blend mask are Layer 1 R - Layer 2 G - Layer 3 B - Main Layer A
float4 GetBlendMask(LayerTexCoord layerTexCoord, float4 vertexColor, bool useLodSampling = false, float lod = 0)
{
// Caution:
// Blend mask are Main Layer A - Layer 1 R - Layer 2 G - Layer 3 B
// Value for main layer is not use for blending itself but for alternate weighting like density.
// Settings this specific Main layer blend mask in alpha allow to be transparent in case we don't use it and 1 is provide by default.
float4 blendMasks = useLodSampling ? SAMPLE_UVMAPPING_TEXTURE2D_LOD(_LayerMaskMap, sampler_LayerMaskMap, layerTexCoord.blendMask, lod) : SAMPLE_UVMAPPING_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, layerTexCoord.blendMask);
// Wind uses vertex alpha as an intensity parameter.
// So in case Layered shader uses wind, we need to hardcode the alpha here so that the main layer can be visible without affecting wind intensity.
// It also means that when using wind, users can't use vertex color to modulate the effect of influence from the main layer.
float4 maskVertexColor = vertexColor;
#if defined(_LAYER_MASK_VERTEX_COLOR_MUL)
#if defined(_VERTEX_WIND)
// For multiplicative vertex color blend mask. 1.0f is the neutral value
maskVertexColor.a = 1.0f;
#endif
blendMasks *= maskVertexColor;
#elif defined(_LAYER_MASK_VERTEX_COLOR_ADD)
#if defined(_VERTEX_WIND)
// For additive vertex color blend mask. 0.5f is the neutral value (0.5 * 2.0 - 1.0 = 0.0)
maskVertexColor.a = 0.5f;
#endif
blendMasks = saturate(blendMasks + maskVertexColor * 2.0 - 1.0);
#endif
return blendMasks;
}
float GetInfluenceMask(LayerTexCoord layerTexCoord, bool useLodSampling = false, float lod = 0)
{
// 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;
}
// Calculate weights to apply to each layer
// Caution: This function must not be use for per vertex/pixel displacement, there is a dedicated function for them.
// This function handle triplanar
void ComputeLayerWeights(FragInputs input, LayerTexCoord layerTexCoord, float4 inputAlphaMask, float4 blendMasks, out float outWeights[_MAX_LAYER])
{
for (int i = 0; i < _MAX_LAYER; ++i)
{
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)
float4 useOpacityAsDensityParam = float4(_OpacityAsDensity0, _OpacityAsDensity1, _OpacityAsDensity2, _OpacityAsDensity3);
blendMasks.argb = lerp(blendMasks.argb, opacityAsDensity, useOpacityAsDensityParam);
#endif
#if LAYERS_HEIGHTMAP_ENABLE
float height0 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base0).r - _HeightCenter0) * _HeightAmplitude0;
float height1 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base1).r - _HeightCenter1) * _HeightAmplitude1;
float height2 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base2).r - _HeightCenter2) * _HeightAmplitude2;
float height3 = (SAMPLE_UVMAPPING_TEXTURE2D(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base3).r - _HeightCenter3) * _HeightAmplitude3;
// 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
SetEnabledHeightByLayer(height0, height1, height2, height3);
// 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
#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);
}
float3 ComputeMainNormalInfluence(float influenceMask, FragInputs input, float3 normalTS0, float3 normalTS1, float3 normalTS2, float3 normalTS3, LayerTexCoord layerTexCoord, float inputMainLayerMask, float weights[_MAX_LAYER])
{
// Get our regular normal from regular layering
float3 normalTS = BlendLayeredVector3(normalTS0, normalTS1, normalTS2, normalTS3, weights);
// THen get Main Layer Normal influence factor. Main layer is 0 because it can't be influence. In this case the final lerp return normalTS.
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseNormal1, _InheritBaseNormal2, _InheritBaseNormal3, weights) * influenceMask;
// We will add smoothly the contribution of the normal map by lerping between vertex normal ( (0,0,1) in tangent space) and the actual normal from the main layer depending on the influence factor.
// Note: that we don't take details map into account here.
#ifdef SURFACE_GRADIENT
float3 neutralNormalTS = float3(0.0, 0.0, 0.0);
#else
float3 neutralNormalTS = float3(0.0, 0.0, 1.0);
#endif
float3 mainNormalTS = lerp(neutralNormalTS, normalTS0, influenceFactor);
// Add on our regular normal a bit of Main Layer normal base on influence factor. Note that this affect only the "visible" normal.
#ifdef SURFACE_GRADIENT
return normalTS + influenceFactor * mainNormalTS * inputMainLayerMask;
#else
return lerp(normalTS, BlendNormalRNM(normalTS, mainNormalTS), influenceFactor * inputMainLayerMask); // Multiply by inputMainLayerMask in order to avoid influence where main layer should never be present
#endif
}
float3 ComputeMainBaseColorInfluence(float influenceMask, float3 baseColor0, float3 baseColor1, float3 baseColor2, float3 baseColor3, LayerTexCoord layerTexCoord, float inputMainLayerMask, float weights[_MAX_LAYER])
{
float3 baseColor = BlendLayeredVector3(baseColor0, baseColor1, baseColor2, baseColor3, weights);
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseColor1, _InheritBaseColor2, _InheritBaseColor3, weights) * influenceMask * inputMainLayerMask; // Multiply by inputMainLayerMask in order to avoid influence where main layer should never be present
// We want to calculate the mean color of the texture. For this we will sample a low mipmap
float textureBias = 15.0; // Use maximum bias
float3 baseMeanColor0 = SAMPLE_UVMAPPING_TEXTURE2D_BIAS(_BaseColorMap0, sampler_BaseColorMap0, layerTexCoord.base0, textureBias).rgb *_BaseColor0.rgb;
float3 baseMeanColor1 = SAMPLE_UVMAPPING_TEXTURE2D_BIAS(_BaseColorMap1, sampler_BaseColorMap0, layerTexCoord.base1, textureBias).rgb *_BaseColor1.rgb;
float3 baseMeanColor2 = SAMPLE_UVMAPPING_TEXTURE2D_BIAS(_BaseColorMap2, sampler_BaseColorMap0, layerTexCoord.base2, textureBias).rgb *_BaseColor2.rgb;
float3 baseMeanColor3 = SAMPLE_UVMAPPING_TEXTURE2D_BIAS(_BaseColorMap3, sampler_BaseColorMap0, layerTexCoord.base3, textureBias).rgb *_BaseColor3.rgb;
float3 meanColor = BlendLayeredVector3(baseMeanColor0, baseMeanColor1, baseMeanColor2, baseMeanColor3, weights);
// If we inherit from base layer, we will add a bit of it
// We add variance of current visible level and the base color 0 or mean (to retrieve initial color) depends on influence
// (baseColor - meanColor) + lerp(meanColor, baseColor0, inheritBaseColor) simplify to
// saturate(influenceFactor * (baseColor0 - meanColor) + baseColor);
// There is a special case when baseColor < meanColor to avoid getting negative values.
float3 factor = baseColor > meanColor ? (baseColor0 - meanColor) : (baseColor0 * baseColor / max(meanColor, 0.001) - baseColor); // max(to avoid divide by 0)
return influenceFactor * factor + baseColor;
}
#include "LayeredLitDataDisplacement.hlsl"
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(posInput.unPositionSS, unity_LODFade.x);
#endif
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
GetLayerTexCoord(input, layerTexCoord);
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
float depthOffset = ApplyPerPixelDisplacement(input, V, layerTexCoord, blendMasks);
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
SurfaceData surfaceData0, surfaceData1, surfaceData2, surfaceData3;
float3 normalTS0, normalTS1, normalTS2, normalTS3;
float3 bentNormalTS0, bentNormalTS1, bentNormalTS2, bentNormalTS3;
float alpha0 = GetSurfaceData0(input, layerTexCoord, surfaceData0, normalTS0, bentNormalTS0);
float alpha1 = GetSurfaceData1(input, layerTexCoord, surfaceData1, normalTS1, bentNormalTS1);
float alpha2 = GetSurfaceData2(input, layerTexCoord, surfaceData2, normalTS2, bentNormalTS2);
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.
float weights[_MAX_LAYER];
ComputeLayerWeights(input, layerTexCoord, float4(alpha0, alpha1, alpha2, alpha3), blendMasks, weights);
// For layered shader, alpha of base color is used as either an opacity mask, a composition mask for inheritance parameters or a density mask.
float alpha = PROP_BLEND_SCALAR(alpha, weights);
#ifdef _ALPHATEST_ON
DoAlphaTest(alpha, _AlphaCutoff);
#endif
float3 normalTS;
float3 bentNormalTS;
float3 bentNormalWS;
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
#ifdef _INFLUENCEMASK_MAP
float influenceMask = GetInfluenceMask(layerTexCoord);
#else
float influenceMask = 1.0;
#endif
if (influenceMask > 0.0f)
{
surfaceData.baseColor = ComputeMainBaseColorInfluence(influenceMask, surfaceData0.baseColor, surfaceData1.baseColor, surfaceData2.baseColor, surfaceData3.baseColor, layerTexCoord, blendMasks.a, weights);
normalTS = ComputeMainNormalInfluence(influenceMask, input, normalTS0, normalTS1, normalTS2, normalTS3, layerTexCoord, blendMasks.a, weights);
bentNormalTS = ComputeMainNormalInfluence(influenceMask, input, bentNormalTS0, bentNormalTS1, bentNormalTS2, bentNormalTS3, layerTexCoord, blendMasks.a, weights);
}
else
#endif
{
surfaceData.baseColor = SURFACEDATA_BLEND_VECTOR3(surfaceData, baseColor, weights);
normalTS = BlendLayeredVector3(normalTS0, normalTS1, normalTS2, normalTS3, weights);
bentNormalTS = BlendLayeredVector3(bentNormalTS0, bentNormalTS1, bentNormalTS2, bentNormalTS3, weights);
}
surfaceData.perceptualSmoothness = SURFACEDATA_BLEND_SCALAR(surfaceData, perceptualSmoothness, weights);
surfaceData.ambientOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, ambientOcclusion, weights);
surfaceData.metallic = SURFACEDATA_BLEND_SCALAR(surfaceData, metallic, weights);
surfaceData.tangentWS = normalize(input.worldToTangent[0].xyz); // The tangent is not normalize in worldToTangent for mikkt. Tag: SURFACE_GRADIENT
surfaceData.subsurfaceRadius = SURFACEDATA_BLEND_SCALAR(surfaceData, subsurfaceRadius, weights);
surfaceData.thickness = SURFACEDATA_BLEND_SCALAR(surfaceData, thickness, weights);
surfaceData.subsurfaceProfile = SURFACEDATA_BLEND_SSS_PROFILE(surfaceData, subsurfaceProfile, weights);
// Layered shader support either SSS or standard (can't mix them)
#ifdef _MATID_SSS
surfaceData.materialId = MATERIALID_LIT_SSS;
#else // Default
surfaceData.materialId = MATERIALID_LIT_STANDARD;
#endif
// Init other parameters
surfaceData.anisotropy = 0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
surfaceData.coatNormalWS = float3(0.0, 0.0, 0.0);
surfaceData.coatCoverage = 0.0f;
surfaceData.coatIOR = 0.5;
// Transparency parameters
// Use thickness from SSS
surfaceData.ior = 1.0;
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
surfaceData.atDistance = 1000000.0;
surfaceData.transmittanceMask = 0.0;
GetNormalWS(input, V, normalTS, surfaceData.normalWS);
// Use bent normal to sample GI if available
// If any layer use a bent normal map, then bentNormalTS contain the interpolated result of bentnormal and normalmap (in case no bent normal are available)
// Note: the code in LitDataInternal ensure that we fallback on normal map for layer that have no bentnormal
#if defined(_BENTNORMALMAP0) || defined(_BENTNORMALMAP1) || defined(_BENTNORMALMAP2) || defined(_BENTNORMALMAP3)
GetNormalWS(input, V, bentNormalTS, bentNormalWS);
#else // if no bent normal are available at all just keep the calculation fully
bentNormalWS = surfaceData.normalWS;
#endif
// By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.
// If user provide bent normal then we process a better term
#if (defined(_BENTNORMALMAP0) || defined(_BENTNORMALMAP1) || defined(_BENTNORMALMAP2) || defined(_BENTNORMALMAP3)) && defined(_ENABLESPECULAROCCLUSION)
// If we have bent normal and ambient occlusion, process a specular occlusion
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData);
#elif defined(_MASKMAP0) || defined(_MASKMAP1) || defined(_MASKMAP2) || defined(_MASKMAP3)
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(dot(surfaceData.normalWS, V), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
#else
surfaceData.specularOcclusion = 1.0;
#endif
GetBuiltinData(input, surfaceData, alpha, bentNormalWS, depthOffset, builtinData);
}
#include "../Lit/LitDataMeshModification.hlsl"

10
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitData.hlsl.meta


fileFormatVersion: 2
guid: ff68514b73492dd4bbf3e466f3cfcd99
timeCreated: 1508932230
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

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

正在加载...
取消
保存