浏览代码

Merge remote-tracking branch 'origin/Unity-2017.3' into Reorganize-HDRP-GraphicTests

/Yibing-Project-2
Remy 7 年前
当前提交
cffd854a
共有 38 个文件被更改,包括 1744 次插入2124 次删除
  1. 56
      SampleScenes/HDTest/GraphicTest/LayeredTessellation/Material/Layer-2-woord-rock.mat
  2. 1
      SampleScenes/HDTest/GraphicTest/LayeredTessellation/Material/Layer-2-woord-rock.mat.meta
  3. 8
      ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl
  4. 256
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  5. 2
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowMoments.hlsl
  6. 25
      ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  7. 6
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
  8. 4
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl
  9. 4
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl
  10. 3
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  11. 20
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  12. 20
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  13. 6
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs
  14. 1
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  15. 30
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  16. 4
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  17. 967
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  18. 5
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl
  19. 4
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
  20. 998
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LtcData.DisneyDiffuse.cs
  21. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl
  22. 7
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs
  23. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader
  24. 9
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/UnlitData.hlsl
  25. 2
      ScriptableRenderPipeline/HDRenderPipeline/Sky/AtmosphericScattering/AtmosphericScattering.cs.hlsl
  26. 4
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/_OldToCleanup_/HDRPAsset/HDRenderPipelineResourcesTest.asset
  27. 763
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitData.hlsl
  28. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitData.hlsl.meta
  29. 360
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitDataDisplacement.hlsl
  30. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitDataDisplacement.hlsl.meta
  31. 220
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataDisplacement.hlsl
  32. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataDisplacement.hlsl.meta
  33. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataIndividualLayer.hlsl.meta
  34. 10
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataMeshModification.hlsl.meta
  35. 9
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl.meta
  36. 9
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl.meta
  37. 0
      /ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataMeshModification.hlsl
  38. 0
      /ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataIndividualLayer.hlsl

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


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

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

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

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

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

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

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

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


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

8
ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl


}
}
// Remap from [0, 1.5] to [0, 1] range.
acc.z /= 1.5;
acc /= sampleCount;
return acc / sampleCount;
// Remap from the [0.5, 1.5] to the [0, 1] range.
acc.z -= 0.5;
return acc;
}
uint GetIBLRuntimeFilterSampleCount(uint mipLevel)

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


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

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

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

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

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

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

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


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

25
ScriptableRenderPipeline/Core/Shadow/Shadow.cs


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

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

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

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

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

6
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs


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

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


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

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


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

3
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


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

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

20
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


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

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

1
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs


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

30
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


#ifdef LIT_DIFFUSE_LAMBERT_BRDF
diffuseFGD = 1.0;
#else
// Remap from [0, 1] to [0, 1.5] range.
diffuseFGD = 1.5 * preFGD.z;
// Remap from the [0, 1] to the [0.5, 1.5] range.
diffuseFGD = preFGD.z + 0.5;
#endif
reflectivity = preFGD.y;

// envDiffuseLighting is used for refraction in this Lit material. Use the weight to balance between transmission and reflection
diffuseLighting = lerp(directDiffuseLighting + bakeDiffuseLighting, accLighting.envDiffuseLighting, accLighting.envDiffuseLightingWeight);
specularLighting = accLighting.dirSpecularLighting + accLighting.punctualSpecularLighting + accLighting.areaSpecularLighting + accLighting.envSpecularLighting;
// Rescale the GGX to account for the multiple scattering.
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO)
{
diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO)
{
diffuseLighting = GetSpecularOcclusionFromAmbientOcclusion(preLightData.NdotV, indirectAmbientOcclusion, bsdfData.roughness);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
#if GTAO_MULTIBOUNCE_APPROX
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO)
{
diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO)
{
diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
#endif
#endif
}

4
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader


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

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

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

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


