浏览代码

Merge pull request #466 from Unity-Technologies/Add-Per-Pixel-scale

Revamp of Parallax occlusoin mapping + depth offset
/stochastic_alpha_test
GitHub 7 年前
当前提交
2002ee68
共有 29 个文件被更改,包括 921 次插入579 次删除
  1. 41
      SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Rock.mat
  2. 53
      SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood triplanar.mat
  3. 27
      SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood.mat
  4. 39
      SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Rock.mat
  5. 31
      SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Wood.mat
  6. 38
      SampleScenes/HDTest/GraphicTest/Triplanar/Material/Wood triplanar.mat
  7. 48
      SampleScenes/HDTest/HDRenderLoopTest.unity
  8. 16
      ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl
  9. 9
      ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl
  10. 3
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  11. 7
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl
  12. 16
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.hlsl
  13. 97
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  14. 29
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  15. 29
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  16. 140
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  17. 31
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  18. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  19. 24
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  20. 671
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  21. 7
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  22. 43
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  23. 26
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  24. 6
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitDepthPass.hlsl
  25. 4
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitDistortionPass.hlsl
  26. 6
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/ShaderPass/LitVelocityPass.hlsl
  27. 9
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/TessellationShare.hlsl
  28. 19
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VaryingMesh.hlsl
  29. 18
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VertMesh.hlsl

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


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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

48
SampleScenes/HDTest/HDRenderLoopTest.unity


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

16
ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl


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

9
ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl


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

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

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

3
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs


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

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


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

16
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.hlsl


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

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

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

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


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

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

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

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

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

29
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


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

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

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DEPTHOFFSET_ON
#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _VERTEX_WIND
#pragma shader_feature _LAYER_TILING_COUPLED_WITH_UNIFORM_OBJECT_SCALE

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

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


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

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

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DEPTHOFFSET_ON
#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT _TESSELLATION_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _VERTEX_WIND
#pragma shader_feature _TESSELLATION_PHONG

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

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


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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

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

24
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader


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

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DEPTHOFFSET_ON
#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _VERTEX_WIND
#pragma shader_feature _ _REFRACTION_THINPLANE _REFRACTION_THICKPLANE _REFRACTION_THICKSPHERE

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


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

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

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

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

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

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

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

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

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

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

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

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

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

#if defined(_HEIGHT_BASED_BLEND)
#if defined(_HEIGHTMAP0) || defined(_HEIGHTMAP1) || defined(_HEIGHTMAP2) || defined(_HEIGHTMAP3)
#if LAYERS_HEIGHTMAP_ENABLE
// Height is affected by tiling property and by object scale (depends on option).
// Apply scaling from tiling properties (TexWorldScale and tiling from BaseColor)
ApplyDisplacementTileScale(height0, height1, height2, height3);
// Nullify height that are not used, so compiler can remove unused case
float4 heights = float4(height0, height1, height2, height3);
// 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
// HACK: use height0 to avoid compiler error for unused sampler - To remove when we can have a sampler without a textures
#if !defined(_PER_PIXEL_DISPLACEMENT)
// We don't use height 0 for the height blend based mode
heights.y += (heights.x * 0.0001);
#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);
blendMasks = ApplyHeightBlend(heights, blendMasks);
#endif
// If no heightmap is set on any layer, we don't need to try and blend them based on height...
#endif
ComputeMaskWeights(blendMasks, outWeights);

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

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

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

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


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

// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
float3 _EmissionColor;
float4 _InvPrimScale; // Only XY are used
// Wind
float _InitialBend;
float _Stiffness;

float4 _SpecularColor;
float _TexWorldScale;
float _InvTilingScale;
float4 _UVMappingMask;
float4 _UVDetailsMappingMask;

float4 _LayerMaskMap_ST;
float _TexWorldScaleBlendMask;
PROP_DECL(float, _TexWorldScale);
PROP_DECL(float, _InvTilingScale);
float4 _UVMappingMaskBlendMask;
PROP_DECL(float4, _UVMappingMask);
PROP_DECL(float4, _UVDetailsMappingMask);

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


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

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

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

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

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

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

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


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

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DEPTHOFFSET_ON
#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT _TESSELLATION_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
#pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
#pragma shader_feature _TESSELLATION_PHONG
#pragma shader_feature _ _TESSELLATION_PHONG
#pragma shader_feature _ _MAPPING_PLANAR _MAPPING_TRIPLANAR
#pragma shader_feature _NORMALMAP_TANGENT_SPACE

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


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

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

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


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

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


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

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

9
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/TessellationShare.hlsl


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

19
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VaryingMesh.hlsl


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

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

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

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

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

18
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VertMesh.hlsl


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

#ifdef _VERTEX_DISPLACEMENT_OBJECT_SCALE
// TODO: This should be an uniform for the object, this code should be remove (and is specific to Lit.shader) once we have it. - Workaround for now
output.objectScale = objectScale;
#endif
// TODO: TEMP: Velocity has a flow as it doens't have normal. This need to be fix. In the mean time, generate fix normal so compiler doesn't complain - When fix, think to also enable ATTRIBUTES_NEED_NORMAL in LitVelocityPass.hlsl
#if (SHADERPASS == SHADERPASS_VELOCITY)
output.normalWS = float3(0.0, 0.0, 1.0);

正在加载...
取消
保存