浏览代码

ShaderLibrary, change REAL to real

/feature-ReflectionProbeFit
sebastienlagarde 7 年前
当前提交
ecdf681c
共有 42 个文件被更改,包括 2405 次插入2405 次删除
  1. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/API/D3D11.hlsl
  2. 28
      ScriptableRenderPipeline/Core/ShaderLibrary/API/GLCore.hlsl
  3. 32
      ScriptableRenderPipeline/Core/ShaderLibrary/API/GLES2.hlsl
  4. 28
      ScriptableRenderPipeline/Core/ShaderLibrary/API/GLES3.hlsl
  5. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/API/Metal.hlsl
  6. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/API/PSSL.hlsl
  7. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/API/Vulkan.hlsl
  8. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/API/XBoxOne.hlsl
  9. 132
      ScriptableRenderPipeline/Core/ShaderLibrary/AreaLighting.hlsl
  10. 74
      ScriptableRenderPipeline/Core/ShaderLibrary/BC6H.hlsl
  11. 190
      ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl
  12. 196
      ScriptableRenderPipeline/Core/ShaderLibrary/Color.hlsl
  13. 206
      ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl
  14. 144
      ScriptableRenderPipeline/Core/ShaderLibrary/CommonLighting.hlsl
  15. 58
      ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl
  16. 6
      ScriptableRenderPipeline/Core/ShaderLibrary/CommonShadow.hlsl
  17. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/Debug.hlsl
  18. 94
      ScriptableRenderPipeline/Core/ShaderLibrary/EntityLighting.hlsl
  19. 76
      ScriptableRenderPipeline/Core/ShaderLibrary/GeometricTools.hlsl
  20. 320
      ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl
  21. 42
      ScriptableRenderPipeline/Core/ShaderLibrary/Macros.hlsl
  22. 60
      ScriptableRenderPipeline/Core/ShaderLibrary/NormalSurfaceGradient.hlsl
  23. 250
      ScriptableRenderPipeline/Core/ShaderLibrary/Packing.hlsl
  24. 56
      ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl
  25. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/QuaternionMath.hlsl
  26. 18
      ScriptableRenderPipeline/Core/ShaderLibrary/Random.hlsl
  27. 32
      ScriptableRenderPipeline/Core/ShaderLibrary/Refraction.hlsl
  28. 434
      ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/Fibonacci.hlsl
  29. 752
      ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/Hammersley.hlsl
  30. 16
      ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/SampleUVMapping.hlsl
  31. 6
      ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl
  32. 22
      ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/SampleUVMappingNormalInternal.hlsl
  33. 208
      ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/Sampling.hlsl
  34. 58
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  35. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Shadow.hlsl
  36. 320
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  37. 74
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowMoments.hlsl
  38. 494
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowSampling.hlsl
  39. 40
      ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowTexFetch.hlsl
  40. 44
      ScriptableRenderPipeline/Core/ShaderLibrary/Tessellation.hlsl
  41. 26
      ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl
  42. 82
      ScriptableRenderPipeline/Core/ShaderLibrary/Wind.hlsl

24
ScriptableRenderPipeline/Core/ShaderLibrary/API/D3D11.hlsl


#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (REAL(1.0))
#define UNITY_NEAR_CLIP_VALUE (real(1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (REAL(0.0))
#define UNITY_RAW_FAR_CLIP_VALUE (real(0.0))
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))

#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, REAL3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, REAL3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, REAL3(coord2, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, real3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, real3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, real3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, REAL4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, REAL4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, REAL4(coord3, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, real4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, real4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, real4(coord3, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, REAL3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, real3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, REAL4((coord4).xyz, index), (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, real4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r

#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, REAL3(coord2, index))
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, real3(coord2, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, REAL4(coord3, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, real4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)

28
ScriptableRenderPipeline/Core/ShaderLibrary/API/GLCore.hlsl


#define UNITY_UV_STARTS_AT_TOP 0
#define UNITY_REVERSED_Z 0
#define UNITY_GATHER_SUPPORTED 0
#define UNITY_NEAR_CLIP_VALUE (REAL(-1.0))
#define UNITY_NEAR_CLIP_VALUE (real(-1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (REAL(1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (real(1.0))
#define FRONT_FACE_TYPE REAL
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > REAL(0.0)) ? (FRONT) : (BACK))
#define FRONT_FACE_TYPE real
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > real(0.0)) ? (FRONT) : (BACK))
#define CBUFFER_START(name)
#define CBUFFER_END

#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, REAL3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, REAL3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, REAL3(coord2, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, real3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, real3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, real3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, REAL4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, REAL4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, REAL4(coord3, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, real4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, real4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, real4(coord3, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, REAL3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, real3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, REAL4((coord4).xyz, index), (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, real4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r

#if (SHADER_TARGET >= 45)
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, REAL3(coord2, index))
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, real3(coord2, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, REAL4(coord3, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, real4(coord3, index))
#else
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).rrrr
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index).rrrr

32
ScriptableRenderPipeline/Core/ShaderLibrary/API/GLES2.hlsl


#define UNITY_UV_STARTS_AT_TOP 0
#define UNITY_REVERSED_Z 0
#define UNITY_GATHER_SUPPORTED 0
#define UNITY_NEAR_CLIP_VALUE (REAL(-1.0))
#define UNITY_NEAR_CLIP_VALUE (real(-1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (REAL(1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (real(1.0))
#define FRONT_FACE_TYPE REAL
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > REAL(0.0)) ? (FRONT) : (BACK))
#define FRONT_FACE_TYPE real
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > real(0.0)) ? (FRONT) : (BACK))
#define CBUFFER_START(name)
#define CBUFFER_END

#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName, coord2)
#if (SHADER_TARGET >= 30)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, REAL4(coord2, 0, lod))
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, real4(coord2, 0, lod))
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, REAL4(coord2, 0, bias))
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, real4(coord2, 0, bias))
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) SAMPLE_TEXTURECUBE(textureName, samplerName, REAL3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, REAL3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, REAL3(coord2, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) SAMPLE_TEXTURECUBE(textureName, samplerName, real3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, real3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, real3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, REAL4(coord3, bias))
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, real4(coord3, bias))
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)

#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, REAL4(coord3.xy, index, coord3.w))
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, real4(coord3.xy, index, coord3.w))
#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) SHADOWCUBE_SAMPLE(textureName, samplerName, coord4)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4)

#define LOAD_TEXTURE2D(textureName, unCoord2) REAL4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) REAL4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) REAL4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) REAL4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) REAL4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D(textureName, unCoord2) real4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) real4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) real4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) real4(0, 0, 0, 0) // Not supported
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) real4(0, 0, 0, 0) // Not supported
// Gather not supported. Fallback to regular texture sampling.
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).rrrr

28
ScriptableRenderPipeline/Core/ShaderLibrary/API/GLES3.hlsl


#define UNITY_UV_STARTS_AT_TOP 0
#define UNITY_REVERSED_Z 0
#define UNITY_GATHER_SUPPORTED 0
#define UNITY_NEAR_CLIP_VALUE (REAL(-1.0))
#define UNITY_NEAR_CLIP_VALUE (real(-1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (REAL(1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (real(1.0))
#define FRONT_FACE_TYPE REAL
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > REAL(0.0)) ? (FRONT) : (BACK))
#define FRONT_FACE_TYPE real
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > real(0.0)) ? (FRONT) : (BACK))
#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error ##funcName is not supported on GLES 3.0

#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, REAL3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, REAL3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, REAL3(coord2, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, real3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, real3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, real3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, REAL4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, REAL4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, REAL4(coord3, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, real4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, real4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, real4(coord3, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, REAL3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, real3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, REAL4((coord4).xyz, index), (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, real4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r

#if (SHADER_TARGET >= 45)
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, REAL3(coord2, index))
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, real3(coord2, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, REAL4(coord3, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, real4(coord3, index))
#else
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).rrrr
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index).rrrr

24
ScriptableRenderPipeline/Core/ShaderLibrary/API/Metal.hlsl


#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (REAL(1.0))
#define UNITY_NEAR_CLIP_VALUE (real(1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (REAL(0.0))
#define UNITY_RAW_FAR_CLIP_VALUE (real(0.0))
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))

#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, REAL3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, REAL3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, REAL3(coord2, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, real3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, real3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, real3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, REAL4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, REAL4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, REAL4(coord3, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, real4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, real4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, real4(coord3, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, REAL3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, real3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, REAL4((coord4).xyz, index), (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, real4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r

#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, REAL3(coord2, index))
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, real3(coord2, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, REAL4(coord3, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, real4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)

24
ScriptableRenderPipeline/Core/ShaderLibrary/API/PSSL.hlsl


#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (REAL(1.0))
#define UNITY_NEAR_CLIP_VALUE (real(1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (REAL(0.0))
#define UNITY_RAW_FAR_CLIP_VALUE (real(0.0))
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))

#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, REAL3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, REAL3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, REAL3(coord2, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, real3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, real3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, real3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, REAL4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, REAL4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, REAL4(coord3, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, real4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, real4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, real4(coord3, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, REAL3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, real3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, REAL4((coord4).xyz, index), (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, real4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r

#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, REAL3(coord2, index))
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, real3(coord2, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, REAL4(coord3, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, real4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)

24
ScriptableRenderPipeline/Core/ShaderLibrary/API/Vulkan.hlsl


#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (REAL(1.0))
#define UNITY_NEAR_CLIP_VALUE (real(1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (REAL(0.0))
#define UNITY_RAW_FAR_CLIP_VALUE (real(0.0))
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))

#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, REAL3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, REAL3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, REAL3(coord2, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, real3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, real3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, real3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, REAL4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, REAL4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, REAL4(coord3, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, real4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, real4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, real4(coord3, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, REAL3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, real3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, REAL4((coord4).xyz, index), (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, real4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r

#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, REAL3(coord2, index))
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, real3(coord2, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, REAL4(coord3, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, real4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)

24
ScriptableRenderPipeline/Core/ShaderLibrary/API/XBoxOne.hlsl


#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (REAL(1.0))
#define UNITY_NEAR_CLIP_VALUE (real(1.0))
#define UNITY_RAW_FAR_CLIP_VALUE (REAL(0.0))
#define UNITY_RAW_FAR_CLIP_VALUE (real(0.0))
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))

#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, REAL3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, REAL3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, REAL3(coord2, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, real3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, real3(coord2, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, real3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, REAL4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, REAL4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, REAL4(coord3, index), bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, real4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, real4(coord3, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, real4(coord3, index), bias)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, REAL3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, real3((coord3).xy, index), (coord3).z)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, REAL4((coord4).xyz, index), (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, real4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r

#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, REAL3(coord2, index))
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, real3(coord2, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, REAL4(coord3, index))
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, real4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)

132
ScriptableRenderPipeline/Core/ShaderLibrary/AreaLighting.hlsl


#define APPROXIMATE_SPHERE_LIGHT_NUMERICALLY
// Not normalized by the factor of 1/TWO_PI.
REAL3 ComputeEdgeFactor(REAL3 V1, REAL3 V2)
real3 ComputeEdgeFactor(real3 V1, real3 V2)
REAL V1oV2 = dot(V1, V2);
REAL3 V1xV2 = cross(V1, V2);
real V1oV2 = dot(V1, V2);
real3 V1xV2 = cross(V1, V2);
#if 0
return V1xV2 * (rsqrt(1.0 - V1oV2 * V1oV2) * acos(V1oV2));
#else

REAL x = abs(V1oV2);
REAL y = 1.5707921083647782 + x * (-0.9995697178013095 + x * (0.778026455830408 + x * (-0.6173111361273548 + x * (0.4202724111150622 + x * (-0.19452783598217288 + x * 0.04232040013661036)))));
real x = abs(V1oV2);
real y = 1.5707921083647782 + x * (-0.9995697178013095 + x * (0.778026455830408 + x * (-0.6173111361273548 + x * (0.4202724111150622 + x * (-0.19452783598217288 + x * 0.04232040013661036)))));
if (V1oV2 < 0)
{

// Not normalized by the factor of 1/TWO_PI.
// Ref: Improving radiosity solutions through the use of analytically determined form-factors.
REAL IntegrateEdge(REAL3 V1, REAL3 V2)
real IntegrateEdge(real3 V1, real3 V2)
// 'sinSqSigma' is the sine^2 of the REAL of the opening angle of the sphere as seen from the shaded point.
// 'sinSqSigma' is the sine^2 of the real of the opening angle of the sphere as seen from the shaded point.
REAL DiffuseSphereLightIrradiance(REAL sinSqSigma, REAL cosOmega)
real DiffuseSphereLightIrradiance(real sinSqSigma, real cosOmega)
REAL x = sinSqSigma;
REAL y = cosOmega;
real x = sinSqSigma;
real y = cosOmega;
// Use a numerical fit found in Mathematica. Mean absolute error: 0.00476944.
// You can use the following Mathematica code to reproduce our results:

#else
#if 0 // Ref: Area Light Sources for Real-Time Graphics, page 4 (1996).
REAL sinSqOmega = saturate(1 - cosOmega * cosOmega);
REAL cosSqSigma = saturate(1 - sinSqSigma);
REAL sinSqGamma = saturate(cosSqSigma / sinSqOmega);
REAL cosSqGamma = saturate(1 - sinSqGamma);
real sinSqOmega = saturate(1 - cosOmega * cosOmega);
real cosSqSigma = saturate(1 - sinSqSigma);
real sinSqGamma = saturate(cosSqSigma / sinSqOmega);
real cosSqGamma = saturate(1 - sinSqGamma);
REAL sinSigma = sqrt(sinSqSigma);
REAL sinGamma = sqrt(sinSqGamma);
REAL cosGamma = sqrt(cosSqGamma);
real sinSigma = sqrt(sinSqSigma);
real sinGamma = sqrt(sinSqGamma);
real cosGamma = sqrt(cosSqGamma);
REAL sigma = asin(sinSigma);
REAL omega = acos(cosOmega);
REAL gamma = asin(sinGamma);
real sigma = asin(sinSigma);
real omega = acos(cosOmega);
real gamma = asin(sinGamma);
if (omega >= HALF_PI + sigma)
{

REAL e = sinSqSigma * cosOmega;
real e = sinSqSigma * cosOmega;
[branch]
if (omega < HALF_PI - sigma)

}
else
{
REAL g = (-2 * sqrt(sinSqOmega * cosSqSigma) + sinGamma) * cosGamma + (HALF_PI - gamma);
REAL h = cosOmega * (cosGamma * sqrt(saturate(sinSqSigma - cosSqGamma)) + sinSqSigma * asin(saturate(cosGamma / sinSigma)));
real g = (-2 * sqrt(sinSqOmega * cosSqSigma) + sinGamma) * cosGamma + (HALF_PI - gamma);
real h = cosOmega * (cosGamma * sqrt(saturate(sinSqSigma - cosSqGamma)) + sinSqSigma * asin(saturate(cosGamma / sinSigma)));
if (omega < HALF_PI)
{

}
}
#else // Ref: Moving Frostbite to Physically Based Rendering, page 47 (2015, optimized).
REAL cosSqOmega = cosOmega * cosOmega; // y^2
real cosSqOmega = cosOmega * cosOmega; // y^2
[branch]
if (cosSqOmega > sinSqSigma) // (y^2)>x

else
{
REAL cotSqSigma = rcp(sinSqSigma) - 1; // 1/x-1
REAL tanSqSigma = rcp(cotSqSigma); // x/(1-x)
REAL sinSqOmega = 1 - cosSqOmega; // 1-y^2
real cotSqSigma = rcp(sinSqSigma) - 1; // 1/x-1
real tanSqSigma = rcp(cotSqSigma); // x/(1-x)
real sinSqOmega = 1 - cosSqOmega; // 1-y^2
REAL w = sinSqOmega * tanSqSigma; // (1-y^2)*(x/(1-x))
REAL x = -cosOmega * rsqrt(w); // -y*Sqrt[(1/x-1)/(1-y^2)]
REAL y = sqrt(sinSqOmega * tanSqSigma - cosSqOmega); // Sqrt[(1-y^2)*(x/(1-x))-y^2]
REAL z = y * cotSqSigma; // Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
real w = sinSqOmega * tanSqSigma; // (1-y^2)*(x/(1-x))
real x = -cosOmega * rsqrt(w); // -y*Sqrt[(1/x-1)/(1-y^2)]
real y = sqrt(sinSqOmega * tanSqSigma - cosSqOmega); // Sqrt[(1-y^2)*(x/(1-x))-y^2]
real z = y * cotSqSigma; // Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
REAL a = cosOmega * acos(x) - z; // y*ArcCos[-y*Sqrt[(1/x-1)/(1-y^2)]]-Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
REAL b = atan(y); // ArcTan[Sqrt[(1-y^2)*(x/(1-x))-y^2]]
real a = cosOmega * acos(x) - z; // y*ArcCos[-y*Sqrt[(1/x-1)/(1-y^2)]]-Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
real b = atan(y); // ArcTan[Sqrt[(1-y^2)*(x/(1-x))-y^2]]
return saturate(INV_PI * (a * sinSqSigma + b));
}

// Expects non-normalized vertex positions.
REAL PolygonIrradiance(REAL4x3 L)
real PolygonIrradiance(real4x3 L)
{
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
[unroll]

}
REAL3 F = REAL3(0, 0, 0);
real3 F = real3(0, 0, 0);
REAL3 V1 = L[edge];
REAL3 V2 = L[(edge + 1) % 4];
real3 V1 = L[edge];
real3 V2 = L[(edge + 1) % 4];
REAL f2 = saturate(dot(F, F));
REAL sinSqSigma = min(sqrt(f2), 0.999);
REAL cosOmega = clamp(F.z * rsqrt(f2), -1, 1);
real f2 = saturate(dot(F, F));
real sinSqSigma = min(sqrt(f2), 0.999);
real cosOmega = clamp(F.z * rsqrt(f2), -1, 1);
return DiffuseSphereLightIrradiance(sinSqSigma, cosOmega);
#else

// The fifth vertex for cases when clipping cuts off one corner.
// Due to a compiler bug, copying L into a vector array with 5 rows
// messes something up, so we need to stick with the matrix + the L4 vertex.
REAL3 L4 = L[3];
real3 L4 = L[3];
// This switch is surprisingly fast. Tried replacing it with a lookup array of vertices.
// Even though that replaced the switch with just some indexing and no branches, it became

}
// 3. Integrate
REAL sum = 0;
real sum = 0;
sum += IntegrateEdge(L[0], L[1]);
sum += IntegrateEdge(L[1], L[2]);
sum += IntegrateEdge(L[2], L[3]);

#endif
}
REAL LineFpo(REAL tLDDL, REAL lrcpD, REAL rcpD)
real LineFpo(real tLDDL, real lrcpD, real rcpD)
REAL LineFwt(REAL tLDDL, REAL l)
real LineFwt(real tLDDL, real l)
{
// Compute: l * ((l / d) / (d * d + l * l)).
return l * tLDDL;

// 'tangent' is the line's tangent direction.
// 'normal' is the direction orthogonal to the tangent. It is the shortest vector between
// the shaded point and the line, pointing away from the shaded point.
REAL LineIrradiance(REAL l1, REAL l2, REAL3 normal, REAL3 tangent)
real LineIrradiance(real l1, real l2, real3 normal, real3 tangent)
REAL d = length(normal);
REAL l1rcpD = l1 * rcp(d);
REAL l2rcpD = l2 * rcp(d);
REAL tLDDL1 = l1rcpD / (d * d + l1 * l1);
REAL tLDDL2 = l2rcpD / (d * d + l2 * l2);
REAL intWt = LineFwt(tLDDL2, l2) - LineFwt(tLDDL1, l1);
REAL intP0 = LineFpo(tLDDL2, l2rcpD, rcp(d)) - LineFpo(tLDDL1, l1rcpD, rcp(d));
real d = length(normal);
real l1rcpD = l1 * rcp(d);
real l2rcpD = l2 * rcp(d);
real tLDDL1 = l1rcpD / (d * d + l1 * l1);
real tLDDL2 = l2rcpD / (d * d + l2 * l2);
real intWt = LineFwt(tLDDL2, l2) - LineFwt(tLDDL1, l1);
real intP0 = LineFpo(tLDDL2, l2rcpD, rcp(d)) - LineFpo(tLDDL1, l1rcpD, rcp(d));
REAL ComputeLineWidthFactor(REAL3x3 invM, REAL3 ortho)
real ComputeLineWidthFactor(real3x3 invM, real3 ortho)
REAL det = invM._11 * invM._22 - invM._22 * invM._31 * invM._13;
REAL3x3 cof = {invM._22, 0.0, -invM._22 * invM._31,
real det = invM._11 * invM._22 - invM._22 * invM._31 * invM._13;
real3x3 cof = {invM._22, 0.0, -invM._22 * invM._31,
0.0, invM._11 - invM._13 * invM._31, 0.0,
-invM._13 * invM._22, 0.0, invM._11 * invM._22};

// For line lights.
REAL LTCEvaluate(REAL3 P1, REAL3 P2, REAL3 B, REAL3x3 invM)
real LTCEvaluate(real3 P1, real3 P2, real3 B, real3x3 invM)
{
// Inverse-transform the endpoints.
P1 = mul(P1, invM);

if (P1.z <= 0.0 && P2.z <= 0.0) return 0.0;
REAL width = ComputeLineWidthFactor(invM, B);
real width = ComputeLineWidthFactor(invM, B);
if (P1.z > P2.z)
{

// Recompute the length and the tangent in the new coordinate system.
REAL len = length(P2 - P1);
REAL3 T = normalize(P2 - P1);
real len = length(P2 - P1);
real3 T = normalize(P2 - P1);
REAL t = -P1.z / T.z;
P1 = REAL3(P1.xy + t * T.xy, 0.0);
real t = -P1.z / T.z;
P1 = real3(P1.xy + t * T.xy, 0.0);
// Set the length of the visible part of the light.
len -= t;

// between the shaded point and the line, pointing away from the shaded point.
// Can be interpreted as a point on the line, since the shaded point is at the origin.
REAL proj = dot(P1, T);
REAL3 P0 = P1 - proj * T;
real proj = dot(P1, T);
real3 P0 = P1 - proj * T;
REAL l1 = proj;
REAL l2 = l1 + len;
real l1 = proj;
real l2 = l1 + len;
REAL irradiance = LineIrradiance(l1, l2, P0, T);
real irradiance = LineIrradiance(l1, l2, P0, T);
// Guard against numerical precision issues.
return max(INV_PI * width * irradiance, 0.0);

74
ScriptableRenderPipeline/Core/ShaderLibrary/BC6H.hlsl


// Doc: https://msdn.microsoft.com/en-us/library/windows/desktop/hh308952(v=vs.85).aspx
// Measure compression error
REAL CalcMSLE(REAL3 a, REAL3 b)
real CalcMSLE(real3 a, real3 b)
REAL3 err = log2(( b + 1.0) / (a + 1.0 ));
real3 err = log2(( b + 1.0) / (a + 1.0 ));
REAL3 Quantize7(REAL3 x)
real3 Quantize7(real3 x)
REAL3 Quantize9(REAL3 x)
real3 Quantize9(real3 x)
REAL3 Quantize10(REAL3 x)
real3 Quantize10(real3 x)
REAL3 Unquantize7(REAL3 x)
real3 Unquantize7(real3 x)
REAL3 Unquantize9(REAL3 x)
real3 Unquantize9(real3 x)
REAL3 Unquantize10(REAL3 x)
real3 Unquantize10(real3 x)
{
return (x * 65536.0 + 0x8000) / 1024.0;
}

uint ComputeIndex3( REAL texelPos, REAL endPoint0Pos, REAL endPoint1Pos )
uint ComputeIndex3( real texelPos, real endPoint0Pos, real endPoint1Pos )
REAL r = ( texelPos - endPoint0Pos ) / ( endPoint1Pos - endPoint0Pos );
real r = ( texelPos - endPoint0Pos ) / ( endPoint1Pos - endPoint0Pos );
uint ComputeIndex4( REAL texelPos, REAL endPoint0Pos, REAL endPoint1Pos )
uint ComputeIndex4( real texelPos, real endPoint0Pos, real endPoint1Pos )
REAL r = ( texelPos - endPoint0Pos ) / ( endPoint1Pos - endPoint0Pos );
real r = ( texelPos - endPoint0Pos ) / ( endPoint1Pos - endPoint0Pos );
void SignExtend( inout REAL3 v1, uint mask, uint signFlag )
void SignExtend( inout real3 v1, uint mask, uint signFlag )
{
int3 v = (int3) v1;
v.x = ( v.x & mask ) | ( v.x < 0 ? signFlag : 0 );

}
// 2nd step for unquantize
REAL3 FinishUnquantize( REAL3 endpoint0Unq, REAL3 endpoint1Unq, REAL weight )
real3 FinishUnquantize( real3 endpoint0Unq, real3 endpoint1Unq, real weight )
REAL3 comp = ( endpoint0Unq * ( 64.0 - weight ) + endpoint1Unq * weight + 32.0 ) * ( 31.0 / 4096.0 );
real3 comp = ( endpoint0Unq * ( 64.0 - weight ) + endpoint1Unq * weight + 32.0 ) * ( 31.0 / 4096.0 );
void EncodeMode11( inout uint4 block, inout REAL blockMSLE, REAL3 texels[ 16 ] )
void EncodeMode11( inout uint4 block, inout real blockMSLE, real3 texels[ 16 ] )
REAL3 blockMin = texels[ 0 ];
REAL3 blockMax = texels[ 0 ];
real3 blockMin = texels[ 0 ];
real3 blockMax = texels[ 0 ];
uint i;
for (i = 1; i < 16; ++i )
{

// refine endpoints in log2 RGB space
REAL3 refinedBlockMin = blockMax;
REAL3 refinedBlockMax = blockMin;
real3 refinedBlockMin = blockMax;
real3 refinedBlockMax = blockMin;
for (i = 0; i < 16; ++i )
{
refinedBlockMin = min( refinedBlockMin, texels[ i ] == blockMin ? refinedBlockMin : texels[ i ] );

REAL3 logBlockMax = log2( blockMax + 1.0 );
REAL3 logBlockMin = log2( blockMin + 1.0 );
REAL3 logRefinedBlockMax = log2( refinedBlockMax + 1.0 );
REAL3 logRefinedBlockMin = log2( refinedBlockMin + 1.0 );
REAL3 logBlockMaxExt = ( logBlockMax - logBlockMin ) * ( 1.0 / 32.0 );
real3 logBlockMax = log2( blockMax + 1.0 );
real3 logBlockMin = log2( blockMin + 1.0 );
real3 logRefinedBlockMax = log2( refinedBlockMax + 1.0 );
real3 logRefinedBlockMin = log2( refinedBlockMin + 1.0 );
real3 logBlockMaxExt = ( logBlockMax - logBlockMin ) * ( 1.0 / 32.0 );
REAL3 blockDir = blockMax - blockMin;
real3 blockDir = blockMax - blockMin;
REAL3 endpoint0 = Quantize10( blockMin );
REAL3 endpoint1 = Quantize10( blockMax );
REAL endPoint0Pos = f32tof16( dot( blockMin, blockDir ) );
REAL endPoint1Pos = f32tof16( dot( blockMax, blockDir ) );
real3 endpoint0 = Quantize10( blockMin );
real3 endpoint1 = Quantize10( blockMax );
real endPoint0Pos = f32tof16( dot( blockMin, blockDir ) );
real endPoint1Pos = f32tof16( dot( blockMax, blockDir ) );
REAL fixupTexelPos = f32tof16( dot( texels[ 0 ], blockDir ) );
real fixupTexelPos = f32tof16( dot( texels[ 0 ], blockDir ) );
uint fixupIndex = ComputeIndex4( fixupTexelPos, endPoint0Pos, endPoint1Pos );
if ( fixupIndex > 7 )
{

uint indices[ 16 ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (i = 0; i < 16; ++i )
{
REAL texelPos = f32tof16( dot( texels[ i ], blockDir ) );
real texelPos = f32tof16( dot( texels[ i ], blockDir ) );
REAL3 endpoint0Unq = Unquantize10( endpoint0 );
REAL3 endpoint1Unq = Unquantize10( endpoint1 );
REAL msle = 0.0;
real3 endpoint0Unq = Unquantize10( endpoint0 );
real3 endpoint1Unq = Unquantize10( endpoint1 );
real msle = 0.0;
REAL weight = floor( ( indices[ i ] * 64.0 ) / 15.0 + 0.5);
REAL3 texelUnc = FinishUnquantize( endpoint0Unq, endpoint1Unq, weight );
real weight = floor( ( indices[ i ] * 64.0 ) / 15.0 + 0.5);
real3 texelUnc = FinishUnquantize( endpoint0Unq, endpoint1Unq, weight );
msle += CalcMSLE( texels[ i ], texelUnc );
}

190
ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl


// Fresnel term
//-----------------------------------------------------------------------------
REAL F_Schlick(REAL f0, REAL f90, REAL u)
real F_Schlick(real f0, real f90, real u)
REAL x = 1.0 - u;
REAL x2 = x * x;
REAL x5 = x * x2 * x2;
real x = 1.0 - u;
real x2 = x * x;
real x5 = x * x2 * x2;
REAL F_Schlick(REAL f0, REAL u)
real F_Schlick(real f0, real u)
REAL3 F_Schlick(REAL3 f0, REAL f90, REAL u)
real3 F_Schlick(real3 f0, real f90, real u)
REAL x = 1.0 - u;
REAL x2 = x * x;
REAL x5 = x * x2 * x2;
real x = 1.0 - u;
real x2 = x * x;
real x5 = x * x2 * x2;
REAL3 F_Schlick(REAL3 f0, REAL u)
real3 F_Schlick(real3 f0, real u)
REAL F_Transm_Schlick(REAL f0, REAL f90, REAL u)
real F_Transm_Schlick(real f0, real f90, real u)
REAL x = 1.0 - u;
REAL x2 = x * x;
REAL x5 = x * x2 * x2;
real x = 1.0 - u;
real x2 = x * x;
real x5 = x * x2 * x2;
REAL F_Transm_Schlick(REAL f0, REAL u)
real F_Transm_Schlick(real f0, real u)
REAL3 F_Transm_Schlick(REAL3 f0, REAL f90, REAL u)
real3 F_Transm_Schlick(real3 f0, real f90, real u)
REAL x = 1.0 - u;
REAL x2 = x * x;
REAL x5 = x * x2 * x2;
real x = 1.0 - u;
real x2 = x * x;
real x5 = x * x2 * x2;
REAL3 F_Transm_Schlick(REAL3 f0, REAL u)
real3 F_Transm_Schlick(real3 f0, real u)
{
return F_Transm_Schlick(f0, 1.0, u); // sub mul mul mad mad*3
}

//-----------------------------------------------------------------------------
REAL D_GGXNoPI(REAL NdotH, REAL roughness)
real D_GGXNoPI(real NdotH, real roughness)
REAL a2 = Sq(roughness);
REAL s = (NdotH * a2 - NdotH) * NdotH + 1.0;
real a2 = Sq(roughness);
real s = (NdotH * a2 - NdotH) * NdotH + 1.0;
REAL D_GGX(REAL NdotH, REAL roughness)
real D_GGX(real NdotH, real roughness)
REAL G_MaskingSmithGGX(REAL NdotV, REAL roughness)
real G_MaskingSmithGGX(real NdotV, real roughness)
{
// G1(V, H) = HeavisideStep(VdotH) / (1 + Λ(V)).
// Λ(V) = -0.5 + 0.5 * sqrt(1 + 1 / a²).

}
// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, p. 12.
REAL D_GGX_Visible(REAL NdotH, REAL NdotV, REAL VdotH, REAL roughness)
real D_GGX_Visible(real NdotH, real NdotV, real VdotH, real roughness)
REAL GetSmithJointGGXPartLambdaV(REAL NdotV, REAL roughness)
real GetSmithJointGGXPartLambdaV(real NdotV, real roughness)
REAL a2 = Sq(roughness);
real a2 = Sq(roughness);
REAL V_SmithJointGGX(REAL NdotL, REAL NdotV, REAL roughness, REAL partLambdaV)
real V_SmithJointGGX(real NdotL, real NdotV, real roughness, real partLambdaV)
REAL a2 = Sq(roughness);
real a2 = Sq(roughness);
// Original formulation:
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5

// Reorder code to be more optimal:
REAL lambdaV = NdotL * partLambdaV;
REAL lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
REAL V_SmithJointGGX(REAL NdotL, REAL NdotV, REAL roughness)
real V_SmithJointGGX(real NdotL, real NdotV, real roughness)
REAL partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
real partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
REAL DV_SmithJointGGX(REAL NdotH, REAL NdotL, REAL NdotV, REAL roughness, REAL partLambdaV)
real DV_SmithJointGGX(real NdotH, real NdotL, real NdotV, real roughness, real partLambdaV)
REAL a2 = Sq(roughness);
REAL s = (NdotH * a2 - NdotH) * NdotH + 1.0;
real a2 = Sq(roughness);
real s = (NdotH * a2 - NdotH) * NdotH + 1.0;
REAL lambdaV = NdotL * partLambdaV;
REAL lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
REAL2 D = REAL2(a2, s * s); // Fraction without the multiplier (1/Pi)
REAL2 G = REAL2(1, lambdaV + lambdaL); // Fraction without the multiplier (1/2)
real2 D = real2(a2, s * s); // Fraction without the multiplier (1/Pi)
real2 G = real2(1, lambdaV + lambdaL); // Fraction without the multiplier (1/2)
REAL DV_SmithJointGGX(REAL NdotH, REAL NdotL, REAL NdotV, REAL roughness)
real DV_SmithJointGGX(real NdotH, real NdotL, real NdotV, real roughness)
REAL partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
real partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
return DV_SmithJointGGX(NdotH, NdotL, NdotV, roughness, partLambdaV);
}

// Otherwise, the worst case relative error is around 10%.
// https://www.desmos.com/calculator/wtp8lnjutx
REAL GetSmithJointGGXPartLambdaVApprox(REAL NdotV, REAL roughness)
real GetSmithJointGGXPartLambdaVApprox(real NdotV, real roughness)
REAL a = roughness;
real a = roughness;
REAL V_SmithJointGGXApprox(REAL NdotL, REAL NdotV, REAL roughness, REAL partLambdaV)
real V_SmithJointGGXApprox(real NdotL, real NdotV, real roughness, real partLambdaV)
REAL a = roughness;
real a = roughness;
REAL lambdaV = NdotL * partLambdaV;
REAL lambdaL = NdotV * (NdotL * (1 - a) + a);
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * (NdotL * (1 - a) + a);
REAL V_SmithJointGGXApprox(REAL NdotL, REAL NdotV, REAL roughness)
real V_SmithJointGGXApprox(real NdotL, real NdotV, real roughness)
REAL partLambdaV = GetSmithJointGGXPartLambdaVApprox(NdotV, roughness);
real partLambdaV = GetSmithJointGGXPartLambdaVApprox(NdotV, roughness);
REAL D_GGXAnisoNoPI(REAL TdotH, REAL BdotH, REAL NdotH, REAL roughnessT, REAL roughnessB)
real D_GGXAnisoNoPI(real TdotH, real BdotH, real NdotH, real roughnessT, real roughnessB)
REAL a2 = roughnessT * roughnessB;
REAL3 v = REAL3(roughnessB * TdotH, roughnessT * BdotH, a2 * NdotH);
REAL s = dot(v, v);
real a2 = roughnessT * roughnessB;
real3 v = real3(roughnessB * TdotH, roughnessT * BdotH, a2 * NdotH);
real s = dot(v, v);
REAL D_GGXAniso(REAL TdotH, REAL BdotH, REAL NdotH, REAL roughnessT, REAL roughnessB)
real D_GGXAniso(real TdotH, real BdotH, real NdotH, real roughnessT, real roughnessB)
REAL GetSmithJointGGXAnisoPartLambdaV(REAL TdotV, REAL BdotV, REAL NdotV, REAL roughnessT, REAL roughnessB)
real GetSmithJointGGXAnisoPartLambdaV(real TdotV, real BdotV, real NdotV, real roughnessT, real roughnessB)
return length(REAL3(roughnessT * TdotV, roughnessB * BdotV, NdotV));
return length(real3(roughnessT * TdotV, roughnessB * BdotV, NdotV));
REAL V_SmithJointGGXAniso(REAL TdotV, REAL BdotV, REAL NdotV, REAL TdotL, REAL BdotL, REAL NdotL, REAL roughnessT, REAL roughnessB, REAL partLambdaV)
real V_SmithJointGGXAniso(real TdotV, real BdotV, real NdotV, real TdotL, real BdotL, real NdotL, real roughnessT, real roughnessB, real partLambdaV)
REAL lambdaV = NdotL * partLambdaV;
REAL lambdaL = NdotV * length(REAL3(roughnessT * TdotL, roughnessB * BdotL, NdotL));
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * length(real3(roughnessT * TdotL, roughnessB * BdotL, NdotL));
REAL V_SmithJointGGXAniso(REAL TdotV, REAL BdotV, REAL NdotV, REAL TdotL, REAL BdotL, REAL NdotL, REAL roughnessT, REAL roughnessB)
real V_SmithJointGGXAniso(real TdotV, real BdotV, real NdotV, real TdotL, real BdotL, real NdotL, real roughnessT, real roughnessB)
REAL partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
real partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
REAL DV_SmithJointGGXAniso(REAL TdotH, REAL BdotH, REAL NdotH, REAL NdotV,
REAL TdotL, REAL BdotL, REAL NdotL,
REAL roughnessT, REAL roughnessB, REAL partLambdaV)
real DV_SmithJointGGXAniso(real TdotH, real BdotH, real NdotH, real NdotV,
real TdotL, real BdotL, real NdotL,
real roughnessT, real roughnessB, real partLambdaV)
REAL a2 = roughnessT * roughnessB;
REAL3 v = REAL3(roughnessB * TdotH, roughnessT * BdotH, a2 * NdotH);
REAL s = dot(v, v);
real a2 = roughnessT * roughnessB;
real3 v = real3(roughnessB * TdotH, roughnessT * BdotH, a2 * NdotH);
real s = dot(v, v);
REAL lambdaV = NdotL * partLambdaV;
REAL lambdaL = NdotV * length(REAL3(roughnessT * TdotL, roughnessB * BdotL, NdotL));
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * length(real3(roughnessT * TdotL, roughnessB * BdotL, NdotL));
REAL2 D = REAL2(a2 * a2 * a2, s * s); // Fraction without the multiplier (1/Pi)
REAL2 G = REAL2(1, lambdaV + lambdaL); // Fraction without the multiplier (1/2)
real2 D = real2(a2 * a2 * a2, s * s); // Fraction without the multiplier (1/Pi)
real2 G = real2(1, lambdaV + lambdaL); // Fraction without the multiplier (1/2)
REAL DV_SmithJointGGXAniso(REAL TdotH, REAL BdotH, REAL NdotH,
REAL TdotV, REAL BdotV, REAL NdotV,
REAL TdotL, REAL BdotL, REAL NdotL,
REAL roughnessT, REAL roughnessB)
real DV_SmithJointGGXAniso(real TdotH, real BdotH, real NdotH,
real TdotV, real BdotV, real NdotV,
real TdotL, real BdotL, real NdotL,
real roughnessT, real roughnessB)
REAL partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
real partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, NdotV, TdotL, BdotL, NdotL,
roughnessT, roughnessB, partLambdaV);
}

//-----------------------------------------------------------------------------
REAL LambertNoPI()
real LambertNoPI()
REAL Lambert()
real Lambert()
REAL DisneyDiffuseNoPI(REAL NdotV, REAL NdotL, REAL LdotV, REAL perceptualRoughness)
real DisneyDiffuseNoPI(real NdotV, real NdotL, real LdotV, real perceptualRoughness)
// REAL fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
REAL fd90 = 0.5 + (perceptualRoughness + perceptualRoughness * LdotV);
// real fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
real fd90 = 0.5 + (perceptualRoughness + perceptualRoughness * LdotV);
REAL lightScatter = F_Schlick(1.0, fd90, NdotL);
REAL viewScatter = F_Schlick(1.0, fd90, NdotV);
real lightScatter = F_Schlick(1.0, fd90, NdotL);
real viewScatter = F_Schlick(1.0, fd90, NdotV);
// Normalize the BRDF for polar view angles of up to (Pi/4).
// We use the worst case of (roughness = albedo = 1), and, for each view angle,

return rcp(1.03571) * (lightScatter * viewScatter);
}
REAL DisneyDiffuse(REAL NdotV, REAL NdotL, REAL LdotV, REAL perceptualRoughness)
real DisneyDiffuse(real NdotV, real NdotL, real LdotV, real perceptualRoughness)
REAL3 DiffuseGGXNoPI(REAL3 albedo, REAL NdotV, REAL NdotL, REAL NdotH, REAL LdotV, REAL roughness)
real3 DiffuseGGXNoPI(real3 albedo, real NdotV, real NdotL, real NdotH, real LdotV, real roughness)
REAL facing = 0.5 + 0.5 * LdotV; // (LdotH)^2
REAL rough = facing * (0.9 - 0.4 * facing) * (0.5 / NdotH + 1);
REAL transmitL = F_Transm_Schlick(0, NdotL);
REAL transmitV = F_Transm_Schlick(0, NdotV);
REAL smooth = transmitL * transmitV * 1.05; // Normalize F_t over the hemisphere
REAL single = lerp(smooth, rough, roughness); // Rescaled by PI
REAL multiple = roughness * (0.1159 * PI); // Rescaled by PI
real facing = 0.5 + 0.5 * LdotV; // (LdotH)^2
real rough = facing * (0.9 - 0.4 * facing) * (0.5 / NdotH + 1);
real transmitL = F_Transm_Schlick(0, NdotL);
real transmitV = F_Transm_Schlick(0, NdotV);
real smooth = transmitL * transmitV * 1.05; // Normalize F_t over the hemisphere
real single = lerp(smooth, rough, roughness); // Rescaled by PI
real multiple = roughness * (0.1159 * PI); // Rescaled by PI
REAL3 DiffuseGGX(REAL3 albedo, REAL NdotV, REAL NdotL, REAL NdotH, REAL LdotV, REAL roughness)
real3 DiffuseGGX(real3 albedo, real NdotV, real NdotL, real NdotH, real LdotV, real roughness)
{
// Note that we could save 2 cycles by inlining the multiplication by INV_PI.
return INV_PI * DiffuseGGXNoPI(albedo, NdotV, NdotL, NdotH, LdotV, roughness);

196
ScriptableRenderPipeline/Core/ShaderLibrary/Color.hlsl


//-----------------------------------------------------------------------------
// Gamma20
REAL Gamma20ToLinear(REAL c)
real Gamma20ToLinear(real c)
REAL3 Gamma20ToLinear(REAL3 c)
real3 Gamma20ToLinear(real3 c)
REAL4 Gamma20ToLinear(REAL4 c)
real4 Gamma20ToLinear(real4 c)
return REAL4(Gamma20ToLinear(c.rgb), c.a);
return real4(Gamma20ToLinear(c.rgb), c.a);
REAL LinearToGamma20(REAL c)
real LinearToGamma20(real c)
REAL3 LinearToGamma20(REAL3 c)
real3 LinearToGamma20(real3 c)
REAL4 LinearToGamma20(REAL4 c)
real4 LinearToGamma20(real4 c)
return REAL4(LinearToGamma20(c.rgb), c.a);
return real4(LinearToGamma20(c.rgb), c.a);
REAL Gamma22ToLinear(REAL c)
real Gamma22ToLinear(real c)
REAL3 Gamma22ToLinear(REAL3 c)
real3 Gamma22ToLinear(real3 c)
return pow(c.rgb, REAL3(2.2, 2.2, 2.2));
return pow(c.rgb, real3(2.2, 2.2, 2.2));
REAL4 Gamma22ToLinear(REAL4 c)
real4 Gamma22ToLinear(real4 c)
return REAL4(Gamma22ToLinear(c.rgb), c.a);
return real4(Gamma22ToLinear(c.rgb), c.a);
REAL LinearToGamma22(REAL c)
real LinearToGamma22(real c)
REAL3 LinearToGamma22(REAL3 c)
real3 LinearToGamma22(real3 c)
return pow(c.rgb, REAL3(0.454545454545455, 0.454545454545455, 0.454545454545455));
return pow(c.rgb, real3(0.454545454545455, 0.454545454545455, 0.454545454545455));
REAL4 LinearToGamma22(REAL4 c)
real4 LinearToGamma22(real4 c)
return REAL4(LinearToGamma22(c.rgb), c.a);
return real4(LinearToGamma22(c.rgb), c.a);
REAL3 SRGBToLinear(REAL3 c)
real3 SRGBToLinear(real3 c)
REAL3 linearRGBLo = c / 12.92;
REAL3 linearRGBHi = pow((c + 0.055) / 1.055, REAL3(2.4, 2.4, 2.4));
REAL3 linearRGB = (c <= 0.04045) ? linearRGBLo : linearRGBHi;
real3 linearRGBLo = c / 12.92;
real3 linearRGBHi = pow((c + 0.055) / 1.055, real3(2.4, 2.4, 2.4));
real3 linearRGB = (c <= 0.04045) ? linearRGBLo : linearRGBHi;
REAL4 SRGBToLinear(REAL4 c)
real4 SRGBToLinear(real4 c)
return REAL4(SRGBToLinear(c.rgb), c.a);
return real4(SRGBToLinear(c.rgb), c.a);
REAL3 LinearToSRGB(REAL3 c)
real3 LinearToSRGB(real3 c)
REAL3 sRGBLo = c * 12.92;
REAL3 sRGBHi = (pow(c, REAL3(1.0/2.4, 1.0/2.4, 1.0/2.4)) * 1.055) - 0.055;
REAL3 sRGB = (c <= 0.0031308) ? sRGBLo : sRGBHi;
real3 sRGBLo = c * 12.92;
real3 sRGBHi = (pow(c, real3(1.0/2.4, 1.0/2.4, 1.0/2.4)) * 1.055) - 0.055;
real3 sRGB = (c <= 0.0031308) ? sRGBLo : sRGBHi;
REAL4 LinearToSRGB(REAL4 c)
real4 LinearToSRGB(real4 c)
return REAL4(LinearToSRGB(c.rgb), c.a);
return real4(LinearToSRGB(c.rgb), c.a);
REAL3 FastSRGBToLinear(REAL3 c)
real3 FastSRGBToLinear(real3 c)
REAL4 FastSRGBToLinear(REAL4 c)
real4 FastSRGBToLinear(real4 c)
return REAL4(FastSRGBToLinear(c.rgb), c.a);
return real4(FastSRGBToLinear(c.rgb), c.a);
REAL3 FastLinearToSRGB(REAL3 c)
real3 FastLinearToSRGB(real3 c)
REAL4 FastLinearToSRGB(REAL4 c)
real4 FastLinearToSRGB(real4 c)
return REAL4(FastLinearToSRGB(c.rgb), c.a);
return real4(FastLinearToSRGB(c.rgb), c.a);
}
//-----------------------------------------------------------------------------

// Convert rgb to luminance
// with rgb in linear space with sRGB primaries and D65 white point
REAL Luminance(REAL3 linearRgb)
real Luminance(real3 linearRgb)
return dot(linearRgb, REAL3(0.2126729f, 0.7151522f, 0.0721750f));
return dot(linearRgb, real3(0.2126729f, 0.7151522f, 0.0721750f));
REAL Luminance(REAL4 linearRgba)
real Luminance(real4 linearRgba)
{
return Luminance(linearRgba.rgb);
}

// Ref: http://www.nvidia.com/object/real-time-ycocg-dxt-compression.html
#define YCOCG_CHROMA_BIAS (128.0 / 255.0)
REAL3 RGBToYCoCg(REAL3 rgb)
real3 RGBToYCoCg(real3 rgb)
REAL3 YCoCg;
YCoCg.x = dot(rgb, REAL3(0.25, 0.5, 0.25));
YCoCg.y = dot(rgb, REAL3(0.5, 0.0, -0.5)) + YCOCG_CHROMA_BIAS;
YCoCg.z = dot(rgb, REAL3(-0.25, 0.5, -0.25)) + YCOCG_CHROMA_BIAS;
real3 YCoCg;
YCoCg.x = dot(rgb, real3(0.25, 0.5, 0.25));
YCoCg.y = dot(rgb, real3(0.5, 0.0, -0.5)) + YCOCG_CHROMA_BIAS;
YCoCg.z = dot(rgb, real3(-0.25, 0.5, -0.25)) + YCOCG_CHROMA_BIAS;
REAL3 YCoCgToRGB(REAL3 YCoCg)
real3 YCoCgToRGB(real3 YCoCg)
REAL Y = YCoCg.x;
REAL Co = YCoCg.y - YCOCG_CHROMA_BIAS;
REAL Cg = YCoCg.z - YCOCG_CHROMA_BIAS;
real Y = YCoCg.x;
real Co = YCoCg.y - YCOCG_CHROMA_BIAS;
real Cg = YCoCg.z - YCOCG_CHROMA_BIAS;
REAL3 rgb;
real3 rgb;
rgb.r = Y + Co - Cg;
rgb.g = Y + Cg;
rgb.b = Y - Co - Cg;

// Following function can be use to reconstruct chroma component for a checkboard YCoCg pattern
// Reference: The Compact YCoCg Frame Buffer
REAL YCoCgCheckBoardEdgeFilter(REAL centerLum, REAL2 a0, REAL2 a1, REAL2 a2, REAL2 a3)
real YCoCgCheckBoardEdgeFilter(real centerLum, real2 a0, real2 a1, real2 a2, real2 a3)
REAL4 lum = REAL4(a0.x, a1.x, a2.x, a3.x);
// Optimize: REAL4 w = 1.0 - step(30.0 / 255.0, abs(lum - centerLum));
REAL4 w = 1.0 - saturate((abs(lum.xxxx - centerLum) - 30.0 / 255.0) * HALF_MAX);
REAL W = w.x + w.y + w.z + w.w;
real4 lum = real4(a0.x, a1.x, a2.x, a3.x);
// Optimize: real4 w = 1.0 - step(30.0 / 255.0, abs(lum - centerLum));
real4 w = 1.0 - saturate((abs(lum.xxxx - centerLum) - 30.0 / 255.0) * HALF_MAX);
real W = w.x + w.y + w.z + w.w;
// handle the special case where all the weights are zero.
return (W == 0.0) ? a0.y : (w.x * a0.y + w.y* a1.y + w.z* a2.y + w.w * a3.y) / W;
}

// Hue [0.0, 1.0]
// Sat [0.0, 1.0]
// Lum [0.0, HALF_MAX]
REAL3 RgbToHsv(REAL3 c)
real3 RgbToHsv(real3 c)
const REAL4 K = REAL4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
REAL4 p = lerp(REAL4(c.bg, K.wz), REAL4(c.gb, K.xy), step(c.b, c.g));
REAL4 q = lerp(REAL4(p.xyw, c.r), REAL4(c.r, p.yzx), step(p.x, c.r));
REAL d = q.x - min(q.w, q.y);
const REAL e = 1.0e-4;
return REAL3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
const real4 K = real4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
real4 p = lerp(real4(c.bg, K.wz), real4(c.gb, K.xy), step(c.b, c.g));
real4 q = lerp(real4(p.xyw, c.r), real4(c.r, p.yzx), step(p.x, c.r));
real d = q.x - min(q.w, q.y);
const real e = 1.0e-4;
return real3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
REAL3 HsvToRgb(REAL3 c)
real3 HsvToRgb(real3 c)
const REAL4 K = REAL4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
REAL3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
const real4 K = real4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
real3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}

struct ParamsPQ
{
REAL N, M;
REAL C1, C2, C3;
real N, M;
real C1, C2, C3;
};
static const ParamsPQ PQ =

2392.0 / 4096.0 * 32.0, // C3
};
REAL3 LinearToPQ(REAL3 x, REAL maxPQValue)
real3 LinearToPQ(real3 x, real maxPQValue)
REAL3 nd = (PQ.C1 + PQ.C2 * x) / (1.0 + PQ.C3 * x);
real3 nd = (PQ.C1 + PQ.C2 * x) / (1.0 + PQ.C3 * x);
REAL3 LinearToPQ(REAL3 x)
real3 LinearToPQ(real3 x)
REAL3 PQToLinear(REAL3 x, REAL maxPQValue)
real3 PQToLinear(real3 x, real maxPQValue)
REAL3 nd = max(x - PQ.C1, 0.0) / (PQ.C2 - (PQ.C3 * x));
real3 nd = max(x - PQ.C1, 0.0) / (PQ.C2 - (PQ.C3 * x));
REAL3 PQToLinear(REAL3 x)
real3 PQToLinear(real3 x)
{
return PQToLinear(x, DEFAULT_MAX_PQ);
}

struct ParamsLogC
{
REAL cut;
REAL a, b, c, d, e, f;
real cut;
real a, b, c, d, e, f;
};
static const ParamsLogC LogC =

0.092819 // f
};
REAL LinearToLogC_Precise(REAL x)
real LinearToLogC_Precise(real x)
REAL o;
real o;
if (x > LogC.cut)
o = LogC.c * log10(LogC.a * x + LogC.b) + LogC.d;
else

REAL3 LinearToLogC(REAL3 x)
real3 LinearToLogC(real3 x)
return REAL3(
return real3(
LinearToLogC_Precise(x.x),
LinearToLogC_Precise(x.y),
LinearToLogC_Precise(x.z)

#endif
}
REAL LogCToLinear_Precise(REAL x)
real LogCToLinear_Precise(real x)
REAL o;
real o;
if (x > LogC.e * LogC.cut + LogC.f)
o = (pow(10.0, (x - LogC.d) / LogC.c) - LogC.b) / LogC.a;
else

REAL3 LogCToLinear(REAL3 x)
real3 LogCToLinear(real3 x)
return REAL3(
return real3(
LogCToLinear_Precise(x.x),
LogCToLinear_Precise(x.y),
LogCToLinear_Precise(x.z)

// Fast reversible tonemapper
// http://gpuopen.com/optimized-reversible-tonemapper-for-resolve/
REAL3 FastTonemap(REAL3 c)
real3 FastTonemap(real3 c)
REAL4 FastTonemap(REAL4 c)
real4 FastTonemap(real4 c)
return REAL4(FastTonemap(c.rgb), c.a);
return real4(FastTonemap(c.rgb), c.a);
REAL3 FastTonemap(REAL3 c, REAL w)
real3 FastTonemap(real3 c, real w)
REAL4 FastTonemap(REAL4 c, REAL w)
real4 FastTonemap(real4 c, real w)
return REAL4(FastTonemap(c.rgb, w), c.a);
return real4(FastTonemap(c.rgb, w), c.a);
REAL3 FastTonemapInvert(REAL3 c)
real3 FastTonemapInvert(real3 c)
REAL4 FastTonemapInvert(REAL4 c)
real4 FastTonemapInvert(real4 c)
return REAL4(FastTonemapInvert(c.rgb), c.a);
return real4(FastTonemapInvert(c.rgb), c.a);
REAL3 ApplyLut3D(TEXTURE3D_ARGS(tex, samplerTex), REAL3 uvw, REAL2 scaleOffset)
real3 ApplyLut3D(TEXTURE3D_ARGS(tex, samplerTex), real3 uvw, real2 scaleOffset)
REAL shift = floor(uvw.z);
real shift = floor(uvw.z);
uvw.xy = uvw.xy * scaleOffset.y * scaleOffset.xx + scaleOffset.xx * 0.5;
uvw.x += shift * scaleOffset.x;
return SAMPLE_TEXTURE3D(tex, samplerTex, uvw).rgb;

// scaleOffset = (1 / lut_width, 1 / lut_height, lut_height - 1)
REAL3 ApplyLut2D(TEXTURE2D_ARGS(tex, samplerTex), REAL3 uvw, REAL3 scaleOffset)
real3 ApplyLut2D(TEXTURE2D_ARGS(tex, samplerTex), real3 uvw, real3 scaleOffset)
REAL shift = floor(uvw.z);
real shift = floor(uvw.z);
SAMPLE_TEXTURE2D(tex, samplerTex, uvw.xy + REAL2(scaleOffset.y, 0.0)).rgb,
SAMPLE_TEXTURE2D(tex, samplerTex, uvw.xy + real2(scaleOffset.y, 0.0)).rgb,
uvw.z - shift
);
return uvw;

// params = (lut_height, 0.5 / lut_width, 0.5 / lut_height, lut_height / lut_height - 1)
REAL3 GetLutStripValue(REAL2 uv, REAL4 params)
real3 GetLutStripValue(real2 uv, real4 params)
REAL3 color;
real3 color;
color.r = frac(uv.x * params.x);
color.b = uv.x - color.r / params.x;
color.g = uv.y;

206
ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl


// The reason is that for compute shader we need to guarantee that the layout of CBs is consistent across kernels. Something that we can't control with the global namespace (uniforms get optimized out if not used, modifying the global CBuffer layout per kernel)
// Structure definition that are share between C# and hlsl.
// These structures need to be align on REAL4 to respect various packing rules from sahder language.
// These structures need to be align on real4 to respect various packing rules from sahder language.
// This mean that these structure need to be padded.
// Do not use "in", only "out" or "inout" as califier, not "inline" keyword either, useless.

// headers from ShaderLibrary do not include "common.hlsl", this should be included in the .shader using it (or Material.hlsl)
// Rules: When doing an array for constant buffer variables, we always use REAL4 to avoid any packing issue, particularly between compute shader and pixel shaders
// Rules: When doing an array for constant buffer variables, we always use real4 to avoid any packing issue, particularly between compute shader and pixel shaders
// uniform REAL4 packedArray[3];
// static REAL unpackedArray[12] = (REAL[12]packedArray;
// uniform real4 packedArray[3];
// static real unpackedArray[12] = (real[12]packedArray;
#ifndef REAL
#define REAL float
#define REAL2 float2
#define REAL3 float3
#define REAL4 float4
#ifndef real
#define real float
#define real2 float2
#define real3 float3
#define real4 float4
#define REAL2x2 float2x2
#define REAL2x3 float2x3
#define REAL3x2 float3x2
#define REAL3x3 float3x3
#define REAL3x4 float3x4
#define REAL4x3 float4x3
#define REAL4x4 float4x4
#define real2x2 float2x2
#define real2x3 float2x3
#define real3x2 float3x2
#define real3x3 float3x3
#define real3x4 float3x4
#define real4x3 float4x3
#define real4x4 float4x4
#define REAL_MIN FLT_MIN
#define REAL_MAX FLT_MAX

#ifndef INTRINSIC_CUBEMAP_FACE_ID
// TODO: implement this. Is the reference implementation of cubemapID provide by AMD the reverse of our ?
/*
REAL CubemapFaceID(REAL3 dir)
real CubemapFaceID(real3 dir)
REAL faceID;
real faceID;
if (abs(dir.z) >= abs(dir.x) && abs(dir.z) >= abs(dir.y))
{
faceID = (dir.z < 0.0) ? 5.0 : 4.0;

}
*/
void GetCubeFaceID(REAL3 dir, out int faceIndex)
void GetCubeFaceID(real3 dir, out int faceIndex)
REAL3 adir = abs(dir);
real3 adir = abs(dir);
// +Z -Z
faceIndex = dir.z > 0.0 ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z;

// Common math functions
// ----------------------------------------------------------------------------
REAL DegToRad(REAL deg)
real DegToRad(real deg)
REAL RadToDeg(REAL rad)
real RadToDeg(real rad)
{
return rad * (180.0 / PI);
}

// Input [0, 1] and output [0, PI/2]
// 9 VALU
REAL FastACosPos(REAL inX)
real FastACosPos(real inX)
REAL x = abs(inX);
REAL res = (0.0468878 * x + -0.203471) * x + 1.570796; // p(x)
real x = abs(inX);
real res = (0.0468878 * x + -0.203471) * x + 1.570796; // p(x)
res *= sqrt(1.0 - x);
return res;

// Input [-1, 1] and output [0, PI]
// 12 VALU
REAL FastACos(REAL inX)
real FastACos(real inX)
REAL res = FastACosPos(inX);
real res = FastACosPos(inX);
return (inX >= 0) ? res : PI - res; // Undo range reduction
}

// input [-1, 1] and output [-PI/2, PI/2]
REAL FastASin(REAL x)
real FastASin(real x)
{
return HALF_PI - FastACos(x);
}

// 4 VGPR, 14 FR (10 FR, 1 QR), 2 scalar
// input [0, infinity] and output [0, PI/2]
REAL FastATanPos(REAL x)
real FastATanPos(real x)
REAL t0 = (x < 1.0) ? x : 1.0 / x;
REAL t1 = t0 * t0;
REAL poly = 0.0872929;
real t0 = (x < 1.0) ? x : 1.0 / x;
real t1 = t0 * t0;
real poly = 0.0872929;
poly = -0.301895 + poly * t1;
poly = 1.0 + poly * t1;
poly = poly * t0;

// 4 VGPR, 16 FR (12 FR, 1 QR), 2 scalar
// input [-infinity, infinity] and output [-PI/2, PI/2]
REAL FastATan(REAL x)
real FastATan(real x)
REAL t0 = FastATanPos(abs(x));
real t0 = FastATanPos(abs(x));
return (x < 0.0) ? -t0 : t0;
}

// Computes (FastSign(s) * x) using 2x VALU.
// See the comment about FastSign() below.
REAL FastMulBySignOf(REAL s, REAL x, bool ignoreNegZero = true)
real FastMulBySignOf(real s, real x, bool ignoreNegZero = true)
{
#if !defined(SHADER_API_GLES)
if (ignoreNegZero)

// Therefore, we treat -0 as +0 by default: FastSign(+0) = FastSign(-0) = 1.
// If (ignoreNegZero = false), FastSign(-0, false) = -1.
// Note that the sign() function in HLSL implements signum, which returns 0 for 0.
REAL FastSign(REAL s, bool ignoreNegZero = true)
real FastSign(real s, bool ignoreNegZero = true)
{
return FastMulBySignOf(s, 1.0, ignoreNegZero);
}

// Returns the new tangent (the normal is unaffected).
REAL3 Orthonormalize(REAL3 tangent, REAL3 normal)
real3 Orthonormalize(real3 tangent, real3 normal)
REAL Smoothstep01(REAL x)
real Smoothstep01(real x)
{
return x * x * (3.0 - (2.0 * x));
}

// ----------------------------------------------------------------------------
REAL ComputeTextureLOD(REAL2 uv)
real ComputeTextureLOD(real2 uv)
REAL2 ddx_ = ddx(uv);
REAL2 ddy_ = ddy(uv);
REAL d = max(dot(ddx_, ddx_), dot(ddy_, ddy_));
real2 ddx_ = ddx(uv);
real2 ddy_ = ddy(uv);
real d = max(dot(ddx_, ddx_), dot(ddy_, ddy_));
return max(0.5 * log2(d), 0.0);
}

REAL ComputeTextureLOD(REAL2 uv, REAL4 texelSize)
real ComputeTextureLOD(real2 uv, real4 texelSize)
{
uv *= texelSize.zw;

// Texture format sampling
// ----------------------------------------------------------------------------
REAL2 DirectionToLatLongCoordinate(REAL3 unDir)
real2 DirectionToLatLongCoordinate(real3 unDir)
REAL3 dir = normalize(unDir);
real3 dir = normalize(unDir);
return REAL2(1.0 - 0.5 * INV_PI * atan2(dir.x, -dir.z), asin(dir.y) * INV_PI + 0.5);
return real2(1.0 - 0.5 * INV_PI * atan2(dir.x, -dir.z), asin(dir.y) * INV_PI + 0.5);
REAL3 LatlongToDirectionCoordinate(REAL2 coord)
real3 LatlongToDirectionCoordinate(real2 coord)
REAL theta = coord.y * PI;
REAL phi = (coord.x * 2.f * PI - PI*0.5f);
real theta = coord.y * PI;
real phi = (coord.x * 2.f * PI - PI*0.5f);
REAL cosTheta = cos(theta);
REAL sinTheta = sqrt(1.0 - min(1.0, cosTheta*cosTheta));
REAL cosPhi = cos(phi);
REAL sinPhi = sin(phi);
real cosTheta = cos(theta);
real sinTheta = sqrt(1.0 - min(1.0, cosTheta*cosTheta));
real cosPhi = cos(phi);
real sinPhi = sin(phi);
REAL3 direction = REAL3(sinTheta*cosPhi, cosTheta, sinTheta*sinPhi);
real3 direction = real3(sinTheta*cosPhi, cosTheta, sinTheta*sinPhi);
direction.xy *= -1.0;
return direction;
}

// Z buffer to linear 0..1 depth (0 at near plane, 1 at far plane).
// Does not correctly handle oblique view frustums.
REAL Linear01DepthFromNear(REAL depth, REAL4 zBufferParam)
real Linear01DepthFromNear(real depth, real4 zBufferParam)
{
return 1.0 / (zBufferParam.x + zBufferParam.y / depth);
}

REAL Linear01Depth(REAL depth, REAL4 zBufferParam)
real Linear01Depth(real depth, real4 zBufferParam)
{
return 1.0 / (zBufferParam.x * depth + zBufferParam.y);
}

REAL LinearEyeDepth(REAL depth, REAL4 zBufferParam)
real LinearEyeDepth(real depth, real4 zBufferParam)
{
return 1.0 / (zBufferParam.z * depth + zBufferParam.w);
}

// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
REAL LinearEyeDepth(REAL2 positionNDC, REAL deviceDepth, REAL4 invProjParam)
real LinearEyeDepth(real2 positionNDC, real deviceDepth, real4 invProjParam)
REAL4 positionCS = REAL4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
REAL viewSpaceZ = rcp(dot(positionCS, invProjParam));
real4 positionCS = real4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
real viewSpaceZ = rcp(dot(positionCS, invProjParam));
// The view space uses a right-handed coordinate system.
return -viewSpaceZ;
}

// Typically, this is the cheapest variant, provided you've already computed 'positionWS'.
REAL LinearEyeDepth(REAL3 positionWS, REAL4x4 viewProjMatrix)
real LinearEyeDepth(real3 positionWS, real4x4 viewProjMatrix)
return mul(viewProjMatrix, REAL4(positionWS, 1.0)).w;
return mul(viewProjMatrix, real4(positionWS, 1.0)).w;
}
// ----------------------------------------------------------------------------

static const REAL3x3 k_identity3x3 = {1, 0, 0,
0, 1, 0,
0, 0, 1};
static const real3x3 k_identity3x3 = { 1, 0, 0,
0, 1, 0,
0, 0, 1};
static const REAL4x4 k_identity4x4 = {1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
static const real4x4 k_identity4x4 = { 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
REAL2 ComputeNormalizedDeviceCoordinates(REAL3 position, REAL4x4 clipSpaceTransform = k_identity4x4)
real2 ComputeNormalizedDeviceCoordinates(real3 position, real4x4 clipSpaceTransform = k_identity4x4)
REAL4 positionCS = mul(clipSpaceTransform, REAL4(position, 1.0));
REAL2 positionNDC = positionCS.xy * (rcp(positionCS.w) * 0.5) + 0.5;
real4 positionCS = mul(clipSpaceTransform, real4(position, 1.0));
real2 positionNDC = positionCS.xy * (rcp(positionCS.w) * 0.5) + 0.5;
#if UNITY_UV_STARTS_AT_TOP
positionNDC.y = 1.0 - positionNDC.y;
#endif

REAL4 ComputeClipSpacePosition(REAL2 positionNDC, REAL deviceDepth)
real4 ComputeClipSpacePosition(real2 positionNDC, real deviceDepth)
return REAL4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
return real4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
REAL3 ComputeViewSpacePosition(REAL2 positionNDC, REAL deviceDepth, REAL4x4 invProjMatrix)
real3 ComputeViewSpacePosition(real2 positionNDC, real deviceDepth, real4x4 invProjMatrix)
REAL4 positionCS = ComputeClipSpacePosition(positionNDC, deviceDepth);
REAL4 positionVS = mul(invProjMatrix, positionCS);
real4 positionCS = ComputeClipSpacePosition(positionNDC, deviceDepth);
real4 positionVS = mul(invProjMatrix, positionCS);
REAL3 ComputeWorldSpacePosition(REAL2 positionNDC, REAL deviceDepth, REAL4x4 invViewProjMatrix)
real3 ComputeWorldSpacePosition(real2 positionNDC, real deviceDepth, real4x4 invViewProjMatrix)
REAL4 positionCS = ComputeClipSpacePosition(positionNDC, deviceDepth);
REAL4 hpositionWS = mul(invViewProjMatrix, positionCS);
real4 positionCS = ComputeClipSpacePosition(positionNDC, deviceDepth);
real4 hpositionWS = mul(invViewProjMatrix, positionCS);
return hpositionWS.xyz / hpositionWS.w;
}

struct PositionInputs
{
REAL3 positionWS; // World space position (could be camera-relative)
REAL2 positionNDC; // Normalized screen UVs : [0, 1) (with the REAL-pixel offset)
real3 positionWS; // World space position (could be camera-relative)
real2 positionNDC; // Normalized screen UVs : [0, 1) (with the real-pixel offset)
REAL deviceDepth; // Depth from the depth buffer : [0, 1] (typically reversed)
REAL linearDepth; // View space Z coordinate : [Near, Far]
real deviceDepth; // Depth from the depth buffer : [0, 1] (typically reversed)
real linearDepth; // View space Z coordinate : [Near, Far]
};
// This function is use to provide an easy way to sample into a screen texture, either from a pixel or a compute shaders.

PositionInputs GetPositionInput(REAL2 positionSS, REAL2 invScreenSize, uint2 tileCoord) // Specify explicit tile coordinates so that we can easily make it lane invariant for compute evaluation.
PositionInputs GetPositionInput(real2 positionSS, real2 invScreenSize, uint2 tileCoord) // Specify explicit tile coordinates so that we can easily make it lane invariant for compute evaluation.
{
PositionInputs posInput;
ZERO_INITIALIZE(PositionInputs, posInput);

// In case of compute shader an extra REAL offset is added to the screenPos to shift the integer position to pixel center.
posInput.positionNDC.xy += REAL2(0.5, 0.5);
// In case of compute shader an extra real offset is added to the screenPos to shift the integer position to pixel center.
posInput.positionNDC.xy += real2(0.5, 0.5);
#endif
posInput.positionNDC *= invScreenSize;

return posInput;
}
PositionInputs GetPositionInput(REAL2 positionSS, REAL2 invScreenSize)
PositionInputs GetPositionInput(real2 positionSS, real2 invScreenSize)
{
return GetPositionInput(positionSS, invScreenSize, uint2(0, 0));
}

void UpdatePositionInput(REAL deviceDepth, REAL linearDepth, REAL3 positionWS, inout PositionInputs posInput)
void UpdatePositionInput(real deviceDepth, real linearDepth, real3 positionWS, inout PositionInputs posInput)
{
posInput.deviceDepth = deviceDepth;
posInput.linearDepth = linearDepth;

// From deferred or compute shader
// depth must be the depth from the raw depth buffer. This allow to handle all kind of depth automatically with the inverse view projection matrix.
// For information. In Unity Depth is always in range 0..1 (even on OpenGL) but can be reversed.
void UpdatePositionInput(REAL deviceDepth, REAL4x4 invViewProjMatrix, REAL4x4 viewProjMatrix, inout PositionInputs posInput)
void UpdatePositionInput(real deviceDepth, real4x4 invViewProjMatrix, real4x4 viewProjMatrix, inout PositionInputs posInput)
posInput.linearDepth = mul(viewProjMatrix, REAL4(posInput.positionWS, 1.0)).w;
posInput.linearDepth = mul(viewProjMatrix, real4(posInput.positionWS, 1.0)).w;
void ApplyDepthOffsetPositionInput(REAL3 V, REAL depthOffsetVS, REAL4x4 viewProjMatrix, inout PositionInputs posInput)
void ApplyDepthOffsetPositionInput(real3 V, real depthOffsetVS, real4x4 viewProjMatrix, inout PositionInputs posInput)
REAL4 positionCS = mul(viewProjMatrix, REAL4(posInput.positionWS, 1.0));
real4 positionCS = mul(viewProjMatrix, real4(posInput.positionWS, 1.0));
posInput.linearDepth = positionCS.w;
posInput.deviceDepth = positionCS.z / positionCS.w;
}

// ----------------------------------------------------------------------------
// Normalize that account for vectors with zero length
REAL3 SafeNormalize(REAL3 inVec)
real3 SafeNormalize(real3 inVec)
REAL dp3 = max(REAL_MIN, dot(inVec, inVec));
real dp3 = max(REAL_MIN, dot(inVec, inVec));
REAL2 GetFullScreenTriangleTexCoord(uint vertexID)
real2 GetFullScreenTriangleTexCoord(uint vertexID)
return REAL2((vertexID << 1) & 2, 1.0 - (vertexID & 2));
return real2((vertexID << 1) & 2, 1.0 - (vertexID & 2));
return REAL2((vertexID << 1) & 2, vertexID & 2);
return real2((vertexID << 1) & 2, vertexID & 2);
REAL4 GetFullScreenTriangleVertexPosition(uint vertexID, REAL z = UNITY_NEAR_CLIP_VALUE)
real4 GetFullScreenTriangleVertexPosition(uint vertexID, real z = UNITY_NEAR_CLIP_VALUE)
REAL2 uv = REAL2((vertexID << 1) & 2, vertexID & 2);
return REAL4(uv * 2.0 - 1.0, z, 1.0);
real2 uv = real2((vertexID << 1) & 2, vertexID & 2);
return real4(uv * 2.0 - 1.0, z, 1.0);
}
#if !defined(SHADER_API_GLES)

// LOD1 must use this function with ditherFactor 0..1
void LODDitheringTransition(uint2 positionSS, REAL ditherFactor)
void LODDitheringTransition(uint2 positionSS, real ditherFactor)
REAL p = GenerateHashedRandomFloat(positionSS);
real p = GenerateHashedRandomFloat(positionSS);
// We want to have a symmetry between 0..0.5 ditherFactor and 0.5..1 so no pixels are transparent during the transition
// this is handled by this test which reverse the pattern

144
ScriptableRenderPipeline/Core/ShaderLibrary/CommonLighting.hlsl


#define UNITY_COMMON_LIGHTING_INCLUDED
// These clamping function to max of floating point 16 bit are use to prevent INF in code in case of extreme value
REAL ClampToFloat16Max(REAL value)
real ClampToFloat16Max(real value)
REAL2 ClampToFloat16Max(REAL2 value)
real2 ClampToFloat16Max(real2 value)
REAL3 ClampToFloat16Max(REAL3 value)
real3 ClampToFloat16Max(real3 value)
REAL4 ClampToFloat16Max(REAL4 value)
real4 ClampToFloat16Max(real4 value)
{
return min(value, HALF_MAX);
}

// of dimensions [-1, 1]^3 to a vector centered within the unit sphere.
// The function expects 'v' to be within the cube (possibly unexpected results otherwise).
// Ref: http://mathproofs.blogspot.com/2005/07/mapping-cube-to-sphere.html
REAL3 MapCubeToSphere(REAL3 v)
real3 MapCubeToSphere(real3 v)
REAL3 v2 = v * v;
REAL2 vr3 = v2.xy * rcp(3.0);
return v * sqrt((REAL3)1.0 - 0.5 * v2.yzx - 0.5 * v2.zxy + vr3.yxx * v2.zzy);
real3 v2 = v * v;
real2 vr3 = v2.xy * rcp(3.0);
return v * sqrt((real3)1.0 - 0.5 * v2.yzx - 0.5 * v2.zxy + vr3.yxx * v2.zzy);
REAL ComputeCubeToSphereMapSqMagnitude(REAL3 v)
real ComputeCubeToSphereMapSqMagnitude(real3 v)
REAL3 v2 = v * v;
real3 v2 = v * v;
// Note: dot(v, v) is often computed before this function is called,
// so the compiler should optimize and use the precomputed result here.
return dot(v, v) - v2.x * v2.y - v2.y * v2.z - v2.z * v2.x + v2.x * v2.y * v2.z;

// Ref: http://bpeers.com/blog/?itemid=1017
REAL ComputeCubemapTexelSolidAngle(REAL3 L, REAL texelArea)
real ComputeCubemapTexelSolidAngle(real3 L, real texelArea)
REAL d = Max3(abs(L.x), abs(L.y), abs(L.z));
real d = Max3(abs(L.x), abs(L.y), abs(L.z));
REAL invDist = d;
real invDist = d;
// dw = dA * cosTheta / (dist * dist), cosTheta = 1.0 / dist,
// where 'dA' is the area of the cube map texel.

//-----------------------------------------------------------------------------
// Ref: Moving Frostbite to PBR
REAL SmoothDistanceAttenuation(REAL squaredDistance, REAL invSqrAttenuationRadius)
real SmoothDistanceAttenuation(real squaredDistance, real invSqrAttenuationRadius)
REAL factor = squaredDistance * invSqrAttenuationRadius;
REAL smoothFactor = saturate(1.0 - factor * factor);
real factor = squaredDistance * invSqrAttenuationRadius;
real smoothFactor = saturate(1.0 - factor * factor);
REAL GetDistanceAttenuation(REAL sqrDist, REAL invSqrAttenuationRadius)
real GetDistanceAttenuation(real sqrDist, real invSqrAttenuationRadius)
REAL attenuation = 1.0 / (max(PUNCTUAL_LIGHT_THRESHOLD * PUNCTUAL_LIGHT_THRESHOLD, sqrDist));
real attenuation = 1.0 / (max(PUNCTUAL_LIGHT_THRESHOLD * PUNCTUAL_LIGHT_THRESHOLD, sqrDist));
REAL GetDistanceAttenuation(REAL3 unL, REAL invSqrAttenuationRadius)
real GetDistanceAttenuation(real3 unL, real invSqrAttenuationRadius)
REAL sqrDist = dot(unL, unL);
real sqrDist = dot(unL, unL);
REAL GetAngleAttenuation(REAL3 L, REAL3 lightDir, REAL lightAngleScale, REAL lightAngleOffset)
real GetAngleAttenuation(real3 L, real3 lightDir, real lightAngleScale, real lightAngleOffset)
REAL cd = dot(lightDir, L);
REAL attenuation = saturate(cd * lightAngleScale + lightAngleOffset);
real cd = dot(lightDir, L);
real attenuation = saturate(cd * lightAngleScale + lightAngleOffset);
// smooth the transition
attenuation *= attenuation;

// The transformation is performed along the major axis of the ellipsoid (corresponding to 'r1').
// Both the ellipsoid (e.i. 'axis') and 'unL' should be in the same coordinate system.
// 'unL' should be computed from the center of the ellipsoid.
REAL GetEllipsoidalDistanceAttenuation(REAL3 unL, REAL invSqRadius,
REAL3 axis, REAL invAspectRatio)
real GetEllipsoidalDistanceAttenuation(real3 unL, real invSqRadius,
real3 axis, real invAspectRatio)
REAL projL = dot(unL, axis);
real projL = dot(unL, axis);
REAL diff = projL - projL * invAspectRatio;
real diff = projL - projL * invAspectRatio;
REAL sqDist = dot(unL, unL);
real sqDist = dot(unL, unL);
return SmoothDistanceAttenuation(sqDist, invSqRadius);
}

REAL GetEllipsoidalDistanceAttenuation(REAL3 unL, REAL3 invHalfDim)
real GetEllipsoidalDistanceAttenuation(real3 unL, real3 invHalfDim)
REAL sqDist = dot(unL, unL);
real sqDist = dot(unL, unL);
return SmoothDistanceAttenuation(sqDist, 1.0);
}

// 'unL' should be computed from the center of the box.
REAL GetBoxDistanceAttenuation(REAL3 unL, REAL3 invHalfDim)
real GetBoxDistanceAttenuation(real3 unL, real3 invHalfDim)
{
// Transform the light vector so that we can work with
// with the box as if it was a [-1, 1]^2 cube.

if (Max3(abs(unL.x), abs(unL.y), abs(unL.z)) > 1.0) return 0.0;
REAL sqDist = ComputeCubeToSphereMapSqMagnitude(unL);
real sqDist = ComputeCubeToSphereMapSqMagnitude(unL);
return SmoothDistanceAttenuation(sqDist, 1.0);
}

REAL2 GetIESTextureCoordinate(REAL3x3 lightToWord, REAL3 L)
real2 GetIESTextureCoordinate(real3x3 lightToWord, real3 L)
REAL3 dir = mul(lightToWord, -L); // Using matrix on left side do a transpose
real3 dir = mul(lightToWord, -L); // Using matrix on left side do a transpose
REAL2 sphericalCoord; // .x is theta, .y is phi
real2 sphericalCoord; // .x is theta, .y is phi
REAL theta = atan2(dir.y, dir.x);
real theta = atan2(dir.y, dir.x);
sphericalCoord.x = theta * INV_TWO_PI;
return sphericalCoord;

//-----------------------------------------------------------------------------
// Ref: Horizon Occlusion for Normal Mapped Reflections: http://marmosetco.tumblr.com/post/81245981087
REAL GetHorizonOcclusion(REAL3 V, REAL3 normalWS, REAL3 vertexNormal, REAL horizonFade)
real GetHorizonOcclusion(real3 V, real3 normalWS, real3 vertexNormal, real horizonFade)
REAL3 R = reflect(-V, normalWS);
REAL specularOcclusion = saturate(1.0 + horizonFade * dot(R, vertexNormal));
real3 R = reflect(-V, normalWS);
real specularOcclusion = saturate(1.0 + horizonFade * dot(R, vertexNormal));
// smooth it
return specularOcclusion * specularOcclusion;
}

REAL GetSpecularOcclusionFromAmbientOcclusion(REAL NdotV, REAL ambientOcclusion, REAL roughness)
real GetSpecularOcclusionFromAmbientOcclusion(real NdotV, real ambientOcclusion, real roughness)
{
return saturate(PositivePow(NdotV + ambientOcclusion, exp2(-16.0 * roughness - 1.0)) - 1.0 + ambientOcclusion);
}

REAL3 GTAOMultiBounce(REAL visibility, REAL3 albedo)
real3 GTAOMultiBounce(real visibility, real3 albedo)
REAL3 a = 2.0404 * albedo - 0.3324;
REAL3 b = -4.7951 * albedo + 0.6417;
REAL3 c = 2.7552 * albedo + 0.6903;
real3 a = 2.0404 * albedo - 0.3324;
real3 b = -4.7951 * albedo + 0.6417;
real3 c = 2.7552 * albedo + 0.6903;
REAL x = visibility;
real x = visibility;
REAL SphericalCapIntersectionSolidArea(REAL cosC1, REAL cosC2, REAL cosB)
real SphericalCapIntersectionSolidArea(real cosC1, real cosC2, real cosB)
REAL r1 = FastACos(cosC1);
REAL r2 = FastACos(cosC2);
REAL rd = FastACos(cosB);
REAL area = 0.0;
real r1 = FastACos(cosC1);
real r2 = FastACos(cosC2);
real rd = FastACos(cosB);
real area = 0.0;
if (rd <= max(r1, r2) - min(r1, r2))
{

}
else
{
REAL diff = abs(r1 - r2);
REAL den = r1 + r2 - diff;
REAL x = 1.0 - saturate((rd - diff) / den);
real diff = abs(r1 - r2);
real den = r1 + r2 - diff;
real x = 1.0 - saturate((rd - diff) / den);
area = smoothstep(0.0, 1.0, x);
area *= TWO_PI - TWO_PI * max(cosC1, cosC2);
}

// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
REAL ComputeWrappedDiffuseLighting(REAL NdotL, REAL w)
real ComputeWrappedDiffuseLighting(real NdotL, real w)
{
return saturate((NdotL + w) / ((1 + w) * (1 + w)));
}

// Inputs: normalized normal and view vectors.
// Outputs: front-facing normal, and the new non-negative value of the cosine of the view angle.
// Important: call Orthonormalize() on the tangent and recompute the bitangent afterwards.
REAL3 GetViewReflectedNormal(REAL3 N, REAL3 V, out REAL NdotV)
real3 GetViewReflectedNormal(real3 N, real3 V, out real NdotV)
{
// Fragments of front-facing geometry can have back-facing normals due to interpolation,
// normal mapping and decals. This can cause visible artifacts from both direct (negative or

// For one, it does not solve the incorrect lookup direction problem, since the normal itself
// is not modified. There is a more insidious issue, however. 'NdotV' is a constituent element
// of the mathematical system describing the relationships between different vectors - and
// not just normal and view vectors, but also light vectors, REAL vectors, tangent vectors, etc.
// not just normal and view vectors, but also light vectors, real vectors, tangent vectors, etc.
// Changing only one angle (or its cosine) leaves the system in an inconsistent state, where
// certain relationships can take on different values depending on whether 'NdotV' is used
// in the calculation or not. Therefore, it is important to change the normal (or another

// Generates an orthonormal right-handed basis from a unit vector.
// Ref: http://marc-b-reynolds.github.io/quaternions/2016/07/06/Orthonormal.html
REAL3x3 GetLocalFrame(REAL3 localZ)
real3x3 GetLocalFrame(real3 localZ)
REAL x = localZ.x;
REAL y = localZ.y;
REAL z = localZ.z;
REAL sz = FastSign(z);
REAL a = 1 / (sz + z);
REAL ya = y * a;
REAL b = x * ya;
REAL c = x * sz;
real x = localZ.x;
real y = localZ.y;
real z = localZ.z;
real sz = FastSign(z);
real a = 1 / (sz + z);
real ya = y * a;
real b = x * ya;
real c = x * sz;
REAL3 localX = REAL3(c * x * a - 1, sz * b, c);
REAL3 localY = REAL3(b, y * ya - sz, y);
real3 localX = real3(c * x * a - 1, sz * b, c);
real3 localY = real3(b, y * ya - sz, y);
return REAL3x3(localX, localY, localZ);
return real3x3(localX, localY, localZ);
REAL3x3 GetLocalFrame(REAL3 localZ, REAL3 localX)
real3x3 GetLocalFrame(real3 localZ, real3 localX)
REAL3 localY = cross(localZ, localX);
real3 localY = cross(localZ, localX);
return REAL3x3(localX, localY, localZ);
return real3x3(localX, localY, localZ);
REAL IORToFresnel0(REAL ior)
real IORToFresnel0(real ior)
{
return Sq((ior - 1.0) / (ior + 1.0));
}

58
ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl


// Helper functions for roughness
//-----------------------------------------------------------------------------
REAL PerceptualRoughnessToRoughness(REAL perceptualRoughness)
real PerceptualRoughnessToRoughness(real perceptualRoughness)
REAL RoughnessToPerceptualRoughness(REAL roughness)
real RoughnessToPerceptualRoughness(real roughness)
REAL PerceptualSmoothnessToRoughness(REAL perceptualSmoothness)
real PerceptualSmoothnessToRoughness(real perceptualSmoothness)
REAL PerceptualSmoothnessToPerceptualRoughness(REAL perceptualSmoothness)
real PerceptualSmoothnessToPerceptualRoughness(real perceptualSmoothness)
{
return (1.0 - perceptualSmoothness);
}

// Note: making the constant too small results in aliasing.
REAL ClampRoughnessForAnalyticalLights(REAL roughness)
real ClampRoughnessForAnalyticalLights(real roughness)
{
return max(roughness, 1.0/1024.0);
}

// If IBL needs the linear roughness value for some reason, it can be computed as follows:
// REAL roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);
void ConvertAnisotropyToRoughness(REAL perceptualRoughness, REAL anisotropy, out REAL roughnessT, out REAL roughnessB)
// real roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);
void ConvertAnisotropyToRoughness(real perceptualRoughness, real anisotropy, out real roughnessT, out real roughnessB)
REAL roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
real roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
// Use the parametrization of Sony Imageworks.
// Ref: Revisiting Physically Based Shading at Imageworks, p. 15.

// ref https://www.gamedev.net/topic/678043-how-to-blend-world-space-normals/#entry5287707
// assume compositing in world space
// Note: Using vtxNormal = REAL3(0, 0, 1) give the BlendNormalRNM formulation.
// Note: Using vtxNormal = real3(0, 0, 1) give the BlendNormalRNM formulation.
REAL3 BlendNormalWorldspaceRNM(REAL3 n1, REAL3 n2, REAL3 vtxNormal)
real3 BlendNormalWorldspaceRNM(real3 n1, real3 n2, real3 vtxNormal)
REAL4 q = REAL4(cross(vtxNormal, n2), dot(vtxNormal, n2) + 1.0) / sqrt(2.0 * (dot(vtxNormal, n2) + 1));
real4 q = real4(cross(vtxNormal, n2), dot(vtxNormal, n2) + 1.0) / sqrt(2.0 * (dot(vtxNormal, n2) + 1));
// Rotate the normal
return n1 * (q.w * q.w - dot(q.xyz, q.xyz)) + 2 * q.xyz * dot(q.xyz, n1) + 2 * q.w * cross(q.xyz, n1);

// Reoriented Normal Mapping
// Blending when n1 and n2 are already 'unpacked' and normalised
// assume compositing in tangent space
REAL3 BlendNormalRNM(REAL3 n1, REAL3 n2)
real3 BlendNormalRNM(real3 n1, real3 n2)
REAL3 t = n1.xyz + REAL3(0.0, 0.0, 1.0);
REAL3 u = n2.xyz * REAL3(-1.0, -1.0, 1.0);
REAL3 r = (t / t.z) * dot(t, u) - u;
real3 t = n1.xyz + real3(0.0, 0.0, 1.0);
real3 u = n2.xyz * real3(-1.0, -1.0, 1.0);
real3 r = (t / t.z) * dot(t, u) - u;
REAL3 BlendNormal(REAL3 n1, REAL3 n2)
real3 BlendNormal(real3 n1, real3 n2)
return normalize(REAL3(n1.xy * n2.z + n2.xy * n1.z, n1.z * n2.z));
return normalize(real3(n1.xy * n2.z + n2.xy * n1.z, n1.z * n2.z));
REAL3 ComputeTriplanarWeights(REAL3 normal)
real3 ComputeTriplanarWeights(real3 normal)
REAL3 blendWeights = abs(normal);
real3 blendWeights = abs(normal);
blendWeights = max(blendWeights, REAL3(0.0, 0.0, 0.0));
blendWeights = max(blendWeights, real3(0.0, 0.0, 0.0));
blendWeights /= dot(blendWeights, 1.0);
return blendWeights;

void GetTriplanarCoordinate(REAL3 position, out REAL2 uvXZ, out REAL2 uvXY, out REAL2 uvZY)
void GetTriplanarCoordinate(real3 position, out real2 uvXZ, out real2 uvXY, out real2 uvZY)
uvXZ = REAL2(position.z, position.x);
uvXY = REAL2(position.x, position.y);
uvZY = REAL2(position.z, position.y);
uvXZ = real2(position.z, position.x);
uvXY = real2(position.x, position.y);
uvZY = real2(position.z, position.y);
REAL LerpWhiteTo(REAL b, REAL t)
real LerpWhiteTo(real b, real t)
REAL oneMinusT = 1.0 - t;
real oneMinusT = 1.0 - t;
REAL3 LerpWhiteTo(REAL3 b, REAL t)
real3 LerpWhiteTo(real3 b, real t)
REAL oneMinusT = 1.0 - t;
return REAL3(oneMinusT, oneMinusT, oneMinusT) + b * t;
real oneMinusT = 1.0 - t;
return real3(oneMinusT, oneMinusT, oneMinusT) + b * t;
}

6
ScriptableRenderPipeline/Core/ShaderLibrary/CommonShadow.hlsl


// Ref: https://mynameismjp.wordpress.com/2015/02/18/shadow-sample-update/
// Calculates the offset to use for sampling the shadow map, based on the surface normal
REAL3 GetShadowPosOffset(REAL NdotL, REAL3 normalWS, REAL2 invShadowMapSize)
real3 GetShadowPosOffset(real NdotL, real3 normalWS, real2 invShadowMapSize)
REAL texelSize = 2.0 * invShadowMapSize.x;
REAL offsetScaleNormalize = saturate(1.0 - NdotL);
real texelSize = 2.0 * invShadowMapSize.x;
real offsetScaleNormalize = saturate(1.0 - NdotL);
// return texelSize * OffsetScale * offsetScaleNormalize * normalWS;
return texelSize * offsetScaleNormalize * normalWS;
}

24
ScriptableRenderPipeline/Core/ShaderLibrary/Debug.hlsl


// Given an enum (represented by an int here), return a color.
// Use for DebugView of enum
REAL3 GetIndexColor(int index)
real3 GetIndexColor(int index)
REAL3 outColor = REAL3(1.0, 0.0, 0.0);
real3 outColor = real3(1.0, 0.0, 0.0);
outColor = REAL3(1.0, 0.5, 0.5);
outColor = real3(1.0, 0.5, 0.5);
outColor = REAL3(0.5, 1.0, 0.5);
outColor = real3(0.5, 1.0, 0.5);
outColor = REAL3(0.5, 0.5, 1.0);
outColor = real3(0.5, 0.5, 1.0);
outColor = REAL3(1.0, 1.0, 0.5);
outColor = real3(1.0, 1.0, 0.5);
outColor = REAL3(1.0, 0.5, 1.0);
outColor = real3(1.0, 0.5, 1.0);
outColor = REAL3(0.5, 1.0, 1.0);
outColor = real3(0.5, 1.0, 1.0);
outColor = REAL3(0.25, 0.75, 1.0);
outColor = real3(0.25, 0.75, 1.0);
outColor = REAL3(1.0, 0.75, 0.25);
outColor = real3(1.0, 0.75, 0.25);
outColor = REAL3(0.75, 1.0, 0.25);
outColor = real3(0.75, 1.0, 0.25);
outColor = REAL3(0.75, 0.25, 1.0);
outColor = real3(0.75, 0.25, 1.0);
return outColor;
}

94
ScriptableRenderPipeline/Core/ShaderLibrary/EntityLighting.hlsl


// TODO: Check if PI is correctly handled!
// Ref: "Efficient Evaluation of Irradiance Environment Maps" from ShaderX 2
REAL3 SHEvalLinearL0L1(REAL3 N, REAL4 shAr, REAL4 shAg, REAL4 shAb)
real3 SHEvalLinearL0L1(real3 N, real4 shAr, real4 shAg, real4 shAb)
REAL4 vA = REAL4(N, 1.0);
real4 vA = real4(N, 1.0);
REAL3 x1;
real3 x1;
// Linear (L1) + constant (L0) polynomial terms
x1.r = dot(shAr, vA);
x1.g = dot(shAg, vA);

}
REAL3 SHEvalLinearL2(REAL3 N, REAL4 shBr, REAL4 shBg, REAL4 shBb, REAL4 shC)
real3 SHEvalLinearL2(real3 N, real4 shBr, real4 shBg, real4 shBb, real4 shC)
REAL3 x2;
real3 x2;
REAL4 vB = N.xyzz * N.yzzx;
real4 vB = N.xyzz * N.yzzx;
REAL vC = N.x * N.x - N.y * N.y;
REAL3 x3 = shC.rgb * vC;
real vC = N.x * N.x - N.y * N.y;
real3 x3 = shC.rgb * vC;
REAL3 SampleSH9(REAL4 SHCoefficients[7], REAL3 N)
real3 SampleSH9(real4 SHCoefficients[7], real3 N)
REAL4 shAr = SHCoefficients[0];
REAL4 shAg = SHCoefficients[1];
REAL4 shAb = SHCoefficients[2];
REAL4 shBr = SHCoefficients[3];
REAL4 shBg = SHCoefficients[4];
REAL4 shBb = SHCoefficients[5];
REAL4 shCr = SHCoefficients[6];
real4 shAr = SHCoefficients[0];
real4 shAg = SHCoefficients[1];
real4 shAb = SHCoefficients[2];
real4 shBr = SHCoefficients[3];
real4 shBg = SHCoefficients[4];
real4 shBb = SHCoefficients[5];
real4 shCr = SHCoefficients[6];
REAL3 res = SHEvalLinearL0L1(N, shAr, shAg, shAb);
real3 res = SHEvalLinearL0L1(N, shAr, shAg, shAb);
// Quadratic polynomials
res += SHEvalLinearL2(N, shBr, shBg, shBb, shCr);

// TODO: the packing here is inefficient as we will fetch values far away from each other and they may not fit into the cache - Suggest we pack RGB continuously
// TODO: The calcul of texcoord could be perform with a single matrix multicplication calcualted on C++ side that will fold probeVolumeMin and probeVolumeSizeInv into it and handle the identity case, no reasons to do it in C++ (ask Ionut about it)
// It should also handle the camera relative path (if the render pipeline use it)
REAL3 SampleProbeVolumeSH4(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), REAL3 positionWS, REAL3 normalWS, REAL4x4 WorldToTexture,
REAL transformToLocal, REAL texelSizeX, REAL3 probeVolumeMin, REAL3 probeVolumeSizeInv)
real3 SampleProbeVolumeSH4(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), real3 positionWS, real3 normalWS, real4x4 WorldToTexture,
real transformToLocal, real texelSizeX, real3 probeVolumeMin, real3 probeVolumeSizeInv)
REAL3 position = (transformToLocal == 1.0) ? mul(WorldToTexture, REAL4(positionWS, 1.0)).xyz : positionWS;
REAL3 texCoord = (position - probeVolumeMin) * probeVolumeSizeInv.xyz;
real3 position = (transformToLocal == 1.0) ? mul(WorldToTexture, real4(positionWS, 1.0)).xyz : positionWS;
real3 texCoord = (position - probeVolumeMin) * probeVolumeSizeInv.xyz;
// Clamp to edge of the "internal" texture, as R is from REAL texel to size of R texture minus REAL texel.
// Clamp to edge of the "internal" texture, as R is from real texel to size of R texture minus real texel.
REAL4 shAr = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
real4 shAr = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
REAL4 shAg = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
real4 shAg = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
REAL4 shAb = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
real4 shAb = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
REAL4 SampleProbeOcclusion(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), REAL3 positionWS, REAL4x4 WorldToTexture,
REAL transformToLocal, REAL texelSizeX, REAL3 probeVolumeMin, REAL3 probeVolumeSizeInv)
real4 SampleProbeOcclusion(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), real3 positionWS, real4x4 WorldToTexture,
real transformToLocal, real texelSizeX, real3 probeVolumeMin, real3 probeVolumeSizeInv)
REAL3 position = (transformToLocal == 1.0) ? mul(WorldToTexture, REAL4(positionWS, 1.0)).xyz : positionWS;
REAL3 texCoord = (position - probeVolumeMin) * probeVolumeSizeInv.xyz;
real3 position = (transformToLocal == 1.0) ? mul(WorldToTexture, real4(positionWS, 1.0)).xyz : positionWS;
real3 texCoord = (position - probeVolumeMin) * probeVolumeSizeInv.xyz;
// Sample fourth texture in the atlas
// We need to compute proper U coordinate to sample.

// Same goes for emissive packed as an input for Enlighten with another hard coded multiplier.
// TODO: This function is used with the LightTransport pass to encode lightmap or emissive
REAL4 PackEmissiveRGBM(REAL3 rgb)
real4 PackEmissiveRGBM(real3 rgb)
REAL kOneOverRGBMMaxRange = 1.0 / EMISSIVE_RGBM_SCALE;
const REAL kMinMultiplier = 2.0 * 1e-2;
real kOneOverRGBMMaxRange = 1.0 / EMISSIVE_RGBM_SCALE;
const real kMinMultiplier = 2.0 * 1e-2;
REAL4 rgbm = REAL4(rgb * kOneOverRGBMMaxRange, 1.0);
real4 rgbm = real4(rgb * kOneOverRGBMMaxRange, 1.0);
rgbm.a = max(max(rgbm.r, rgbm.g), max(rgbm.b, kMinMultiplier));
rgbm.a = ceil(rgbm.a * 255.0) / 255.0;

return rgbm;
}
REAL3 UnpackLightmapRGBM(REAL4 rgbmInput)
real3 UnpackLightmapRGBM(real4 rgbmInput)
REAL3 UnpackLightmapDoubleLDR(REAL4 encodedColor)
real3 UnpackLightmapDoubleLDR(real4 encodedColor)
REAL3 DecodeLightmap(REAL4 encodedIlluminance)
real3 DecodeLightmap(real4 encodedIlluminance)
{
#if defined(UNITY_LIGHTMAP_RGBM_ENCODING)
return UnpackLightmapRGBM(encodedIlluminance);

}
REAL3 DecodeHDREnvironment(REAL4 encodedIrradiance, REAL4 decodeInstructions)
real3 DecodeHDREnvironment(real4 encodedIrradiance, real4 decodeInstructions)
REAL alpha = max(decodeInstructions.w * (encodedIrradiance.a - 1.0) + 1.0, 0.0);
real alpha = max(decodeInstructions.w * (encodedIrradiance.a - 1.0) + 1.0, 0.0);
REAL3 SampleSingleLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), REAL2 uv, REAL4 transform, bool encodedLightmap)
real3 SampleSingleLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), real2 uv, real4 transform, bool encodedLightmap)
REAL3 illuminance = REAL3(0.0, 0.0, 0.0);
real3 illuminance = real3(0.0, 0.0, 0.0);
REAL4 encodedIlluminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba;
real4 encodedIlluminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba;
illuminance = DecodeLightmap(encodedIlluminance);
}
else

return illuminance;
}
REAL3 SampleDirectionalLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), TEXTURE2D_ARGS(lightmapDirTex, lightmapDirSampler), REAL2 uv, REAL4 transform, REAL3 normalWS, bool encodedLightmap)
real3 SampleDirectionalLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), TEXTURE2D_ARGS(lightmapDirTex, lightmapDirSampler), real2 uv, real4 transform, real3 normalWS, bool encodedLightmap)
// in a way, that using it for REAL Lambert and then dividing by a "rebalancing coefficient"
// in a way, that using it for real Lambert and then dividing by a "rebalancing coefficient"
// gives a result close to plain diffuse response lightmaps, but normalmapped.
// Note that dir is not unit length on purpose. Its length is "directionality", like

uv = uv * transform.xy + transform.zw;
REAL4 direction = SAMPLE_TEXTURE2D(lightmapDirTex, lightmapDirSampler, uv);
real4 direction = SAMPLE_TEXTURE2D(lightmapDirTex, lightmapDirSampler, uv);
REAL3 illuminance = REAL3(0.0, 0.0, 0.0);
real3 illuminance = real3(0.0, 0.0, 0.0);
REAL4 encodedIlluminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba;
real4 encodedIlluminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba;
illuminance = DecodeLightmap(encodedIlluminance);
}
else

REAL halfLambert = dot(normalWS, direction.xyz - 0.5) + 0.5;
real halfLambert = dot(normalWS, direction.xyz - 0.5) + 0.5;
return illuminance * halfLambert / max(1e-4, direction.w);
}

76
ScriptableRenderPipeline/Core/ShaderLibrary/GeometricTools.hlsl


// return furthest near intersection in x and closest far intersection in y
// if (intersections.y > intersections.x) the ray hit the box, else it miss it
// Assume dir is normalize
REAL2 BoxRayIntersect(REAL3 start, REAL3 dir, REAL3 boxMin, REAL3 boxMax)
real2 BoxRayIntersect(real3 start, real3 dir, real3 boxMin, real3 boxMax)
REAL3 invDir = 1.0 / dir;
real3 invDir = 1.0 / dir;
REAL3 firstPlaneIntersect = (boxMin - start) * invDir;
REAL3 secondPlaneIntersect = (boxMax - start) * invDir;
real3 firstPlaneIntersect = (boxMin - start) * invDir;
real3 secondPlaneIntersect = (boxMax - start) * invDir;
REAL3 closestPlane = min(firstPlaneIntersect, secondPlaneIntersect);
REAL3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect);
real3 closestPlane = min(firstPlaneIntersect, secondPlaneIntersect);
real3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect);
REAL2 intersections;
real2 intersections;
// Find the furthest near intersection
intersections.x = max(closestPlane.x, max(closestPlane.y, closestPlane.z));
// Find the closest far intersection

// This simplified version assume that we care about the result only when we are inside the box
// Assume dir is normalize
REAL BoxRayIntersectSimple(REAL3 start, REAL3 dir, REAL3 boxMin, REAL3 boxMax)
real BoxRayIntersectSimple(real3 start, real3 dir, real3 boxMin, real3 boxMax)
REAL3 invDir = 1.0 / dir;
real3 invDir = 1.0 / dir;
REAL3 rbmin = (boxMin - start) * invDir;
REAL3 rbmax = (boxMax - start) * invDir;
real3 rbmin = (boxMin - start) * invDir;
real3 rbmax = (boxMax - start) * invDir;
REAL3 rbminmax = (dir > 0.0) ? rbmax : rbmin;
real3 rbminmax = (dir > 0.0) ? rbmax : rbmin;
REAL2 SphereRayIntersect(REAL3 start, REAL3 dir, REAL radius, out bool intersect)
real2 SphereRayIntersect(real3 start, real3 dir, real radius, out bool intersect)
REAL a = dot(dir, dir);
REAL b = dot(dir, start) * 2.0;
REAL c = dot(start, start) - radius * radius;
REAL discriminant = b * b - 4.0 * a * c;
real a = dot(dir, dir);
real b = dot(dir, start) * 2.0;
real c = dot(start, start) - radius * radius;
real discriminant = b * b - 4.0 * a * c;
REAL2 intersections = REAL2(0.0, 0.0);
real2 intersections = real2(0.0, 0.0);
intersect = false;
if (discriminant < 0.0 || a == 0.0)
{

else
{
REAL sqrtDiscriminant = sqrt(discriminant);
real sqrtDiscriminant = sqrt(discriminant);
intersections.x = (-b - sqrtDiscriminant) / (2.0 * a);
intersections.y = (-b + sqrtDiscriminant) / (2.0 * a);
intersect = true;

// This simplified version assume that we care about the result only when we are inside the sphere
// Assume Sphere is at the origin (i.e start = position - spherePosition) and dir is normalized
// Ref: http://http.developer.nvidia.com/GPUGems/gpugems_ch19.html
REAL SphereRayIntersectSimple(REAL3 start, REAL3 dir, REAL radius)
real SphereRayIntersectSimple(real3 start, real3 dir, real radius)
REAL b = dot(dir, start) * 2.0;
REAL c = dot(start, start) - radius * radius;
REAL discriminant = b * b - 4.0 * c;
real b = dot(dir, start) * 2.0;
real c = dot(start, start) - radius * radius;
real discriminant = b * b - 4.0 * c;
REAL3 RayPlaneIntersect(in REAL3 rayOrigin, in REAL3 rayDirection, in REAL3 planeOrigin, in REAL3 planeNormal)
real3 RayPlaneIntersect(in real3 rayOrigin, in real3 rayDirection, in real3 planeOrigin, in real3 planeNormal)
REAL dist = dot(planeNormal, planeOrigin - rayOrigin) / dot(planeNormal, rayDirection);
real dist = dot(planeNormal, planeOrigin - rayOrigin) / dot(planeNormal, rayDirection);
return rayOrigin + rayDirection * dist;
}

// Box is AABB
REAL DistancePointBox(REAL3 position, REAL3 boxMin, REAL3 boxMax)
real DistancePointBox(real3 position, real3 boxMin, real3 boxMax)
return length(max(max(position - boxMax, boxMin - position), REAL3(0.0, 0.0, 0.0)));
return length(max(max(position - boxMax, boxMin - position), real3(0.0, 0.0, 0.0)));
REAL3 ProjectPointOnPlane(REAL3 position, REAL3 planePosition, REAL3 planeNormal)
real3 ProjectPointOnPlane(real3 position, real3 planePosition, real3 planeNormal)
{
return position - (dot(position - planePosition, planeNormal) * planeNormal);
}

// Positive -> in front (above), negative -> behind (below).
REAL DistanceFromPlane(REAL3 p, REAL4 plane)
real DistanceFromPlane(real3 p, real4 plane)
return dot(REAL4(p, 1.0), plane);
return dot(real4(p, 1.0), plane);
bool CullTriangleFrustum(REAL3 p0, REAL3 p1, REAL3 p2, REAL epsilon, REAL4 frustumPlanes[6], int numPlanes)
bool CullTriangleFrustum(real3 p0, real3 p1, real3 p2, real epsilon, real4 frustumPlanes[6], int numPlanes)
{
bool outside = false;

// Returns 'true' if the edge of the triangle is outside of the frustum.
// The edges are defined s.t. they are on the opposite side of the point with the given index.
// 'epsilon' is the (negative) distance to (outside of) the frustum below which we cull the triangle.
bool3 CullTriangleEdgesFrustum(REAL3 p0, REAL3 p1, REAL3 p2, REAL epsilon, REAL4 frustumPlanes[6], int numPlanes)
bool3 CullTriangleEdgesFrustum(real3 p0, real3 p1, real3 p2, real epsilon, real4 frustumPlanes[6], int numPlanes)
{
bool3 edgesOutside = false;

// Returns 'true' if a triangle defined by 3 vertices is back-facing.
// 'epsilon' is the (negative) value of dot(N, V) below which we cull the triangle.
// 'winding' can be used to change the order: pass 1 for (p0 -> p1 -> p2), or -1 for (p0 -> p2 -> p1).
bool CullTriangleBackFace(REAL3 p0, REAL3 p1, REAL3 p2, REAL epsilon, REAL3 viewPos, REAL winding)
bool CullTriangleBackFace(real3 p0, real3 p1, real3 p2, real epsilon, real3 viewPos, real winding)
REAL3 edge1 = p1 - p0;
REAL3 edge2 = p2 - p0;
real3 edge1 = p1 - p0;
real3 edge2 = p2 - p0;
REAL3 N = cross(edge1, edge2);
REAL3 V = viewPos - p0;
REAL NdotV = dot(N, V) * winding;
real3 N = cross(edge1, edge2);
real3 V = viewPos - p0;
real NdotV = dot(N, V) * winding;
// Optimize:
// NdotV / (length(N) * length(V)) < Epsilon

320
ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl


// approximating the cone of the specular lobe, and then computing the MIP map level
// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution.
REAL PerceptualRoughnessToMipmapLevel(REAL perceptualRoughness, uint mipMapCount)
real PerceptualRoughnessToMipmapLevel(real perceptualRoughness, uint mipMapCount)
{
perceptualRoughness = perceptualRoughness * (1.7 - 0.7 * perceptualRoughness);

REAL PerceptualRoughnessToMipmapLevel(REAL perceptualRoughness)
real PerceptualRoughnessToMipmapLevel(real perceptualRoughness)
{
return PerceptualRoughnessToMipmapLevel(perceptualRoughness, UNITY_SPECCUBE_LOD_STEPS);
}

// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution and adds reflection (contact) hardening.
// TODO: optimize!
REAL PerceptualRoughnessToMipmapLevel(REAL perceptualRoughness, REAL NdotR)
real PerceptualRoughnessToMipmapLevel(real perceptualRoughness, real NdotR)
REAL m = PerceptualRoughnessToRoughness(perceptualRoughness);
real m = PerceptualRoughnessToRoughness(perceptualRoughness);
REAL n = (2.0 / max(FLT_EPS, m * m)) - 2.0;
real n = (2.0 / max(FLT_EPS, m * m)) - 2.0;
// Remap from n_dot_h formulation to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html
n /= (4.0 * max(NdotR, FLT_EPS));

}
// The inverse of the *approximated* version of perceptualRoughnessToMipmapLevel().
REAL MipmapLevelToPerceptualRoughness(REAL mipmapLevel)
real MipmapLevelToPerceptualRoughness(real mipmapLevel)
REAL perceptualRoughness = saturate(mipmapLevel / UNITY_SPECCUBE_LOD_STEPS);
real perceptualRoughness = saturate(mipmapLevel / UNITY_SPECCUBE_LOD_STEPS);
return saturate(1.7 / 1.4 - sqrt(2.89 / 1.96 - (2.8 / 1.96) * perceptualRoughness));
}

// Ref: Donald Revie - Implementing Fur Using Deferred Shading (GPU Pro 2)
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to the normal.
// The returned normal is NOT normalized.
REAL3 ComputeGrainNormal(REAL3 grainDir, REAL3 V)
real3 ComputeGrainNormal(real3 grainDir, real3 V)
REAL3 B = cross(grainDir, V);
real3 B = cross(grainDir, V);
return cross(B, grainDir);
}

REAL3 GetAnisotropicModifiedNormal(REAL3 grainDir, REAL3 N, REAL3 V, REAL anisotropy)
real3 GetAnisotropicModifiedNormal(real3 grainDir, real3 N, real3 V, real anisotropy)
REAL3 grainNormal = ComputeGrainNormal(grainDir, V);
real3 grainNormal = ComputeGrainNormal(grainDir, V);
REAL3 GetSpecularDominantDir(REAL3 N, REAL3 R, REAL roughness, REAL NdotV)
real3 GetSpecularDominantDir(real3 N, real3 R, real roughness, real NdotV)
REAL a = 1.0 - roughness;
REAL s = sqrt(a);
real a = 1.0 - roughness;
real s = sqrt(a);
REAL lerpFactor = (s + roughness) * a;
real lerpFactor = (s + roughness) * a;
REAL lerpFactor = (s + roughness) * saturate(a * a + lerp(0.0, a, NdotV * NdotV));
real lerpFactor = (s + roughness) * saturate(a * a + lerp(0.0, a, NdotV * NdotV));
#endif
// The result is not normalized as we fetch in a cubemap

// To simulate the streching of highlight at grazing angle for IBL we shrink the roughness
// which allow to fake an anisotropic specular lobe.
// Ref: http://www.frostbite.com/2015/08/stochastic-screen-space-reflections/ - slide 84
REAL AnisotropicStrechAtGrazingAngle(REAL roughness, REAL perceptualRoughness, REAL NdotV)
real AnisotropicStrechAtGrazingAngle(real roughness, real perceptualRoughness, real NdotV)
{
return roughness * lerp(saturate(NdotV * 2.0), 1.0, perceptualRoughness);
}

// ----------------------------------------------------------------------------
void SampleGGXDir(REAL2 u,
REAL3 V,
REAL3x3 localToWorld,
REAL roughness,
out REAL3 L,
out REAL NdotL,
out REAL NdotH,
out REAL VdotH,
void SampleGGXDir(real2 u,
real3 V,
real3x3 localToWorld,
real roughness,
out real3 L,
out real NdotL,
out real NdotH,
out real VdotH,
REAL cosTheta = sqrt((1.0 - u.x) / (1.0 + (roughness * roughness - 1.0) * u.x));
REAL phi = TWO_PI * u.y;
real cosTheta = sqrt((1.0 - u.x) / (1.0 + (roughness * roughness - 1.0) * u.x));
real phi = TWO_PI * u.y;
REAL3 localH = SphericalToCartesian(phi, cosTheta);
real3 localH = SphericalToCartesian(phi, cosTheta);
REAL3 localV;
real3 localV;
localV = REAL3(0.0, 0.0, 1.0);
localV = real3(0.0, 0.0, 1.0);
VdotH = NdotH;
}
else

}
// Compute { localL = reflect(-localV, localH) }
REAL3 localL = -localV + 2.0 * VdotH * localH;
real3 localL = -localV + 2.0 * VdotH * localH;
NdotL = localL.z;
L = mul(localL, localToWorld);

void SampleVisibleAnisoGGXDir(REAL2 u, REAL3 V, REAL3x3 localToWorld,
REAL roughnessT, REAL roughnessB,
out REAL3 L,
out REAL NdotL,
out REAL NdotH,
out REAL VdotH,
void SampleVisibleAnisoGGXDir(real2 u, real3 V, real3x3 localToWorld,
real roughnessT, real roughnessB,
out real3 L,
out real NdotL,
out real NdotH,
out real VdotH,
REAL3 localV = mul(V, transpose(localToWorld));
real3 localV = mul(V, transpose(localToWorld));
REAL3x3 viewToLocal;
real3x3 viewToLocal;
if (VeqN)
{
viewToLocal = k_identity3x3;

viewToLocal[2] = normalize(REAL3(roughnessT * localV.x, roughnessB * localV.y, localV.z));
viewToLocal[0] = (viewToLocal[2].z < 0.9999) ? normalize(cross(viewToLocal[2], REAL3(0, 0, 1))) : REAL3(1, 0, 0);
viewToLocal[2] = normalize(real3(roughnessT * localV.x, roughnessB * localV.y, localV.z));
viewToLocal[0] = (viewToLocal[2].z < 0.9999) ? normalize(cross(viewToLocal[2], real3(0, 0, 1))) : real3(1, 0, 0);
REAL r = sqrt(u.x);
REAL b = viewToLocal[2].z + 1;
REAL a = rcp(b);
REAL c = (u.y < a) ? u.y * b : 1 + (u.y * b - 1) / viewToLocal[2].z;
REAL phi = PI * c;
REAL p1 = r * cos(phi);
REAL p2 = r * sin(phi) * ((u.y < a) ? 1 : viewToLocal[2].z);
real r = sqrt(u.x);
real b = viewToLocal[2].z + 1;
real a = rcp(b);
real c = (u.y < a) ? u.y * b : 1 + (u.y * b - 1) / viewToLocal[2].z;
real phi = PI * c;
real p1 = r * cos(phi);
real p2 = r * sin(phi) * ((u.y < a) ? 1 : viewToLocal[2].z);
REAL3 viewH = normalize(REAL3(roughnessT * p1, roughnessB * p2, sqrt(1 - p1 * p1 - p2 * p2)));
real3 viewH = normalize(real3(roughnessT * p1, roughnessB * p2, sqrt(1 - p1 * p1 - p2 * p2)));
REAL3 localH = mul(viewH, viewToLocal);
real3 localH = mul(viewH, viewToLocal);
REAL3 localL = -localV + 2 * VdotH * localH;
real3 localL = -localV + 2 * VdotH * localH;
NdotL = localL.z;
L = mul(localL, localToWorld);

void SampleAnisoGGXDir(REAL2 u,
REAL3 V,
REAL3 N,
REAL3 tangentX,
REAL3 tangentY,
REAL roughnessT,
REAL roughnessB,
out REAL3 H,
out REAL3 L)
void SampleAnisoGGXDir(real2 u,
real3 V,
real3 N,
real3 tangentX,
real3 tangentY,
real roughnessT,
real roughnessB,
out real3 H,
out real3 L)
// Convert sample from REAL angle to incident angle
// Convert sample from real angle to incident angle
void ImportanceSampleLambert(REAL2 u,
REAL3x3 localToWorld,
out REAL3 L,
out REAL NdotL,
out REAL weightOverPdf)
void ImportanceSampleLambert(real2 u,
real3x3 localToWorld,
out real3 L,
out real NdotL,
out real weightOverPdf)
REAL3 localL = SampleHemisphereCosine(u.x, u.y);
real3 localL = SampleHemisphereCosine(u.x, u.y);
NdotL = localL.z;

}
// weightOverPdf return the weight (without the Fresnel term) over pdf. Fresnel term must be apply by the caller.
void ImportanceSampleGGX(REAL2 u,
REAL3 V,
REAL3x3 localToWorld,
REAL roughness,
REAL NdotV,
out REAL3 L,
out REAL VdotH,
out REAL NdotL,
out REAL weightOverPdf)
void ImportanceSampleGGX(real2 u,
real3 V,
real3x3 localToWorld,
real roughness,
real NdotV,
out real3 L,
out real VdotH,
out real NdotL,
out real weightOverPdf)
REAL NdotH;
real NdotH;
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, VdotH);
// Importance sampling weight for each sample

// Remind (L.H) == (V.H)
// F is apply outside the function
REAL Vis = V_SmithJointGGX(NdotL, NdotV, roughness);
real Vis = V_SmithJointGGX(NdotL, NdotV, roughness);
void ImportanceSampleAnisoGGX(REAL2 u,
REAL3 V,
REAL3x3 localToWorld,
REAL roughnessT,
REAL roughnessB,
REAL NdotV,
out REAL3 L,
out REAL VdotH,
out REAL NdotL,
out REAL weightOverPdf)
void ImportanceSampleAnisoGGX(real2 u,
real3 V,
real3x3 localToWorld,
real roughnessT,
real roughnessB,
real NdotV,
out real3 L,
out real VdotH,
out real NdotL,
out real weightOverPdf)
REAL3 tangentX = localToWorld[0];
REAL3 tangentY = localToWorld[1];
REAL3 N = localToWorld[2];
real3 tangentX = localToWorld[0];
real3 tangentY = localToWorld[1];
real3 N = localToWorld[2];
REAL3 H;
real3 H;
REAL NdotH = saturate(dot(N, H));
real NdotH = saturate(dot(N, H));
// Note: since L and V are symmetric around H, LdotH == VdotH
VdotH = saturate(dot(V, H));
NdotL = saturate(dot(N, L));

// F is apply outside the function
// For anisotropy we must not saturate these values
REAL TdotV = dot(tangentX, V);
REAL BdotV = dot(tangentY, V);
REAL TdotL = dot(tangentX, L);
REAL BdotL = dot(tangentY, L);
real TdotV = dot(tangentX, V);
real BdotV = dot(tangentY, V);
real TdotL = dot(tangentX, L);
real BdotL = dot(tangentY, L);
REAL Vis = V_SmithJointGGXAniso(TdotV, BdotV, NdotV, TdotL, BdotL, NdotL, roughnessT, roughnessB);
real Vis = V_SmithJointGGXAniso(TdotV, BdotV, NdotV, TdotL, BdotL, NdotL, roughnessT, roughnessB);
weightOverPdf = 4.0 * Vis * NdotL * VdotH / NdotH;
}

// Ref: Listing 18 in "Moving Frostbite to PBR" + https://knarkowicz.wordpress.com/2014/12/27/analytical-dfg-term-for-ibl/
REAL4 IntegrateGGXAndDisneyFGD(REAL3 V, REAL3 N, REAL roughness, uint sampleCount = 8192)
real4 IntegrateGGXAndDisneyFGD(real3 V, real3 N, real roughness, uint sampleCount = 8192)
REAL NdotV = saturate(dot(N, V));
REAL4 acc = REAL4(0.0, 0.0, 0.0, 0.0);
real NdotV = saturate(dot(N, V));
real4 acc = real4(0.0, 0.0, 0.0, 0.0);
REAL2 randNum = InitRandom(V.xy * 0.5 + 0.5);
real2 randNum = InitRandom(V.xy * 0.5 + 0.5);
REAL3x3 localToWorld = GetLocalFrame(N);
real3x3 localToWorld = GetLocalFrame(N);
REAL2 u = frac(randNum + Hammersley2d(i, sampleCount));
real2 u = frac(randNum + Hammersley2d(i, sampleCount));
REAL VdotH;
REAL NdotL;
REAL weightOverPdf;
real VdotH;
real NdotL;
real weightOverPdf;
REAL3 L; // Unused
real3 L; // Unused
ImportanceSampleGGX(u, V, localToWorld, roughness, NdotV,
L, VdotH, NdotL, weightOverPdf);

if (NdotL > 0.0)
{
REAL LdotV = dot(L, V);
REAL disneyDiffuse = DisneyDiffuseNoPI(NdotV, NdotL, LdotV, RoughnessToPerceptualRoughness(roughness));
real LdotV = dot(L, V);
real disneyDiffuse = DisneyDiffuseNoPI(NdotV, NdotL, LdotV, RoughnessToPerceptualRoughness(roughness));
acc.z += disneyDiffuse * weightOverPdf;
}

}
// Ref: Listing 19 in "Moving Frostbite to PBR"
REAL4 IntegrateLD(TEXTURECUBE_ARGS(tex, sampl),
real4 IntegrateLD(TEXTURECUBE_ARGS(tex, sampl),
REAL3 V,
REAL3 N,
REAL roughness,
REAL index, // Current MIP level minus one
REAL invOmegaP,
real3 V,
real3 N,
real roughness,
real index, // Current MIP level minus one
real invOmegaP,
REAL3x3 localToWorld = GetLocalFrame(N);
real3x3 localToWorld = GetLocalFrame(N);
REAL NdotV = 1; // N == V
REAL partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
real NdotV = 1; // N == V
real partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
REAL3 lightInt = REAL3(0.0, 0.0, 0.0);
REAL cbsdfInt = 0.0;
real3 lightInt = real3(0.0, 0.0, 0.0);
real cbsdfInt = 0.0;
REAL3 L;
REAL NdotL, NdotH, LdotH;
real3 L;
real NdotL, NdotH, LdotH;
if (usePrecomputedSamples)
{

// or Structured buffer, or perhaps even declare all the constants in an
// HLSL header to allow the compiler to inline everything.
REAL3 localL = LOAD_TEXTURE2D(ggxIblSamples, uint2(i, index)).xyz;
real3 localL = LOAD_TEXTURE2D(ggxIblSamples, uint2(i, index)).xyz;
L = mul(localL, localToWorld);
NdotL = localL.z;

{
REAL2 u = Fibonacci2d(i, sampleCount);
real2 u = Fibonacci2d(i, sampleCount);
// Note: if (N == V), all of the microsurface normals are visible.
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, LdotH, true);

REAL mipLevel;
real mipLevel;
if (!prefilter) // BRDF importance sampling
{

// - OmegaS: Solid angle associated with the sample
// - OmegaP: Solid angle associated with the texel of the cubemap
REAL omegaS;
real omegaS;
if (usePrecomputedSamples)
{

{
// REAL PDF = D * NdotH * Jacobian, where Jacobian = 1 / (4 * LdotH).
// real PDF = D * NdotH * Jacobian, where Jacobian = 1 / (4 * LdotH).
REAL pdf = 0.25 * D_GGX(NdotH, roughness);
real pdf = 0.25 * D_GGX(NdotH, roughness);
// REAL omegaP = FOUR_PI / (6.0 * cubemapWidth * cubemapWidth);
const REAL mipBias = roughness;
// real omegaP = FOUR_PI / (6.0 * cubemapWidth * cubemapWidth);
const real mipBias = roughness;
REAL3 val = SAMPLE_TEXTURECUBE_LOD(tex, sampl, L, mipLevel).rgb;
real3 val = SAMPLE_TEXTURECUBE_LOD(tex, sampl, L, mipLevel).rgb;
// The goal of this function is to use Monte-Carlo integration to find
// X = Integral{Radiance(L) * CBSDF(L, N, V) dL} / Integral{CBSDF(L, N, V) dL}.

#ifndef USE_KARIS_APPROXIMATION
// The choice of the Fresnel factor does not appear to affect the result.
REAL F = 1; // F_Schlick(F0, LdotH);
REAL V = V_SmithJointGGX(NdotL, NdotV, roughness, partLambdaV);
REAL G = V * NdotL * NdotV; // 4 cancels out
real F = 1; // F_Schlick(F0, LdotH);
real V = V_SmithJointGGX(NdotL, NdotV, roughness, partLambdaV);
real G = V * NdotL * NdotV; // 4 cancels out
lightInt += F * G * val;
cbsdfInt += F * G;

#endif
}
return REAL4(lightInt / cbsdfInt, 1.0);
return real4(lightInt / cbsdfInt, 1.0);
uint BinarySearchRow(uint j, REAL needle, TEXTURE2D(haystack), uint n)
uint BinarySearchRow(uint j, real needle, TEXTURE2D(haystack), uint n)
REAL v = LOAD_TEXTURE2D(haystack, uint2(i, j)).r;
real v = LOAD_TEXTURE2D(haystack, uint2(i, j)).r;
if (needle < v)
{

return i;
}
REAL4 IntegrateLD_MIS(TEXTURECUBE_ARGS(envMap, sampler_envMap),
real4 IntegrateLD_MIS(TEXTURECUBE_ARGS(envMap, sampler_envMap),
REAL3 V,
REAL3 N,
REAL roughness,
REAL invOmegaP,
real3 V,
real3 N,
real roughness,
real invOmegaP,
REAL3x3 localToWorld = GetLocalFrame(N);
real3x3 localToWorld = GetLocalFrame(N);
REAL2 randNum = InitRandom(V.xy * 0.5 + 0.5);
real2 randNum = InitRandom(V.xy * 0.5 + 0.5);
REAL3 lightInt = REAL3(0.0, 0.0, 0.0);
REAL cbsdfInt = 0.0;
real3 lightInt = real3(0.0, 0.0, 0.0);
real cbsdfInt = 0.0;
/*
// Dedicate 50% of samples to light sampling at 1.0 roughness.

*/
// The value of the integral of intensity values of the environment map (as a 2D step function).
REAL envMapInt2dStep = LOAD_TEXTURE2D(marginalRowDensities, uint2(height, 0)).r;
real envMapInt2dStep = LOAD_TEXTURE2D(marginalRowDensities, uint2(height, 0)).r;
REAL envMapIntSphere = envMapInt2dStep * INV_FOUR_PI;
real envMapIntSphere = envMapInt2dStep * INV_FOUR_PI;
REAL2 s = frac(randNum + Hammersley2d(i, sampleCount));
real2 s = frac(randNum + Hammersley2d(i, sampleCount));
// Sample a row from the marginal distribution.
uint y = BinarySearchRow(0, s.x, marginalRowDensities, height - 1);

// Compute the coordinates of the sample.
// Note: we take the sample in between two texels, and also apply the REAL-texel offset.
// Note: we take the sample in between two texels, and also apply the real-texel offset.
REAL u = saturate((REAL)x / width + 1.0 / width);
REAL v = saturate((REAL)y / height + 1.0 / height);
REAL3 L = ConvertEquiarealToCubemap(u, v);
real u = saturate((real)x / width + 1.0 / width);
real v = saturate((real)y / height + 1.0 / height);
real3 L = ConvertEquiarealToCubemap(u, v);
REAL NdotL = saturate(dot(N, L));
real NdotL = saturate(dot(N, L));
REAL3 val = SAMPLE_TEXTURECUBE_LOD(envMap, sampler_envMap, L, 0).rgb;
REAL pdf = (val.r + val.g + val.b) / envMapIntSphere;
real3 val = SAMPLE_TEXTURECUBE_LOD(envMap, sampler_envMap, L, 0).rgb;
real pdf = (val.r + val.g + val.b) / envMapIntSphere;
REAL NdotH = sqrt(NdotL * 0.5 + 0.5);
real NdotH = sqrt(NdotL * 0.5 + 0.5);
// *********************************************************************************
// Our goal is to use Monte-Carlo integration with importance sampling to evaluate

// Weight = D * NdotL / (4 * PDF).
// *********************************************************************************
REAL weight = D_GGX(NdotH, roughness) * NdotL / (4.0 * pdf);
real weight = D_GGX(NdotH, roughness) * NdotL / (4.0 * pdf);
lightInt += weight * val;
cbsdfInt += weight;

// Prevent NaNs arising from the division of 0 by 0.
cbsdfInt = max(cbsdfInt, FLT_EPS);
return REAL4(lightInt / cbsdfInt, 1.0);
return real4(lightInt / cbsdfInt, 1.0);
}
#endif // UNITY_IMAGE_BASED_LIGHTING_INCLUDED

42
ScriptableRenderPipeline/Core/ShaderLibrary/Macros.hlsl


#define CENTIMETERS_PER_METER 100
#define METERS_PER_CENTIMETER rcp(CENTIMETERS_PER_METER)
#define FLT_EPS 5.960464478e-8 // 2^-24, machine epsilon: 1 + EPS = 1 (REAL of the ULP for 1)
#define FLT_EPS 5.960464478e-8 // 2^-24, machine epsilon: 1 + EPS = 1 (real of the ULP for 1)
#define FLT_MIN 1.175494351e-38 // Minimum representable positive floating-point number
#define FLT_MAX 3.402823466e+38 // Maximum representable floating-point number
#define HALF_MIN 6.103515625e-5 // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Small_Float_Formats

#define TEMPLATE_1_FLT(FunctionName, Parameter1, FunctionBody) \
REAL FunctionName(REAL Parameter1) { FunctionBody; } \
REAL2 FunctionName(REAL2 Parameter1) { FunctionBody; } \
REAL3 FunctionName(REAL3 Parameter1) { FunctionBody; } \
REAL4 FunctionName(REAL4 Parameter1) { FunctionBody; }
real FunctionName(real Parameter1) { FunctionBody; } \
real2 FunctionName(real2 Parameter1) { FunctionBody; } \
real3 FunctionName(real3 Parameter1) { FunctionBody; } \
real4 FunctionName(real4 Parameter1) { FunctionBody; }
#ifdef SHADER_API_GLES
#define TEMPLATE_1_INT(FunctionName, Parameter1, FunctionBody) \

#endif
#define TEMPLATE_2_FLT(FunctionName, Parameter1, Parameter2, FunctionBody) \
REAL FunctionName(REAL Parameter1, REAL Parameter2) { FunctionBody; } \
REAL2 FunctionName(REAL2 Parameter1, REAL2 Parameter2) { FunctionBody; } \
REAL3 FunctionName(REAL3 Parameter1, REAL3 Parameter2) { FunctionBody; } \
REAL4 FunctionName(REAL4 Parameter1, REAL4 Parameter2) { FunctionBody; }
real FunctionName(real Parameter1, real Parameter2) { FunctionBody; } \
real2 FunctionName(real2 Parameter1, real2 Parameter2) { FunctionBody; } \
real3 FunctionName(real3 Parameter1, real3 Parameter2) { FunctionBody; } \
real4 FunctionName(real4 Parameter1, real4 Parameter2) { FunctionBody; }
#ifdef SHADER_API_GLES

#endif
#define TEMPLATE_3_FLT(FunctionName, Parameter1, Parameter2, Parameter3, FunctionBody) \
REAL FunctionName(REAL Parameter1, REAL Parameter2, REAL Parameter3) { FunctionBody; } \
REAL2 FunctionName(REAL2 Parameter1, REAL2 Parameter2, REAL2 Parameter3) { FunctionBody; } \
REAL3 FunctionName(REAL3 Parameter1, REAL3 Parameter2, REAL3 Parameter3) { FunctionBody; } \
REAL4 FunctionName(REAL4 Parameter1, REAL4 Parameter2, REAL4 Parameter3) { FunctionBody; }
real FunctionName(real Parameter1, real Parameter2, real Parameter3) { FunctionBody; } \
real2 FunctionName(real2 Parameter1, real2 Parameter2, real2 Parameter3) { FunctionBody; } \
real3 FunctionName(real3 Parameter1, real3 Parameter2, real3 Parameter3) { FunctionBody; } \
real4 FunctionName(real4 Parameter1, real4 Parameter2, real4 Parameter3) { FunctionBody; }
#ifdef SHADER_API_GLES
#define TEMPLATE_3_INT(FunctionName, Parameter1, Parameter2, Parameter3, FunctionBody) \

#ifdef SHADER_API_GLES
#define TEMPLATE_SWAP(FunctionName) \
void FunctionName(inout REAL a, inout REAL b) { REAL t = a; a = b; b = t; } \
void FunctionName(inout REAL2 a, inout REAL2 b) { REAL2 t = a; a = b; b = t; } \
void FunctionName(inout REAL3 a, inout REAL3 b) { REAL3 t = a; a = b; b = t; } \
void FunctionName(inout REAL4 a, inout REAL4 b) { REAL4 t = a; a = b; b = t; } \
void FunctionName(inout real a, inout real b) { real t = a; a = b; b = t; } \
void FunctionName(inout real2 a, inout real2 b) { real2 t = a; a = b; b = t; } \
void FunctionName(inout real3 a, inout real3 b) { real3 t = a; a = b; b = t; } \
void FunctionName(inout real4 a, inout real4 b) { real4 t = a; a = b; b = t; } \
void FunctionName(inout int a, inout int b) { int t = a; a = b; b = t; } \
void FunctionName(inout int2 a, inout int2 b) { int2 t = a; a = b; b = t; } \
void FunctionName(inout int3 a, inout int3 b) { int3 t = a; a = b; b = t; } \

void FunctionName(inout bool4 a, inout bool4 b) { bool4 t = a; a = b; b = t; }
#else
#define TEMPLATE_SWAP(FunctionName) \
void FunctionName(inout REAL a, inout REAL b) { REAL t = a; a = b; b = t; } \
void FunctionName(inout REAL2 a, inout REAL2 b) { REAL2 t = a; a = b; b = t; } \
void FunctionName(inout REAL3 a, inout REAL3 b) { REAL3 t = a; a = b; b = t; } \
void FunctionName(inout REAL4 a, inout REAL4 b) { REAL4 t = a; a = b; b = t; } \
void FunctionName(inout real a, inout real b) { real t = a; a = b; b = t; } \
void FunctionName(inout real2 a, inout real2 b) { real2 t = a; a = b; b = t; } \
void FunctionName(inout real3 a, inout real3 b) { real3 t = a; a = b; b = t; } \
void FunctionName(inout real4 a, inout real4 b) { real4 t = a; a = b; b = t; } \
void FunctionName(inout int a, inout int b) { int t = a; a = b; b = t; } \
void FunctionName(inout int2 a, inout int2 b) { int2 t = a; a = b; b = t; } \
void FunctionName(inout int3 a, inout int3 b) { int3 t = a; a = b; b = t; } \

60
ScriptableRenderPipeline/Core/ShaderLibrary/NormalSurfaceGradient.hlsl


// this produces an orthonormal basis of the tangent and bitangent WITHOUT vertex level tangent/bitangent for any UV including procedurally generated
// method released with the demo for publication of "bump mapping unparametrized surfaces on the GPU"
// http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
void SurfaceGradientGenBasisTB(REAL3 nrmVertexNormal, REAL3 sigmaX, REAL3 sigmaY, REAL flipSign, REAL2 texST, out REAL3 vT, out REAL3 vB)
void SurfaceGradientGenBasisTB(real3 nrmVertexNormal, real3 sigmaX, real3 sigmaY, real flipSign, real2 texST, out real3 vT, out real3 vB)
REAL2 dSTdx = ddx_fine(texST), dSTdy = ddy_fine(texST);
real2 dSTdx = ddx_fine(texST), dSTdy = ddy_fine(texST);
REAL det = dot(dSTdx, REAL2(dSTdy.y, -dSTdy.x));
REAL sign_det = det < 0 ? -1 : 1;
real det = dot(dSTdx, real2(dSTdy.y, -dSTdy.x));
real sign_det = det < 0 ? -1 : 1;
REAL2 invC0 = sign_det * REAL2(dSTdy.y, -dSTdx.y);
real2 invC0 = sign_det * real2(dSTdy.y, -dSTdx.y);
vT = sigmaX * invC0.x + sigmaY * invC0.y;
if (abs(det) > 0.0)
vT = normalize(vT);

// surface gradient from an on the fly TBN (deriv obtained using tspaceNormalToDerivative()) or from conventional vertex level TBN (mikktspace compliant and deriv obtained using tspaceNormalToDerivative())
REAL3 SurfaceGradientFromTBN(REAL2 deriv, REAL3 vT, REAL3 vB)
real3 SurfaceGradientFromTBN(real2 deriv, real3 vT, real3 vB)
{
return deriv.x * vT + deriv.y * vB;
}

// this allows us to mix the contribution together with a series of other contributions including tangent space normals
// v does not need to be unit length as long as it establishes the direction.
REAL3 SurfaceGradientFromPerturbedNormal(REAL3 nrmVertexNormal, REAL3 v)
real3 SurfaceGradientFromPerturbedNormal(real3 nrmVertexNormal, real3 v)
REAL3 n = nrmVertexNormal;
REAL s = 1.0 / max(FLT_EPS, abs(dot(n, v)));
real3 n = nrmVertexNormal;
real s = 1.0 / max(FLT_EPS, abs(dot(n, v)));
return s * (dot(n, v) * n - v);
}

REAL3 SurfaceGradientFromVolumeGradient(REAL3 nrmVertexNormal, REAL3 grad)
real3 SurfaceGradientFromVolumeGradient(real3 nrmVertexNormal, real3 grad)
{
return grad - dot(nrmVertexNormal, grad) * nrmVertexNormal;
}

// derivs obtained using tspaceNormalToDerivative() and weights using computeTriplanarWeights().
REAL3 SurfaceGradientFromTriplanarProjection(REAL3 nrmVertexNormal, REAL3 triplanarWeights, REAL2 deriv_xplane, REAL2 deriv_yplane, REAL2 deriv_zplane)
real3 SurfaceGradientFromTriplanarProjection(real3 nrmVertexNormal, real3 triplanarWeights, real2 deriv_xplane, real2 deriv_yplane, real2 deriv_zplane)
const REAL w0 = triplanarWeights.x, w1 = triplanarWeights.y, w2 = triplanarWeights.z;
const real w0 = triplanarWeights.x, w1 = triplanarWeights.y, w2 = triplanarWeights.z;
REAL3 volumeGrad = REAL3(w2 * deriv_zplane.x + w1 * deriv_yplane.y, w2 * deriv_zplane.y + w0 * deriv_xplane.y, w0 * deriv_xplane.x + w1 * deriv_yplane.x);
real3 volumeGrad = real3(w2 * deriv_zplane.x + w1 * deriv_yplane.y, w2 * deriv_zplane.y + w0 * deriv_xplane.y, w0 * deriv_xplane.x + w1 * deriv_yplane.x);
REAL3 SurfaceGradientResolveNormal(REAL3 nrmVertexNormal, REAL3 surfGrad)
real3 SurfaceGradientResolveNormal(real3 nrmVertexNormal, real3 surfGrad)
{
return normalize(nrmVertexNormal - surfGrad);
}

// So a max angle of 89.55 degrees ;) id argue thats close enough to the vertical limit at 90 degrees
// vT is channels.xy of a tangent space normal in[-1; 1]
// out: convert vT to a derivative
REAL2 UnpackDerivativeNormalAG(REAL4 packedNormal, REAL scale = 1.0)
real2 UnpackDerivativeNormalAG(real4 packedNormal, real scale = 1.0)
const REAL fS = 1.0 / (128.0 * 128.0);
REAL2 vT = packedNormal.wy * 2.0 - 1.0;
REAL2 vTsq = vT * vT;
REAL nz_sq = 1 - vTsq.x - vTsq.y;
REAL maxcompxy_sq = fS * max(vTsq.x, vTsq.y);
REAL z_inv = rsqrt(max(nz_sq, maxcompxy_sq));
REAL2 deriv = -z_inv * REAL2(vT.x, vT.y);
const real fS = 1.0 / (128.0 * 128.0);
real2 vT = packedNormal.wy * 2.0 - 1.0;
real2 vTsq = vT * vT;
real nz_sq = 1 - vTsq.x - vTsq.y;
real maxcompxy_sq = fS * max(vTsq.x, vTsq.y);
real z_inv = rsqrt(max(nz_sq, maxcompxy_sq));
real2 deriv = -z_inv * real2(vT.x, vT.y);
REAL2 UnpackDerivativeNormalRGorAG(REAL4 packedNormal, REAL scale = 1.0)
real2 UnpackDerivativeNormalRGorAG(real4 packedNormal, real scale = 1.0)
{
// This do the trick
packedNormal.w *= packedNormal.x;

REAL2 UnpackDerivativeNormalRGB(REAL4 packedNormal, REAL scale = 1.0)
real2 UnpackDerivativeNormalRGB(real4 packedNormal, real scale = 1.0)
const REAL fS = 1.0 / (128.0 * 128.0);
REAL3 vT = packedNormal.xyz * 2.0 - 1.0;
REAL3 vTsq = vT * vT;
REAL maxcompxy_sq = fS * max(vTsq.x, vTsq.y);
REAL z_inv = rsqrt(max(vTsq.z, maxcompxy_sq));
REAL2 deriv = -z_inv * REAL2(vT.x, vT.y);
const real fS = 1.0 / (128.0 * 128.0);
real3 vT = packedNormal.xyz * 2.0 - 1.0;
real3 vTsq = vT * vT;
real maxcompxy_sq = fS * max(vTsq.x, vTsq.y);
real z_inv = rsqrt(max(vTsq.z, maxcompxy_sq));
real2 deriv = -z_inv * real2(vT.x, vT.y);
return deriv * scale;
}

250
ScriptableRenderPipeline/Core/ShaderLibrary/Packing.hlsl


// Normal packing
//-----------------------------------------------------------------------------
REAL3 PackNormalMaxComponent(REAL3 n)
real3 PackNormalMaxComponent(real3 n)
REAL3 UnpackNormalMaxComponent(REAL3 n)
real3 UnpackNormalMaxComponent(real3 n)
{
return normalize(n * 2.0 - 1.0);
}

// return REAL between [-1, 1]
REAL2 PackNormalOctEncode(REAL3 n)
// return real between [-1, 1]
real2 PackNormalOctEncode(real3 n)
//REAL l1norm = dot(abs(n), 1.0);
//REAL2 res0 = n.xy * (1.0 / l1norm);
//real l1norm = dot(abs(n), 1.0);
//real2 res0 = n.xy * (1.0 / l1norm);
//REAL2 val = 1.0 - abs(res0.yx);
//return (n.zz < REAL2(0.0, 0.0) ? (res0 >= 0.0 ? val : -val) : res0);
//real2 val = 1.0 - abs(res0.yx);
//return (n.zz < real2(0.0, 0.0) ? (res0 >= 0.0 ? val : -val) : res0);
REAL t = saturate(-n.z);
real t = saturate(-n.z);
REAL3 UnpackNormalOctEncode(REAL2 f)
real3 UnpackNormalOctEncode(real2 f)
REAL3 n = REAL3(f.x, f.y, 1.0 - abs(f.x) - abs(f.y));
real3 n = real3(f.x, f.y, 1.0 - abs(f.x) - abs(f.y));
//REAL2 val = 1.0 - abs(n.yx);
//n.xy = (n.zz < REAL2(0.0, 0.0) ? (n.xy >= 0.0 ? val : -val) : n.xy);
//real2 val = 1.0 - abs(n.yx);
//n.xy = (n.zz < real2(0.0, 0.0) ? (n.xy >= 0.0 ? val : -val) : n.xy);
REAL t = max(-n.z, 0.0);
real t = max(-n.z, 0.0);
REAL2 PackNormalHemiOctEncode(REAL3 n)
real2 PackNormalHemiOctEncode(real3 n)
REAL l1norm = dot(abs(n), 1.0);
REAL2 res = n.xy * (1.0 / l1norm);
real l1norm = dot(abs(n), 1.0);
real2 res = n.xy * (1.0 / l1norm);
return REAL2(res.x + res.y, res.x - res.y);
return real2(res.x + res.y, res.x - res.y);
REAL3 UnpackNormalHemiOctEncode(REAL2 f)
real3 UnpackNormalHemiOctEncode(real2 f)
REAL2 val = REAL2(f.x + f.y, f.x - f.y) * 0.5;
REAL3 n = REAL3(val, 1.0 - dot(abs(val), 1.0));
real2 val = real2(f.x + f.y, f.x - f.y) * 0.5;
real3 n = real3(val, 1.0 - dot(abs(val), 1.0));
return normalize(n);
}

// v0 = REAL3(1.0, 0.0, -1.0 / sqrt(2.0));
// v1 = REAL3(-1.0, 0.0, -1.0 / sqrt(2.0));
// v2 = REAL3(0.0, 1.0, 1.0 / sqrt(2.0));
// v3 = REAL3(0.0, -1.0, 1.0 / sqrt(2.0));
// v0 = real3(1.0, 0.0, -1.0 / sqrt(2.0));
// v1 = real3(-1.0, 0.0, -1.0 / sqrt(2.0));
// v2 = real3(0.0, 1.0, 1.0 / sqrt(2.0));
// v3 = real3(0.0, -1.0, 1.0 / sqrt(2.0));
static const REAL3 tetraBasisNormal[4] =
static const real3 tetraBasisNormal[4] =
REAL3(0., 0.816497, -0.57735),
REAL3(-0.816497, 0., 0.57735),
REAL3(0.816497, 0., 0.57735),
REAL3(0., -0.816497, -0.57735)
real3(0., 0.816497, -0.57735),
real3(-0.816497, 0., 0.57735),
real3(0.816497, 0., 0.57735),
real3(0., -0.816497, -0.57735)
static const REAL3x3 tetraBasisArray[4] =
static const real3x3 tetraBasisArray[4] =
REAL3x3(-1., 0., 0.,0., 0.57735, 0.816497,0., 0.816497, -0.57735),
REAL3x3(0., -1., 0.,0.57735, 0., 0.816497,-0.816497, 0., 0.57735),
REAL3x3(0., 1., 0.,-0.57735, 0., 0.816497,0.816497, 0., 0.57735),
REAL3x3(1., 0., 0.,0., -0.57735, 0.816497,0., -0.816497, -0.57735)
real3x3(-1., 0., 0.,0., 0.57735, 0.816497,0., 0.816497, -0.57735),
real3x3(0., -1., 0.,0.57735, 0., 0.816497,-0.816497, 0., 0.57735),
real3x3(0., 1., 0.,-0.57735, 0., 0.816497,0.816497, 0., 0.57735),
real3x3(1., 0., 0.,0., -0.57735, 0.816497,0., -0.816497, -0.57735)
REAL2 PackNormalTetraEncode(REAL3 n, out uint faceIndex)
real2 PackNormalTetraEncode(real3 n, out uint faceIndex)
REAL dot0 = dot(n, tetraBasisNormal[0]);
REAL dot1 = dot(n, tetraBasisNormal[1]);
REAL dot2 = dot(n, tetraBasisNormal[2]);
REAL dot3 = dot(n, tetraBasisNormal[3]);
real dot0 = dot(n, tetraBasisNormal[0]);
real dot1 = dot(n, tetraBasisNormal[1]);
real dot2 = dot(n, tetraBasisNormal[2]);
real dot3 = dot(n, tetraBasisNormal[3]);
REAL maxi0 = max(dot0, dot1);
REAL maxi1 = max(dot2, dot3);
REAL maxi = max(maxi0, maxi1);
real maxi0 = max(dot0, dot1);
real maxi1 = max(dot2, dot3);
real maxi = max(maxi0, maxi1);
// Get the index from the greatest dot
if (maxi == dot0)

}
// Assume f [-1..1]
REAL3 UnpackNormalTetraEncode(REAL2 f, uint faceIndex)
real3 UnpackNormalTetraEncode(real2 f, uint faceIndex)
REAL3 n = REAL3(f.xy, sqrt(1.0 - dot(f.xy, f.xy)));
real3 n = real3(f.xy, sqrt(1.0 - dot(f.xy, f.xy)));
REAL3 UnpackNormalRGB(REAL4 packedNormal, REAL scale = 1.0)
real3 UnpackNormalRGB(real4 packedNormal, real scale = 1.0)
REAL3 normal;
real3 normal;
REAL3 UnpackNormalAG(REAL4 packedNormal, REAL scale = 1.0)
real3 UnpackNormalAG(real4 packedNormal, real scale = 1.0)
REAL3 normal;
real3 normal;
normal.xy = packedNormal.wy * 2.0 - 1.0;
normal.xy *= scale;
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));

// Unpack normal as DXT5nm (1, y, 0, x) or BC5 (x, y, 0, 1)
REAL3 UnpackNormalmapRGorAG(REAL4 packedNormal, REAL scale = 1.0)
real3 UnpackNormalmapRGorAG(real4 packedNormal, real scale = 1.0)
{
// This do the trick
packedNormal.w *= packedNormal.x;

#if !defined(SHADER_API_GLES)
// Ref: http://realtimecollisiondetection.net/blog/?p=15
REAL4 PackToLogLuv(REAL3 vRGB)
real4 PackToLogLuv(real3 vRGB)
const REAL3x3 M = REAL3x3(
const real3x3 M = real3x3(
REAL4 vResult;
REAL3 Xp_Y_XYZp = mul(vRGB, M);
Xp_Y_XYZp = max(Xp_Y_XYZp, REAL3(1e-6, 1e-6, 1e-6));
real4 vResult;
real3 Xp_Y_XYZp = mul(vRGB, M);
Xp_Y_XYZp = max(Xp_Y_XYZp, real3(1e-6, 1e-6, 1e-6));
REAL Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
real Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
REAL3 UnpackFromLogLuv(REAL4 vLogLuv)
real3 UnpackFromLogLuv(real4 vLogLuv)
const REAL3x3 InverseM = REAL3x3(
const real3x3 InverseM = real3x3(
REAL Le = vLogLuv.z * 255.0 + vLogLuv.w;
REAL3 Xp_Y_XYZp;
real Le = vLogLuv.z * 255.0 + vLogLuv.w;
real3 Xp_Y_XYZp;
REAL3 vRGB = mul(Xp_Y_XYZp, InverseM);
return max(vRGB, REAL3(0.0, 0.0, 0.0));
real3 vRGB = mul(Xp_Y_XYZp, InverseM);
return max(vRGB, real3(0.0, 0.0, 0.0));
uint PackToR11G11B10f(REAL3 rgb)
uint PackToR11G11B10f(real3 rgb)
{
uint r = (f32tof16(rgb.x) << 17) & 0xFFE00000;
uint g = (f32tof16(rgb.y) << 6) & 0x001FFC00;

REAL3 UnpackFromR11G11B10f(uint rgb)
real3 UnpackFromR11G11B10f(uint rgb)
REAL r = f16tof32((rgb >> 17) & 0x7FF0);
REAL g = f16tof32((rgb >> 6) & 0x7FF0);
REAL b = f16tof32((rgb << 5) & 0x7FE0);
return REAL3(r, g, b);
real r = f16tof32((rgb >> 17) & 0x7FF0);
real g = f16tof32((rgb >> 6) & 0x7FF0);
real b = f16tof32((rgb << 5) & 0x7FE0);
return real3(r, g, b);
}
#endif // SHADER_API_GLES

/*
// This is GCN intrinsic
uint FindBiggestComponent(REAL4 q)
uint FindBiggestComponent(real4 q)
{
uint xyzIndex = CubeMapFaceID(q.x, q.y, q.z) * 0.5f;
uint wIndex = 3;

}
// Pack a quaternion into a 10:10:10:2
REAL4 PackQuat(REAL4 quat)
real4 PackQuat(real4 quat)
{
uint index = FindBiggestComponent(quat);

REAL4 packedQuat;
real4 packedQuat;
packedQuat.xyz = quat.xyz * FastSign(quat.w) * sqrt(0.5) + 0.5;
packedQuat.w = index / 3.0;

// Unpack a quaternion from a 10:10:10:2
REAL4 UnpackQuat(REAL4 packedQuat)
real4 UnpackQuat(real4 packedQuat)
REAL4 quat;
real4 quat;
quat.xyz = packedQuat.xyz * sqrt(2.0) - (1.0 / sqrt(2.0));
quat.w = sqrt(1.0 - saturate(dot(quat.xyz, quat.xyz)));

// Integer packing
//-----------------------------------------------------------------------------
// Packs an integer stored using at most 'numBits' into a [0..1] REAL.
REAL PackInt(uint i, uint numBits)
// Packs an integer stored using at most 'numBits' into a [0..1] real.
real PackInt(uint i, uint numBits)
// Unpacks a [0..1] REAL into an integer of size 'numBits'.
uint UnpackInt(REAL f, uint numBits)
// Unpacks a [0..1] real into an integer of size 'numBits'.
uint UnpackInt(real f, uint numBits)
// Packs a [0..255] integer into a [0..1] REAL.
REAL PackByte(uint i)
// Packs a [0..255] integer into a [0..1] real.
real PackByte(uint i)
// Unpacks a [0..1] REAL into a [0..255] integer.
uint UnpackByte(REAL f)
// Unpacks a [0..1] real into a [0..255] integer.
uint UnpackByte(real f)
// Packs a [0..65535] integer into a [0..1] REAL.
REAL PackShort(uint i)
// Packs a [0..65535] integer into a [0..1] real.
real PackShort(uint i)
// Unpacks a [0..1] REAL into a [0..65535] integer.
uint UnpackShort(REAL f)
// Unpacks a [0..1] real into a [0..65535] integer.
uint UnpackShort(real f)
// Packs 8 lowermost bits of a [0..65535] integer into a [0..1] REAL.
REAL PackShortLo(uint i)
// Packs 8 lowermost bits of a [0..65535] integer into a [0..1] real.
real PackShortLo(uint i)
// Packs 8 uppermost bits of a [0..65535] integer into a [0..1] REAL.
REAL PackShortHi(uint i)
// Packs 8 uppermost bits of a [0..65535] integer into a [0..1] real.
real PackShortHi(uint i)
REAL Pack2Byte(REAL2 inputs)
real Pack2Byte(real2 inputs)
REAL2 temp = inputs * REAL2(255.0, 255.0);
real2 temp = inputs * real2(255.0, 255.0);
REAL combined = temp.x + temp.y;
real combined = temp.x + temp.y;
REAL2 Unpack2Byte(REAL inputs)
real2 Unpack2Byte(real inputs)
REAL temp = round(inputs * 65535.0);
REAL ipart;
REAL fpart = modf(temp / 256.0, ipart);
REAL2 result = REAL2(ipart, round(256.0 * fpart));
return result * (1.0 / REAL2(255.0, 255.0));
real temp = round(inputs * 65535.0);
real ipart;
real fpart = modf(temp / 256.0, ipart);
real2 result = real2(ipart, round(256.0 * fpart));
return result * (1.0 / real2(255.0, 255.0));
// Encode a REAL in [0..1] and an int in [0..maxi - 1] as a REAL [0..1] to be store in log2(precision) bit
// Encode a real in [0..1] and an int in [0..maxi - 1] as a real [0..1] to be store in log2(precision) bit
// maxi must be a power of two and define the number of bit dedicated 0..1 to the int part (log2(maxi))
// Example: precision is 256.0, maxi is 2, i is [0..1] encode on 1 bit. f is [0..1] encode on 7 bit.
// Example: precision is 256.0, maxi is 4, i is [0..3] encode on 2 bit. f is [0..1] encode on 6 bit.

//...
REAL PackFloatInt(REAL f, int i, REAL maxi, REAL precision)
real PackFloatInt(real f, int i, real maxi, real precision)
REAL precisionMinusOne = precision - 1.0;
REAL t1 = ((precision / maxi) - 1.0) / precisionMinusOne;
REAL t2 = (precision / maxi) / precisionMinusOne;
real precisionMinusOne = precision - 1.0;
real t1 = ((precision / maxi) - 1.0) / precisionMinusOne;
real t2 = (precision / maxi) / precisionMinusOne;
return t1 * f + t2 * REAL(i);
return t1 * f + t2 * real(i);
void UnpackFloatInt(REAL val, REAL maxi, REAL precision, out REAL f, out int i)
void UnpackFloatInt(real val, real maxi, real precision, out real f, out int i)
REAL precisionMinusOne = precision - 1.0;
REAL t1 = ((precision / maxi) - 1.0) / precisionMinusOne;
REAL t2 = (precision / maxi) / precisionMinusOne;
real precisionMinusOne = precision - 1.0;
real t1 = ((precision / maxi) - 1.0) / precisionMinusOne;
real t2 = (precision / maxi) / precisionMinusOne;
//f = (val - t2 * REAL(i)) / t1 => convert in mads form
f = saturate((-t2 * REAL(i) + val) / t1); // Saturate in case of precision issue
//f = (val - t2 * real(i)) / t1 => convert in mads form
f = saturate((-t2 * real(i) + val) / t1); // Saturate in case of precision issue
REAL PackFloatInt8bit(REAL f, int i, REAL maxi)
real PackFloatInt8bit(real f, int i, real maxi)
void UnpackFloatInt8bit(REAL val, REAL maxi, out REAL f, out int i)
void UnpackFloatInt8bit(real val, real maxi, out real f, out int i)
REAL PackFloatInt10bit(REAL f, int i, REAL maxi)
real PackFloatInt10bit(real f, int i, real maxi)
void UnpackFloatInt10bit(REAL val, REAL maxi, out REAL f, out int i)
void UnpackFloatInt10bit(real val, real maxi, out real f, out int i)
REAL PackFloatInt16bit(REAL f, int i, REAL maxi)
real PackFloatInt16bit(real f, int i, real maxi)
void UnpackFloatInt16bit(REAL val, REAL maxi, out REAL f, out int i)
void UnpackFloatInt16bit(real val, real maxi, out real f, out int i)
{
UnpackFloatInt(val, maxi, 65536.0, f, i);
}

//-----------------------------------------------------------------------------
// src must be between 0.0 and 1.0
uint PackFloatToUInt(REAL src, uint offset, uint numBits)
uint PackFloatToUInt(real src, uint offset, uint numBits)
REAL UnpackUIntToFloat(uint src, uint offset, uint numBits)
real UnpackUIntToFloat(uint src, uint offset, uint numBits)
return REAL(BitFieldExtract(src, offset, numBits)) * rcp(maxInt);
return real(BitFieldExtract(src, offset, numBits)) * rcp(maxInt);
uint PackToR10G10B10A2(REAL4 rgba)
uint PackToR10G10B10A2(real4 rgba)
{
return (PackFloatToUInt(rgba.x, 0, 10) |
PackFloatToUInt(rgba.y, 10, 10) |

REAL4 UnpackFromR10G10B10A2(uint rgba)
real4 UnpackFromR10G10B10A2(uint rgba)
REAL4 ouput;
real4 ouput;
ouput.x = UnpackUIntToFloat(rgba, 0, 10);
ouput.y = UnpackUIntToFloat(rgba, 10, 10);
ouput.z = UnpackUIntToFloat(rgba, 20, 10);

// Both the input and the output are in the [0, 1] range.
REAL2 PackFloatToR8G8(REAL f)
real2 PackFloatToR8G8(real f)
return REAL2(PackShortLo(i), PackShortHi(i));
return real2(PackShortLo(i), PackShortHi(i));
REAL UnpackFloatFromR8G8(REAL2 f)
real UnpackFloatFromR8G8(real2 f)
{
uint lo = UnpackByte(f.x);
uint hi = UnpackByte(f.y);

56
ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl


// it return the offset to apply to the UVSet provide in PerPixelHeightDisplacementParam
// viewDirTS is view vector in texture space matching the UVSet
// ref: https://www.gamedev.net/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262
REAL2 ParallaxOcclusionMapping(REAL lod, REAL lodThreshold, int numSteps, REAL3 viewDirTS, PerPixelHeightDisplacementParam ppdParam, out REAL outHeight)
real2 ParallaxOcclusionMapping(real lod, real lodThreshold, int numSteps, real3 viewDirTS, PerPixelHeightDisplacementParam ppdParam, out real outHeight)
REAL stepSize = 1.0 / (REAL)numSteps;
real stepSize = 1.0 / (real)numSteps;
// REAL parallaxLimit = -length(viewDirTS.xy) / viewDirTS.z;
// REAL2 parallaxDir = normalize(Out.viewDirTS.xy);
// REAL2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
// real parallaxLimit = -length(viewDirTS.xy) / viewDirTS.z;
// real2 parallaxDir = normalize(Out.viewDirTS.xy);
// real2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
REAL2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z);
REAL2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS;
real2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z);
real2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS;
REAL2 texOffsetCurrent = REAL2(0.0, 0.0);
REAL prevHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam);
real2 texOffsetCurrent = real2(0.0, 0.0);
real prevHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam);
REAL currHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam);
REAL rayHeight = 1.0 - stepSize; // Start at top less one sample
real currHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam);
real rayHeight = 1.0 - stepSize; // Start at top less one sample
// Linear search
for (int stepIndex = 0; stepIndex < numSteps; ++stepIndex)

#define POM_SECANT_METHOD 1
#if POM_SECANT_METHOD
REAL pt0 = rayHeight + stepSize;
REAL pt1 = rayHeight;
REAL delta0 = pt0 - prevHeight;
REAL delta1 = pt1 - currHeight;
real pt0 = rayHeight + stepSize;
real pt1 = rayHeight;
real delta0 = pt0 - prevHeight;
real delta1 = pt1 - currHeight;
REAL delta;
REAL2 offset;
real delta;
real2 offset;
// Secant method to affine the search
// Ref: Faster Relief Mapping Using the Secant Method - Eric Risser

REAL intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
real intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
// Retrieve offset require to find this intersectionHeight
offset = (1 - intersectionHeight) * texOffsetPerStep * numSteps;

#else // regular POM intersection
//REAL pt0 = rayHeight + stepSize;
//REAL pt1 = rayHeight;
//REAL delta0 = pt0 - prevHeight;
//REAL delta1 = pt1 - currHeight;
//REAL intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
//REAL2 offset = (1 - intersectionHeight) * texOffsetPerStep * numSteps;
//real pt0 = rayHeight + stepSize;
//real pt1 = rayHeight;
//real delta0 = pt0 - prevHeight;
//real delta1 = pt1 - currHeight;
//real intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
//real2 offset = (1 - intersectionHeight) * texOffsetPerStep * numSteps;
REAL delta0 = currHeight - rayHeight;
REAL delta1 = (rayHeight + stepSize) - prevHeight;
REAL ratio = delta0 / (delta0 + delta1);
REAL2 offset = texOffsetCurrent - ratio * texOffsetPerStep;
real delta0 = currHeight - rayHeight;
real delta1 = (rayHeight + stepSize) - prevHeight;
real ratio = delta0 / (delta0 + delta1);
real2 offset = texOffsetCurrent - ratio * texOffsetPerStep;
currHeight = ComputePerPixelHeightDisplacement(offset, lod, ppdParam);

24
ScriptableRenderPipeline/Core/ShaderLibrary/QuaternionMath.hlsl


// Ref: https://cedec.cesa.or.jp/2015/session/ENG/14698.html The Rendering Materials of Far Cry 4
REAL4 TangentSpaceToQuat(REAL3 tagent, REAL3 bitangent, REAL3 normal)
real4 TangentSpaceToQuat(real3 tagent, real3 bitangent, real3 normal)
REAL4 quat;
real4 quat;
quat.x = normal.y - bitangent.z;
quat.y = tangent.z - normal.x;
quat.z = bitangent.x - tangent.y;

}
void QuatToTangentSpace(REAL4 quaterion, out REAL3 tangent, out REAL3 bitangent, out REAL3 normal)
void QuatToTangentSpace(real4 quaterion, out real3 tangent, out real3 bitangent, out real3 normal)
tangent = REAL3(1.0, 0.0, 0.0)
+ REAL3(-2.0, 2.0, 2.0) * quat.y * quat.yxw
+ REAL3(-2.0, -2.0, 2.0) * quat.z * quaternion.zwx;
tangent = real3(1.0, 0.0, 0.0)
+ real3(-2.0, 2.0, 2.0) * quat.y * quat.yxw
+ real3(-2.0, -2.0, 2.0) * quat.z * quaternion.zwx;
bitangent = REAL3(0.0, 1.0, 0.0)
+ REAL3(2.0, -2.0, 2.0) * quat.z * quat.wzy
+ REAL3(2.0, -2.0, -2.0) * quat.x * quaternion.yxw;
bitangent = real3(0.0, 1.0, 0.0)
+ real3(2.0, -2.0, 2.0) * quat.z * quat.wzy
+ real3(2.0, -2.0, -2.0) * quat.x * quaternion.yxw;
normal = REAL3(0.0, 0.0, 1.0)
+ REAL3(2.0, 2.0, -2.0) * quat.x * quat.zwx
+ REAL3(-2.0, 2.0, -2.0) * quat.y * quaternion.wzy;
normal = real3(0.0, 0.0, 1.0)
+ real3(2.0, 2.0, -2.0) * quat.x * quat.zwx
+ real3(-2.0, 2.0, -2.0) * quat.y * quaternion.wzy;
}
#endif // UNITY_QUATERNIONMATH_INCLUDED

18
ScriptableRenderPipeline/Core/ShaderLibrary/Random.hlsl


return JenkinsHash(v.x ^ JenkinsHash(v.y) ^ JenkinsHash(v.z) ^ JenkinsHash(v.w));
}
// Construct a REAL with REAL-open range [0, 1) using low 23 bits.
// Construct a real with real-open range [0, 1) using low 23 bits.
REAL ConstructFloat(int m) {
real ConstructFloat(int m) {
const int ieeeMantissa = 0x007FFFFF; // Binary FP32 mantissa bitmask
const int ieeeOne = 0x3F800000; // 1.0 in FP32 IEEE

REAL f = asfloat(m); // Range [1, 2)
real f = asfloat(m); // Range [1, 2)
REAL ConstructFloat(uint m)
real ConstructFloat(uint m)
// Pseudo-random value in REAL-open range [0, 1). The distribution is reasonably uniform.
// Pseudo-random value in real-open range [0, 1). The distribution is reasonably uniform.
REAL GenerateHashedRandomFloat(uint x)
real GenerateHashedRandomFloat(uint x)
REAL GenerateHashedRandomFloat(uint2 v)
real GenerateHashedRandomFloat(uint2 v)
REAL GenerateHashedRandomFloat(uint3 v)
real GenerateHashedRandomFloat(uint3 v)
REAL GenerateHashedRandomFloat(uint4 v)
real GenerateHashedRandomFloat(uint4 v)
{
return ConstructFloat(JenkinsHash(v));
}

32
ScriptableRenderPipeline/Core/ShaderLibrary/Refraction.hlsl


struct RefractionModelResult
{
REAL distance; // length of the transmission during refraction through the shape
REAL3 positionWS; // out ray position
REAL3 rayWS; // out ray direction
real distance; // length of the transmission during refraction through the shape
real3 positionWS; // out ray position
real3 rayWS; // out ray direction
RefractionModelResult RefractionModelSphere(REAL3 V, REAL3 positionWS, REAL3 normalWS, REAL ior, REAL thickness)
RefractionModelResult RefractionModelSphere(real3 V, real3 positionWS, real3 normalWS, real ior, real thickness)
{
// Sphere shape model:
// We approximate locally the shape of the object as sphere, that is tangent to the shape.

// First refraction (tangent sphere in)
// Refracted ray
REAL3 R1 = refract(-V, normalWS, 1.0 / ior);
real3 R1 = refract(-V, normalWS, 1.0 / ior);
REAL3 C = positionWS - normalWS * thickness * 0.5;
real3 C = positionWS - normalWS * thickness * 0.5;
REAL NoR1 = dot(normalWS, R1);
real NoR1 = dot(normalWS, R1);
REAL distance = -NoR1 * thickness;
real distance = -NoR1 * thickness;
REAL3 P1 = positionWS + R1 * distance;
real3 P1 = positionWS + R1 * distance;
REAL3 N1 = normalize(C - P1);
real3 N1 = normalize(C - P1);
REAL3 R2 = refract(R1, N1, ior);
REAL N1oR2 = dot(N1, R2);
REAL VoR1 = dot(V, R1);
real3 R2 = refract(R1, N1, ior);
real N1oR2 = dot(N1, R2);
real VoR1 = dot(V, R1);
RefractionModelResult result;
result.distance = distance;

return result;
}
RefractionModelResult RefractionModelPlane(REAL3 V, REAL3 positionWS, REAL3 normalWS, REAL ior, REAL thickness)
RefractionModelResult RefractionModelPlane(real3 V, real3 positionWS, real3 normalWS, real ior, real thickness)
{
// Plane shape model:
// We approximate locally the shape of the object as a plane with normal {normalWS} at {positionWS}

REAL3 R = refract(-V, normalWS, 1.0 / ior);
real3 R = refract(-V, normalWS, 1.0 / ior);
REAL distance = thickness / dot(R, -normalWS);
real distance = thickness / dot(R, -normalWS);
RefractionModelResult result;
result.distance = distance;

434
ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/Fibonacci.hlsl


// Computes a point using the Fibonacci sequence of length N.
// Input: Fib[N - 1], Fib[N - 2], and the index 'i' of the point.
// Ref: Efficient Quadrature Rules for Illumination Integrals
REAL2 Fibonacci2dSeq(REAL fibN1, REAL fibN2, uint i)
real2 Fibonacci2dSeq(real fibN1, real fibN2, uint i)
return REAL2(i / fibN1 + (0.5/ fibN1), frac(i * (fibN2 / fibN1)));
return real2(i / fibN1 + (0.5/ fibN1), frac(i * (fibN2 / fibN1)));
REAL2 Golden2dSeq(uint i, REAL n)
real2 Golden2dSeq(uint i, real n)
return REAL2(i / n + (0.5/ n), frac(i * rcp(GOLDEN_RATIO)));
return real2(i / n + (0.5/ n), frac(i * rcp(GOLDEN_RATIO)));
}
static const uint k_FibonacciSeq[] = {

static const REAL2 k_Fibonacci2dSeq21[] = {
REAL2(0.02380952, 0.00000000),
REAL2(0.07142857, 0.61904764),
REAL2(0.11904762, 0.23809528),
REAL2(0.16666667, 0.85714293),
REAL2(0.21428572, 0.47619057),
REAL2(0.26190478, 0.09523821),
REAL2(0.30952382, 0.71428585),
REAL2(0.35714287, 0.33333349),
REAL2(0.40476191, 0.95238113),
REAL2(0.45238096, 0.57142878),
REAL2(0.50000000, 0.19047642),
REAL2(0.54761904, 0.80952406),
REAL2(0.59523809, 0.42857170),
REAL2(0.64285713, 0.04761887),
REAL2(0.69047618, 0.66666698),
REAL2(0.73809522, 0.28571510),
REAL2(0.78571427, 0.90476227),
REAL2(0.83333331, 0.52380943),
REAL2(0.88095236, 0.14285755),
REAL2(0.92857140, 0.76190567),
REAL2(0.97619045, 0.38095284)
static const real2 k_Fibonacci2dSeq21[] = {
real2(0.02380952, 0.00000000),
real2(0.07142857, 0.61904764),
real2(0.11904762, 0.23809528),
real2(0.16666667, 0.85714293),
real2(0.21428572, 0.47619057),
real2(0.26190478, 0.09523821),
real2(0.30952382, 0.71428585),
real2(0.35714287, 0.33333349),
real2(0.40476191, 0.95238113),
real2(0.45238096, 0.57142878),
real2(0.50000000, 0.19047642),
real2(0.54761904, 0.80952406),
real2(0.59523809, 0.42857170),
real2(0.64285713, 0.04761887),
real2(0.69047618, 0.66666698),
real2(0.73809522, 0.28571510),
real2(0.78571427, 0.90476227),
real2(0.83333331, 0.52380943),
real2(0.88095236, 0.14285755),
real2(0.92857140, 0.76190567),
real2(0.97619045, 0.38095284)
static const REAL2 k_Fibonacci2dSeq34[] = {
REAL2(0.01470588, 0.00000000),
REAL2(0.04411765, 0.61764705),
REAL2(0.07352941, 0.23529410),
REAL2(0.10294118, 0.85294116),
REAL2(0.13235295, 0.47058821),
REAL2(0.16176471, 0.08823538),
REAL2(0.19117647, 0.70588231),
REAL2(0.22058824, 0.32352924),
REAL2(0.25000000, 0.94117641),
REAL2(0.27941176, 0.55882359),
REAL2(0.30882353, 0.17647076),
REAL2(0.33823529, 0.79411745),
REAL2(0.36764705, 0.41176462),
REAL2(0.39705881, 0.02941132),
REAL2(0.42647058, 0.64705849),
REAL2(0.45588234, 0.26470566),
REAL2(0.48529410, 0.88235283),
REAL2(0.51470590, 0.50000000),
REAL2(0.54411763, 0.11764717),
REAL2(0.57352942, 0.73529434),
REAL2(0.60294116, 0.35294151),
REAL2(0.63235295, 0.97058773),
REAL2(0.66176468, 0.58823490),
REAL2(0.69117647, 0.20588207),
REAL2(0.72058821, 0.82352924),
REAL2(0.75000000, 0.44117641),
REAL2(0.77941179, 0.05882263),
REAL2(0.80882353, 0.67646980),
REAL2(0.83823532, 0.29411697),
REAL2(0.86764705, 0.91176414),
REAL2(0.89705884, 0.52941132),
REAL2(0.92647058, 0.14705849),
REAL2(0.95588237, 0.76470566),
REAL2(0.98529410, 0.38235283)
static const real2 k_Fibonacci2dSeq34[] = {
real2(0.01470588, 0.00000000),
real2(0.04411765, 0.61764705),
real2(0.07352941, 0.23529410),
real2(0.10294118, 0.85294116),
real2(0.13235295, 0.47058821),
real2(0.16176471, 0.08823538),
real2(0.19117647, 0.70588231),
real2(0.22058824, 0.32352924),
real2(0.25000000, 0.94117641),
real2(0.27941176, 0.55882359),
real2(0.30882353, 0.17647076),
real2(0.33823529, 0.79411745),
real2(0.36764705, 0.41176462),
real2(0.39705881, 0.02941132),
real2(0.42647058, 0.64705849),
real2(0.45588234, 0.26470566),
real2(0.48529410, 0.88235283),
real2(0.51470590, 0.50000000),
real2(0.54411763, 0.11764717),
real2(0.57352942, 0.73529434),
real2(0.60294116, 0.35294151),
real2(0.63235295, 0.97058773),
real2(0.66176468, 0.58823490),
real2(0.69117647, 0.20588207),
real2(0.72058821, 0.82352924),
real2(0.75000000, 0.44117641),
real2(0.77941179, 0.05882263),
real2(0.80882353, 0.67646980),
real2(0.83823532, 0.29411697),
real2(0.86764705, 0.91176414),
real2(0.89705884, 0.52941132),
real2(0.92647058, 0.14705849),
real2(0.95588237, 0.76470566),
real2(0.98529410, 0.38235283)
static const REAL2 k_Fibonacci2dSeq55[] = {
REAL2(0.00909091, 0.00000000),
REAL2(0.02727273, 0.61818182),
REAL2(0.04545455, 0.23636365),
REAL2(0.06363636, 0.85454547),
REAL2(0.08181818, 0.47272730),
REAL2(0.10000000, 0.09090900),
REAL2(0.11818182, 0.70909095),
REAL2(0.13636364, 0.32727289),
REAL2(0.15454546, 0.94545460),
REAL2(0.17272727, 0.56363630),
REAL2(0.19090909, 0.18181801),
REAL2(0.20909090, 0.80000019),
REAL2(0.22727273, 0.41818190),
REAL2(0.24545455, 0.03636360),
REAL2(0.26363635, 0.65454578),
REAL2(0.28181818, 0.27272701),
REAL2(0.30000001, 0.89090919),
REAL2(0.31818181, 0.50909138),
REAL2(0.33636364, 0.12727261),
REAL2(0.35454544, 0.74545479),
REAL2(0.37272727, 0.36363602),
REAL2(0.39090911, 0.98181820),
REAL2(0.40909091, 0.60000038),
REAL2(0.42727274, 0.21818161),
REAL2(0.44545454, 0.83636379),
REAL2(0.46363637, 0.45454597),
REAL2(0.48181817, 0.07272720),
REAL2(0.50000000, 0.69090843),
REAL2(0.51818180, 0.30909157),
REAL2(0.53636366, 0.92727280),
REAL2(0.55454546, 0.54545403),
REAL2(0.57272726, 0.16363716),
REAL2(0.59090906, 0.78181839),
REAL2(0.60909092, 0.39999962),
REAL2(0.62727273, 0.01818275),
REAL2(0.64545453, 0.63636398),
REAL2(0.66363639, 0.25454521),
REAL2(0.68181819, 0.87272835),
REAL2(0.69999999, 0.49090958),
REAL2(0.71818179, 0.10909081),
REAL2(0.73636365, 0.72727203),
REAL2(0.75454545, 0.34545517),
REAL2(0.77272725, 0.96363640),
REAL2(0.79090911, 0.58181763),
REAL2(0.80909091, 0.20000076),
REAL2(0.82727271, 0.81818199),
REAL2(0.84545457, 0.43636322),
REAL2(0.86363637, 0.05454636),
REAL2(0.88181818, 0.67272758),
REAL2(0.89999998, 0.29090881),
REAL2(0.91818184, 0.90909195),
REAL2(0.93636364, 0.52727318),
REAL2(0.95454544, 0.14545441),
REAL2(0.97272730, 0.76363754),
REAL2(0.99090910, 0.38181686)
static const real2 k_Fibonacci2dSeq55[] = {
real2(0.00909091, 0.00000000),
real2(0.02727273, 0.61818182),
real2(0.04545455, 0.23636365),
real2(0.06363636, 0.85454547),
real2(0.08181818, 0.47272730),
real2(0.10000000, 0.09090900),
real2(0.11818182, 0.70909095),
real2(0.13636364, 0.32727289),
real2(0.15454546, 0.94545460),
real2(0.17272727, 0.56363630),
real2(0.19090909, 0.18181801),
real2(0.20909090, 0.80000019),
real2(0.22727273, 0.41818190),
real2(0.24545455, 0.03636360),
real2(0.26363635, 0.65454578),
real2(0.28181818, 0.27272701),
real2(0.30000001, 0.89090919),
real2(0.31818181, 0.50909138),
real2(0.33636364, 0.12727261),
real2(0.35454544, 0.74545479),
real2(0.37272727, 0.36363602),
real2(0.39090911, 0.98181820),
real2(0.40909091, 0.60000038),
real2(0.42727274, 0.21818161),
real2(0.44545454, 0.83636379),
real2(0.46363637, 0.45454597),
real2(0.48181817, 0.07272720),
real2(0.50000000, 0.69090843),
real2(0.51818180, 0.30909157),
real2(0.53636366, 0.92727280),
real2(0.55454546, 0.54545403),
real2(0.57272726, 0.16363716),
real2(0.59090906, 0.78181839),
real2(0.60909092, 0.39999962),
real2(0.62727273, 0.01818275),
real2(0.64545453, 0.63636398),
real2(0.66363639, 0.25454521),
real2(0.68181819, 0.87272835),
real2(0.69999999, 0.49090958),
real2(0.71818179, 0.10909081),
real2(0.73636365, 0.72727203),
real2(0.75454545, 0.34545517),
real2(0.77272725, 0.96363640),
real2(0.79090911, 0.58181763),
real2(0.80909091, 0.20000076),
real2(0.82727271, 0.81818199),
real2(0.84545457, 0.43636322),
real2(0.86363637, 0.05454636),
real2(0.88181818, 0.67272758),
real2(0.89999998, 0.29090881),
real2(0.91818184, 0.90909195),
real2(0.93636364, 0.52727318),
real2(0.95454544, 0.14545441),
real2(0.97272730, 0.76363754),
real2(0.99090910, 0.38181686)
static const REAL2 k_Fibonacci2dSeq89[] = {
REAL2(0.00561798, 0.00000000),
REAL2(0.01685393, 0.61797750),
REAL2(0.02808989, 0.23595500),
REAL2(0.03932584, 0.85393250),
REAL2(0.05056180, 0.47191000),
REAL2(0.06179775, 0.08988762),
REAL2(0.07303371, 0.70786500),
REAL2(0.08426967, 0.32584238),
REAL2(0.09550562, 0.94382000),
REAL2(0.10674157, 0.56179762),
REAL2(0.11797753, 0.17977524),
REAL2(0.12921348, 0.79775238),
REAL2(0.14044943, 0.41573000),
REAL2(0.15168539, 0.03370762),
REAL2(0.16292135, 0.65168476),
REAL2(0.17415731, 0.26966286),
REAL2(0.18539326, 0.88764000),
REAL2(0.19662921, 0.50561714),
REAL2(0.20786516, 0.12359524),
REAL2(0.21910113, 0.74157238),
REAL2(0.23033708, 0.35955048),
REAL2(0.24157304, 0.97752762),
REAL2(0.25280899, 0.59550476),
REAL2(0.26404494, 0.21348286),
REAL2(0.27528089, 0.83146000),
REAL2(0.28651685, 0.44943714),
REAL2(0.29775280, 0.06741524),
REAL2(0.30898875, 0.68539238),
REAL2(0.32022473, 0.30336952),
REAL2(0.33146068, 0.92134666),
REAL2(0.34269664, 0.53932571),
REAL2(0.35393259, 0.15730286),
REAL2(0.36516854, 0.77528000),
REAL2(0.37640449, 0.39325714),
REAL2(0.38764045, 0.01123428),
REAL2(0.39887640, 0.62921333),
REAL2(0.41011235, 0.24719048),
REAL2(0.42134830, 0.86516762),
REAL2(0.43258426, 0.48314476),
REAL2(0.44382024, 0.10112190),
REAL2(0.45505619, 0.71910095),
REAL2(0.46629214, 0.33707809),
REAL2(0.47752810, 0.95505524),
REAL2(0.48876405, 0.57303238),
REAL2(0.50000000, 0.19100952),
REAL2(0.51123595, 0.80898666),
REAL2(0.52247190, 0.42696571),
REAL2(0.53370786, 0.04494286),
REAL2(0.54494381, 0.66292000),
REAL2(0.55617976, 0.28089714),
REAL2(0.56741571, 0.89887428),
REAL2(0.57865167, 0.51685333),
REAL2(0.58988762, 0.13483047),
REAL2(0.60112357, 0.75280762),
REAL2(0.61235952, 0.37078476),
REAL2(0.62359548, 0.98876190),
REAL2(0.63483149, 0.60673904),
REAL2(0.64606744, 0.22471619),
REAL2(0.65730339, 0.84269333),
REAL2(0.66853935, 0.46067429),
REAL2(0.67977530, 0.07865143),
REAL2(0.69101125, 0.69662857),
REAL2(0.70224720, 0.31460571),
REAL2(0.71348315, 0.93258286),
REAL2(0.72471911, 0.55056000),
REAL2(0.73595506, 0.16853714),
REAL2(0.74719101, 0.78651428),
REAL2(0.75842696, 0.40449142),
REAL2(0.76966292, 0.02246857),
REAL2(0.78089887, 0.64044571),
REAL2(0.79213482, 0.25842667),
REAL2(0.80337077, 0.87640381),
REAL2(0.81460673, 0.49438095),
REAL2(0.82584268, 0.11235809),
REAL2(0.83707863, 0.73033524),
REAL2(0.84831458, 0.34831238),
REAL2(0.85955054, 0.96628952),
REAL2(0.87078649, 0.58426666),
REAL2(0.88202250, 0.20224380),
REAL2(0.89325845, 0.82022095),
REAL2(0.90449440, 0.43820190),
REAL2(0.91573036, 0.05617905),
REAL2(0.92696631, 0.67415619),
REAL2(0.93820226, 0.29213333),
REAL2(0.94943821, 0.91011047),
REAL2(0.96067417, 0.52808762),
REAL2(0.97191012, 0.14606476),
REAL2(0.98314607, 0.76404190),
REAL2(0.99438202, 0.38201904)
static const real2 k_Fibonacci2dSeq89[] = {
real2(0.00561798, 0.00000000),
real2(0.01685393, 0.61797750),
real2(0.02808989, 0.23595500),
real2(0.03932584, 0.85393250),
real2(0.05056180, 0.47191000),
real2(0.06179775, 0.08988762),
real2(0.07303371, 0.70786500),
real2(0.08426967, 0.32584238),
real2(0.09550562, 0.94382000),
real2(0.10674157, 0.56179762),
real2(0.11797753, 0.17977524),
real2(0.12921348, 0.79775238),
real2(0.14044943, 0.41573000),
real2(0.15168539, 0.03370762),
real2(0.16292135, 0.65168476),
real2(0.17415731, 0.26966286),
real2(0.18539326, 0.88764000),
real2(0.19662921, 0.50561714),
real2(0.20786516, 0.12359524),
real2(0.21910113, 0.74157238),
real2(0.23033708, 0.35955048),
real2(0.24157304, 0.97752762),
real2(0.25280899, 0.59550476),
real2(0.26404494, 0.21348286),
real2(0.27528089, 0.83146000),
real2(0.28651685, 0.44943714),
real2(0.29775280, 0.06741524),
real2(0.30898875, 0.68539238),
real2(0.32022473, 0.30336952),
real2(0.33146068, 0.92134666),
real2(0.34269664, 0.53932571),
real2(0.35393259, 0.15730286),
real2(0.36516854, 0.77528000),
real2(0.37640449, 0.39325714),
real2(0.38764045, 0.01123428),
real2(0.39887640, 0.62921333),
real2(0.41011235, 0.24719048),
real2(0.42134830, 0.86516762),
real2(0.43258426, 0.48314476),
real2(0.44382024, 0.10112190),
real2(0.45505619, 0.71910095),
real2(0.46629214, 0.33707809),
real2(0.47752810, 0.95505524),
real2(0.48876405, 0.57303238),
real2(0.50000000, 0.19100952),
real2(0.51123595, 0.80898666),
real2(0.52247190, 0.42696571),
real2(0.53370786, 0.04494286),
real2(0.54494381, 0.66292000),
real2(0.55617976, 0.28089714),
real2(0.56741571, 0.89887428),
real2(0.57865167, 0.51685333),
real2(0.58988762, 0.13483047),
real2(0.60112357, 0.75280762),
real2(0.61235952, 0.37078476),
real2(0.62359548, 0.98876190),
real2(0.63483149, 0.60673904),
real2(0.64606744, 0.22471619),
real2(0.65730339, 0.84269333),
real2(0.66853935, 0.46067429),
real2(0.67977530, 0.07865143),
real2(0.69101125, 0.69662857),
real2(0.70224720, 0.31460571),
real2(0.71348315, 0.93258286),
real2(0.72471911, 0.55056000),
real2(0.73595506, 0.16853714),
real2(0.74719101, 0.78651428),
real2(0.75842696, 0.40449142),
real2(0.76966292, 0.02246857),
real2(0.78089887, 0.64044571),
real2(0.79213482, 0.25842667),
real2(0.80337077, 0.87640381),
real2(0.81460673, 0.49438095),
real2(0.82584268, 0.11235809),
real2(0.83707863, 0.73033524),
real2(0.84831458, 0.34831238),
real2(0.85955054, 0.96628952),
real2(0.87078649, 0.58426666),
real2(0.88202250, 0.20224380),
real2(0.89325845, 0.82022095),
real2(0.90449440, 0.43820190),
real2(0.91573036, 0.05617905),
real2(0.92696631, 0.67415619),
real2(0.93820226, 0.29213333),
real2(0.94943821, 0.91011047),
real2(0.96067417, 0.52808762),
real2(0.97191012, 0.14606476),
real2(0.98314607, 0.76404190),
real2(0.99438202, 0.38201904)
REAL2 Fibonacci2d(uint i, uint sampleCount)
real2 Fibonacci2d(uint i, uint sampleCount)
{
switch (sampleCount)
{

}
// Returns the radius as the X coordinate, and the angle as the Y coordinate.
REAL2 SampleDiskFibonacci(uint i, uint sampleCount)
real2 SampleDiskFibonacci(uint i, uint sampleCount)
REAL2 f = Fibonacci2d(i, sampleCount);
return REAL2(f.x, TWO_PI * f.y);
real2 f = Fibonacci2d(i, sampleCount);
return real2(f.x, TWO_PI * f.y);
REAL2 SampleHemisphereFibonacci(uint i, uint sampleCount)
real2 SampleHemisphereFibonacci(uint i, uint sampleCount)
REAL2 f = Fibonacci2d(i, sampleCount);
return REAL2(1 - f.x, TWO_PI * f.y);
real2 f = Fibonacci2d(i, sampleCount);
return real2(1 - f.x, TWO_PI * f.y);
REAL2 SampleSphereFibonacci(uint i, uint sampleCount)
real2 SampleSphereFibonacci(uint i, uint sampleCount)
REAL2 f = Fibonacci2d(i, sampleCount);
return REAL2(1 - 2 * f.x, TWO_PI * f.y);
real2 f = Fibonacci2d(i, sampleCount);
return real2(1 - 2 * f.x, TWO_PI * f.y);
}
#endif // UNITY_FIBONACCI_INCLUDED

752
ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/Hammersley.hlsl


#endif
}
REAL VanDerCorputBase2(uint i)
real VanDerCorputBase2(uint i)
REAL2 Hammersley2dSeq(uint i, uint sequenceLength)
real2 Hammersley2dSeq(uint i, uint sequenceLength)
return REAL2(REAL(i) / REAL(sequenceLength), VanDerCorputBase2(i));
return real2(real(i) / real(sequenceLength), VanDerCorputBase2(i));
static const REAL2 k_Hammersley2dSeq16[] = {
REAL2(0.00000000, 0.00000000),
REAL2(0.06250000, 0.50000000),
REAL2(0.12500000, 0.25000000),
REAL2(0.18750000, 0.75000000),
REAL2(0.25000000, 0.12500000),
REAL2(0.31250000, 0.62500000),
REAL2(0.37500000, 0.37500000),
REAL2(0.43750000, 0.87500000),
REAL2(0.50000000, 0.06250000),
REAL2(0.56250000, 0.56250000),
REAL2(0.62500000, 0.31250000),
REAL2(0.68750000, 0.81250000),
REAL2(0.75000000, 0.18750000),
REAL2(0.81250000, 0.68750000),
REAL2(0.87500000, 0.43750000),
REAL2(0.93750000, 0.93750000)
static const real2 k_Hammersley2dSeq16[] = {
real2(0.00000000, 0.00000000),
real2(0.06250000, 0.50000000),
real2(0.12500000, 0.25000000),
real2(0.18750000, 0.75000000),
real2(0.25000000, 0.12500000),
real2(0.31250000, 0.62500000),
real2(0.37500000, 0.37500000),
real2(0.43750000, 0.87500000),
real2(0.50000000, 0.06250000),
real2(0.56250000, 0.56250000),
real2(0.62500000, 0.31250000),
real2(0.68750000, 0.81250000),
real2(0.75000000, 0.18750000),
real2(0.81250000, 0.68750000),
real2(0.87500000, 0.43750000),
real2(0.93750000, 0.93750000)
static const REAL2 k_Hammersley2dSeq32[] = {
REAL2(0.00000000, 0.00000000),
REAL2(0.03125000, 0.50000000),
REAL2(0.06250000, 0.25000000),
REAL2(0.09375000, 0.75000000),
REAL2(0.12500000, 0.12500000),
REAL2(0.15625000, 0.62500000),
REAL2(0.18750000, 0.37500000),
REAL2(0.21875000, 0.87500000),
REAL2(0.25000000, 0.06250000),
REAL2(0.28125000, 0.56250000),
REAL2(0.31250000, 0.31250000),
REAL2(0.34375000, 0.81250000),
REAL2(0.37500000, 0.18750000),
REAL2(0.40625000, 0.68750000),
REAL2(0.43750000, 0.43750000),
REAL2(0.46875000, 0.93750000),
REAL2(0.50000000, 0.03125000),
REAL2(0.53125000, 0.53125000),
REAL2(0.56250000, 0.28125000),
REAL2(0.59375000, 0.78125000),
REAL2(0.62500000, 0.15625000),
REAL2(0.65625000, 0.65625000),
REAL2(0.68750000, 0.40625000),
REAL2(0.71875000, 0.90625000),
REAL2(0.75000000, 0.09375000),
REAL2(0.78125000, 0.59375000),
REAL2(0.81250000, 0.34375000),
REAL2(0.84375000, 0.84375000),
REAL2(0.87500000, 0.21875000),
REAL2(0.90625000, 0.71875000),
REAL2(0.93750000, 0.46875000),
REAL2(0.96875000, 0.96875000)
static const real2 k_Hammersley2dSeq32[] = {
real2(0.00000000, 0.00000000),
real2(0.03125000, 0.50000000),
real2(0.06250000, 0.25000000),
real2(0.09375000, 0.75000000),
real2(0.12500000, 0.12500000),
real2(0.15625000, 0.62500000),
real2(0.18750000, 0.37500000),
real2(0.21875000, 0.87500000),
real2(0.25000000, 0.06250000),
real2(0.28125000, 0.56250000),
real2(0.31250000, 0.31250000),
real2(0.34375000, 0.81250000),
real2(0.37500000, 0.18750000),
real2(0.40625000, 0.68750000),
real2(0.43750000, 0.43750000),
real2(0.46875000, 0.93750000),
real2(0.50000000, 0.03125000),
real2(0.53125000, 0.53125000),
real2(0.56250000, 0.28125000),
real2(0.59375000, 0.78125000),
real2(0.62500000, 0.15625000),
real2(0.65625000, 0.65625000),
real2(0.68750000, 0.40625000),
real2(0.71875000, 0.90625000),
real2(0.75000000, 0.09375000),
real2(0.78125000, 0.59375000),
real2(0.81250000, 0.34375000),
real2(0.84375000, 0.84375000),
real2(0.87500000, 0.21875000),
real2(0.90625000, 0.71875000),
real2(0.93750000, 0.46875000),
real2(0.96875000, 0.96875000)
static const REAL2 k_Hammersley2dSeq64[] = {
REAL2(0.00000000, 0.00000000),
REAL2(0.01562500, 0.50000000),
REAL2(0.03125000, 0.25000000),
REAL2(0.04687500, 0.75000000),
REAL2(0.06250000, 0.12500000),
REAL2(0.07812500, 0.62500000),
REAL2(0.09375000, 0.37500000),
REAL2(0.10937500, 0.87500000),
REAL2(0.12500000, 0.06250000),
REAL2(0.14062500, 0.56250000),
REAL2(0.15625000, 0.31250000),
REAL2(0.17187500, 0.81250000),
REAL2(0.18750000, 0.18750000),
REAL2(0.20312500, 0.68750000),
REAL2(0.21875000, 0.43750000),
REAL2(0.23437500, 0.93750000),
REAL2(0.25000000, 0.03125000),
REAL2(0.26562500, 0.53125000),
REAL2(0.28125000, 0.28125000),
REAL2(0.29687500, 0.78125000),
REAL2(0.31250000, 0.15625000),
REAL2(0.32812500, 0.65625000),
REAL2(0.34375000, 0.40625000),
REAL2(0.35937500, 0.90625000),
REAL2(0.37500000, 0.09375000),
REAL2(0.39062500, 0.59375000),
REAL2(0.40625000, 0.34375000),
REAL2(0.42187500, 0.84375000),
REAL2(0.43750000, 0.21875000),
REAL2(0.45312500, 0.71875000),
REAL2(0.46875000, 0.46875000),
REAL2(0.48437500, 0.96875000),
REAL2(0.50000000, 0.01562500),
REAL2(0.51562500, 0.51562500),
REAL2(0.53125000, 0.26562500),
REAL2(0.54687500, 0.76562500),
REAL2(0.56250000, 0.14062500),
REAL2(0.57812500, 0.64062500),
REAL2(0.59375000, 0.39062500),
REAL2(0.60937500, 0.89062500),
REAL2(0.62500000, 0.07812500),
REAL2(0.64062500, 0.57812500),
REAL2(0.65625000, 0.32812500),
REAL2(0.67187500, 0.82812500),
REAL2(0.68750000, 0.20312500),
REAL2(0.70312500, 0.70312500),
REAL2(0.71875000, 0.45312500),
REAL2(0.73437500, 0.95312500),
REAL2(0.75000000, 0.04687500),
REAL2(0.76562500, 0.54687500),
REAL2(0.78125000, 0.29687500),
REAL2(0.79687500, 0.79687500),
REAL2(0.81250000, 0.17187500),
REAL2(0.82812500, 0.67187500),
REAL2(0.84375000, 0.42187500),
REAL2(0.85937500, 0.92187500),
REAL2(0.87500000, 0.10937500),
REAL2(0.89062500, 0.60937500),
REAL2(0.90625000, 0.35937500),
REAL2(0.92187500, 0.85937500),
REAL2(0.93750000, 0.23437500),
REAL2(0.95312500, 0.73437500),
REAL2(0.96875000, 0.48437500),
REAL2(0.98437500, 0.98437500)
static const real2 k_Hammersley2dSeq64[] = {
real2(0.00000000, 0.00000000),
real2(0.01562500, 0.50000000),
real2(0.03125000, 0.25000000),
real2(0.04687500, 0.75000000),
real2(0.06250000, 0.12500000),
real2(0.07812500, 0.62500000),
real2(0.09375000, 0.37500000),
real2(0.10937500, 0.87500000),
real2(0.12500000, 0.06250000),
real2(0.14062500, 0.56250000),
real2(0.15625000, 0.31250000),
real2(0.17187500, 0.81250000),
real2(0.18750000, 0.18750000),
real2(0.20312500, 0.68750000),
real2(0.21875000, 0.43750000),
real2(0.23437500, 0.93750000),
real2(0.25000000, 0.03125000),
real2(0.26562500, 0.53125000),
real2(0.28125000, 0.28125000),
real2(0.29687500, 0.78125000),
real2(0.31250000, 0.15625000),
real2(0.32812500, 0.65625000),
real2(0.34375000, 0.40625000),
real2(0.35937500, 0.90625000),
real2(0.37500000, 0.09375000),
real2(0.39062500, 0.59375000),
real2(0.40625000, 0.34375000),
real2(0.42187500, 0.84375000),
real2(0.43750000, 0.21875000),
real2(0.45312500, 0.71875000),
real2(0.46875000, 0.46875000),
real2(0.48437500, 0.96875000),
real2(0.50000000, 0.01562500),
real2(0.51562500, 0.51562500),
real2(0.53125000, 0.26562500),
real2(0.54687500, 0.76562500),
real2(0.56250000, 0.14062500),
real2(0.57812500, 0.64062500),
real2(0.59375000, 0.39062500),
real2(0.60937500, 0.89062500),
real2(0.62500000, 0.07812500),
real2(0.64062500, 0.57812500),
real2(0.65625000, 0.32812500),
real2(0.67187500, 0.82812500),
real2(0.68750000, 0.20312500),
real2(0.70312500, 0.70312500),
real2(0.71875000, 0.45312500),
real2(0.73437500, 0.95312500),
real2(0.75000000, 0.04687500),
real2(0.76562500, 0.54687500),
real2(0.78125000, 0.29687500),
real2(0.79687500, 0.79687500),
real2(0.81250000, 0.17187500),
real2(0.82812500, 0.67187500),
real2(0.84375000, 0.42187500),
real2(0.85937500, 0.92187500),
real2(0.87500000, 0.10937500),
real2(0.89062500, 0.60937500),
real2(0.90625000, 0.35937500),
real2(0.92187500, 0.85937500),
real2(0.93750000, 0.23437500),
real2(0.95312500, 0.73437500),
real2(0.96875000, 0.48437500),
real2(0.98437500, 0.98437500)
static const REAL2 k_Hammersley2dSeq256[] = {
REAL2(0.00000000, 0.00000000),
REAL2(0.00390625, 0.50000000),
REAL2(0.00781250, 0.25000000),
REAL2(0.01171875, 0.75000000),
REAL2(0.01562500, 0.12500000),
REAL2(0.01953125, 0.62500000),
REAL2(0.02343750, 0.37500000),
REAL2(0.02734375, 0.87500000),
REAL2(0.03125000, 0.06250000),
REAL2(0.03515625, 0.56250000),
REAL2(0.03906250, 0.31250000),
REAL2(0.04296875, 0.81250000),
REAL2(0.04687500, 0.18750000),
REAL2(0.05078125, 0.68750000),
REAL2(0.05468750, 0.43750000),
REAL2(0.05859375, 0.93750000),
REAL2(0.06250000, 0.03125000),
REAL2(0.06640625, 0.53125000),
REAL2(0.07031250, 0.28125000),
REAL2(0.07421875, 0.78125000),
REAL2(0.07812500, 0.15625000),
REAL2(0.08203125, 0.65625000),
REAL2(0.08593750, 0.40625000),
REAL2(0.08984375, 0.90625000),
REAL2(0.09375000, 0.09375000),
REAL2(0.09765625, 0.59375000),
REAL2(0.10156250, 0.34375000),
REAL2(0.10546875, 0.84375000),
REAL2(0.10937500, 0.21875000),
REAL2(0.11328125, 0.71875000),
REAL2(0.11718750, 0.46875000),
REAL2(0.12109375, 0.96875000),
REAL2(0.12500000, 0.01562500),
REAL2(0.12890625, 0.51562500),
REAL2(0.13281250, 0.26562500),
REAL2(0.13671875, 0.76562500),
REAL2(0.14062500, 0.14062500),
REAL2(0.14453125, 0.64062500),
REAL2(0.14843750, 0.39062500),
REAL2(0.15234375, 0.89062500),
REAL2(0.15625000, 0.07812500),
REAL2(0.16015625, 0.57812500),
REAL2(0.16406250, 0.32812500),
REAL2(0.16796875, 0.82812500),
REAL2(0.17187500, 0.20312500),
REAL2(0.17578125, 0.70312500),
REAL2(0.17968750, 0.45312500),
REAL2(0.18359375, 0.95312500),
REAL2(0.18750000, 0.04687500),
REAL2(0.19140625, 0.54687500),
REAL2(0.19531250, 0.29687500),
REAL2(0.19921875, 0.79687500),
REAL2(0.20312500, 0.17187500),
REAL2(0.20703125, 0.67187500),
REAL2(0.21093750, 0.42187500),
REAL2(0.21484375, 0.92187500),
REAL2(0.21875000, 0.10937500),
REAL2(0.22265625, 0.60937500),
REAL2(0.22656250, 0.35937500),
REAL2(0.23046875, 0.85937500),
REAL2(0.23437500, 0.23437500),
REAL2(0.23828125, 0.73437500),
REAL2(0.24218750, 0.48437500),
REAL2(0.24609375, 0.98437500),
REAL2(0.25000000, 0.00781250),
REAL2(0.25390625, 0.50781250),
REAL2(0.25781250, 0.25781250),
REAL2(0.26171875, 0.75781250),
REAL2(0.26562500, 0.13281250),
REAL2(0.26953125, 0.63281250),
REAL2(0.27343750, 0.38281250),
REAL2(0.27734375, 0.88281250),
REAL2(0.28125000, 0.07031250),
REAL2(0.28515625, 0.57031250),
REAL2(0.28906250, 0.32031250),
REAL2(0.29296875, 0.82031250),
REAL2(0.29687500, 0.19531250),
REAL2(0.30078125, 0.69531250),
REAL2(0.30468750, 0.44531250),
REAL2(0.30859375, 0.94531250),
REAL2(0.31250000, 0.03906250),
REAL2(0.31640625, 0.53906250),
REAL2(0.32031250, 0.28906250),
REAL2(0.32421875, 0.78906250),
REAL2(0.32812500, 0.16406250),
REAL2(0.33203125, 0.66406250),
REAL2(0.33593750, 0.41406250),
REAL2(0.33984375, 0.91406250),
REAL2(0.34375000, 0.10156250),
REAL2(0.34765625, 0.60156250),
REAL2(0.35156250, 0.35156250),
REAL2(0.35546875, 0.85156250),
REAL2(0.35937500, 0.22656250),
REAL2(0.36328125, 0.72656250),
REAL2(0.36718750, 0.47656250),
REAL2(0.37109375, 0.97656250),
REAL2(0.37500000, 0.02343750),
REAL2(0.37890625, 0.52343750),
REAL2(0.38281250, 0.27343750),
REAL2(0.38671875, 0.77343750),
REAL2(0.39062500, 0.14843750),
REAL2(0.39453125, 0.64843750),
REAL2(0.39843750, 0.39843750),
REAL2(0.40234375, 0.89843750),
REAL2(0.40625000, 0.08593750),
REAL2(0.41015625, 0.58593750),
REAL2(0.41406250, 0.33593750),
REAL2(0.41796875, 0.83593750),
REAL2(0.42187500, 0.21093750),
REAL2(0.42578125, 0.71093750),
REAL2(0.42968750, 0.46093750),
REAL2(0.43359375, 0.96093750),
REAL2(0.43750000, 0.05468750),
REAL2(0.44140625, 0.55468750),
REAL2(0.44531250, 0.30468750),
REAL2(0.44921875, 0.80468750),
REAL2(0.45312500, 0.17968750),
REAL2(0.45703125, 0.67968750),
REAL2(0.46093750, 0.42968750),
REAL2(0.46484375, 0.92968750),
REAL2(0.46875000, 0.11718750),
REAL2(0.47265625, 0.61718750),
REAL2(0.47656250, 0.36718750),
REAL2(0.48046875, 0.86718750),
REAL2(0.48437500, 0.24218750),
REAL2(0.48828125, 0.74218750),
REAL2(0.49218750, 0.49218750),
REAL2(0.49609375, 0.99218750),
REAL2(0.50000000, 0.00390625),
REAL2(0.50390625, 0.50390625),
REAL2(0.50781250, 0.25390625),
REAL2(0.51171875, 0.75390625),
REAL2(0.51562500, 0.12890625),
REAL2(0.51953125, 0.62890625),
REAL2(0.52343750, 0.37890625),
REAL2(0.52734375, 0.87890625),
REAL2(0.53125000, 0.06640625),
REAL2(0.53515625, 0.56640625),
REAL2(0.53906250, 0.31640625),
REAL2(0.54296875, 0.81640625),
REAL2(0.54687500, 0.19140625),
REAL2(0.55078125, 0.69140625),
REAL2(0.55468750, 0.44140625),
REAL2(0.55859375, 0.94140625),
REAL2(0.56250000, 0.03515625),
REAL2(0.56640625, 0.53515625),
REAL2(0.57031250, 0.28515625),
REAL2(0.57421875, 0.78515625),
REAL2(0.57812500, 0.16015625),
REAL2(0.58203125, 0.66015625),
REAL2(0.58593750, 0.41015625),
REAL2(0.58984375, 0.91015625),
REAL2(0.59375000, 0.09765625),
REAL2(0.59765625, 0.59765625),
REAL2(0.60156250, 0.34765625),
REAL2(0.60546875, 0.84765625),
REAL2(0.60937500, 0.22265625),
REAL2(0.61328125, 0.72265625),
REAL2(0.61718750, 0.47265625),
REAL2(0.62109375, 0.97265625),
REAL2(0.62500000, 0.01953125),
REAL2(0.62890625, 0.51953125),
REAL2(0.63281250, 0.26953125),
REAL2(0.63671875, 0.76953125),
REAL2(0.64062500, 0.14453125),
REAL2(0.64453125, 0.64453125),
REAL2(0.64843750, 0.39453125),
REAL2(0.65234375, 0.89453125),
REAL2(0.65625000, 0.08203125),
REAL2(0.66015625, 0.58203125),
REAL2(0.66406250, 0.33203125),
REAL2(0.66796875, 0.83203125),
REAL2(0.67187500, 0.20703125),
REAL2(0.67578125, 0.70703125),
REAL2(0.67968750, 0.45703125),
REAL2(0.68359375, 0.95703125),
REAL2(0.68750000, 0.05078125),
REAL2(0.69140625, 0.55078125),
REAL2(0.69531250, 0.30078125),
REAL2(0.69921875, 0.80078125),
REAL2(0.70312500, 0.17578125),
REAL2(0.70703125, 0.67578125),
REAL2(0.71093750, 0.42578125),
REAL2(0.71484375, 0.92578125),
REAL2(0.71875000, 0.11328125),
REAL2(0.72265625, 0.61328125),
REAL2(0.72656250, 0.36328125),
REAL2(0.73046875, 0.86328125),
REAL2(0.73437500, 0.23828125),
REAL2(0.73828125, 0.73828125),
REAL2(0.74218750, 0.48828125),
REAL2(0.74609375, 0.98828125),
REAL2(0.75000000, 0.01171875),
REAL2(0.75390625, 0.51171875),
REAL2(0.75781250, 0.26171875),
REAL2(0.76171875, 0.76171875),
REAL2(0.76562500, 0.13671875),
REAL2(0.76953125, 0.63671875),
REAL2(0.77343750, 0.38671875),
REAL2(0.77734375, 0.88671875),
REAL2(0.78125000, 0.07421875),
REAL2(0.78515625, 0.57421875),
REAL2(0.78906250, 0.32421875),
REAL2(0.79296875, 0.82421875),
REAL2(0.79687500, 0.19921875),
REAL2(0.80078125, 0.69921875),
REAL2(0.80468750, 0.44921875),
REAL2(0.80859375, 0.94921875),
REAL2(0.81250000, 0.04296875),
REAL2(0.81640625, 0.54296875),
REAL2(0.82031250, 0.29296875),
REAL2(0.82421875, 0.79296875),
REAL2(0.82812500, 0.16796875),
REAL2(0.83203125, 0.66796875),
REAL2(0.83593750, 0.41796875),
REAL2(0.83984375, 0.91796875),
REAL2(0.84375000, 0.10546875),
REAL2(0.84765625, 0.60546875),
REAL2(0.85156250, 0.35546875),
REAL2(0.85546875, 0.85546875),
REAL2(0.85937500, 0.23046875),
REAL2(0.86328125, 0.73046875),
REAL2(0.86718750, 0.48046875),
REAL2(0.87109375, 0.98046875),
REAL2(0.87500000, 0.02734375),
REAL2(0.87890625, 0.52734375),
REAL2(0.88281250, 0.27734375),
REAL2(0.88671875, 0.77734375),
REAL2(0.89062500, 0.15234375),
REAL2(0.89453125, 0.65234375),
REAL2(0.89843750, 0.40234375),
REAL2(0.90234375, 0.90234375),
REAL2(0.90625000, 0.08984375),
REAL2(0.91015625, 0.58984375),
REAL2(0.91406250, 0.33984375),
REAL2(0.91796875, 0.83984375),
REAL2(0.92187500, 0.21484375),
REAL2(0.92578125, 0.71484375),
REAL2(0.92968750, 0.46484375),
REAL2(0.93359375, 0.96484375),
REAL2(0.93750000, 0.05859375),
REAL2(0.94140625, 0.55859375),
REAL2(0.94531250, 0.30859375),
REAL2(0.94921875, 0.80859375),
REAL2(0.95312500, 0.18359375),
REAL2(0.95703125, 0.68359375),
REAL2(0.96093750, 0.43359375),
REAL2(0.96484375, 0.93359375),
REAL2(0.96875000, 0.12109375),
REAL2(0.97265625, 0.62109375),
REAL2(0.97656250, 0.37109375),
REAL2(0.98046875, 0.87109375),
REAL2(0.98437500, 0.24609375),
REAL2(0.98828125, 0.74609375),
REAL2(0.99218750, 0.49609375),
REAL2(0.99609375, 0.99609375)
static const real2 k_Hammersley2dSeq256[] = {
real2(0.00000000, 0.00000000),
real2(0.00390625, 0.50000000),
real2(0.00781250, 0.25000000),
real2(0.01171875, 0.75000000),
real2(0.01562500, 0.12500000),
real2(0.01953125, 0.62500000),
real2(0.02343750, 0.37500000),
real2(0.02734375, 0.87500000),
real2(0.03125000, 0.06250000),
real2(0.03515625, 0.56250000),
real2(0.03906250, 0.31250000),
real2(0.04296875, 0.81250000),
real2(0.04687500, 0.18750000),
real2(0.05078125, 0.68750000),
real2(0.05468750, 0.43750000),
real2(0.05859375, 0.93750000),
real2(0.06250000, 0.03125000),
real2(0.06640625, 0.53125000),
real2(0.07031250, 0.28125000),
real2(0.07421875, 0.78125000),
real2(0.07812500, 0.15625000),
real2(0.08203125, 0.65625000),
real2(0.08593750, 0.40625000),
real2(0.08984375, 0.90625000),
real2(0.09375000, 0.09375000),
real2(0.09765625, 0.59375000),
real2(0.10156250, 0.34375000),
real2(0.10546875, 0.84375000),
real2(0.10937500, 0.21875000),
real2(0.11328125, 0.71875000),
real2(0.11718750, 0.46875000),
real2(0.12109375, 0.96875000),
real2(0.12500000, 0.01562500),
real2(0.12890625, 0.51562500),
real2(0.13281250, 0.26562500),
real2(0.13671875, 0.76562500),
real2(0.14062500, 0.14062500),
real2(0.14453125, 0.64062500),
real2(0.14843750, 0.39062500),
real2(0.15234375, 0.89062500),
real2(0.15625000, 0.07812500),
real2(0.16015625, 0.57812500),
real2(0.16406250, 0.32812500),
real2(0.16796875, 0.82812500),
real2(0.17187500, 0.20312500),
real2(0.17578125, 0.70312500),
real2(0.17968750, 0.45312500),
real2(0.18359375, 0.95312500),
real2(0.18750000, 0.04687500),
real2(0.19140625, 0.54687500),
real2(0.19531250, 0.29687500),
real2(0.19921875, 0.79687500),
real2(0.20312500, 0.17187500),
real2(0.20703125, 0.67187500),
real2(0.21093750, 0.42187500),
real2(0.21484375, 0.92187500),
real2(0.21875000, 0.10937500),
real2(0.22265625, 0.60937500),
real2(0.22656250, 0.35937500),
real2(0.23046875, 0.85937500),
real2(0.23437500, 0.23437500),
real2(0.23828125, 0.73437500),
real2(0.24218750, 0.48437500),
real2(0.24609375, 0.98437500),
real2(0.25000000, 0.00781250),
real2(0.25390625, 0.50781250),
real2(0.25781250, 0.25781250),
real2(0.26171875, 0.75781250),
real2(0.26562500, 0.13281250),
real2(0.26953125, 0.63281250),
real2(0.27343750, 0.38281250),
real2(0.27734375, 0.88281250),
real2(0.28125000, 0.07031250),
real2(0.28515625, 0.57031250),
real2(0.28906250, 0.32031250),
real2(0.29296875, 0.82031250),
real2(0.29687500, 0.19531250),
real2(0.30078125, 0.69531250),
real2(0.30468750, 0.44531250),
real2(0.30859375, 0.94531250),
real2(0.31250000, 0.03906250),
real2(0.31640625, 0.53906250),
real2(0.32031250, 0.28906250),
real2(0.32421875, 0.78906250),
real2(0.32812500, 0.16406250),
real2(0.33203125, 0.66406250),
real2(0.33593750, 0.41406250),
real2(0.33984375, 0.91406250),
real2(0.34375000, 0.10156250),
real2(0.34765625, 0.60156250),
real2(0.35156250, 0.35156250),
real2(0.35546875, 0.85156250),
real2(0.35937500, 0.22656250),
real2(0.36328125, 0.72656250),
real2(0.36718750, 0.47656250),
real2(0.37109375, 0.97656250),
real2(0.37500000, 0.02343750),
real2(0.37890625, 0.52343750),
real2(0.38281250, 0.27343750),
real2(0.38671875, 0.77343750),
real2(0.39062500, 0.14843750),
real2(0.39453125, 0.64843750),
real2(0.39843750, 0.39843750),
real2(0.40234375, 0.89843750),
real2(0.40625000, 0.08593750),
real2(0.41015625, 0.58593750),
real2(0.41406250, 0.33593750),
real2(0.41796875, 0.83593750),
real2(0.42187500, 0.21093750),
real2(0.42578125, 0.71093750),
real2(0.42968750, 0.46093750),
real2(0.43359375, 0.96093750),
real2(0.43750000, 0.05468750),
real2(0.44140625, 0.55468750),
real2(0.44531250, 0.30468750),
real2(0.44921875, 0.80468750),
real2(0.45312500, 0.17968750),
real2(0.45703125, 0.67968750),
real2(0.46093750, 0.42968750),
real2(0.46484375, 0.92968750),
real2(0.46875000, 0.11718750),
real2(0.47265625, 0.61718750),
real2(0.47656250, 0.36718750),
real2(0.48046875, 0.86718750),
real2(0.48437500, 0.24218750),
real2(0.48828125, 0.74218750),
real2(0.49218750, 0.49218750),
real2(0.49609375, 0.99218750),
real2(0.50000000, 0.00390625),
real2(0.50390625, 0.50390625),
real2(0.50781250, 0.25390625),
real2(0.51171875, 0.75390625),
real2(0.51562500, 0.12890625),
real2(0.51953125, 0.62890625),
real2(0.52343750, 0.37890625),
real2(0.52734375, 0.87890625),
real2(0.53125000, 0.06640625),
real2(0.53515625, 0.56640625),
real2(0.53906250, 0.31640625),
real2(0.54296875, 0.81640625),
real2(0.54687500, 0.19140625),
real2(0.55078125, 0.69140625),
real2(0.55468750, 0.44140625),
real2(0.55859375, 0.94140625),
real2(0.56250000, 0.03515625),
real2(0.56640625, 0.53515625),
real2(0.57031250, 0.28515625),
real2(0.57421875, 0.78515625),
real2(0.57812500, 0.16015625),
real2(0.58203125, 0.66015625),
real2(0.58593750, 0.41015625),
real2(0.58984375, 0.91015625),
real2(0.59375000, 0.09765625),
real2(0.59765625, 0.59765625),
real2(0.60156250, 0.34765625),
real2(0.60546875, 0.84765625),
real2(0.60937500, 0.22265625),
real2(0.61328125, 0.72265625),
real2(0.61718750, 0.47265625),
real2(0.62109375, 0.97265625),
real2(0.62500000, 0.01953125),
real2(0.62890625, 0.51953125),
real2(0.63281250, 0.26953125),
real2(0.63671875, 0.76953125),
real2(0.64062500, 0.14453125),
real2(0.64453125, 0.64453125),
real2(0.64843750, 0.39453125),
real2(0.65234375, 0.89453125),
real2(0.65625000, 0.08203125),
real2(0.66015625, 0.58203125),
real2(0.66406250, 0.33203125),
real2(0.66796875, 0.83203125),
real2(0.67187500, 0.20703125),
real2(0.67578125, 0.70703125),
real2(0.67968750, 0.45703125),
real2(0.68359375, 0.95703125),
real2(0.68750000, 0.05078125),
real2(0.69140625, 0.55078125),
real2(0.69531250, 0.30078125),
real2(0.69921875, 0.80078125),
real2(0.70312500, 0.17578125),
real2(0.70703125, 0.67578125),
real2(0.71093750, 0.42578125),
real2(0.71484375, 0.92578125),
real2(0.71875000, 0.11328125),
real2(0.72265625, 0.61328125),
real2(0.72656250, 0.36328125),
real2(0.73046875, 0.86328125),
real2(0.73437500, 0.23828125),
real2(0.73828125, 0.73828125),
real2(0.74218750, 0.48828125),
real2(0.74609375, 0.98828125),
real2(0.75000000, 0.01171875),
real2(0.75390625, 0.51171875),
real2(0.75781250, 0.26171875),
real2(0.76171875, 0.76171875),
real2(0.76562500, 0.13671875),
real2(0.76953125, 0.63671875),
real2(0.77343750, 0.38671875),
real2(0.77734375, 0.88671875),
real2(0.78125000, 0.07421875),
real2(0.78515625, 0.57421875),
real2(0.78906250, 0.32421875),
real2(0.79296875, 0.82421875),
real2(0.79687500, 0.19921875),
real2(0.80078125, 0.69921875),
real2(0.80468750, 0.44921875),
real2(0.80859375, 0.94921875),
real2(0.81250000, 0.04296875),
real2(0.81640625, 0.54296875),
real2(0.82031250, 0.29296875),
real2(0.82421875, 0.79296875),
real2(0.82812500, 0.16796875),
real2(0.83203125, 0.66796875),
real2(0.83593750, 0.41796875),
real2(0.83984375, 0.91796875),
real2(0.84375000, 0.10546875),
real2(0.84765625, 0.60546875),
real2(0.85156250, 0.35546875),
real2(0.85546875, 0.85546875),
real2(0.85937500, 0.23046875),
real2(0.86328125, 0.73046875),
real2(0.86718750, 0.48046875),
real2(0.87109375, 0.98046875),
real2(0.87500000, 0.02734375),
real2(0.87890625, 0.52734375),
real2(0.88281250, 0.27734375),
real2(0.88671875, 0.77734375),
real2(0.89062500, 0.15234375),
real2(0.89453125, 0.65234375),
real2(0.89843750, 0.40234375),
real2(0.90234375, 0.90234375),
real2(0.90625000, 0.08984375),
real2(0.91015625, 0.58984375),
real2(0.91406250, 0.33984375),
real2(0.91796875, 0.83984375),
real2(0.92187500, 0.21484375),
real2(0.92578125, 0.71484375),
real2(0.92968750, 0.46484375),
real2(0.93359375, 0.96484375),
real2(0.93750000, 0.05859375),
real2(0.94140625, 0.55859375),
real2(0.94531250, 0.30859375),
real2(0.94921875, 0.80859375),
real2(0.95312500, 0.18359375),
real2(0.95703125, 0.68359375),
real2(0.96093750, 0.43359375),
real2(0.96484375, 0.93359375),
real2(0.96875000, 0.12109375),
real2(0.97265625, 0.62109375),
real2(0.97656250, 0.37109375),
real2(0.98046875, 0.87109375),
real2(0.98437500, 0.24609375),
real2(0.98828125, 0.74609375),
real2(0.99218750, 0.49609375),
real2(0.99609375, 0.99609375)
REAL2 Hammersley2d(uint i, uint sampleCount)
real2 Hammersley2d(uint i, uint sampleCount)
{
switch (sampleCount)
{

16
ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/SampleUVMapping.hlsl


struct UVMapping
{
int mappingType;
REAL2 uv; // Current uv or planar uv
real2 uv; // Current uv or planar uv
REAL2 uvZY;
REAL2 uvXZ;
REAL2 uvXY;
real2 uvZY;
real2 uvXZ;
real2 uvXY;
REAL3 normalWS; // vertex normal
REAL3 triplanarWeights;
real3 normalWS; // vertex normal
real3 triplanarWeights;
REAL3 tangentWS;
REAL3 bitangentWS;
real3 tangentWS;
real3 bitangentWS;
// TODO: store also object normal map for object triplanar
#endif
};

6
ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl


// Also we use multiple inclusion to handle the various variation for lod and bias
// param can be unused, lod or bias
REAL4 ADD_FUNC_SUFFIX(SampleUVMapping)(TEXTURE2D_ARGS(textureName, samplerName), UVMapping uvMapping, REAL param)
real4 ADD_FUNC_SUFFIX(SampleUVMapping)(TEXTURE2D_ARGS(textureName, samplerName), UVMapping uvMapping, real param)
REAL3 triplanarWeights = uvMapping.triplanarWeights;
REAL4 val = REAL4(0.0, 0.0, 0.0, 0.0);
real3 triplanarWeights = uvMapping.triplanarWeights;
real4 val = real4(0.0, 0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvZY, param);

22
ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/SampleUVMappingNormalInternal.hlsl


REAL3 ADD_FUNC_SUFFIX(ADD_NORMAL_FUNC_SUFFIX(SampleUVMappingNormal))(TEXTURE2D_ARGS(textureName, samplerName), UVMapping uvMapping, REAL scale, REAL param)
real3 ADD_FUNC_SUFFIX(ADD_NORMAL_FUNC_SUFFIX(SampleUVMappingNormal))(TEXTURE2D_ARGS(textureName, samplerName), UVMapping uvMapping, real scale, real param)
REAL3 triplanarWeights = uvMapping.triplanarWeights;
real3 triplanarWeights = uvMapping.triplanarWeights;
REAL2 derivXplane;
REAL2 derivYPlane;
REAL2 derivZPlane;
derivXplane = derivYPlane = derivZPlane = REAL2(0.0, 0.0);
real2 derivXplane;
real2 derivYPlane;
real2 derivZPlane;
derivXplane = derivYPlane = derivZPlane = real2(0.0, 0.0);
if (triplanarWeights.x > 0.0)
derivXplane = triplanarWeights.x * UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvZY, param), scale);

// Assume derivXplane, derivYPlane and derivZPlane sampled using (z,y), (z,x) and (x,y) respectively.
// TODO: Check with morten convention! Do it follow ours ?
REAL3 volumeGrad = REAL3(derivZPlane.x + derivYPlane.y, derivZPlane.y + derivXplane.y, derivXplane.x + derivYPlane.x);
real3 volumeGrad = real3(derivZPlane.x + derivYPlane.y, derivZPlane.y + derivXplane.y, derivXplane.x + derivYPlane.x);
REAL3 val = REAL3(0.0, 0.0, 0.0);
real3 val = real3(0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvZY, param), scale);

else if (uvMapping.mappingType == UV_MAPPING_PLANAR)
{
// Note: Planar is on uv coordinate (and not uvXZ)
REAL2 derivYPlane = UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param), scale);
real2 derivYPlane = UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param), scale);
REAL3 volumeGrad = REAL3(derivYPlane.y, 0.0, derivYPlane.x);
real3 volumeGrad = real3(derivYPlane.y, 0.0, derivYPlane.x);
return SurfaceGradientFromVolumeGradient(uvMapping.normalWS, volumeGrad);
}
#endif

REAL2 deriv = UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param), scale);
real2 deriv = UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param), scale);
return SurfaceGradientFromTBN(deriv, uvMapping.tangentWS, uvMapping.bitangentWS);
#else
return UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param), scale);

208
ScriptableRenderPipeline/Core/ShaderLibrary/Sampling/Sampling.hlsl


#include "Fibonacci.hlsl"
#include "Hammersley.hlsl"
REAL Hash(uint s)
real Hash(uint s)
{
s = s ^ 2747636419u;
s = s * 2654435769u;

s = s * 2654435769u;
return REAL(s) / 4294967295.0;
return real(s) / 4294967295.0;
REAL2 InitRandom(REAL2 input)
real2 InitRandom(real2 input)
REAL2 r;
real2 r;
r.x = Hash(uint(input.x * 4294967295.0));
r.y = Hash(uint(input.y * 4294967295.0));

//-----------------------------------------------------------------------------
// Transforms the unit vector from the spherical to the Cartesian (right-handed, Z up) coordinate.
REAL3 SphericalToCartesian(REAL phi, REAL cosTheta)
real3 SphericalToCartesian(real phi, real cosTheta)
REAL sinPhi, cosPhi;
real sinPhi, cosPhi;
REAL sinTheta = sqrt(saturate(1.0 - cosTheta * cosTheta));
real sinTheta = sqrt(saturate(1.0 - cosTheta * cosTheta));
return REAL3(sinTheta * cosPhi, sinTheta * sinPhi, cosTheta);
return real3(sinTheta * cosPhi, sinTheta * sinPhi, cosTheta);
REAL3 TransformGLtoDX(REAL3 v)
real3 TransformGLtoDX(real3 v)
REAL3 ConvertEquiarealToCubemap(REAL u, REAL v)
real3 ConvertEquiarealToCubemap(real u, real v)
REAL phi = TWO_PI - TWO_PI * u;
REAL cosTheta = 1.0 - 2.0 * v;
real phi = TWO_PI - TWO_PI * u;
real cosTheta = 1.0 - 2.0 * v;
REAL2 CubemapTexelToNVC(uint2 unPositionTXS, uint cubemapSize)
real2 CubemapTexelToNVC(uint2 unPositionTXS, uint cubemapSize)
return 2.0 * REAL2(unPositionTXS) / REAL(max(cubemapSize - 1, 1)) - 1.0;
return 2.0 * real2(unPositionTXS) / real(max(cubemapSize - 1, 1)) - 1.0;
static const REAL3 CUBEMAP_FACE_BASIS_MAPPING[6][3] =
static const real3 CUBEMAP_FACE_BASIS_MAPPING[6][3] =
REAL3(0.0, 0.0, -1.0),
REAL3(0.0, -1.0, 0.0),
REAL3(1.0, 0.0, 0.0)
real3(0.0, 0.0, -1.0),
real3(0.0, -1.0, 0.0),
real3(1.0, 0.0, 0.0)
REAL3(0.0, 0.0, 1.0),
REAL3(0.0, -1.0, 0.0),
REAL3(-1.0, 0.0, 0.0)
real3(0.0, 0.0, 1.0),
real3(0.0, -1.0, 0.0),
real3(-1.0, 0.0, 0.0)
REAL3(1.0, 0.0, 0.0),
REAL3(0.0, 0.0, 1.0),
REAL3(0.0, 1.0, 0.0)
real3(1.0, 0.0, 0.0),
real3(0.0, 0.0, 1.0),
real3(0.0, 1.0, 0.0)
REAL3(1.0, 0.0, 0.0),
REAL3(0.0, 0.0, -1.0),
REAL3(0.0, -1.0, 0.0)
real3(1.0, 0.0, 0.0),
real3(0.0, 0.0, -1.0),
real3(0.0, -1.0, 0.0)
REAL3(1.0, 0.0, 0.0),
REAL3(0.0, -1.0, 0.0),
REAL3(0.0, 0.0, 1.0)
real3(1.0, 0.0, 0.0),
real3(0.0, -1.0, 0.0),
real3(0.0, 0.0, 1.0)
REAL3(-1.0, 0.0, 0.0),
REAL3(0.0, -1.0, 0.0),
REAL3(0.0, 0.0, -1.0)
real3(-1.0, 0.0, 0.0),
real3(0.0, -1.0, 0.0),
real3(0.0, 0.0, -1.0)
REAL3 CubemapTexelToDirection(REAL2 positionNVC, uint faceId)
real3 CubemapTexelToDirection(real2 positionNVC, uint faceId)
REAL3 dir = CUBEMAP_FACE_BASIS_MAPPING[faceId][0] * positionNVC.x
real3 dir = CUBEMAP_FACE_BASIS_MAPPING[faceId][0] * positionNVC.x
+ CUBEMAP_FACE_BASIS_MAPPING[faceId][1] * positionNVC.y
+ CUBEMAP_FACE_BASIS_MAPPING[faceId][2];

// Performs uniform sampling of the unit disk.
// Ref: PBRT v3, p. 777.
REAL2 SampleDiskUniform(REAL u1, REAL u2)
real2 SampleDiskUniform(real u1, real u2)
REAL r = sqrt(u1);
REAL phi = TWO_PI * u2;
real r = sqrt(u1);
real phi = TWO_PI * u2;
REAL sinPhi, cosPhi;
real sinPhi, cosPhi;
return r * REAL2(cosPhi, sinPhi);
return r * real2(cosPhi, sinPhi);
REAL3 SampleHemisphereCosine(REAL u1, REAL u2)
real3 SampleHemisphereCosine(real u1, real u2)
REAL3 localL;
real3 localL;
// Since we don't really care about the area distortion,
// we substitute uniform disk sampling for the concentric one.

return localL;
}
REAL3 SampleHemisphereUniform(REAL u1, REAL u2)
real3 SampleHemisphereUniform(real u1, real u2)
REAL phi = TWO_PI * u2;
REAL cosTheta = 1.0 - u1;
real phi = TWO_PI * u2;
real cosTheta = 1.0 - u1;
REAL3 SampleSphereUniform(REAL u1, REAL u2)
real3 SampleSphereUniform(real u1, real u2)
REAL phi = TWO_PI * u2;
REAL cosTheta = 1.0 - 2.0 * u1;
real phi = TWO_PI * u2;
real cosTheta = 1.0 - 2.0 * u1;
void SampleSphere( REAL2 u,
REAL4x4 localToWorld,
REAL radius,
out REAL lightPdf,
out REAL3 P,
out REAL3 Ns)
void SampleSphere( real2 u,
real4x4 localToWorld,
real radius,
out real lightPdf,
out real3 P,
out real3 Ns)
REAL u1 = u.x;
REAL u2 = u.y;
real u1 = u.x;
real u2 = u.y;
Ns = SampleSphereUniform(u1, u2);

lightPdf = 1.0 / (FOUR_PI * radius * radius);
}
void SampleHemisphere( REAL2 u,
REAL4x4 localToWorld,
REAL radius,
out REAL lightPdf,
out REAL3 P,
out REAL3 Ns)
void SampleHemisphere( real2 u,
real4x4 localToWorld,
real radius,
out real lightPdf,
out real3 P,
out real3 Ns)
REAL u1 = u.x;
REAL u2 = u.y;
real u1 = u.x;
real u2 = u.y;
// Random point at hemisphere surface
Ns = -SampleHemisphereUniform(u1, u2); // We want the y down hemisphere

P = mul(REAL4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (REAL3x3)(localToWorld));
P = mul(real4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (real3x3)(localToWorld));
// pdf is inverse of area
lightPdf = 1.0 / (TWO_PI * radius * radius);

void SampleCylinder(REAL2 u,
REAL4x4 localToWorld,
REAL radius,
REAL width,
out REAL lightPdf,
out REAL3 P,
out REAL3 Ns)
void SampleCylinder(real2 u,
real4x4 localToWorld,
real radius,
real width,
out real lightPdf,
out real3 P,
out real3 Ns)
REAL u1 = u.x;
REAL u2 = u.y;
real u1 = u.x;
real u2 = u.y;
REAL t = (u1 - 0.5) * width;
REAL theta = 2.0 * PI * u2;
REAL cosTheta = cos(theta);
REAL sinTheta = sin(theta);
real t = (u1 - 0.5) * width;
real theta = 2.0 * PI * u2;
real cosTheta = cos(theta);
real sinTheta = sin(theta);
P = REAL3(t, radius * cosTheta, radius * sinTheta);
Ns = normalize(REAL3(0.0, cosTheta, sinTheta));
P = real3(t, radius * cosTheta, radius * sinTheta);
Ns = normalize(real3(0.0, cosTheta, sinTheta));
P = mul(REAL4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (REAL3x3)(localToWorld));
P = mul(real4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (real3x3)(localToWorld));
void SampleRectangle( REAL2 u,
REAL4x4 localToWorld,
REAL width,
REAL height,
out REAL lightPdf,
out REAL3 P,
out REAL3 Ns)
void SampleRectangle( real2 u,
real4x4 localToWorld,
real width,
real height,
out real lightPdf,
out real3 P,
out real3 Ns)
P = REAL3((u.x - 0.5) * width, (u.y - 0.5) * height, 0);
Ns = REAL3(0, 0, -1); // Light point backward (-Z)
P = real3((u.x - 0.5) * width, (u.y - 0.5) * height, 0);
Ns = real3(0, 0, -1); // Light point backward (-Z)
P = mul(REAL4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (REAL3x3)(localToWorld));
P = mul(real4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (real3x3)(localToWorld));
void SampleDisk(REAL2 u,
REAL4x4 localToWorld,
REAL radius,
out REAL lightPdf,
out REAL3 P,
out REAL3 Ns)
void SampleDisk(real2 u,
real4x4 localToWorld,
real radius,
out real lightPdf,
out real3 P,
out real3 Ns)
P = REAL3(radius * SampleDiskUniform(u.x, u.y), 0);
Ns = REAL3(0.0, 0.0, -1.0); // Light point backward (-Z)
P = real3(radius * SampleDiskUniform(u.x, u.y), 0);
Ns = real3(0.0, 0.0, -1.0); // Light point backward (-Z)
P = mul(REAL4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (REAL3x3)(localToWorld));
P = mul(real4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (real3x3)(localToWorld));
// pdf is inverse of area
lightPdf = 1.0 / (PI * radius * radius);

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


#include "../ShadowMoments.hlsl"
#if MAX_MSAA > 1
Texture2DMS<REAL> depthTex;
Texture2DMS<real> depthTex;
Texture2D<REAL> depthTex;
Texture2D<real> depthTex;
uniform REAL4 blurWeightsStorage[3]; // Unity expects REAL arrays to be tightly packed
static REAL blurWeights[12] = (REAL[12])blurWeightsStorage;
uniform real4 blurWeightsStorage[3]; // Unity expects real arrays to be tightly packed
static real blurWeights[12] = (real[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
REAL2 DepthToMoments( REAL depth )
real2 DepthToMoments( real depth )
return REAL2( depth, depth * depth );
return real2( depth, depth * depth );
uniform REAL evsmExponent;
uniform real evsmExponent;
REAL2 DepthToMoments( REAL depth )
real2 DepthToMoments( real depth )
REAL2 moments = ShadowMoments_WarpDepth( depth, evsmExponent.xx );
return REAL2( moments.x, moments.x * moments.x );
real2 moments = ShadowMoments_WarpDepth( depth, evsmExponent.xx );
return real2( moments.x, moments.x * moments.x );
uniform REAL2 evsmExponents;
uniform real2 evsmExponents;
REAL4 DepthToMoments( REAL depth )
real4 DepthToMoments( real depth )
REAL2 moments = ShadowMoments_WarpDepth( depth, evsmExponents );
return REAL4( moments.xy, moments.xy * moments.xy );
real2 moments = ShadowMoments_WarpDepth( depth, evsmExponents );
return real4( moments.xy, moments.xy * moments.xy );
REAL4 DepthToMoments( REAL depth )
real4 DepthToMoments( real depth )
REAL dsq = depth * depth;
return REAL4( depth, dsq, depth * dsq, dsq * dsq );
real dsq = depth * depth;
return real4( depth, dsq, depth * dsq, dsq * dsq );
}
}
#else

#define BLUR_BORDER (BLUR_SIZE / 2)
#define LDS_STRIDE (THREADS + BLUR_BORDER + BLUR_BORDER)
#define moment_t MERGE_NAME( REAL, SHADOW_MOMENTS )
#define moment_t MERGE_NAME( real, SHADOW_MOMENTS )
groupshared REAL moments1[THREADS * LDS_STRIDE]; // contains the blurred first moment
groupshared REAL moments2[THREADS * LDS_STRIDE]; // contains the blurred second moment
groupshared REAL moments3[THREADS * LDS_STRIDE]; // contains the blurred third moment
groupshared REAL moments4[THREADS * LDS_STRIDE]; // contains the blurred fourth moment
groupshared real moments1[THREADS * LDS_STRIDE]; // contains the blurred first moment
groupshared real moments2[THREADS * LDS_STRIDE]; // contains the blurred second moment
groupshared real moments3[THREADS * LDS_STRIDE]; // contains the blurred third moment
groupshared real moments4[THREADS * LDS_STRIDE]; // contains the blurred fourth moment
groupshared REAL sampleWeights[MAX_MSAA];
groupshared REAL sumWeights;
groupshared real sampleWeights[MAX_MSAA];
groupshared real sumWeights;
int getLDSIdx( int2 pos, int stride )
{

uint width, height, sampleCnt;
depthTex.GetDimensions( width, height, sampleCnt );
sampleCnt = clamp( sampleCnt, 2, MAX_MSAA );
REAL sampleCntRcp = 1.0 / sampleCnt;
real sampleCntRcp = 1.0 / sampleCnt;
REAL2 spos = depthTex.GetSamplePosition( groupThreadId.x );
real2 spos = depthTex.GetSamplePosition( groupThreadId.x );
REAL sum = 0.0;
real sum = 0.0;
for( uint i = 0; i < sampleCnt; i++ )
sum += sampleWeights[i];
sumWeights = 1.0 / sum;

[loop]
for( uint is = 0; is < sampleCnt; is++ )
{
REAL depth = depthTex.Load( min( srcIdx, validSrc ), is ).x;
real 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.

writeToShared( avgMoments, int2( ldsIdx.x, groupThreadId.y ), LDS_STRIDE );
#else
REAL depth = depthTex.Load( int3( min( srcIdx, validSrc ), 0 ) ).x;
real 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.

24
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/Shadow.hlsl


SHADOW_DEFINE_SAMPLING_FUNCS( SHADOWCONTEXT_MAX_TEX2DARRAY, SHADOWCONTEXT_MAX_TEXCUBEARRAY, SHADOWCONTEXT_MAX_COMPSAMPLER, SHADOWCONTEXT_MAX_SAMPLER )
// helper function to extract shadowmap data from the ShadowData struct
void UnpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx, out REAL slice )
void UnpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx, out real slice )
slice = (REAL)(shadowmapId & 0xffff);
slice = (real)(shadowmapId & 0xffff);
}
void UnpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx )
{

void UnpackShadowmapId( uint shadowmapId, out REAL slice )
void UnpackShadowmapId( uint shadowmapId, out real slice )
slice = (REAL)(shadowmapId & 0xffff);
slice = (real)(shadowmapId & 0xffff);
}
void UnpackShadowType( uint packedShadowType, out uint shadowType, out uint shadowAlgorithm )

}
// shadow sampling prototypes
REAL GetPunctualShadowAttenuation( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int shadowDataIndex, REAL4 L );
REAL GetPunctualShadowAttenuation( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int shadowDataIndex, REAL4 L, REAL2 positionSS );
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L );
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L, real2 positionSS );
REAL GetDirectionalShadowAttenuation( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int shadowDataIndex, REAL3 L );
REAL GetDirectionalShadowAttenuation( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int shadowDataIndex, REAL3 L, REAL2 positionSS );
real GetDirectionalShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L );
real GetDirectionalShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L, real2 positionSS );
REAL GetPunctualShadowAttenuation( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int shadowDataIndex, REAL4 L )
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L )
REAL GetPunctualShadowAttenuation( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int shadowDataIndex, REAL4 L, REAL2 positionSS )
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L, real2 positionSS )
{
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}

REAL GetDirectionalShadowAttenuation( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int shadowDataIndex, REAL3 L )
real GetDirectionalShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L )
REAL GetDirectionalShadowAttenuation( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int shadowDataIndex, REAL3 L, REAL2 positionSS )
real GetDirectionalShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L, real2 positionSS )
{
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}

320
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl


// Helper function to offset depth based on the surface normal and light direction.
// If the light hits the surface perpendicularly there will be no offset.
REAL3 EvalShadow_NormalBias( REAL3 normalWS, REAL NoL, REAL2 texelSize, REAL normalBias )
real3 EvalShadow_NormalBias( real3 normalWS, real NoL, real2 texelSize, real normalBias )
REAL3 EvalShadow_GetTexcoords( ShadowData sd, REAL3 positionWS, out REAL3 posNDC, bool clampToRect )
real3 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS, out real3 posNDC, bool clampToRect )
REAL4 posCS = mul(REAL4(positionWS, 1.0), sd.worldToShadow);
real4 posCS = mul(real4(positionWS, 1.0), sd.worldToShadow);
REAL3 posTC = posNDC * 0.5 + 0.5;
real3 posTC = posNDC * 0.5 + 0.5;
posTC.xy = clampToRect ? clamp( posTC.xy, sd.texelSizeRcp.zw*0.5, 1.0.xx - sd.texelSizeRcp.zw*0.5 ) : posTC.xy;
posTC.xy = posTC.xy * sd.scaleOffset.xy + sd.scaleOffset.zw;
#if UNITY_REVERSED_Z

}
REAL3 EvalShadow_GetTexcoords( ShadowData sd, REAL3 positionWS )
real3 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS )
REAL3 ndc;
real3 ndc;
uint2 EvalShadow_GetTexcoords( ShadowData sd, REAL3 positionWS, out REAL2 closestSampleNDC )
uint2 EvalShadow_GetTexcoords( ShadowData sd, real3 positionWS, out real2 closestSampleNDC )
REAL4 posCS = mul( REAL4( positionWS, 1.0 ), sd.worldToShadow );
REAL2 posNDC = posCS.xy / posCS.w;
real4 posCS = mul( real4( positionWS, 1.0 ), sd.worldToShadow );
real2 posNDC = posCS.xy / posCS.w;
REAL2 posTC = posNDC * 0.5 + 0.5;
real2 posTC = posNDC * 0.5 + 0.5;
int EvalShadow_GetCubeFaceID( REAL3 dir )
int EvalShadow_GetCubeFaceID( real3 dir )
REAL3 adir = abs(dir);
real3 adir = abs(dir);
// +Z -Z
int faceIndex = dir.z > 0.0 ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z;

//
// Point shadows
//
REAL EvalShadow_PointDepth( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int index, REAL4 L )
real EvalShadow_PointDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real4 L )
REAL3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
REAL3 lpos = positionWS + L.xyz * L.w;
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
real3 lpos = positionWS + L.xyz * L.w;
positionWS = biased_posWS;
int faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1;
// load the right shadow data for the current face

positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
REAL slice;
real slice;
REAL EvalShadow_PointDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, REAL3 positionWS, REAL3 normalWS, int index, REAL4 L ) \
real EvalShadow_PointDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real4 L ) \
REAL3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
REAL3 lpos = positionWS + L.xyz * L.w; \
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
real3 lpos = positionWS + L.xyz * L.w; \
positionWS = biased_posWS; \
int faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1; \
/* load the right shadow data for the current face */ \

positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
REAL slice; \
real slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}

//
// Spot shadows
//
REAL EvalShadow_SpotDepth( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int index, REAL3 L )
real EvalShadow_SpotDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L )
{
// load the right shadow data for the current face
ShadowData sd = shadowContext.shadowDatas[index];

// get shadowmap texcoords
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
REAL slice;
real slice;
REAL EvalShadow_SpotDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, REAL3 positionWS, REAL3 normalWS, int index, REAL3 L ) \
real EvalShadow_SpotDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
{ \
/* load the right shadow data for the current face */ \
ShadowData sd = shadowContext.shadowDatas[index]; \

/* get shadowmap texcoords */ \
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
REAL slice; \
real slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}

//
// Punctual shadows for Point and Spot
//
REAL EvalShadow_PunctualDepth( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int index, REAL4 L )
real EvalShadow_PunctualDepth( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real4 L )
{
// load the right shadow data for the current face
int faceIndex = 0;

[branch]
if( shadowType == GPUSHADOWTYPE_POINT )
{
REAL3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
REAL3 lpos = positionWS + L.xyz * L.w;
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
real3 lpos = positionWS + L.xyz * L.w;
positionWS = biased_posWS;
faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1;
}

sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
// get shadowmap texcoords
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
REAL slice;
real slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );

REAL EvalShadow_PunctualDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, REAL3 positionWS, REAL3 normalWS, int index, REAL4 L ) \
real EvalShadow_PunctualDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real4 L ) \
{ \
/* load the right shadow data for the current face */ \
int faceIndex = 0; \

[branch] \
if( shadowType == GPUSHADOWTYPE_POINT ) \
{ \
REAL3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
REAL3 lpos = positionWS + L.xyz * L.w; \
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
real3 lpos = positionWS + L.xyz * L.w; \
positionWS = biased_posWS; \
faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1; \
} \

sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* get shadowmap texcoords */ \
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
REAL slice; \
real slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}

#define kMaxShadowCascades 4
#define SHADOW_REPEAT_CASCADE( _x ) _x, _x, _x, _x
int EvalShadow_GetSplitSphereIndexForDirshadows( REAL3 positionWS, REAL4 dirShadowSplitSpheres[4], out REAL relDistance )
int EvalShadow_GetSplitSphereIndexForDirshadows( real3 positionWS, real4 dirShadowSplitSpheres[4], out real relDistance )
REAL3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
REAL3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
REAL3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
REAL3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
REAL4 distances2 = REAL4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
real3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
real3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
real3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
real3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
real4 distances2 = real4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
REAL4 dirShadowSplitSphereSqRadii;
real4 dirShadowSplitSphereSqRadii;
REAL4 weights = REAL4( distances2 < dirShadowSplitSphereSqRadii );
real4 weights = real4( distances2 < dirShadowSplitSphereSqRadii );
int idx = int( 4.0 - dot( weights, REAL4( 4.0, 3.0, 2.0, 1.0 ) ) );
int idx = int( 4.0 - dot( weights, real4( 4.0, 3.0, 2.0, 1.0 ) ) );
int EvalShadow_GetSplitSphereIndexForDirshadows( REAL3 positionWS, REAL4 dirShadowSplitSpheres[4] )
int EvalShadow_GetSplitSphereIndexForDirshadows( real3 positionWS, real4 dirShadowSplitSpheres[4] )
REAL relDist;
real relDist;
uint EvalShadow_LoadSplitSpheres( ShadowContext shadowContext, int index, out REAL4 splitSpheres[4] )
uint EvalShadow_LoadSplitSpheres( ShadowContext shadowContext, int index, out real4 splitSpheres[4] )
{
uint offset = GetPayloadOffset( shadowContext.shadowDatas[index] );

return offset + 4;
}
REAL EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int index, REAL3 L )
real EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L )
REAL4 dirShadowSplitSpheres[4];
real4 dirShadowSplitSpheres[4];
REAL relDistance;
real relDistance;
REAL4 scales = asfloat( shadowContext.payloads[payloadOffset] );
real4 scales = asfloat( shadowContext.payloads[payloadOffset] );
REAL4 borders = asfloat( shadowContext.payloads[payloadOffset] );
real4 borders = asfloat( shadowContext.payloads[payloadOffset] );
REAL border = borders[shadowSplitIndex];
REAL alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
real border = borders[shadowSplitIndex];
real alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
REAL3 orig_pos = positionWS;
real3 orig_pos = positionWS;
REAL3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
REAL3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz );
REAL3 wposDir = normalize( -splitSphere + positionWS );
REAL cascDot = dot( cascadeDir, wposDir );
real3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
real3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz );
real3 wposDir = normalize( -splitSphere + positionWS );
real cascDot = dot( cascadeDir, wposDir );
REAL3 posNDC;
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true );
real3 posNDC;
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true );
REAL slice;
real slice;
REAL shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
REAL shadow1 = 1.0;
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
real shadow1 = 1.0;
shadowSplitIndex++;
if( shadowSplitIndex < kMaxShadowCascades )

}
#define EvalShadow_CascadedDepth_( _samplerType ) \
REAL EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, REAL3 positionWS, REAL3 normalWS, int index, REAL3 L ) \
real EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
REAL4 dirShadowSplitSpheres[kMaxShadowCascades]; \
real4 dirShadowSplitSpheres[kMaxShadowCascades]; \
REAL relDistance; \
real relDistance; \
REAL4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
real4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
REAL4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
real4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
REAL border = borders[shadowSplitIndex]; \
REAL alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
real border = borders[shadowSplitIndex]; \
real alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
REAL3 orig_pos = positionWS; \
real3 orig_pos = positionWS; \
REAL3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
REAL3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz ); \
REAL3 wposDir = normalize( -splitSphere + positionWS ); \
REAL cascDot = dot( cascadeDir, wposDir ); \
real3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
real3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( shadowSplitIndex+1, kMaxShadowCascades-1 )].xyz ); \
real3 wposDir = normalize( -splitSphere + positionWS ); \
real cascDot = dot( cascadeDir, wposDir ); \
REAL3 posNDC; \
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
real3 posNDC; \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
REAL slice; \
real slice; \
REAL shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
REAL shadow1 = 1.0; \
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
real shadow1 = 1.0; \
\
shadowSplitIndex++; \
if( shadowSplitIndex < kMaxShadowCascades ) \

return shadow; \
} \
\
REAL EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, REAL3 positionWS, REAL3 normalWS, int index, REAL3 L ) \
real EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
{ \
uint shadowAlgorithms[kMaxShadowCascades] = { SHADOW_REPEAT_CASCADE( shadowAlgorithm ) }; \
return EvalShadow_CascadedDepth_Blend( shadowContext, shadowAlgorithms, tex, samp, positionWS, normalWS, index, L ); \

#undef EvalShadow_CascadedDepth_
REAL EvalShadow_hash12( REAL2 pos )
real EvalShadow_hash12( real2 pos )
REAL3 p3 = frac( pos.xyx * REAL3( 443.8975, 397.2973, 491.1871 ) );
real3 p3 = frac( pos.xyx * real3( 443.8975, 397.2973, 491.1871 ) );
REAL EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int index, REAL3 L )
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L )
REAL4 dirShadowSplitSpheres[kMaxShadowCascades];
real4 dirShadowSplitSpheres[kMaxShadowCascades];
REAL relDistance;
real relDistance;
REAL4 scales = asfloat( shadowContext.payloads[payloadOffset] );
real4 scales = asfloat( shadowContext.payloads[payloadOffset] );
REAL4 borders = asfloat( shadowContext.payloads[payloadOffset] );
real4 borders = asfloat( shadowContext.payloads[payloadOffset] );
REAL border = borders[shadowSplitIndex];
REAL alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
real border = borders[shadowSplitIndex];
real alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border );
REAL3 orig_pos = positionWS;
real3 orig_pos = positionWS;
REAL3 posNDC;
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true );
real3 posNDC;
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true );
REAL3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
REAL3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( 3, shadowSplitIndex + 1 )].xyz );
REAL3 wposDir = normalize( -splitSphere + positionWS );
REAL cascDot = dot( cascadeDir, wposDir );
real3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz;
real3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[min( 3, shadowSplitIndex + 1 )].xyz );
real3 wposDir = normalize( -splitSphere + positionWS );
real cascDot = dot( cascadeDir, wposDir );
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) );
if( shadowSplitIndex < nextSplit && step( EvalShadow_hash12( posTC.xy ), alpha ) )

}
// sample the texture
uint texIdx, sampIdx;
REAL slice;
real slice;
REAL shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
REAL EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, REAL3 positionWS, REAL3 normalWS, int index, REAL3 L ) \
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithms[kMaxShadowCascades], Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
REAL4 dirShadowSplitSpheres[kMaxShadowCascades]; \
real4 dirShadowSplitSpheres[kMaxShadowCascades]; \
REAL relDistance; \
real relDistance; \
REAL4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
real4 scales = asfloat( shadowContext.payloads[payloadOffset] ); \
REAL4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
real4 borders = asfloat( shadowContext.payloads[payloadOffset] ); \
REAL border = borders[shadowSplitIndex]; \
REAL alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
real border = borders[shadowSplitIndex]; \
real alpha = border <= 0.0 ? 0.0 : saturate( (relDistance - (1.0 - border)) / border ); \
REAL3 orig_pos = positionWS; \
real3 orig_pos = positionWS; \
REAL3 posNDC; \
REAL3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
real3 posNDC; \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, posNDC, true ); \
REAL3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
REAL3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[nextSplit].xyz ); \
REAL3 wposDir = normalize( -splitSphere + positionWS ); \
REAL cascDot = dot( cascadeDir, wposDir ); \
real3 splitSphere = dirShadowSplitSpheres[shadowSplitIndex].xyz; \
real3 cascadeDir = normalize( -splitSphere + dirShadowSplitSpheres[nextSplit].xyz ); \
real3 wposDir = normalize( -splitSphere + positionWS ); \
real cascDot = dot( cascadeDir, wposDir ); \
alpha = cascDot > 0.0 ? alpha : lerp( alpha, 0.0, saturate( -cascDot * 4.0 ) ); \
\
if( shadowSplitIndex != nextSplit && step( EvalShadow_hash12( posTC.xy ), alpha ) ) \

posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
} \
/* sample the texture */ \
REAL slice; \
real slice; \
REAL shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithms[shadowSplitIndex], tex, samp ); \
REAL EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, REAL3 positionWS, REAL3 normalWS, int index, REAL3 L ) \
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \
{ \
uint shadowAlgorithms[kMaxShadowCascades] = { SHADOW_REPEAT_CASCADE( shadowAlgorithm ) }; \
return EvalShadow_CascadedDepth_Dither( shadowContext, shadowAlgorithms, tex, samp, positionWS, normalWS, index, L ); \

//------------------------------------------------------------------------------------------------------------------------------------
REAL3 EvalShadow_GetClosestSample_Point( ShadowContext shadowContext, REAL3 positionWS, int index, REAL3 L )
real3 EvalShadow_GetClosestSample_Point( ShadowContext shadowContext, real3 positionWS, int index, real3 L )
{
// get the algorithm
ShadowData sd = shadowContext.shadowDatas[index];

REAL4 closestNDC = { 0,0,0,1 };
real4 closestNDC = { 0,0,0,1 };
REAL slice;
real slice;
REAL4 closestWS = mul( closestNDC, sd.shadowToWorld );
real4 closestWS = mul( closestNDC, sd.shadowToWorld );
REAL3 EvalShadow_GetClosestSample_Point( ShadowContext shadowContext, Texture2DArray tex, REAL3 positionWS, int index, REAL3 L )
real3 EvalShadow_GetClosestSample_Point( ShadowContext shadowContext, Texture2DArray tex, real3 positionWS, int index, real3 L )
{
// get the algorithm
ShadowData sd = shadowContext.shadowDatas[index];

REAL4 closestNDC = { 0,0,0,1 };
real4 closestNDC = { 0,0,0,1 };
REAL slice;
real slice;
REAL4 closestWS = mul( closestNDC, sd.shadowToWorld );
real4 closestWS = mul( closestNDC, sd.shadowToWorld );
REAL3 EvalShadow_GetClosestSample_Spot( ShadowContext shadowContext, REAL3 positionWS, int index )
real3 EvalShadow_GetClosestSample_Spot( ShadowContext shadowContext, real3 positionWS, int index )
REAL4 closestNDC = { 0,0,0,1 };
real4 closestNDC = { 0,0,0,1 };
REAL slice;
real slice;
REAL4 closestWS = mul( closestNDC, sd.shadowToWorld );
real4 closestWS = mul( closestNDC, sd.shadowToWorld );
REAL3 EvalShadow_GetClosestSample_Spot( ShadowContext shadowContext, Texture2DArray tex, REAL3 positionWS, int index )
real3 EvalShadow_GetClosestSample_Spot( ShadowContext shadowContext, Texture2DArray tex, real3 positionWS, int index )
REAL4 closestNDC = { 0,0,0,1 };
real4 closestNDC = { 0,0,0,1 };
REAL slice;
real slice;
REAL4 closestWS = mul( closestNDC, sd.shadowToWorld );
real4 closestWS = mul( closestNDC, sd.shadowToWorld );
REAL3 EvalShadow_GetClosestSample_Punctual( ShadowContext shadowContext, REAL3 positionWS, int index, REAL3 L )
real3 EvalShadow_GetClosestSample_Punctual( ShadowContext shadowContext, real3 positionWS, int index, real3 L )
{
// get the algorithm
ShadowData sd = shadowContext.shadowDatas[index];

int faceIndex = shadowType == GPUSHADOWTYPE_POINT ? (EvalShadow_GetCubeFaceID( L ) + 1) : 0;
sd = shadowContext.shadowDatas[index + faceIndex];
REAL4 closestNDC = { 0,0,0,1 };
real4 closestNDC = { 0,0,0,1 };
REAL slice;
real slice;
REAL4 closestWS = mul( closestNDC, sd.shadowToWorld );
real4 closestWS = mul( closestNDC, sd.shadowToWorld );
REAL3 EvalShadow_GetClosestSample_Punctual( ShadowContext shadowContext, Texture2DArray tex, REAL3 positionWS, int index, REAL3 L )
real3 EvalShadow_GetClosestSample_Punctual( ShadowContext shadowContext, Texture2DArray tex, real3 positionWS, int index, real3 L )
{
// get the algorithm
ShadowData sd = shadowContext.shadowDatas[index];

int faceIndex = shadowType == GPUSHADOWTYPE_POINT ? (EvalShadow_GetCubeFaceID( L ) + 1) : 0;
sd = shadowContext.shadowDatas[index + faceIndex];
REAL4 closestNDC = { 0,0,0,1 };
real4 closestNDC = { 0,0,0,1 };
REAL slice;
real slice;
REAL4 closestWS = mul( closestNDC, sd.shadowToWorld );
real4 closestWS = mul( closestNDC, sd.shadowToWorld );
REAL3 EvalShadow_GetClosestSample_Cascade( ShadowContext shadowContext, REAL3 positionWS, REAL3 normalWS, int index, REAL4 L )
real3 EvalShadow_GetClosestSample_Cascade( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real4 L )
REAL4 dirShadowSplitSpheres[4];
real4 dirShadowSplitSpheres[4];
REAL relDistance;
real relDistance;
REAL4 scales = asfloat( shadowContext.payloads[payloadOffset] );
real4 scales = asfloat( shadowContext.payloads[payloadOffset] );
REAL4 borders = asfloat( shadowContext.payloads[payloadOffset] );
real4 borders = asfloat( shadowContext.payloads[payloadOffset] );
REAL4 closestNDC = { 0,0,0,1 };
real4 closestNDC = { 0,0,0,1 };
REAL slice;
real slice;
REAL4 closestWS = mul( closestNDC, sd.shadowToWorld );
real4 closestWS = mul( closestNDC, sd.shadowToWorld );
REAL3 EvalShadow_GetClosestSample_Cascade( ShadowContext shadowContext, Texture2DArray tex, REAL3 positionWS, REAL3 normalWS, int index, REAL4 L )
real3 EvalShadow_GetClosestSample_Cascade( ShadowContext shadowContext, Texture2DArray tex, real3 positionWS, real3 normalWS, int index, real4 L )
REAL4 dirShadowSplitSpheres[4];
real4 dirShadowSplitSpheres[4];
REAL relDistance;
real relDistance;
REAL4 scales = asfloat( shadowContext.payloads[payloadOffset] );
real4 scales = asfloat( shadowContext.payloads[payloadOffset] );
REAL4 borders = asfloat( shadowContext.payloads[payloadOffset] );
real4 borders = asfloat( shadowContext.payloads[payloadOffset] );
REAL4 closestNDC = { 0,0,0,1 };
real4 closestNDC = { 0,0,0,1 };
REAL slice;
real slice;
REAL4 closestWS = mul( closestNDC, sd.shadowToWorld );
real4 closestWS = mul( closestNDC, sd.shadowToWorld );
return closestWS.xyz / closestWS.w;
}

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


// Chebychev's inequality (one-tailed version)
// P( x >= t ) <= pmax(t) := sigma^2 / (sigma^2 + (t - u)^2)
// for us t is depth, u is E(x) i.d. the blurred depth
REAL ShadowMoments_ChebyshevsInequality( REAL2 moments, REAL depth, REAL minVariance, REAL lightLeakBias )
real ShadowMoments_ChebyshevsInequality( real2 moments, real depth, real minVariance, real lightLeakBias )
REAL variance = max( moments.y - (moments.x * moments.x), minVariance );
real variance = max( moments.y - (moments.x * moments.x), minVariance );
REAL mD = depth - moments.x;
REAL p = variance / (variance + mD * mD);
real mD = depth - moments.x;
real p = variance / (variance + mD * mD);
p = saturate( (p - lightLeakBias) / (1.0 - lightLeakBias) );
return max( p, depth <= moments.x );

REAL2 ShadowMoments_WarpDepth( REAL depth, REAL2 exponents )
real2 ShadowMoments_WarpDepth( real depth, real2 exponents )
REAL pos = exp( exponents.x * depth );
REAL neg = -exp(-exponents.y * depth );
return REAL2( pos, neg );
real pos = exp( exponents.x * depth );
real neg = -exp(-exponents.y * depth );
return real2( pos, neg );
// Prepare the moments so there's little quantization error when storing the moments at REAL
// Prepare the moments so there's little quantization error when storing the moments at real
REAL4 ShadowMoments_Encode16MSM( REAL depth )
real4 ShadowMoments_Encode16MSM( real depth )
REAL dsq = depth * depth;
REAL4 moments = { depth, dsq, depth * dsq, dsq * dsq };
REAL4x4 mat = { - 2.07224649 , 13.7948857237, 0.105877704 , 9.7924062118,
real dsq = depth * depth;
real4 moments = { depth, dsq, depth * dsq, dsq * dsq };
real4x4 mat = { - 2.07224649 , 13.7948857237, 0.105877704 , 9.7924062118,
REAL4 optimized = mul( moments, mat );
real4 optimized = mul( moments, mat );
REAL4 ShadowMoments_Decode16MSM( REAL4 moments )
real4 ShadowMoments_Decode16MSM( real4 moments )
REAL4x4 mat = { 0.2227744146, 0.1549679261, 0.1451988946, 0.163127443,
real4x4 mat = { 0.2227744146, 0.1549679261, 0.1451988946, 0.163127443,
0.0771972861, 0.1394629426, 0.2120202157, 0.2591432266,
0.7926986636, 0.7963415838, 0.7258694464, 0.6539092497,
0.0319417555, -0.1722823173, -0.2758014811, -0.3376131734 };

// 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( REAL4 moments, REAL depth, REAL momentBias, out REAL3 z, out REAL4 b )
void ShadowMoments_SolveMSM( real4 moments, real depth, real momentBias, out real3 z, out real4 b )
{
// Bias input data to avoid artifacts
z[0] = depth;

REAL L32D22 = mad( -b[0], b[1], b[2] );
REAL D22 = mad( -b[0], b[0], b[1] );
REAL sqDepthVar = mad( -b[1], b[1], b[3] );
REAL D33D22 = dot( REAL2( sqDepthVar, -L32D22 ), REAL2( D22, L32D22 ) );
REAL InvD22 = 1.0 / D22;
REAL L32 = L32D22 * InvD22;
real L32D22 = mad( -b[0], b[1], b[2] );
real D22 = mad( -b[0], b[0], b[1] );
real sqDepthVar = mad( -b[1], b[1], b[3] );
real D33D22 = dot( real2( sqDepthVar, -L32D22 ), real2( D22, L32D22 ) );
real InvD22 = 1.0 / D22;
real L32 = L32D22 * InvD22;
REAL3 c = REAL3( 1.0, z[0], z[0] * z[0] );
real3 c = real3( 1.0, z[0], z[0] * z[0] );
// Forward substitution to solve L * c1 = bz;
c[1] -= b.x;
c[2] -= b.y + L32 * c[1];

c[1] -= L32 * c[2];
c[0] -= dot( c.yz, b.xy );
// Solve the quadratic equation c[0] + c[1] * z + c[2] * z^2 to obtain solutions z[1] and z[2]
REAL p = c[1] / c[2];
REAL q = c[0] / c[2];
REAL D = ((p*p) * 0.25) - q;
REAL r = sqrt( D );
real p = c[1] / c[2];
real q = c[0] / c[2];
real D = ((p*p) * 0.25) - q;
real r = sqrt( D );
REAL ShadowMoments_SolveDelta3MSM( REAL3 z, REAL2 b, REAL lightLeakBias )
real ShadowMoments_SolveDelta3MSM( real3 z, real2 b, real lightLeakBias )
REAL4 switchVal = (z[2] < z[0]) ? REAL4( z[1], z[0], 1.0, 1.0 )
: ((z[1] < z[0]) ? REAL4( z[0], z[1], 0.0, 1.0 ) : 0.0.xxxx);
real4 switchVal = (z[2] < z[0]) ? real4( z[1], z[0], 1.0, 1.0 )
: ((z[1] < z[0]) ? real4( z[0], z[1], 0.0, 1.0 ) : 0.0.xxxx);
REAL quotient = (switchVal[0] * z[2] - b[0] * (switchVal[0] + z[2]) + b[1]) / ((z[2] - switchVal[1]) * (z[0] - z[1]));
REAL attenuation = saturate( switchVal[2] + switchVal[3] * quotient );
real quotient = (switchVal[0] * z[2] - b[0] * (switchVal[0] + z[2]) + b[1]) / ((z[2] - switchVal[1]) * (z[0] - z[1]));
real attenuation = saturate( switchVal[2] + switchVal[3] * quotient );
REAL ShadowMoments_SolveDelta4MSM( REAL3 z, REAL4 b, REAL lightLeakBias)
real ShadowMoments_SolveDelta4MSM( real3 z, real4 b, real lightLeakBias)
REAL zFree = ((b[2] - b[1]) * z[0] + b[2] - b[3]) / ((b[1] - b[0]) * z[0] + b[1] - b[2]);
REAL w1Factor = (z[0] > zFree) ? 1.0 : 0.0;
REAL attenuation = saturate( (b[1] - b[0] + (b[2] - b[0] - (zFree + 1.0) * (b[1] - b[0])) * (zFree - w1Factor - z[0]) / (z[0] * (z[0] - zFree))) / (zFree - w1Factor) + 1.0 - b[0] );
real zFree = ((b[2] - b[1]) * z[0] + b[2] - b[3]) / ((b[1] - b[0]) * z[0] + b[1] - b[2]);
real w1Factor = (z[0] > zFree) ? 1.0 : 0.0;
real attenuation = saturate( (b[1] - b[0] + (b[2] - b[0] - (zFree + 1.0) * (b[1] - b[0])) * (zFree - w1Factor - z[0]) / (z[0] * (z[0] - zFree))) / (zFree - w1Factor) + 1.0 - b[0] );
return saturate( ((1.0 - attenuation) - lightLeakBias) / (1.0 - lightLeakBias) );
}

494
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowSampling.hlsl


// | \
// ---- <-- length of this side is "triangleHeight"
// _ _ _ _ <-- texels
REAL SampleShadow_GetTriangleTexelArea(REAL triangleHeight)
real SampleShadow_GetTriangleTexelArea(real triangleHeight)
{
return triangleHeight - 0.5;
}

// / \
// _ _ _ _ <-- texels
// X Y Z W <-- result indices (in computedArea.xyzw and computedAreaUncut.xyzw)
void SampleShadow_GetTexelAreas_Tent_3x3(REAL offset, out REAL4 computedArea, out REAL4 computedAreaUncut)
void SampleShadow_GetTexelAreas_Tent_3x3(real offset, out real4 computedArea, out real4 computedAreaUncut)
REAL offset01SquaredHalved = (offset + 0.5) * (offset + 0.5) * 0.5;
real offset01SquaredHalved = (offset + 0.5) * (offset + 0.5) * 0.5;
computedAreaUncut.x = computedArea.x = offset01SquaredHalved - offset;
computedAreaUncut.w = computedArea.w = offset01SquaredHalved;

computedAreaUncut.y = SampleShadow_GetTriangleTexelArea(1.5 - offset);
// This area is superior to the one we are looking for if (offset < 0) thus we need to
// subtract the area of the triangle defined by (0,1.5-offset), (0,1.5+offset), (-offset,1.5).
REAL clampedOffsetLeft = min(offset,0);
REAL areaOfSmallLeftTriangle = clampedOffsetLeft * clampedOffsetLeft;
real clampedOffsetLeft = min(offset,0);
real areaOfSmallLeftTriangle = clampedOffsetLeft * clampedOffsetLeft;
REAL clampedOffsetRight = max(offset,0);
REAL areaOfSmallRightTriangle = clampedOffsetRight * clampedOffsetRight;
real clampedOffsetRight = max(offset,0);
real areaOfSmallRightTriangle = clampedOffsetRight * clampedOffsetRight;
void SampleShadow_GetTexelWeights_Tent_3x3(REAL offset, out REAL4 computedWeight)
void SampleShadow_GetTexelWeights_Tent_3x3(real offset, out real4 computedWeight)
REAL4 dummy;
real4 dummy;
SampleShadow_GetTexelAreas_Tent_3x3(offset, computedWeight, dummy);
computedWeight *= 0.44444;//0.44 == 1/(the triangle area)
}

// / \
// _ _ _ _ _ _ <-- texels
// 0 1 2 3 4 5 <-- computed area indices (in texelsWeights[])
void SampleShadow_GetTexelWeights_Tent_5x5(REAL offset, out REAL3 texelsWeightsA, out REAL3 texelsWeightsB)
void SampleShadow_GetTexelWeights_Tent_5x5(real offset, out real3 texelsWeightsA, out real3 texelsWeightsB)
REAL4 computedArea_From3texelTriangle;
REAL4 computedAreaUncut_From3texelTriangle;
real4 computedArea_From3texelTriangle;
real4 computedAreaUncut_From3texelTriangle;
SampleShadow_GetTexelAreas_Tent_3x3(offset, computedArea_From3texelTriangle, computedAreaUncut_From3texelTriangle);
// Triangle slope is 45 degree thus we can almost reuse the result of the 3 texel wide computation.

// / \
// _ _ _ _ _ _ _ _ <-- texels
// 0 1 2 3 4 5 6 7 <-- computed area indices (in texelsWeights[])
void SampleShadow_GetTexelWeights_Tent_7x7(REAL offset, out REAL4 texelsWeightsA, out REAL4 texelsWeightsB)
void SampleShadow_GetTexelWeights_Tent_7x7(real offset, out real4 texelsWeightsA, out real4 texelsWeightsB)
REAL4 computedArea_From3texelTriangle;
REAL4 computedAreaUncut_From3texelTriangle;
real4 computedArea_From3texelTriangle;
real4 computedAreaUncut_From3texelTriangle;
SampleShadow_GetTexelAreas_Tent_3x3(offset, computedArea_From3texelTriangle, computedAreaUncut_From3texelTriangle);
// Triangle slope is 45 degree thus we can almost reuse the result of the 3 texel wide computation.

}
// 3x3 Tent filter (45 degree sloped triangles in U and V)
void SampleShadow_ComputeSamples_Tent_3x3(REAL4 shadowMapTexture_TexelSize, REAL2 coord, out REAL fetchesWeights[4], out REAL2 fetchesUV[4])
void SampleShadow_ComputeSamples_Tent_3x3(real4 shadowMapTexture_TexelSize, real2 coord, out real fetchesWeights[4], out real2 fetchesUV[4])
REAL2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
REAL2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
REAL2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
real2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
real2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
real2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
REAL4 texelsWeightsU, texelsWeightsV;
real4 texelsWeightsU, texelsWeightsV;
REAL2 fetchesWeightsU = texelsWeightsU.xz + texelsWeightsU.yw;
REAL2 fetchesWeightsV = texelsWeightsV.xz + texelsWeightsV.yw;
real2 fetchesWeightsU = texelsWeightsU.xz + texelsWeightsU.yw;
real2 fetchesWeightsV = texelsWeightsV.xz + texelsWeightsV.yw;
REAL2 fetchesOffsetsU = texelsWeightsU.yw / fetchesWeightsU.xy + REAL2(-1.5,0.5);
REAL2 fetchesOffsetsV = texelsWeightsV.yw / fetchesWeightsV.xy + REAL2(-1.5,0.5);
real2 fetchesOffsetsU = texelsWeightsU.yw / fetchesWeightsU.xy + real2(-1.5,0.5);
real2 fetchesOffsetsV = texelsWeightsV.yw / fetchesWeightsV.xy + real2(-1.5,0.5);
REAL2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[3] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.y);
real2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[3] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.y);
fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;
fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;

// 5x5 Tent filter (45 degree sloped triangles in U and V)
void SampleShadow_ComputeSamples_Tent_5x5(REAL4 shadowMapTexture_TexelSize, REAL2 coord, out REAL fetchesWeights[9], out REAL2 fetchesUV[9])
void SampleShadow_ComputeSamples_Tent_5x5(real4 shadowMapTexture_TexelSize, real2 coord, out real fetchesWeights[9], out real2 fetchesUV[9])
REAL2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
REAL2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
REAL2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
real2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
real2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
real2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
REAL3 texelsWeightsU_A, texelsWeightsU_B;
REAL3 texelsWeightsV_A, texelsWeightsV_B;
real3 texelsWeightsU_A, texelsWeightsU_B;
real3 texelsWeightsV_A, texelsWeightsV_B;
REAL3 fetchesWeightsU = REAL3(texelsWeightsU_A.xz, texelsWeightsU_B.y) + REAL3(texelsWeightsU_A.y, texelsWeightsU_B.xz);
REAL3 fetchesWeightsV = REAL3(texelsWeightsV_A.xz, texelsWeightsV_B.y) + REAL3(texelsWeightsV_A.y, texelsWeightsV_B.xz);
real3 fetchesWeightsU = real3(texelsWeightsU_A.xz, texelsWeightsU_B.y) + real3(texelsWeightsU_A.y, texelsWeightsU_B.xz);
real3 fetchesWeightsV = real3(texelsWeightsV_A.xz, texelsWeightsV_B.y) + real3(texelsWeightsV_A.y, texelsWeightsV_B.xz);
REAL3 fetchesOffsetsU = REAL3(texelsWeightsU_A.y, texelsWeightsU_B.xz) / fetchesWeightsU.xyz + REAL3(-2.5,-0.5,1.5);
REAL3 fetchesOffsetsV = REAL3(texelsWeightsV_A.y, texelsWeightsV_B.xz) / fetchesWeightsV.xyz + REAL3(-2.5,-0.5,1.5);
real3 fetchesOffsetsU = real3(texelsWeightsU_A.y, texelsWeightsU_B.xz) / fetchesWeightsU.xyz + real3(-2.5,-0.5,1.5);
real3 fetchesOffsetsV = real3(texelsWeightsV_A.y, texelsWeightsV_B.xz) / fetchesWeightsV.xyz + real3(-2.5,-0.5,1.5);
REAL2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.z, fetchesOffsetsV.x);
fetchesUV[3] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[4] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.y);
fetchesUV[5] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.z, fetchesOffsetsV.y);
fetchesUV[6] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.z);
fetchesUV[7] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.z);
fetchesUV[8] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.z, fetchesOffsetsV.z);
real2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + real2(fetchesOffsetsU.z, fetchesOffsetsV.x);
fetchesUV[3] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[4] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.y);
fetchesUV[5] = bilinearFetchOrigin + real2(fetchesOffsetsU.z, fetchesOffsetsV.y);
fetchesUV[6] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.z);
fetchesUV[7] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.z);
fetchesUV[8] = bilinearFetchOrigin + real2(fetchesOffsetsU.z, fetchesOffsetsV.z);
fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;
fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;

}
// 7x7 Tent filter (45 degree sloped triangles in U and V)
void SampleShadow_ComputeSamples_Tent_7x7(REAL4 shadowMapTexture_TexelSize, REAL2 coord, out REAL fetchesWeights[16], out REAL2 fetchesUV[16])
void SampleShadow_ComputeSamples_Tent_7x7(real4 shadowMapTexture_TexelSize, real2 coord, out real fetchesWeights[16], out real2 fetchesUV[16])
REAL2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
REAL2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
REAL2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
real2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
real2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
real2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
REAL4 texelsWeightsU_A, texelsWeightsU_B;
REAL4 texelsWeightsV_A, texelsWeightsV_B;
real4 texelsWeightsU_A, texelsWeightsU_B;
real4 texelsWeightsV_A, texelsWeightsV_B;
REAL4 fetchesWeightsU = REAL4(texelsWeightsU_A.xz, texelsWeightsU_B.xz) + REAL4(texelsWeightsU_A.yw, texelsWeightsU_B.yw);
REAL4 fetchesWeightsV = REAL4(texelsWeightsV_A.xz, texelsWeightsV_B.xz) + REAL4(texelsWeightsV_A.yw, texelsWeightsV_B.yw);
real4 fetchesWeightsU = real4(texelsWeightsU_A.xz, texelsWeightsU_B.xz) + real4(texelsWeightsU_A.yw, texelsWeightsU_B.yw);
real4 fetchesWeightsV = real4(texelsWeightsV_A.xz, texelsWeightsV_B.xz) + real4(texelsWeightsV_A.yw, texelsWeightsV_B.yw);
REAL4 fetchesOffsetsU = REAL4(texelsWeightsU_A.yw, texelsWeightsU_B.yw) / fetchesWeightsU.xyzw + REAL4(-3.5,-1.5,0.5,2.5);
REAL4 fetchesOffsetsV = REAL4(texelsWeightsV_A.yw, texelsWeightsV_B.yw) / fetchesWeightsV.xyzw + REAL4(-3.5,-1.5,0.5,2.5);
real4 fetchesOffsetsU = real4(texelsWeightsU_A.yw, texelsWeightsU_B.yw) / fetchesWeightsU.xyzw + real4(-3.5,-1.5,0.5,2.5);
real4 fetchesOffsetsV = real4(texelsWeightsV_A.yw, texelsWeightsV_B.yw) / fetchesWeightsV.xyzw + real4(-3.5,-1.5,0.5,2.5);
REAL2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.z, fetchesOffsetsV.x);
fetchesUV[3] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.w, fetchesOffsetsV.x);
fetchesUV[4] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[5] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.y);
fetchesUV[6] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.z, fetchesOffsetsV.y);
fetchesUV[7] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.w, fetchesOffsetsV.y);
fetchesUV[8] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.z);
fetchesUV[9] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.z);
fetchesUV[10] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.z, fetchesOffsetsV.z);
fetchesUV[11] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.w, fetchesOffsetsV.z);
fetchesUV[12] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.x, fetchesOffsetsV.w);
fetchesUV[13] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.y, fetchesOffsetsV.w);
fetchesUV[14] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.z, fetchesOffsetsV.w);
fetchesUV[15] = bilinearFetchOrigin + REAL2(fetchesOffsetsU.w, fetchesOffsetsV.w);
real2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + real2(fetchesOffsetsU.z, fetchesOffsetsV.x);
fetchesUV[3] = bilinearFetchOrigin + real2(fetchesOffsetsU.w, fetchesOffsetsV.x);
fetchesUV[4] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[5] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.y);
fetchesUV[6] = bilinearFetchOrigin + real2(fetchesOffsetsU.z, fetchesOffsetsV.y);
fetchesUV[7] = bilinearFetchOrigin + real2(fetchesOffsetsU.w, fetchesOffsetsV.y);
fetchesUV[8] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.z);
fetchesUV[9] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.z);
fetchesUV[10] = bilinearFetchOrigin + real2(fetchesOffsetsU.z, fetchesOffsetsV.z);
fetchesUV[11] = bilinearFetchOrigin + real2(fetchesOffsetsU.w, fetchesOffsetsV.z);
fetchesUV[12] = bilinearFetchOrigin + real2(fetchesOffsetsU.x, fetchesOffsetsV.w);
fetchesUV[13] = bilinearFetchOrigin + real2(fetchesOffsetsU.y, fetchesOffsetsV.w);
fetchesUV[14] = bilinearFetchOrigin + real2(fetchesOffsetsU.z, fetchesOffsetsV.w);
fetchesUV[15] = bilinearFetchOrigin + real2(fetchesOffsetsU.w, fetchesOffsetsV.w);
fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;
fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;

//
// 1 tap PCF sampling
//
REAL SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, REAL3 tcs, REAL bias, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, real bias, uint slice, uint texIdx, uint sampIdx )
REAL depthBias = asfloat( shadowContext.payloads[payloadOffset].x );
real depthBias = asfloat( shadowContext.payloads[payloadOffset].x );
payloadOffset++;
// add the depth bias

}
REAL SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, REAL3 tcs, REAL bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, real bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
REAL depthBias = asfloat( shadowContext.payloads[payloadOffset].x );
real depthBias = asfloat( shadowContext.payloads[payloadOffset].x );
payloadOffset++;
// add the depth bias

//
// 3x3 tent PCF sampling (4 taps)
//
REAL SampleShadow_PCF_Tent_3x3( ShadowContext shadowContext, inout uint payloadOffset, REAL4 texelSizeRcp, REAL3 coord, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_Tent_3x3( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, uint texIdx, uint sampIdx )
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL depthBias = params.x;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;
REAL4 shadowMapTexture_TexelSize = REAL4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
REAL shadow = 0.0;
REAL fetchesWeights[4];
REAL2 fetchesUV[4];
real shadow = 0.0;
real fetchesWeights[4];
real2 fetchesUV[4];
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z ), slice ).x;
REAL SampleShadow_PCF_Tent_3x3(ShadowContext shadowContext, inout uint payloadOffset, REAL4 texelSizeRcp, REAL3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_Tent_3x3(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL depthBias = params.x;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;
REAL4 shadowMapTexture_TexelSize = REAL4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
REAL shadow = 0.0;
REAL fetchesWeights[4];
REAL2 fetchesUV[4];
real shadow = 0.0;
real fetchesWeights[4];
real2 fetchesUV[4];
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z ), slice ).x;
}
return shadow;
}

//
REAL SampleShadow_PCF_Tent_5x5( ShadowContext shadowContext, inout uint payloadOffset, REAL4 texelSizeRcp, REAL3 coord, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_Tent_5x5( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, uint texIdx, uint sampIdx )
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL depthBias = params.x;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;
REAL4 shadowMapTexture_TexelSize = REAL4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
REAL shadow = 0.0;
REAL fetchesWeights[9];
REAL2 fetchesUV[9];
real shadow = 0.0;
real fetchesWeights[9];
real2 fetchesUV[9];
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z ), slice ).x;
REAL SampleShadow_PCF_Tent_5x5(ShadowContext shadowContext, inout uint payloadOffset, REAL4 texelSizeRcp, REAL3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_Tent_5x5(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL depthBias = params.x;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;
REAL4 shadowMapTexture_TexelSize = REAL4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
REAL shadow = 0.0;
REAL fetchesWeights[9];
REAL2 fetchesUV[9];
real shadow = 0.0;
real fetchesWeights[9];
real2 fetchesUV[9];
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z ), slice ).x;
}
return shadow;

// 7x7 tent PCF sampling (16 taps)
//
REAL SampleShadow_PCF_Tent_7x7( ShadowContext shadowContext, inout uint payloadOffset, REAL4 texelSizeRcp, REAL3 coord, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_Tent_7x7( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, uint texIdx, uint sampIdx )
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL depthBias = params.x;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;
REAL4 shadowMapTexture_TexelSize = REAL4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
REAL shadow = 0.0;
REAL fetchesWeights[16];
REAL2 fetchesUV[16];
real shadow = 0.0;
real fetchesWeights[16];
real2 fetchesUV[16];
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( fetchesUV[i].xy, coord.z ), slice ).x;
REAL SampleShadow_PCF_Tent_7x7(ShadowContext shadowContext, inout uint payloadOffset, REAL4 texelSizeRcp, REAL3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_Tent_7x7(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL depthBias = params.x;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;
REAL4 shadowMapTexture_TexelSize = REAL4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
real4 shadowMapTexture_TexelSize = real4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
REAL shadow = 0.0;
REAL fetchesWeights[16];
REAL2 fetchesUV[16];
real shadow = 0.0;
real fetchesWeights[16];
real2 fetchesUV[16];
SampleShadow_ComputeSamples_Tent_7x7(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);

for( i = 0; i < 1; i++ )
{
shadow += fetchesWeights[ 0] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 0].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 1] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 1].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 2] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 2].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 3] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 3].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 0] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 0].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 1] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 1].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 2] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 2].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 3] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 3].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 4] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 4].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 5] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 5].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 6] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 6].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 7] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 7].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 4] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 4].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 5] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 5].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 6] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 6].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 7] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 7].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 8] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 8].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 9] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[ 9].xy, coord.z ), slice ).x;
shadow += fetchesWeights[10] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[10].xy, coord.z ), slice ).x;
shadow += fetchesWeights[11] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[11].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 8] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 8].xy, coord.z ), slice ).x;
shadow += fetchesWeights[ 9] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[ 9].xy, coord.z ), slice ).x;
shadow += fetchesWeights[10] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[10].xy, coord.z ), slice ).x;
shadow += fetchesWeights[11] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[11].xy, coord.z ), slice ).x;
shadow += fetchesWeights[12] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[12].xy, coord.z ), slice ).x;
shadow += fetchesWeights[13] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[13].xy, coord.z ), slice ).x;
shadow += fetchesWeights[14] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[14].xy, coord.z ), slice ).x;
shadow += fetchesWeights[15] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[15].xy, coord.z ), slice ).x;
shadow += fetchesWeights[12] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[12].xy, coord.z ), slice ).x;
shadow += fetchesWeights[13] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[13].xy, coord.z ), slice ).x;
shadow += fetchesWeights[14] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[14].xy, coord.z ), slice ).x;
shadow += fetchesWeights[15] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[15].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( fetchesUV[i].xy, coord.z ), slice ).x;
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( fetchesUV[i].xy, coord.z ), slice ).x;
}
#endif
return shadow;

// 9 tap adaptive PCF sampling
//
REAL SampleShadow_PCF_9tap_Adaptive( ShadowContext shadowContext, inout uint payloadOffset, REAL4 texelSizeRcp, REAL3 tcs, REAL bias, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_PCF_9tap_Adaptive( ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 tcs, real bias, uint slice, uint texIdx, uint sampIdx )
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL depthBias = params.x;
REAL filterSize = params.y;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;
real filterSize = params.y;
payloadOffset++;
texelSizeRcp *= filterSize;

// Terms0 are weights for the individual samples, the other terms are offsets in texel space
REAL4 vShadow3x3PCFTerms0 = REAL4( 20.0 / 267.0, 33.0 / 267.0, 55.0 / 267.0, 0.0 );
REAL4 vShadow3x3PCFTerms1 = REAL4( texelSizeRcp.x, texelSizeRcp.y, -texelSizeRcp.x, -texelSizeRcp.y );
REAL4 vShadow3x3PCFTerms2 = REAL4( texelSizeRcp.x, texelSizeRcp.y, 0.0, 0.0 );
REAL4 vShadow3x3PCFTerms3 = REAL4(-texelSizeRcp.x, -texelSizeRcp.y, 0.0, 0.0 );
real4 vShadow3x3PCFTerms0 = real4( 20.0 / 267.0, 33.0 / 267.0, 55.0 / 267.0, 0.0 );
real4 vShadow3x3PCFTerms1 = real4( texelSizeRcp.x, texelSizeRcp.y, -texelSizeRcp.x, -texelSizeRcp.y );
real4 vShadow3x3PCFTerms2 = real4( texelSizeRcp.x, texelSizeRcp.y, 0.0, 0.0 );
real4 vShadow3x3PCFTerms3 = real4(-texelSizeRcp.x, -texelSizeRcp.y, 0.0, 0.0 );
REAL4 v20Taps;
v20Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
REAL flSum = dot( v20Taps.xyzw, REAL4( 0.25, 0.25, 0.25, 0.25 ) );
real4 v20Taps;
v20Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
real flSum = dot( v20Taps.xyzw, real4( 0.25, 0.25, 0.25, 0.25 ) );
// fully in light or shadow? -> bail
if( ( flSum == 0.0 ) || ( flSum == 1.0 ) )
return flSum;

REAL4 v33Taps;
v33Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, REAL3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
real4 v33Taps;
v33Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, real3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
flSum += dot( v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy );
flSum += SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, tcs, slice ).x * vShadow3x3PCFTerms0.z;

REAL SampleShadow_PCF_9tap_Adaptive(ShadowContext shadowContext, inout uint payloadOffset, REAL4 texelSizeRcp, REAL3 tcs, REAL bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_PCF_9tap_Adaptive(ShadowContext shadowContext, inout uint payloadOffset, real4 texelSizeRcp, real3 tcs, real bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL depthBias = params.x;
REAL filterSize = params.y;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real depthBias = params.x;
real filterSize = params.y;
payloadOffset++;
texelSizeRcp *= filterSize;

// Terms0 are weights for the individual samples, the other terms are offsets in texel space
REAL4 vShadow3x3PCFTerms0 = REAL4(20.0 / 267.0, 33.0 / 267.0, 55.0 / 267.0, 0.0);
REAL4 vShadow3x3PCFTerms1 = REAL4( texelSizeRcp.x, texelSizeRcp.y, -texelSizeRcp.x, -texelSizeRcp.y);
REAL4 vShadow3x3PCFTerms2 = REAL4( texelSizeRcp.x, texelSizeRcp.y, 0.0, 0.0);
REAL4 vShadow3x3PCFTerms3 = REAL4(-texelSizeRcp.x, -texelSizeRcp.y, 0.0, 0.0);
real4 vShadow3x3PCFTerms0 = real4(20.0 / 267.0, 33.0 / 267.0, 55.0 / 267.0, 0.0);
real4 vShadow3x3PCFTerms1 = real4( texelSizeRcp.x, texelSizeRcp.y, -texelSizeRcp.x, -texelSizeRcp.y);
real4 vShadow3x3PCFTerms2 = real4( texelSizeRcp.x, texelSizeRcp.y, 0.0, 0.0);
real4 vShadow3x3PCFTerms3 = real4(-texelSizeRcp.x, -texelSizeRcp.y, 0.0, 0.0);
REAL4 v20Taps;
v20Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
REAL flSum = dot( v20Taps.xyzw, REAL4( 0.25, 0.25, 0.25, 0.25 ) );
real4 v20Taps;
v20Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
real flSum = dot( v20Taps.xyzw, real4( 0.25, 0.25, 0.25, 0.25 ) );
// fully in light or shadow? -> bail
if( ( flSum == 0.0 ) || ( flSum == 1.0 ) )
return flSum;

REAL4 v33Taps;
v33Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, REAL3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
real4 v33Taps;
v33Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, real3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
flSum += dot( v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy );
flSum += SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, tcs, slice ).x * vShadow3x3PCFTerms0.z;

//
// 1 tap VSM sampling
//
REAL SampleShadow_VSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, REAL3 tcs, uint slice, uint texIdx, uint sampIdx )
real SampleShadow_VSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, uint texIdx, uint sampIdx )
REAL depth = 1.0 - tcs.z;
real depth = 1.0 - tcs.z;
REAL depth = tcs.z;
real depth = tcs.z;
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL lightLeakBias = params.x;
REAL varianceBias = params.y;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real lightLeakBias = params.x;
real varianceBias = params.y;
REAL2 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice ).xy;
real2 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice ).xy;
REAL SampleShadow_VSM_1tap(ShadowContext shadowContext, inout uint payloadOffset, REAL3 tcs, uint slice, Texture2DArray tex, SamplerState samp )
real SampleShadow_VSM_1tap(ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, Texture2DArray tex, SamplerState samp )
REAL depth = 1.0 - tcs.z;
real depth = 1.0 - tcs.z;
REAL depth = tcs.z;
real depth = tcs.z;
REAL2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
REAL lightLeakBias = params.x;
REAL varianceBias = params.y;
real2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
real lightLeakBias = params.x;
real varianceBias = params.y;
REAL2 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 ).xy;
real2 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 ).xy;
return ShadowMoments_ChebyshevsInequality( moments, depth, varianceBias, lightLeakBias );
}

//
REAL SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, REAL3 tcs, uint slice, uint texIdx, uint sampIdx, bool fourMoments )
real SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, uint texIdx, uint sampIdx, bool fourMoments )
REAL depth = 1.0 - tcs.z;
real depth = 1.0 - tcs.z;
REAL depth = tcs.z;
real depth = tcs.z;
REAL4 params = asfloat( shadowContext.payloads[payloadOffset] );
REAL lightLeakBias = params.x;
REAL varianceBias = params.y;
REAL2 evsmExponents = params.zw;
real4 params = asfloat( shadowContext.payloads[payloadOffset] );
real lightLeakBias = params.x;
real varianceBias = params.y;
real2 evsmExponents = params.zw;
REAL2 warpedDepth = ShadowMoments_WarpDepth( depth, evsmExponents );
real2 warpedDepth = ShadowMoments_WarpDepth( depth, evsmExponents );
REAL4 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice );
real4 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice );
REAL2 depthScale = evsmExponents * warpedDepth;
REAL2 minVariance = depthScale * depthScale * varianceBias;
real2 depthScale = evsmExponents * warpedDepth;
real2 minVariance = depthScale * depthScale * varianceBias;
REAL posContrib = ShadowMoments_ChebyshevsInequality( moments.xz, warpedDepth.x, minVariance.x, lightLeakBias );
REAL negContrib = ShadowMoments_ChebyshevsInequality( moments.yw, warpedDepth.y, minVariance.y, lightLeakBias );
real posContrib = ShadowMoments_ChebyshevsInequality( moments.xz, warpedDepth.x, minVariance.x, lightLeakBias );
real negContrib = ShadowMoments_ChebyshevsInequality( moments.yw, warpedDepth.y, minVariance.y, lightLeakBias );
return min( posContrib, negContrib );
}
else

}
REAL SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, REAL3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool fourMoments )
real SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool fourMoments )
REAL depth = 1.0 - tcs.z;
real depth = 1.0 - tcs.z;
REAL depth = tcs.z;
real depth = tcs.z;
REAL4 params = asfloat( shadowContext.payloads[payloadOffset] );
REAL lightLeakBias = params.x;
REAL varianceBias = params.y;
REAL2 evsmExponents = params.zw;
real4 params = asfloat( shadowContext.payloads[payloadOffset] );
real lightLeakBias = params.x;
real varianceBias = params.y;
real2 evsmExponents = params.zw;
REAL2 warpedDepth = ShadowMoments_WarpDepth( depth, evsmExponents );
real2 warpedDepth = ShadowMoments_WarpDepth( depth, evsmExponents );
REAL4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );
real4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );
REAL2 depthScale = evsmExponents * warpedDepth;
REAL2 minVariance = depthScale * depthScale * varianceBias;
real2 depthScale = evsmExponents * warpedDepth;
real2 minVariance = depthScale * depthScale * varianceBias;
REAL posContrib = ShadowMoments_ChebyshevsInequality( moments.xz, warpedDepth.x, minVariance.x, lightLeakBias );
REAL negContrib = ShadowMoments_ChebyshevsInequality( moments.yw, warpedDepth.y, minVariance.y, lightLeakBias );
real posContrib = ShadowMoments_ChebyshevsInequality( moments.xz, warpedDepth.x, minVariance.x, lightLeakBias );
real negContrib = ShadowMoments_ChebyshevsInequality( moments.yw, warpedDepth.y, minVariance.y, lightLeakBias );
return min( posContrib, negContrib );
}
else

//
// 1 tap MSM sampling
//
REAL SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, REAL3 tcs, uint slice, uint texIdx, uint sampIdx, bool useHamburger )
real SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, uint texIdx, uint sampIdx, bool useHamburger )
REAL4 params = asfloat( shadowContext.payloads[payloadOffset] );
REAL lightLeakBias = params.x;
REAL momentBias = params.y;
REAL depthBias = params.z;
REAL bpp16 = params.w;
real4 params = asfloat( shadowContext.payloads[payloadOffset] );
real lightLeakBias = params.x;
real momentBias = params.y;
real depthBias = params.z;
real bpp16 = params.w;
REAL depth = (1.0 - tcs.z) - depthBias;
real depth = (1.0 - tcs.z) - depthBias;
REAL depth = tcs.z + depthBias;
real depth = tcs.z + depthBias;
REAL4 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice );
real4 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice );
REAL3 z;
REAL4 b;
real3 z;
real4 b;
ShadowMoments_SolveMSM( moments, depth, momentBias, z, b );
if( useHamburger )

}
REAL SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, REAL3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool useHamburger )
real SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool useHamburger )
REAL4 params = asfloat( shadowContext.payloads[payloadOffset] );
REAL lightLeakBias = params.x;
REAL momentBias = params.y;
REAL depthBias = params.z;
REAL bpp16 = params.w;
real4 params = asfloat( shadowContext.payloads[payloadOffset] );
real lightLeakBias = params.x;
real momentBias = params.y;
real depthBias = params.z;
real bpp16 = params.w;
REAL depth = (1.0 - tcs.z) - depthBias;
real depth = (1.0 - tcs.z) - depthBias;
REAL depth = tcs.z + depthBias;
real depth = tcs.z + depthBias;
REAL4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );
real4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );
REAL3 z;
REAL4 b;
real3 z;
real4 b;
ShadowMoments_SolveMSM( moments, depth, momentBias, z, b );
if( useHamburger )

//-----------------------------------------------------------------------------------------------------
// helper function to dispatch a specific shadow algorithm
REAL SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, REAL3 posTC, REAL depthBias, uint slice, uint algorithm, uint texIdx, uint sampIdx )
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real depthBias, uint slice, uint algorithm, uint texIdx, uint sampIdx )
{
[branch]
switch( algorithm )

}
}
REAL SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, REAL3 posTC, REAL depthBias, uint slice, uint algorithm, Texture2DArray tex, SamplerComparisonState compSamp )
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real depthBias, uint slice, uint algorithm, Texture2DArray tex, SamplerComparisonState compSamp )
{
[branch]
switch( algorithm )

}
}
REAL SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, REAL3 posTC, REAL depthBias, uint slice, uint algorithm, Texture2DArray tex, SamplerState samp )
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real depthBias, uint slice, uint algorithm, Texture2DArray tex, SamplerState samp )
{
[branch]
switch( algorithm )

40
ScriptableRenderPipeline/Core/ShaderLibrary/Shadow/ShadowTexFetch.hlsl


#if SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// Shader model >= 5.1
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) REAL4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL3 tcs, REAL slice ) { return SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[texIdx], ctxt.compSamplers[sampIdx], tcs, slice ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) REAL4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL2 tcs, REAL slice, REAL lod = 0.0 ) { return SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[texIdx], ctxt.samplers[sampIdx], tcs, slice, lod ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_LOAD( _Tex2DArraySlots ) REAL4 LoadShadow_T2DA( ShadowContext ctxt, uint texIdx, uint2 tcs, uint slice, uint lod = 0 ) { return LOAD_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[texIdx], tcs, slice, lod ).x; }
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) REAL4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL4 tcs, REAL cubeIdx ) { return SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[texIdx], ctxt.compSamplers[sampIdx], tcs, cubeIdx );}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) REAL4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL3 tcs, REAL cubeIdx, REAL lod = 0.0 ) { return SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[texIdx], ctxt.samplers[sampIdx], tcs, cubeIdx, lod ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) real4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real slice ) { return SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[texIdx], ctxt.compSamplers[sampIdx], tcs, slice ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) real4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real2 tcs, real slice, real lod = 0.0 ) { return SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[texIdx], ctxt.samplers[sampIdx], tcs, slice, lod ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_LOAD( _Tex2DArraySlots ) real4 LoadShadow_T2DA( ShadowContext ctxt, uint texIdx, uint2 tcs, uint slice, uint lod = 0 ) { return LOAD_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[texIdx], tcs, slice, lod ).x; }
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) real4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real4 tcs, real cubeIdx ) { return SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[texIdx], ctxt.compSamplers[sampIdx], tcs, cubeIdx );}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) real4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real cubeIdx, real lod = 0.0 ) { return SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[texIdx], ctxt.samplers[sampIdx], tcs, cubeIdx, lod ); }
#else // helper macros if dynamic indexing does not work

REAL4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL3 tcs, REAL slice ) \
real4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real slice ) \
REAL4 res = 1.0.xxxx; \
real4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \

}
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ) \
REAL4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL2 tcs, REAL slice, REAL lod = 0.0 ) \
real4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real2 tcs, real slice, real lod = 0.0 ) \
REAL4 res = 1.0.xxxx; \
real4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \

}
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_LOAD( _Tex2DArraySlots ) \
REAL LoadShadow_T2DA( ShadowContext ctxt, uint texIdx, uint2 tcs, uint slice, uint lod = 0 ) \
real LoadShadow_T2DA( ShadowContext ctxt, uint texIdx, uint2 tcs, uint slice, uint lod = 0 ) \
REAL res = 1.0; \
real res = 1.0; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[branch] if( i == texIdx ) \

# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) \
REAL4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL4 tcs, REAL cubeIdx ) \
real4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real4 tcs, real cubeIdx ) \
REAL4 res = 1.0.xxxx; \
real4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \

}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) \
REAL4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL3 tcs, REAL cubeIdx, REAL lod = 0.0 ) \
real4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real cubeIdx, real lod = 0.0 ) \
REAL4 res = 1.0.xxxx; \
real4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \

#endif // SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// helper macro to suppress code generation if _cnt is 0
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) REAL4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL3 tcs, REAL slice );
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) REAL4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL2 tcs, REAL slice, REAL lod = 0.0 );
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_LOAD( _Tex2DArraySlots ) REAL4 LoadShadow_T2DA( ShadowContext ctxt, uint texIdx, uint2 tcs, uint slice, uint lod = 0 );
#define SHADOW_DECLARE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) REAL4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL4 tcs, REAL cubeIdx );
#define SHADOW_DECLARE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) REAL4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, REAL3 tcs, REAL cubeIdx, REAL lod = 0.0 );
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) real4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real slice );
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) real4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, real2 tcs, real slice, real lod = 0.0 );
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_LOAD( _Tex2DArraySlots ) real4 LoadShadow_T2DA( ShadowContext ctxt, uint texIdx, uint2 tcs, uint slice, uint lod = 0 );
#define SHADOW_DECLARE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) real4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real4 tcs, real cubeIdx );
#define SHADOW_DECLARE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) real4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, real3 tcs, real cubeIdx, real lod = 0.0 );
#define SHADOW_CAT( _left, _right ) _left ## _right

44
ScriptableRenderPipeline/Core/ShaderLibrary/Tessellation.hlsl


// p0, p1, p2 triangle world position
// p0, p1, p2 triangle world vertex normal
REAL3 PhongTessellation(REAL3 positionWS, REAL3 p0, REAL3 p1, REAL3 p2, REAL3 n0, REAL3 n1, REAL3 n2, REAL3 baryCoords, REAL shape)
real3 PhongTessellation(real3 positionWS, real3 p0, real3 p1, real3 p2, real3 n0, real3 n1, real3 n2, real3 baryCoords, real shape)
REAL3 c0 = ProjectPointOnPlane(positionWS, p0, n0);
REAL3 c1 = ProjectPointOnPlane(positionWS, p1, n1);
REAL3 c2 = ProjectPointOnPlane(positionWS, p2, n2);
real3 c0 = ProjectPointOnPlane(positionWS, p0, n0);
real3 c1 = ProjectPointOnPlane(positionWS, p1, n1);
real3 c2 = ProjectPointOnPlane(positionWS, p2, n2);
REAL3 phongPositionWS = baryCoords.x * c0 + baryCoords.y * c1 + baryCoords.z * c2;
real3 phongPositionWS = baryCoords.x * c0 + baryCoords.y * c1 + baryCoords.z * c2;
return lerp(positionWS, phongPositionWS, shape);
}

// Compute both screen and distance based adaptation - return factor between 0 and 1
REAL3 GetScreenSpaceTessFactor(REAL3 p0, REAL3 p1, REAL3 p2, REAL4x4 viewProjectionMatrix, REAL4 screenSize, REAL triangleSize)
real3 GetScreenSpaceTessFactor(real3 p0, real3 p1, real3 p2, real4x4 viewProjectionMatrix, real4 screenSize, real triangleSize)
REAL2 edgeScreenPosition0 = ComputeNormalizedDeviceCoordinates(p0, viewProjectionMatrix) * screenSize.xy;
REAL2 edgeScreenPosition1 = ComputeNormalizedDeviceCoordinates(p1, viewProjectionMatrix) * screenSize.xy;
REAL2 edgeScreenPosition2 = ComputeNormalizedDeviceCoordinates(p2, viewProjectionMatrix) * screenSize.xy;
real2 edgeScreenPosition0 = ComputeNormalizedDeviceCoordinates(p0, viewProjectionMatrix) * screenSize.xy;
real2 edgeScreenPosition1 = ComputeNormalizedDeviceCoordinates(p1, viewProjectionMatrix) * screenSize.xy;
real2 edgeScreenPosition2 = ComputeNormalizedDeviceCoordinates(p2, viewProjectionMatrix) * screenSize.xy;
REAL EdgeScale = 1.0 / triangleSize; // Edge size in reality, but name is simpler
REAL3 tessFactor;
real EdgeScale = 1.0 / triangleSize; // Edge size in reality, but name is simpler
real3 tessFactor;
tessFactor.x = saturate(distance(edgeScreenPosition1, edgeScreenPosition2) * EdgeScale);
tessFactor.y = saturate(distance(edgeScreenPosition0, edgeScreenPosition2) * EdgeScale);
tessFactor.z = saturate(distance(edgeScreenPosition0, edgeScreenPosition1) * EdgeScale);

REAL3 GetDistanceBasedTessFactor(REAL3 p0, REAL3 p1, REAL3 p2, REAL3 cameraPosWS, REAL tessMinDist, REAL tessMaxDist)
real3 GetDistanceBasedTessFactor(real3 p0, real3 p1, real3 p2, real3 cameraPosWS, real tessMinDist, real tessMaxDist)
REAL3 edgePosition0 = 0.5 * (p1 + p2);
REAL3 edgePosition1 = 0.5 * (p0 + p2);
REAL3 edgePosition2 = 0.5 * (p0 + p1);
real3 edgePosition0 = 0.5 * (p1 + p2);
real3 edgePosition1 = 0.5 * (p0 + p2);
real3 edgePosition2 = 0.5 * (p0 + p1);
REAL dist0 = distance(edgePosition0, cameraPosWS);
REAL dist1 = distance(edgePosition1, cameraPosWS);
REAL dist2 = distance(edgePosition2, cameraPosWS);
real dist0 = distance(edgePosition0, cameraPosWS);
real dist1 = distance(edgePosition1, cameraPosWS);
real dist2 = distance(edgePosition2, cameraPosWS);
REAL fadeDist = tessMaxDist - tessMinDist;
REAL3 tessFactor;
real fadeDist = tessMaxDist - tessMinDist;
real3 tessFactor;
tessFactor.x = saturate(1.0 - (dist0 - tessMinDist) / fadeDist);
tessFactor.y = saturate(1.0 - (dist1 - tessMinDist) / fadeDist);
tessFactor.z = saturate(1.0 - (dist2 - tessMinDist) / fadeDist);

REAL4 CalcTriTessFactorsFromEdgeTessFactors(REAL3 triVertexFactors)
real4 CalcTriTessFactorsFromEdgeTessFactors(real3 triVertexFactors)
REAL4 tess;
real4 tess;
tess.x = triVertexFactors.x;
tess.y = triVertexFactors.y;
tess.z = triVertexFactors.z;

26
ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl


#ifndef UNITY_VOLUME_RENDERING_INCLUDED
#define UNITY_VOLUME_RENDERING_INCLUDED
REAL OpticalDepthHomogeneous(REAL extinction, REAL intervalLength)
real OpticalDepthHomogeneous(real extinction, real intervalLength)
REAL Transmittance(REAL opticalDepth)
real Transmittance(real opticalDepth)
REAL TransmittanceIntegralOverHomogeneousInterval(REAL extinction, REAL start, REAL end)
real TransmittanceIntegralOverHomogeneousInterval(real extinction, real start, real end)
REAL3 OpticalDepthHomogeneous(REAL3 extinction, REAL intervalLength)
real3 OpticalDepthHomogeneous(real3 extinction, real intervalLength)
REAL3 Transmittance(REAL3 opticalDepth)
real3 Transmittance(real3 opticalDepth)
REAL3 TransmittanceIntegralOverHomogeneousInterval(REAL3 extinction, REAL start, REAL end)
real3 TransmittanceIntegralOverHomogeneousInterval(real3 extinction, real start, real end)
REAL IsotropicPhaseFunction()
real IsotropicPhaseFunction()
REAL HenyeyGreensteinPhasePartConstant(REAL asymmetry)
real HenyeyGreensteinPhasePartConstant(real asymmetry)
REAL g = asymmetry;
real g = asymmetry;
REAL HenyeyGreensteinPhasePartVarying(REAL asymmetry, REAL LdotD)
real HenyeyGreensteinPhasePartVarying(real asymmetry, real LdotD)
REAL g = asymmetry;
real g = asymmetry;
REAL HenyeyGreensteinPhaseFunction(REAL asymmetry, REAL LdotD)
real HenyeyGreensteinPhaseFunction(real asymmetry, real LdotD)
{
return HenyeyGreensteinPhasePartConstant(asymmetry) *
HenyeyGreensteinPhasePartVarying(asymmetry, LdotD);

REAL3 TransmittanceColorAtDistanceToAbsorption(REAL3 transmittanceColor, REAL atDistance)
real3 TransmittanceColorAtDistanceToAbsorption(real3 transmittanceColor, real atDistance)
{
return -log(transmittanceColor + FLT_EPS) / max(atDistance, FLT_EPS);
}

82
ScriptableRenderPipeline/Core/ShaderLibrary/Wind.hlsl


TEXTURE2D(WIND_SETTINGS_TexGust);
SAMPLER(sampler_WIND_SETTINGS_TexGust);
REAL4 WIND_SETTINGS_WorldDirectionAndSpeed;
REAL WIND_SETTINGS_FlexNoiseScale;
REAL WIND_SETTINGS_ShiverNoiseScale;
REAL WIND_SETTINGS_Turbulence;
REAL WIND_SETTINGS_GustSpeed;
REAL WIND_SETTINGS_GustScale;
REAL WIND_SETTINGS_GustWorldScale;
real4 WIND_SETTINGS_WorldDirectionAndSpeed;
real WIND_SETTINGS_FlexNoiseScale;
real WIND_SETTINGS_ShiverNoiseScale;
real WIND_SETTINGS_Turbulence;
real WIND_SETTINGS_GustSpeed;
real WIND_SETTINGS_GustScale;
real WIND_SETTINGS_GustWorldScale;
REAL AttenuateTrunk(REAL x, REAL s)
real AttenuateTrunk(real x, real s)
REAL r = (x / s);
real r = (x / s);
REAL3 Rotate(REAL3 pivot, REAL3 position, REAL3 rotationAxis, REAL angle)
real3 Rotate(real3 pivot, real3 position, real3 rotationAxis, real angle)
REAL3 cpa = pivot + rotationAxis * dot(rotationAxis, position - pivot);
real3 cpa = pivot + rotationAxis * dot(rotationAxis, position - pivot);
REAL3 Direction;
REAL Strength;
REAL3 ShiverStrength;
REAL3 ShiverDirection;
real3 Direction;
real Strength;
real3 ShiverStrength;
real3 ShiverDirection;
REAL3 texNoise(REAL3 worldPos, REAL LOD)
real3 texNoise(real3 worldPos, real LOD)
REAL texGust(REAL3 worldPos, REAL LOD)
real texGust(real3 worldPos, real LOD)
WindData GetAnalyticalWind(REAL3 WorldPosition, REAL3 PivotPosition, REAL drag, REAL shiverDrag, REAL initialBend, REAL4 time)
WindData GetAnalyticalWind(real3 WorldPosition, real3 PivotPosition, real drag, real shiverDrag, real initialBend, real4 time)
REAL3 normalizedDir = normalize(WIND_SETTINGS_WorldDirectionAndSpeed.xyz);
real3 normalizedDir = normalize(WIND_SETTINGS_WorldDirectionAndSpeed.xyz);
REAL3 worldOffset = normalizedDir * WIND_SETTINGS_WorldDirectionAndSpeed.w * time.y;
REAL3 gustWorldOffset = normalizedDir * WIND_SETTINGS_GustSpeed * time.y;
real3 worldOffset = normalizedDir * WIND_SETTINGS_WorldDirectionAndSpeed.w * time.y;
real3 gustWorldOffset = normalizedDir * WIND_SETTINGS_GustSpeed * time.y;
REAL3 trunk = REAL3(0,0,0);
real3 trunk = real3(0,0,0);
if(WIND_SETTINGS_WorldDirectionAndSpeed.w > 0.0 || WIND_SETTINGS_Turbulence > 0.0)
{

REAL gust = 0.0;
real gust = 0.0;
if(WIND_SETTINGS_GustSpeed > 0.0)
{

REAL3 trunkNoise =
real3 trunkNoise =
(
(normalizedDir * WIND_SETTINGS_WorldDirectionAndSpeed.w)
+ (gust * normalizedDir * WIND_SETTINGS_GustSpeed)

// Shiver Noise
REAL3 shiverNoise = texNoise((WorldPosition - worldOffset)*WIND_SETTINGS_ShiverNoiseScale,0) * shiverDrag * WIND_SETTINGS_Turbulence;
real3 shiverNoise = texNoise((WorldPosition - worldOffset)*WIND_SETTINGS_ShiverNoiseScale,0) * shiverDrag * WIND_SETTINGS_Turbulence;
REAL3 dir = trunkNoise;
REAL flex = length(trunkNoise) + initialBend;
REAL shiver = length(shiverNoise);
real3 dir = trunkNoise;
real flex = length(trunkNoise) + initialBend;
real shiver = length(shiverNoise);
result.Direction = dir;
result.ShiverDirection = shiverNoise;

void ApplyWindDisplacement( inout REAL3 positionWS,
REAL3 normalWS,
REAL3 rootWP,
REAL stiffness,
REAL drag,
REAL shiverDrag,
REAL shiverDirectionality,
REAL initialBend,
REAL shiverMask,
REAL4 time)
void ApplyWindDisplacement( inout real3 positionWS,
real3 normalWS,
real3 rootWP,
real stiffness,
real drag,
real shiverDrag,
real shiverDirectionality,
real initialBend,
real shiverMask,
real4 time)
REAL att = AttenuateTrunk(distance(positionWS, rootWP), stiffness);
REAL3 rotAxis = cross(REAL3(0, 1, 0), wind.Direction);
real att = AttenuateTrunk(distance(positionWS, rootWP), stiffness);
real3 rotAxis = cross(real3(0, 1, 0), wind.Direction);
REAL3 shiverDirection = normalize(lerp(normalWS, normalize(wind.Direction + wind.ShiverDirection), shiverDirectionality));
real3 shiverDirection = normalize(lerp(normalWS, normalize(wind.Direction + wind.ShiverDirection), shiverDirectionality));
positionWS += wind.ShiverStrength * shiverDirection * shiverMask;
}

正在加载...
取消
保存