if (NdotL > 0.0)
{
float3 H = normalize(L + V);
float LdotH = dot(L, H);
float LdotV = dot(L, V);
float disneyDiffuse = DisneyDiffuse(NdotV, NdotL, LdotH, bsdfData.perceptualRoughness);
float disneyDiffuse = DisneyDiffuse(NdotV, NdotL, LdotV, bsdfData.perceptualRoughness);
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function
float4 val = SampleEnv(lightLoopContext, lightData.envIndex, L, 0);

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


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

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

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

13
ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl


#endif
}
// This function must be use instead of clip instruction. It allow to manage in which case the clip is perform
void DoAlphaTest(float alpha, float alphaCutoff)
{
// For Deferred:
// If we have a prepass, we need to remove the clip from the GBuffer pass (otherwise HiZ does not work on PS4) - SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
// For Forward (Lit or Unlit)
// Opaque geometry always has a depth pre-pass so we never want to do the clip here. For transparent we perform the clip as usual.
// Also no alpha test for light transport
#if !(SHADERPASS == SHADERPASS_FORWARD && !defined(_SURFACE_TYPE_TRANSPARENT)) && !(SHADERPASS == SHADERPASS_FORWARD_UNLIT && !defined(_SURFACE_TYPE_TRANSPARENT)) && !defined(SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST) && !(SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)
clip(alpha - alphaCutoff);
#endif
}
float2 CalculateVelocity(float4 positionCS, float4 previousPositionCS)
{
// This test on define is required to remove warning of divide by 0 when initializing empty struct

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


// or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color.
// The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color.
MaterialEditor.FixupEmissiveFlag(material);
// DoubleSidedGI has to be synced with our double sided toggle
var serializedObject = new SerializedObject(material);
var doubleSidedGIppt = serializedObject.FindProperty("m_DoubleSidedGI");
doubleSidedGIppt.boolValue = doubleSidedEnable;
serializedObject.ApplyModifiedProperties();
}
static public void SetupBaseUnlitMaterialPass(Material material)

// NB RenderQueue editor is not shown on purpose: we want to override it based on blend mode
EditorGUI.indentLevel++;
m_MaterialEditor.EnableInstancingField();
m_MaterialEditor.DoubleSidedGIField();
EditorGUI.indentLevel--;
}

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Unlit.shader


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

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


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

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


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

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


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

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

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


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

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


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

360
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitDataDisplacement.hlsl


#include "../Lit/LitDataDisplacement.hlsl"
// Return the maximum amplitude use by all enabled heightmap
// use for tessellation culling and per pixel displacement
// TODO: For vertex displacement this should take into account the modification in ApplyTessellationTileScale but it should be conservative here (as long as tiling is not negative)
float GetMaxDisplacement()
{
float maxDisplacement = 0.0;
// _HeightAmplitudeX can be negative if min and max are inverted, but the max displacement must be positive, take abs()
#if defined(_HEIGHTMAP0)
maxDisplacement = abs(_HeightAmplitude0);
#endif
#if defined(_HEIGHTMAP1)
maxDisplacement = max( abs(_HeightAmplitude1)
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
+ abs(_HeightAmplitude0) * _InheritBaseHeight1
#endif
, maxDisplacement);
#endif
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
maxDisplacement = max( abs(_HeightAmplitude2)
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
+ abs(_HeightAmplitude0) * _InheritBaseHeight2
#endif
, maxDisplacement);
#endif
#endif
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
maxDisplacement = max( abs(_HeightAmplitude3)
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
+ abs(_HeightAmplitude0) * _InheritBaseHeight3
#endif
, maxDisplacement);
#endif
#endif
return maxDisplacement;
}
// Return the minimun uv size for all layers including triplanar
float2 GetMinUvSize(LayerTexCoord layerTexCoord)
{
float2 minUvSize = float2(FLT_MAX, FLT_MAX);
#if defined(_HEIGHTMAP0)
if (layerTexCoord.base0.mappingType == UV_MAPPING_TRIPLANAR)
{
minUvSize = min(layerTexCoord.base0.uvZY * _HeightMap0_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base0.uvXZ * _HeightMap0_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base0.uvXY * _HeightMap0_TexelSize.zw, minUvSize);
}
else
{
minUvSize = min(layerTexCoord.base0.uv * _HeightMap0_TexelSize.zw, minUvSize);
}
#endif
#if defined(_HEIGHTMAP1)
if (layerTexCoord.base1.mappingType == UV_MAPPING_TRIPLANAR)
{
minUvSize = min(layerTexCoord.base1.uvZY * _HeightMap1_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base1.uvXZ * _HeightMap1_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base1.uvXY * _HeightMap1_TexelSize.zw, minUvSize);
}
else
{
minUvSize = min(layerTexCoord.base1.uv * _HeightMap1_TexelSize.zw, minUvSize);
}
#endif
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
if (layerTexCoord.base2.mappingType == UV_MAPPING_TRIPLANAR)
{
minUvSize = min(layerTexCoord.base2.uvZY * _HeightMap2_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base2.uvXZ * _HeightMap2_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base2.uvXY * _HeightMap2_TexelSize.zw, minUvSize);
}
else
{
minUvSize = min(layerTexCoord.base2.uv * _HeightMap2_TexelSize.zw, minUvSize);
}
#endif
#endif
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
if (layerTexCoord.base3.mappingType == UV_MAPPING_TRIPLANAR)
{
minUvSize = min(layerTexCoord.base3.uvZY * _HeightMap3_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base3.uvXZ * _HeightMap3_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base3.uvXY * _HeightMap3_TexelSize.zw, minUvSize);
}
else
{
minUvSize = min(layerTexCoord.base3.uv * _HeightMap3_TexelSize.zw, minUvSize);
}
#endif
#endif
return minUvSize;
}
#if defined(_PIXEL_DISPLACEMENT) && LAYERS_HEIGHTMAP_ENABLE
struct PerPixelHeightDisplacementParam
{
float4 blendMasks;
float2 uv[_MAX_LAYER];
float2 uvSpaceScale[_MAX_LAYER];
#if defined(_MAIN_LAYER_INFLUENCE_MODE) && defined(_HEIGHTMAP0)
float heightInfluence[_MAX_LAYER];
#endif
};
// Calculate displacement for per vertex displacement mapping
float ComputePerPixelHeightDisplacement(float2 texOffsetCurrent, float lod, PerPixelHeightDisplacementParam param)
{
// See function ComputePerVertexDisplacement() for comment about the weights/influenceMask/BlendMask
// Note: Amplitude is handled in uvSpaceScale, no need to multiply by it here.
float height0 = SAMPLE_TEXTURE2D_LOD(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, param.uv[0] + texOffsetCurrent * param.uvSpaceScale[0], lod).r;
float height1 = SAMPLE_TEXTURE2D_LOD(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, param.uv[1] + texOffsetCurrent * param.uvSpaceScale[1], lod).r;
float height2 = SAMPLE_TEXTURE2D_LOD(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, param.uv[2] + texOffsetCurrent * param.uvSpaceScale[2], lod).r;
float height3 = SAMPLE_TEXTURE2D_LOD(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, param.uv[3] + texOffsetCurrent * param.uvSpaceScale[3], lod).r;
SetEnabledHeightByLayer(height0, height1, height2, height3);
float4 blendMasks = param.blendMasks;
#if defined(_HEIGHT_BASED_BLEND)
// Modify blendMask to take into account the height of the layer. Higher height should be more visible.
blendMasks = ApplyHeightBlend(float4(height0, height1, height2, height3), param.blendMasks);
#endif
float weights[_MAX_LAYER];
ComputeMaskWeights(blendMasks, weights);
#if defined(_MAIN_LAYER_INFLUENCE_MODE) && defined(_HEIGHTMAP0)
float influenceMask = blendMasks.a;
#ifdef _INFLUENCEMASK_MAP
influenceMask *= SAMPLE_TEXTURE2D_LOD(_LayerInfluenceMaskMap, sampler_BaseColorMap0, param.uv[0], lod).r;
#endif
height1 += height0 * _InheritBaseHeight1 * influenceMask;
height2 += height0 * _InheritBaseHeight2 * influenceMask;
height3 += height0 * _InheritBaseHeight3 * influenceMask;
#endif
return BlendLayeredScalar(height0, height1, height2, height3, weights);
}
#include "../../../Core/ShaderLibrary/PerPixelDisplacement.hlsl"
#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)
// For these reasons we put the following rules
// Rules:
// - Mapping is the same for all layers that use an Heightmap (i.e all are UV, planar or triplanar)
// - Mapping UV is UV0 only because we need to convert view vector in texture space and this is only available for UV0
// - Heightmap can be enabled per layer
// - 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, float4 blendMasks)
{
#if defined(_PIXEL_DISPLACEMENT) && LAYERS_HEIGHTMAP_ENABLE
bool isPlanar = false;
bool isTriplanar = false;
// To know if we are planar or triplanar just need to check if any of the active heightmap layer is true as they are enforce to be the same mapping
#if defined(_HEIGHTMAP0)
isPlanar = layerTexCoord.base0.mappingType == UV_MAPPING_PLANAR;
isTriplanar = layerTexCoord.base0.mappingType == UV_MAPPING_TRIPLANAR;
#endif
#if defined(_HEIGHTMAP1)
isPlanar = layerTexCoord.base1.mappingType == UV_MAPPING_PLANAR;
isTriplanar = layerTexCoord.base1.mappingType == UV_MAPPING_TRIPLANAR;
#endif
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
isPlanar = layerTexCoord.base2.mappingType == UV_MAPPING_PLANAR;
isTriplanar = layerTexCoord.base2.mappingType == UV_MAPPING_TRIPLANAR;
#endif
#endif
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
isPlanar = layerTexCoord.base3.mappingType == UV_MAPPING_PLANAR;
isTriplanar = layerTexCoord.base3.mappingType == UV_MAPPING_TRIPLANAR;
#endif
#endif
// Compute lod as we will sample inside a loop(so can't use regular sampling)
// Note: It appear that CALCULATE_TEXTURE2D_LOD only return interger lod. We want to use float lod to have smoother transition and fading, so do our own calculation.
// Approximation of lod to used. Be conservative here, we will take the highest mip of all layers.
// Remember, we assume that we used the same mapping for all layer, so only size matter.
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
// TODO: Here we calculate the scale transform from world to UV space , which is what we have done in GetLayerTexCoord but without the texBias.
// Mean we must also apply the same "additionalTiling", currently not apply Also precompute all this!
float maxHeight0 = abs(_HeightAmplitude0);
float maxHeight1 = abs(_HeightAmplitude1);
float maxHeight2 = abs(_HeightAmplitude2);
float maxHeight3 = abs(_HeightAmplitude3);
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;
#endif
float weights[_MAX_LAYER];
ComputeMaskWeights(blendMasks, weights);
float maxHeight = BlendLayeredScalar(maxHeight0, maxHeight1, maxHeight2, maxHeight3, weights);
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;
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;
float uvSpaceScale = BlendLayeredScalar(ppdParam.uvSpaceScale[0], ppdParam.uvSpaceScale[1], ppdParam.uvSpaceScale[2], ppdParam.uvSpaceScale[3], weights);
float2 scaleOffsetDetails0 =_DetailMap0_ST.xy;
float2 scaleOffsetDetails1 =_DetailMap1_ST.xy;
float2 scaleOffsetDetails2 =_DetailMap2_ST.xy;
float2 scaleOffsetDetails3 =_DetailMap3_ST.xy;
float height; // final height processed
float NdotV;
// planar/triplanar
float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(V, uvXZ, uvXY, uvZY);
// 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;
// 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;
// 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;
layerTexCoord.base0.uv += offset;
layerTexCoord.base1.uv += offset;
layerTexCoord.base2.uv += offset;
layerTexCoord.base3.uv += offset;
layerTexCoord.details0.uv += offset * scaleOffsetDetails0;
layerTexCoord.details1.uv += offset * scaleOffsetDetails1;
layerTexCoord.details2.uv += offset * scaleOffsetDetails2;
layerTexCoord.details3.uv += offset * scaleOffsetDetails3;
}
// 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 }.
float verticalDisplacement = maxHeight - height * maxHeight;
return verticalDisplacement / max(NdotV, 0.001);
#else
return 0.0;
#endif
}
// Calculate displacement for per vertex displacement mapping
float3 ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod)
{
#if LAYERS_HEIGHTMAP_ENABLE
float height0 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base0, lod).r - _HeightCenter0) * _HeightAmplitude0;
float height1 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap1, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base1, lod).r - _HeightCenter1) * _HeightAmplitude1;
float height2 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap2, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base2, lod).r - _HeightCenter2) * _HeightAmplitude2;
float height3 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap3, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base3, lod).r - _HeightCenter3) * _HeightAmplitude3;
// Height is affected by tiling property and by object scale (depends on option).
// Apply scaling from tiling properties (TexWorldScale and tiling from BaseColor)
ApplyDisplacementTileScale(height0, height1, height2, height3);
// Nullify height that are not used, so compiler can remove unused case
SetEnabledHeightByLayer(height0, height1, height2, height3);
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);
// _MAIN_LAYER_INFLUENCE_MODE is a pure visual mode that doesn't contribute to the weights of a layer
// The motivation is like this: if a layer is visible, then we will apply influence on top of it (so it is only visual).
// This is what is done for normal and baseColor and we do the same for height.
// Note that if we apply influence before ApplyHeightBlend, then have a different behavior.
#if defined(_MAIN_LAYER_INFLUENCE_MODE) && defined(_HEIGHTMAP0)
// Add main layer influence if any (simply add main layer add on other layer)
// We multiply by the input mask for the first layer (blendMask.a) because if the mask here is black it means that the layer
// is not actually underneath any visible layer so we don't want to inherit its height.
float influenceMask = blendMasks.a;
#ifdef _INFLUENCEMASK_MAP
influenceMask *= GetInfluenceMask(layerTexCoord, true, lod);
#endif
height1 += height0 * _InheritBaseHeight1 * influenceMask;
height2 += height0 * _InheritBaseHeight2 * influenceMask;
height3 += height0 * _InheritBaseHeight3 * influenceMask;
#endif
float heightResult = BlendLayeredScalar(height0, height1, height2, height3, weights).xxx;
// Applying scaling of the object if requested
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
float3 objectScale = GetDisplacementObjectScale(true);
// Reminder: mappingType is know statically, so code below is optimize by the compiler
// Planar and Triplanar are in world space thus it is independent of object scale
return heightResult.xxx * BlendLayeredVector3( ((layerTexCoord.base0.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0)),
((layerTexCoord.base1.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0)),
((layerTexCoord.base2.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0)),
((layerTexCoord.base3.mappingType == UV_MAPPING_UVSET) ? objectScale : float3(1.0, 1.0, 1.0)), weights);
#else
return heightResult.xxx;
#endif
#else
return float3(0.0, 0.0, 0.0);
#endif
}

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


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

220
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataDisplacement.hlsl


// 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
// Note: This function is call by both Per vertex and Per pixel displacement
float GetMaxDisplacement()
{
float maxDisplacement = 0.0;
#if defined(_HEIGHTMAP)
maxDisplacement = abs(_HeightAmplitude); // _HeightAmplitude can be negative if min and max are inverted, but the max displacement must be positive
#endif
return maxDisplacement;
}
// Return the minimun uv size for all layers including triplanar
float2 GetMinUvSize(LayerTexCoord layerTexCoord)
{
float2 minUvSize = float2(FLT_MAX, FLT_MAX);
#if defined(_HEIGHTMAP)
if (layerTexCoord.base.mappingType == UV_MAPPING_TRIPLANAR)
{
minUvSize = min(layerTexCoord.base.uvZY * _HeightMap_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base.uvXZ * _HeightMap_TexelSize.zw, minUvSize);
minUvSize = min(layerTexCoord.base.uvXY * _HeightMap_TexelSize.zw, minUvSize);
}
else
{
minUvSize = min(layerTexCoord.base.uv * _HeightMap_TexelSize.zw, minUvSize);
}
#endif
return minUvSize;
}
struct PerPixelHeightDisplacementParam
{
float2 uv;
};
float ComputePerPixelHeightDisplacement(float2 texOffsetCurrent, float lod, PerPixelHeightDisplacementParam param)
{
// Note: No multiply by amplitude here. This is include in the maxHeight provide to POM
// Tiling is automatically handled correctly here.
return SAMPLE_TEXTURE2D_LOD(_HeightMap, sampler_HeightMap, param.uv + texOffsetCurrent, lod).r;
}
#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
}
float ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
{
#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;
// See comment in layered version for details
float maxHeight = GetMaxDisplacement();
ApplyDisplacementTileScale(maxHeight);
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;
float height = 0; // final height processed
float NdotV = 0;
// planar/triplanar
float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(V, uvXZ, uvXY, uvZY);
// TODO: support object space planar/triplanar ?
// We need to calculate the texture space direction. It depends on the mapping.
if (isTriplanar)
{
float planeHeight;
// Perform a POM in each direction and modify appropriate texture coordinate
[branch] if (layerTexCoord.triplanarWeights.x >= 0.001)
{
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);
// Apply offset to all triplanar UVSet
layerTexCoord.base.uvZY += offset;
layerTexCoord.details.uvZY += offset * scaleOffsetDetails;
height += layerTexCoord.triplanarWeights.x * planeHeight;
NdotV += layerTexCoord.triplanarWeights.x * viewDirTS.z;
}
[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 += offset;
layerTexCoord.details.uvXZ += offset * scaleOffsetDetails;
height += layerTexCoord.triplanarWeights.y * planeHeight;
NdotV += layerTexCoord.triplanarWeights.y * viewDirTS.z;
}
[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 += offset;
layerTexCoord.details.uvXY += offset * scaleOffsetDetails;
height += layerTexCoord.triplanarWeights.z * planeHeight;
NdotV += layerTexCoord.triplanarWeights.z * viewDirTS.z;
}
}
else
{
ppdParam.uv = layerTexCoord.base.uv; // For planar it is uv too, not uvXZ
// 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;
// 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);
// 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
return 0.0;
#endif
}
// Calculate displacement for per vertex displacement mapping
float3 ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod)
{
float height = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap, sampler_HeightMap, layerTexCoord.base, lod).r - _HeightCenter) * _HeightAmplitude;
// 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
}
#endif // #ifndef LAYERED_LIT_SHADER

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataDisplacement.hlsl.meta


fileFormatVersion: 2
guid: 1ee517c3caa96594ca34977000fa20a7
timeCreated: 1508932229
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataIndividualLayer.hlsl.meta


fileFormatVersion: 2
guid: 9460fe0fb917f0c4cbc8da701890bb96
timeCreated: 1508947139
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataMeshModification.hlsl.meta


fileFormatVersion: 2
guid: 9c0c9d4cde3e14c47a78362c1006e06f
timeCreated: 1508947140
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl.meta


fileFormatVersion: 2
guid: e190fae546bdd354e94a04e81eeb67e3
timeCreated: 1483954253
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl.meta


fileFormatVersion: 2
guid: 29d3b1d8672d46b4291970a2666b230e
timeCreated: 1483954252
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl → /ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataMeshModification.hlsl

/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl → /ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataIndividualLayer.hlsl

正在加载...
取消
保存