浏览代码

Merge pull request #801 from Unity-Technologies/pr/798

Pr 798
/main
GitHub 7 年前
当前提交
9d3b9c14
共有 45 个文件被更改,包括 1822 次插入2635 次删除
  1. 1001
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Common.hlsl
  2. 80
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/CommonLighting.hlsl
  3. 498
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Debug.hlsl
  4. 14
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/Shadow.hlsl
  5. 44
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  6. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  7. 618
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/MaterialDebug.cs
  8. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  9. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Deferred.shader
  10. 76
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl
  11. 25
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Deferred.compute
  12. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  13. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopDef.hlsl
  14. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Shadow.hlsl
  15. 20
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/Resources/VolumetricLighting.compute
  16. 1001
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl
  17. 290
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  18. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitBuiltinData.hlsl
  19. 528
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitProperties.hlsl
  20. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitReference.hlsl
  21. 19
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.compute
  22. 72
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Unlit/UnlitProperties.hlsl
  23. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPass.cs
  24. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPass.cs.hlsl
  25. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassForward.hlsl
  26. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl
  27. 1
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/3DObjects/CornelBox/Cornell Box.fbx.meta
  28. 1
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/3DObjects/Sphere/Sphere.fbx.meta
  29. 1
      Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/CommonAssets/Cornell Box.fbx.meta
  30. 1
      Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/040_UpgradeScene/Models/Environment/Floor.fbx.meta
  31. 11
      Tests/Scripts/Editor.meta
  32. 8
      Tests/Editor.meta
  33. 8
      Tests/GraphicsTests/Framework.meta
  34. 8
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Scripts.meta
  35. 8
      Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/040_UpgradeScene/Scripts.meta
  36. 11
      Tests/Scripts/Editor/GraphicTests/HDRenderPipeline/DebugViewController_Editor.cs.meta
  37. 8
      Tests/ShaderGeneratorTests.meta
  38. 8
      Tests/GraphicsTests/Framework/Editor.meta
  39. 8
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Scripts/Editor.meta
  40. 8
      Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/040_UpgradeScene/Scripts/Editor.meta
  41. 8
      Tests/ShaderGeneratorTests/Editor.meta

1001
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Common.hlsl
文件差异内容过多而无法显示
查看文件

80
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/CommonLighting.hlsl


// Attenuation functions
//-----------------------------------------------------------------------------
// Ref: Moving Frostbite to PBR
real SmoothDistanceAttenuation(real squaredDistance, real invSqrAttenuationRadius)
// Ref: Moving Frostbite to PBR.
real QuadraticAttenuation(real attenuation)
{
return attenuation * attenuation;
}
// Non physically based hack to limit light influence to attenuationRadius.
real DistanceAttenuation(real squaredDistance, real invSqrAttenuationRadius)
real smoothFactor = saturate(1.0 - factor * factor);
return smoothFactor * smoothFactor;
return saturate(1.0 - factor * factor);
}
real SmoothDistanceAttenuation(real squaredDistance, real invSqrAttenuationRadius)
{
real smoothFactor = DistanceAttenuation(squaredDistance, invSqrAttenuationRadius);
return QuadraticAttenuation(smoothFactor);
real GetDistanceAttenuation(real sqrDist, real invSqrAttenuationRadius)
real SmoothQuadraticDistanceAttenuation(real distSq, real distRcp, real invSqrAttenuationRadius)
real attenuation = 1.0 / (max(PUNCTUAL_LIGHT_THRESHOLD * PUNCTUAL_LIGHT_THRESHOLD, sqrDist));
// Non physically based hack to limit light influence to attenuationRadius.
attenuation *= SmoothDistanceAttenuation(sqrDist, invSqrAttenuationRadius);
return attenuation;
// Becomes quadratic after the call to QuadraticAttenuation().
real attenuation = min(distRcp, 1.0 / PUNCTUAL_LIGHT_THRESHOLD);
attenuation *= DistanceAttenuation(distSq, invSqrAttenuationRadius);
return QuadraticAttenuation(attenuation);
real GetDistanceAttenuation(real3 unL, real invSqrAttenuationRadius)
real SmoothQuadraticDistanceAttenuation(real3 unL, real invSqrAttenuationRadius)
real sqrDist = dot(unL, unL);
return GetDistanceAttenuation(sqrDist, invSqrAttenuationRadius);
real distSq = dot(unL, unL);
real distRcp = rsqrt(distSq);
return SmoothQuadraticDistanceAttenuation(distSq, distRcp, invSqrAttenuationRadius);
real GetAngleAttenuation(real3 L, real3 lightDir, real lightAngleScale, real lightAngleOffset)
real AngleAttenuation(real cosFwd, real lightAngleScale, real lightAngleOffset)
real cd = dot(lightDir, L);
real attenuation = saturate(cd * lightAngleScale + lightAngleOffset);
// smooth the transition
attenuation *= attenuation;
return saturate(cosFwd * lightAngleScale + lightAngleOffset);
}
return attenuation;
real SmoothAngleAttenuation(real cosFwd, real lightAngleScale, real lightAngleOffset)
{
real attenuation = AngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset);
return QuadraticAttenuation(attenuation);
}
real SmoothAngleAttenuation(real3 L, real3 lightFwdDir, real lightAngleScale, real lightAngleOffset)
{
real cosFwd = dot(-L, lightFwdDir);
return SmoothAngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset);
}
// Combines SmoothQuadraticDistanceAttenuation() and SmoothAngleAttenuation() in an efficient manner.
// distances = {d, d^2, 1/d, d_proj}, where d_proj = dot(lightToSample, lightData.forward).
real SmoothPunctualLightAttenuation(real4 distances, real invSqrAttenuationRadius,
real lightAngleScale, real lightAngleOffset)
{
real distSq = distances.y;
real distRcp = distances.z;
real distProj = distances.w;
real cosFwd = distProj * distRcp;
real attenuation = min(distRcp, 1.0 / PUNCTUAL_LIGHT_THRESHOLD);
attenuation *= DistanceAttenuation(distSq, invSqrAttenuationRadius);
attenuation *= AngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset);
return QuadraticAttenuation(attenuation);
}
// Applies SmoothDistanceAttenuation() after transforming the attenuation ellipsoid into a sphere.

// 'unL' should be computed from the center of the ellipsoid.
real GetEllipsoidalDistanceAttenuation(real3 unL, real invSqRadius,
real3 axis, real invAspectRatio)
real EllipsoidalDistanceAttenuation(real3 unL, real invSqRadius,
real3 axis, real invAspectRatio)
{
// Project the unnormalized light vector onto the axis.
real projL = dot(unL, axis);

// Applies SmoothDistanceAttenuation() using the axis-aligned ellipsoid of the given dimensions.
// Both the ellipsoid and 'unL' should be in the same coordinate system.
// 'unL' should be computed from the center of the ellipsoid.
real GetEllipsoidalDistanceAttenuation(real3 unL, real3 invHalfDim)
real EllipsoidalDistanceAttenuation(real3 unL, real3 invHalfDim)
{
// Transform the light vector so that we can work with
// with the ellipsoid as if it was a unit sphere.

// If the diagonal of the box is 'd', invHalfDim = rcp(0.5 * d).
// Both the box and 'unL' should be in the same coordinate system.
// 'unL' should be computed from the center of the box.
real GetBoxDistanceAttenuation(real3 unL, real3 invHalfDim)
real BoxDistanceAttenuation(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.

498
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Debug.hlsl


#ifndef UNITY_DEBUG_INCLUDED
#define UNITY_DEBUG_INCLUDED
// Given an enum (represented by an int here), return a color.
// Use for DebugView of enum
real3 GetIndexColor(int index)
{
real3 outColor = real3(1.0, 0.0, 0.0);
if (index == 0)
outColor = real3(1.0, 0.5, 0.5);
else if (index == 1)
outColor = real3(0.5, 1.0, 0.5);
else if (index == 2)
outColor = real3(0.5, 0.5, 1.0);
else if (index == 3)
outColor = real3(1.0, 1.0, 0.5);
else if (index == 4)
outColor = real3(1.0, 0.5, 1.0);
else if (index == 5)
outColor = real3(0.5, 1.0, 1.0);
else if (index == 6)
outColor = real3(0.25, 0.75, 1.0);
else if (index == 7)
outColor = real3(1.0, 0.75, 0.25);
else if (index == 8)
outColor = real3(0.75, 1.0, 0.25);
else if (index == 9)
outColor = real3(0.75, 0.25, 1.0);
return outColor;
}
bool SampleDebugFont(int2 pixCoord, uint digit)
{
if (pixCoord.x < 0 || pixCoord.y < 0 || pixCoord.x >= 5 || pixCoord.y >= 9 || digit > 9)
return false;
#define PACK_BITS25(_x0,_x1,_x2,_x3,_x4,_x5,_x6,_x7,_x8,_x9,_x10,_x11,_x12,_x13,_x14,_x15,_x16,_x17,_x18,_x19,_x20,_x21,_x22,_x23,_x24) (_x0|(_x1<<1)|(_x2<<2)|(_x3<<3)|(_x4<<4)|(_x5<<5)|(_x6<<6)|(_x7<<7)|(_x8<<8)|(_x9<<9)|(_x10<<10)|(_x11<<11)|(_x12<<12)|(_x13<<13)|(_x14<<14)|(_x15<<15)|(_x16<<16)|(_x17<<17)|(_x18<<18)|(_x19<<19)|(_x20<<20)|(_x21<<21)|(_x22<<22)|(_x23<<23)|(_x24<<24))
#define _ 0
#define x 1
uint fontData[9][2] = {
{ PACK_BITS25(_,_,x,_,_, _,_,x,_,_, _,x,x,x,_, x,x,x,x,x, _,_,_,x,_), PACK_BITS25(x,x,x,x,x, _,x,x,x,_, x,x,x,x,x, _,x,x,x,_, _,x,x,x,_) },
{ PACK_BITS25(_,x,_,x,_, _,x,x,_,_, x,_,_,_,x, _,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,x, _,_,_,_,x, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, x,_,x,_,_, x,_,_,_,x, _,_,_,x,_, _,_,x,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,_,x, _,_,x,_,_, _,x,_,x,_), PACK_BITS25(x,_,x,x,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,x,_, _,x,x,x,_, _,x,_,x,_), PACK_BITS25(x,x,_,_,x, x,x,x,x,_, _,_,x,_,_, _,x,x,x,_, _,x,x,x,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,x,_,_, _,_,_,_,x, x,_,_,x,_), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,_,x,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,x,_,_,_, _,_,_,_,x, x,x,x,x,x), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(_,x,_,x,_, _,_,x,_,_, x,_,_,_,_, x,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(_,_,x,_,_, x,x,x,x,x, x,x,x,x,x, _,x,x,x,_, _,_,_,x,_), PACK_BITS25(_,x,x,x,_, _,x,x,x,_, _,x,_,_,_, _,x,x,x,_, _,x,x,x,_) }
};
#undef _
#undef x
#undef PACK_BITS25
return (fontData[8 - pixCoord.y][digit >= 5] >> ((digit % 5) * 5 + pixCoord.x)) & 1;
}
bool SampleDebugFontNumber(int2 pixCoord, uint number)
{
pixCoord.y -= 4;
if (number <= 9)
{
return SampleDebugFont(pixCoord - int2(6, 0), number);
}
else
{
return (SampleDebugFont(pixCoord, number / 10) | SampleDebugFont(pixCoord - int2(6, 0), number % 10));
}
}
float4 GetStreamingMipColor(uint mipCount, float4 mipInfo)
{
// alpha is amount to blend with source color (0.0 = use original, 1.0 = use new color)
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
uint originalTextureMipCount = uint(mipInfo.y);
// If material/shader mip info (original mip level) has not been set its not a streamed texture
if (originalTextureMipCount == 0)
return float4(1.0, 1.0, 1.0, 0.0);
uint desiredMipLevel = uint(mipInfo.z);
uint mipCountDesired = uint(originalTextureMipCount)-uint(desiredMipLevel);
if (mipCount == 0)
{
// Magenta if mip count invalid
return float4(1.0, 0.0, 1.0, 1.0);
}
else if (mipCount < mipCountDesired)
{
// red tones when not at the desired mip level (reduction due to budget). Brighter is further from original, alpha 0 when at desired
float ratioToDesired = float(mipCount) / float(mipCountDesired);
return float4(1.0, 0.0, 0.0, 1.0 - ratioToDesired);
}
else if (mipCount >= originalTextureMipCount)
{
// original color when at (or beyond) original mip count
return float4(1.0, 1.0, 1.0, 0.0);
}
else
{
// green tones when not at the original mip level. Brighter is closer to original, alpha 0 when at original
float ratioToOriginal = float(mipCount) / float(originalTextureMipCount);
return float4(0.0, 1.0, 0.0, 1.0 - ratioToOriginal);
}
}
float4 GetSimpleMipCountColor(uint mipCount)
{
// Grey scale for mip counts where mip count of 12 = white
float mipCountColor = float(mipCount) / 12.0;
float4 color = float4(mipCountColor, mipCountColor, mipCountColor, 1.0f);
// alpha is amount to blend with source color (0.0 = use original, 1.0 = use new color)
// Magenta is no valid mip count
// Original colour if greater than 12
return mipCount==0 ? float4(1.0, 0.0, 1.0, 1.0) : (mipCount > 12 ? float4(1.0, 1.0, 1.0, 0.0) : color );
}
float4 GetMipLevelColor(float2 uv, float4 texelSize)
{
// Push down into colors list to "optimal level" in following table.
// .zw is texture width,height so *2 is down one mip, *4 is down two mips
texelSize.zw *= 4.0;
float mipLevel = ComputeTextureLOD(uv, texelSize.wz);
mipLevel = clamp(mipLevel, 0.0, 5.0 - 0.0001);
float4 colors[6] = {
float4(0.0, 0.0, 1.0, 0.8), // 0 BLUE = too little texture detail
float4(0.0, 0.5, 1.0, 0.4), // 1
float4(1.0, 1.0, 1.0, 0.0), // 2 = optimal level
float4(1.0, 0.7, 0.0, 0.2), // 3 (YELLOW tint)
float4(1.0, 0.3, 0.0, 0.6), // 4 (clamped mipLevel 4.9999)
float4(1.0, 0.0, 0.0, 0.8) // 5 RED = too much texture detail (max blended value)
};
int mipLevelInt = floor(mipLevel);
float t = frac(mipLevel);
float4 a = colors[mipLevelInt];
float4 b = colors[mipLevelInt + 1];
float4 color = lerp(a, b, t);
return color;
}
float3 GetDebugMipColor(float3 originalColor, Texture2D tex, float4 texelSize, float2 uv)
{
// https://aras-p.info/blog/2011/05/03/a-way-to-visualize-mip-levels/
float4 mipColor= GetMipLevelColor(uv, texelSize);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugMipCountColor(float3 originalColor, Texture2D tex)
{
uint mipCount = GetMipCount(tex);
float4 mipColor = GetSimpleMipCountColor(mipCount);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugStreamingMipColor(Texture2D tex, float4 mipInfo)
{
uint mipCount = GetMipCount(tex);
return GetStreamingMipColor(mipCount, mipInfo).xyz;
}
float3 GetDebugStreamingMipColorBlended(float3 originalColor, Texture2D tex, float4 mipInfo)
{
uint mipCount = GetMipCount(tex);
float4 mipColor = GetStreamingMipColor(mipCount, mipInfo);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugMipColorIncludingMipReduction(float3 originalColor, Texture2D tex, float4 texelSize, float2 uv, float4 mipInfo)
{
uint originalTextureMipCount = uint(mipInfo.y);
if (originalTextureMipCount != 0)
{
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
// Mip count has been reduced but the texelSize was not updated to take that into account
uint mipCount = GetMipCount(tex);
uint mipReductionLevel = originalTextureMipCount - mipCount;
uint mipReductionFactor = 1 << mipReductionLevel;
if (mipReductionFactor)
{
float oneOverMipReductionFactor = 1.0 / mipReductionFactor;
// texelSize.xy *= mipReductionRatio; // Unused in GetDebugMipColor so lets not re-calculate it
texelSize.zw *= oneOverMipReductionFactor;
}
}
return GetDebugMipColor(originalColor, tex, texelSize, uv);
}
float3 GetDebugMipReductionColor(Texture2D tex, float4 mipInfo)
{
uint originalTextureMipCount = uint(mipInfo.y);
if (originalTextureMipCount != 0)
{
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
// Mip count has been reduced but the texelSize was not updated to take that into account
uint mipCount = GetMipCount(tex);
uint mipReductionLevel = originalTextureMipCount - mipCount;
float mipCol = float(mipReductionLevel) / 12.0;
return float3(0, mipCol, 0);
}
// Can't calculate without original mip count - return magenta
return float3(1.0, 0.0, 1.0);
}
#ifdef DEBUG_DISPLAY
float3 GetTextureDataDebug(uint paramId, float2 uv, Texture2D tex, float4 texelSize, float4 mipInfo, float3 originalColor)
{
switch (paramId)
{
case DEBUGMIPMAPMODE_MIP_RATIO:
return GetDebugMipColorIncludingMipReduction(originalColor, tex, texelSize, uv, mipInfo);
case DEBUGMIPMAPMODE_MIP_COUNT:
return GetDebugMipCountColor(originalColor, tex);
case DEBUGMIPMAPMODE_MIP_COUNT_REDUCTION:
return GetDebugMipReductionColor(tex, mipInfo);
case DEBUGMIPMAPMODE_STREAMING_MIP_BUDGET:
return GetDebugStreamingMipColor(tex, mipInfo);
case DEBUGMIPMAPMODE_STREAMING_MIP:
return GetDebugStreamingMipColorBlended(originalColor, tex, mipInfo);
}
return originalColor;
}
#endif // DEBUG_DISPLAY
#endif // UNITY_DEBUG_INCLUDED
#ifndef UNITY_DEBUG_INCLUDED
#define UNITY_DEBUG_INCLUDED
// Given an enum (represented by an int here), return a color.
// Use for DebugView of enum
real3 GetIndexColor(int index)
{
real3 outColor = real3(1.0, 0.0, 0.0);
if (index == 0)
outColor = real3(1.0, 0.5, 0.5);
else if (index == 1)
outColor = real3(0.5, 1.0, 0.5);
else if (index == 2)
outColor = real3(0.5, 0.5, 1.0);
else if (index == 3)
outColor = real3(1.0, 1.0, 0.5);
else if (index == 4)
outColor = real3(1.0, 0.5, 1.0);
else if (index == 5)
outColor = real3(0.5, 1.0, 1.0);
else if (index == 6)
outColor = real3(0.25, 0.75, 1.0);
else if (index == 7)
outColor = real3(1.0, 0.75, 0.25);
else if (index == 8)
outColor = real3(0.75, 1.0, 0.25);
else if (index == 9)
outColor = real3(0.75, 0.25, 1.0);
return outColor;
}
bool SampleDebugFont(int2 pixCoord, uint digit)
{
if (pixCoord.x < 0 || pixCoord.y < 0 || pixCoord.x >= 5 || pixCoord.y >= 9 || digit > 9)
return false;
#define PACK_BITS25(_x0,_x1,_x2,_x3,_x4,_x5,_x6,_x7,_x8,_x9,_x10,_x11,_x12,_x13,_x14,_x15,_x16,_x17,_x18,_x19,_x20,_x21,_x22,_x23,_x24) (_x0|(_x1<<1)|(_x2<<2)|(_x3<<3)|(_x4<<4)|(_x5<<5)|(_x6<<6)|(_x7<<7)|(_x8<<8)|(_x9<<9)|(_x10<<10)|(_x11<<11)|(_x12<<12)|(_x13<<13)|(_x14<<14)|(_x15<<15)|(_x16<<16)|(_x17<<17)|(_x18<<18)|(_x19<<19)|(_x20<<20)|(_x21<<21)|(_x22<<22)|(_x23<<23)|(_x24<<24))
#define _ 0
#define x 1
uint fontData[9][2] = {
{ PACK_BITS25(_,_,x,_,_, _,_,x,_,_, _,x,x,x,_, x,x,x,x,x, _,_,_,x,_), PACK_BITS25(x,x,x,x,x, _,x,x,x,_, x,x,x,x,x, _,x,x,x,_, _,x,x,x,_) },
{ PACK_BITS25(_,x,_,x,_, _,x,x,_,_, x,_,_,_,x, _,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,x, _,_,_,_,x, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, x,_,x,_,_, x,_,_,_,x, _,_,_,x,_, _,_,x,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,_,x, _,_,x,_,_, _,x,_,x,_), PACK_BITS25(x,_,x,x,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,x,_, _,x,x,x,_, _,x,_,x,_), PACK_BITS25(x,x,_,_,x, x,x,x,x,_, _,_,x,_,_, _,x,x,x,_, _,x,x,x,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,x,_,_, _,_,_,_,x, x,_,_,x,_), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,_,x,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,x,_,_,_, _,_,_,_,x, x,x,x,x,x), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(_,x,_,x,_, _,_,x,_,_, x,_,_,_,_, x,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(_,_,x,_,_, x,x,x,x,x, x,x,x,x,x, _,x,x,x,_, _,_,_,x,_), PACK_BITS25(_,x,x,x,_, _,x,x,x,_, _,x,_,_,_, _,x,x,x,_, _,x,x,x,_) }
};
#undef _
#undef x
#undef PACK_BITS25
return (fontData[8 - pixCoord.y][digit >= 5] >> ((digit % 5) * 5 + pixCoord.x)) & 1;
}
bool SampleDebugFontNumber(int2 pixCoord, uint number)
{
pixCoord.y -= 4;
if (number <= 9)
{
return SampleDebugFont(pixCoord - int2(6, 0), number);
}
else
{
return (SampleDebugFont(pixCoord, number / 10) | SampleDebugFont(pixCoord - int2(6, 0), number % 10));
}
}
float4 GetStreamingMipColor(uint mipCount, float4 mipInfo)
{
// alpha is amount to blend with source color (0.0 = use original, 1.0 = use new color)
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
uint originalTextureMipCount = uint(mipInfo.y);
// If material/shader mip info (original mip level) has not been set its not a streamed texture
if (originalTextureMipCount == 0)
return float4(1.0, 1.0, 1.0, 0.0);
uint desiredMipLevel = uint(mipInfo.z);
uint mipCountDesired = uint(originalTextureMipCount)-uint(desiredMipLevel);
if (mipCount == 0)
{
// Magenta if mip count invalid
return float4(1.0, 0.0, 1.0, 1.0);
}
else if (mipCount < mipCountDesired)
{
// red tones when not at the desired mip level (reduction due to budget). Brighter is further from original, alpha 0 when at desired
float ratioToDesired = float(mipCount) / float(mipCountDesired);
return float4(1.0, 0.0, 0.0, 1.0 - ratioToDesired);
}
else if (mipCount >= originalTextureMipCount)
{
// original color when at (or beyond) original mip count
return float4(1.0, 1.0, 1.0, 0.0);
}
else
{
// green tones when not at the original mip level. Brighter is closer to original, alpha 0 when at original
float ratioToOriginal = float(mipCount) / float(originalTextureMipCount);
return float4(0.0, 1.0, 0.0, 1.0 - ratioToOriginal);
}
}
float4 GetSimpleMipCountColor(uint mipCount)
{
// Grey scale for mip counts where mip count of 12 = white
float mipCountColor = float(mipCount) / 12.0;
float4 color = float4(mipCountColor, mipCountColor, mipCountColor, 1.0f);
// alpha is amount to blend with source color (0.0 = use original, 1.0 = use new color)
// Magenta is no valid mip count
// Original colour if greater than 12
return mipCount==0 ? float4(1.0, 0.0, 1.0, 1.0) : (mipCount > 12 ? float4(1.0, 1.0, 1.0, 0.0) : color );
}
float4 GetMipLevelColor(float2 uv, float4 texelSize)
{
// Push down into colors list to "optimal level" in following table.
// .zw is texture width,height so *2 is down one mip, *4 is down two mips
texelSize.zw *= 4.0;
float mipLevel = ComputeTextureLOD(uv, texelSize.wz);
mipLevel = clamp(mipLevel, 0.0, 5.0 - 0.0001);
float4 colors[6] = {
float4(0.0, 0.0, 1.0, 0.8), // 0 BLUE = too little texture detail
float4(0.0, 0.5, 1.0, 0.4), // 1
float4(1.0, 1.0, 1.0, 0.0), // 2 = optimal level
float4(1.0, 0.7, 0.0, 0.2), // 3 (YELLOW tint)
float4(1.0, 0.3, 0.0, 0.6), // 4 (clamped mipLevel 4.9999)
float4(1.0, 0.0, 0.0, 0.8) // 5 RED = too much texture detail (max blended value)
};
int mipLevelInt = floor(mipLevel);
float t = frac(mipLevel);
float4 a = colors[mipLevelInt];
float4 b = colors[mipLevelInt + 1];
float4 color = lerp(a, b, t);
return color;
}
float3 GetDebugMipColor(float3 originalColor, Texture2D tex, float4 texelSize, float2 uv)
{
// https://aras-p.info/blog/2011/05/03/a-way-to-visualize-mip-levels/
float4 mipColor= GetMipLevelColor(uv, texelSize);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugMipCountColor(float3 originalColor, Texture2D tex)
{
uint mipCount = GetMipCount(tex);
float4 mipColor = GetSimpleMipCountColor(mipCount);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugStreamingMipColor(Texture2D tex, float4 mipInfo)
{
uint mipCount = GetMipCount(tex);
return GetStreamingMipColor(mipCount, mipInfo).xyz;
}
float3 GetDebugStreamingMipColorBlended(float3 originalColor, Texture2D tex, float4 mipInfo)
{
uint mipCount = GetMipCount(tex);
float4 mipColor = GetStreamingMipColor(mipCount, mipInfo);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugMipColorIncludingMipReduction(float3 originalColor, Texture2D tex, float4 texelSize, float2 uv, float4 mipInfo)
{
uint originalTextureMipCount = uint(mipInfo.y);
if (originalTextureMipCount != 0)
{
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
// Mip count has been reduced but the texelSize was not updated to take that into account
uint mipCount = GetMipCount(tex);
uint mipReductionLevel = originalTextureMipCount - mipCount;
uint mipReductionFactor = 1 << mipReductionLevel;
if (mipReductionFactor)
{
float oneOverMipReductionFactor = 1.0 / mipReductionFactor;
// texelSize.xy *= mipReductionRatio; // Unused in GetDebugMipColor so lets not re-calculate it
texelSize.zw *= oneOverMipReductionFactor;
}
}
return GetDebugMipColor(originalColor, tex, texelSize, uv);
}
float3 GetDebugMipReductionColor(Texture2D tex, float4 mipInfo)
{
uint originalTextureMipCount = uint(mipInfo.y);
if (originalTextureMipCount != 0)
{
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
// Mip count has been reduced but the texelSize was not updated to take that into account
uint mipCount = GetMipCount(tex);
uint mipReductionLevel = originalTextureMipCount - mipCount;
float mipCol = float(mipReductionLevel) / 12.0;
return float3(0, mipCol, 0);
}
// Can't calculate without original mip count - return magenta
return float3(1.0, 0.0, 1.0);
}
#ifdef DEBUG_DISPLAY
float3 GetTextureDataDebug(uint paramId, float2 uv, Texture2D tex, float4 texelSize, float4 mipInfo, float3 originalColor)
{
switch (paramId)
{
case DEBUGMIPMAPMODE_MIP_RATIO:
return GetDebugMipColorIncludingMipReduction(originalColor, tex, texelSize, uv, mipInfo);
case DEBUGMIPMAPMODE_MIP_COUNT:
return GetDebugMipCountColor(originalColor, tex);
case DEBUGMIPMAPMODE_MIP_COUNT_REDUCTION:
return GetDebugMipReductionColor(tex, mipInfo);
case DEBUGMIPMAPMODE_STREAMING_MIP_BUDGET:
return GetDebugStreamingMipColor(tex, mipInfo);
case DEBUGMIPMAPMODE_STREAMING_MIP:
return GetDebugStreamingMipColorBlended(originalColor, tex, mipInfo);
}
return originalColor;
}
#endif // DEBUG_DISPLAY
#endif // UNITY_DEBUG_INCLUDED

14
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/Shadow.hlsl


}
// 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, real3 lightPositionWS, real3 L );
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 lightPositionWS, real3 L, real2 positionSS );
// shadow sampling prototypes with screenspace info
real GetDirectionalShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L );

#include "ShadowAlgorithms.hlsl" // engine default algorithms (don't modify)
#ifndef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real4 L )
real GetPunctualShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 lightPositionWS, real3 L )
return EvalShadow_PunctualDepth(shadowContext, positionWS, normalWS, shadowDataIndex, L);
return EvalShadow_PunctualDepth(shadowContext, positionWS, normalWS, shadowDataIndex, lightPositionWS, 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, real3 lightPositionWS, real3 L, real2 positionSS )
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, lightPositionWS, L );
}
#endif

real GetDirectionalShadowAttenuation( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int shadowDataIndex, real3 L, real2 positionSS )
{
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, lightPositionWS, L );
}
#endif

44
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl


//
// 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, real3 lightPositionWS, real3 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 ) ), sd.texelSizeRcp.zw, sd.normalBias );
real3 lpos = lightPositionWS;
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 );
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// get the algorithm

}
#define EvalShadow_PointDepth_( _samplerType ) \
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, real3 lightPositionWS, real3 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 ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
real3 lpos = lightPositionWS; \
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 ); \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \

//
// 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, real3 lightPositionWS, real3 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;
positionWS = biased_posWS;
faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1;
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
real3 lpos = lightPositionWS;
positionWS = biased_posWS;
faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1;
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias );
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );

}
#define EvalShadow_PunctualDepth_( _samplerType ) \
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, real3 lightPositionWS, real3 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; \
positionWS = biased_posWS; \
faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1; \
real3 biased_posWS = positionWS + EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
real3 lpos = lightPositionWS; \
positionWS = biased_posWS; \
faceIndex = EvalShadow_GetCubeFaceID( lpos - biased_posWS ) + 1; \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L.xyz ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
\
sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \

return closestWS.xyz / closestWS.w;
}
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, real3 lightPositionWS, real3 L )
{
// load the right shadow data for the current face
real4 dirShadowSplitSpheres[4];

return closestWS.xyz / closestWS.w;
}
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, real3 lightPositionWS, real3 L )
{
// load the right shadow data for the current face
real4 dirShadowSplitSpheres[4];

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs


public Vector4[] frustumPlaneEquations;
public Camera camera;
public uint taaFrameIndex;
public Vector2 taaFrameRotation;
public Vector4 viewParam;
public PostProcessRenderContext postprocessRenderContext;

const uint taaFrameCount = 8;
taaFrameIndex = taaEnabled ? (uint)Time.renderedFrameCount % taaFrameCount : 0;
taaFrameRotation = new Vector2(Mathf.Sin(taaFrameIndex * (0.5f * Mathf.PI)),
Mathf.Cos(taaFrameIndex * (0.5f * Mathf.PI)));
viewMatrix = gpuView;
projMatrix = gpuProj;

cmd.SetGlobalMatrix(HDShaderIDs._PrevViewProjMatrix, prevViewProjMatrix);
cmd.SetGlobalVectorArray(HDShaderIDs._FrustumPlanes, frustumPlaneEquations);
cmd.SetGlobalInt(HDShaderIDs._TaaFrameIndex, (int)taaFrameIndex);
cmd.SetGlobalVector(HDShaderIDs._TaaFrameRotation, taaFrameRotation);
}
// TODO: We should set all the value below globally and not let it under the control of Unity,

618
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/MaterialDebug.cs


using System.Collections.Generic;
using UnityEngine;
using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace Attributes
{
// 0 is reserved!
[GenerateHLSL]
public enum DebugViewVarying
{
None = 0,
Texcoord0 = 1,
Texcoord1,
Texcoord2,
Texcoord3,
VertexTangentWS,
VertexBitangentWS,
VertexNormalWS,
VertexColor,
VertexColorAlpha,
Last,
};
// Number must be contiguous
[GenerateHLSL]
public enum DebugViewGbuffer
{
None = 0,
Depth = DebugViewVarying.Last,
BakeDiffuseLightingWithAlbedoPlusEmissive,
BakeShadowMask0,
BakeShadowMask1,
BakeShadowMask2,
BakeShadowMask3,
Last,
}
// Number must be contiguous
[GenerateHLSL]
public enum DebugViewProperties
{
None = 0,
Tessellation = DebugViewGbuffer.Last,
PixelDisplacement,
VertexDisplacement,
TessellationDisplacement,
DepthOffset,
Lightmap,
Last,
}
}
[Serializable]
public class MaterialDebugSettings
{
private static bool isDebugViewMaterialInit = false;
public static GUIContent[] debugViewMaterialStrings = null;
public static int[] debugViewMaterialValues = null;
public static GUIContent[] debugViewEngineStrings = null;
public static int[] debugViewEngineValues = null;
public static GUIContent[] debugViewMaterialVaryingStrings = null;
public static int[] debugViewMaterialVaryingValues = null;
public static GUIContent[] debugViewMaterialPropertiesStrings = null;
public static int[] debugViewMaterialPropertiesValues = null;
public static GUIContent[] debugViewMaterialTextureStrings = null;
public static int[] debugViewMaterialTextureValues = null;
public static GUIContent[] debugViewMaterialGBufferStrings = null;
public static int[] debugViewMaterialGBufferValues = null;
public MaterialDebugSettings()
{
BuildDebugRepresentation();
}
// className include the additional "/"
void FillWithProperties(Type type, GUIContent[] debugViewMaterialStrings, int[] debugViewMaterialValues, string className, ref int index)
{
var attributes = type.GetCustomAttributes(true);
// Get attribute to get the start number of the value for the enum
var attr = attributes[0] as GenerateHLSL;
if (!attr.needParamDebug)
{
return;
}
var fields = type.GetFields();
var localIndex = 0;
foreach (var field in fields)
{
var fieldName = field.Name;
// Check if the display name have been override by the users
if (Attribute.IsDefined(field, typeof(SurfaceDataAttributes)))
{
var propertyAttr = (SurfaceDataAttributes[])field.GetCustomAttributes(typeof(SurfaceDataAttributes), false);
if (propertyAttr[0].displayName != "")
{
fieldName = propertyAttr[0].displayName;
}
}
fieldName = className + fieldName;
debugViewMaterialStrings[index] = new GUIContent(fieldName);
debugViewMaterialValues[index] = attr.paramDefinesStart + (int)localIndex;
index++;
localIndex++;
}
}
void FillWithPropertiesEnum(Type type, GUIContent[] debugViewMaterialStrings, int[] debugViewMaterialValues, string prefix, ref int index)
{
var names = Enum.GetNames(type);
var localIndex = 0;
foreach (var value in Enum.GetValues(type))
{
var valueName = prefix + names[localIndex];
debugViewMaterialStrings[index] = new GUIContent(valueName);
debugViewMaterialValues[index] = (int)value;
index++;
localIndex++;
}
}
public class MaterialItem
{
public String className;
public Type surfaceDataType;
public Type bsdfDataType;
};
void BuildDebugRepresentation()
{
if (!isDebugViewMaterialInit)
{
List<RenderPipelineMaterial> materialList = HDUtils.GetRenderPipelineMaterialList();
// TODO: Share this code to retrieve deferred material with HDRenderPipeline
// Find first material that have non 0 Gbuffer count and assign it as deferredMaterial
Type bsdfDataDeferredType = null;
foreach (RenderPipelineMaterial material in materialList)
{
if (material.GetMaterialGBufferCount() > 0)
{
bsdfDataDeferredType = material.GetType().GetNestedType("BSDFData");
}
}
// TODO: Handle the case of no Gbuffer material
Debug.Assert(bsdfDataDeferredType != null);
List<MaterialItem> materialItems = new List<MaterialItem>();
int numSurfaceDataFields = 0;
int numBSDFDataFields = 0;
foreach (RenderPipelineMaterial material in materialList)
{
MaterialItem item = new MaterialItem();
item.className = material.GetType().Name + "/";
item.surfaceDataType = material.GetType().GetNestedType("SurfaceData");
numSurfaceDataFields += item.surfaceDataType.GetFields().Length;
item.bsdfDataType = material.GetType().GetNestedType("BSDFData");
numBSDFDataFields += item.bsdfDataType.GetFields().Length;
materialItems.Add(item);
}
// Material properties debug
var num = typeof(Builtin.BuiltinData).GetFields().Length * materialList.Count // BuildtinData are duplicated for each material
+ numSurfaceDataFields + 1; // +1 for None case
debugViewMaterialStrings = new GUIContent[num];
debugViewMaterialValues = new int[num];
// Special case for None since it cannot be inferred from SurfaceData/BuiltinData
debugViewMaterialStrings[0] = new GUIContent("None");
debugViewMaterialValues[0] = 0;
var index = 1;
// 0 is a reserved number and should not be used (allow to track error)
foreach (MaterialItem item in materialItems)
{
// BuiltinData are duplicated for each material
FillWithProperties(typeof(Builtin.BuiltinData), debugViewMaterialStrings, debugViewMaterialValues, item.className, ref index);
FillWithProperties(item.surfaceDataType, debugViewMaterialStrings, debugViewMaterialValues, item.className, ref index);
}
// Engine properties debug
num = numBSDFDataFields + 1; // +1 for None case
debugViewEngineStrings = new GUIContent[num];
debugViewEngineValues = new int[num];
// 0 is a reserved number and should not be used (allow to track error)
debugViewEngineStrings[0] = new GUIContent("None");
debugViewEngineValues[0] = 0;
index = 1;
foreach (MaterialItem item in materialItems)
{
FillWithProperties(item.bsdfDataType, debugViewEngineStrings, debugViewEngineValues, item.className, ref index);
}
// Attributes debug
var varyingNames = Enum.GetNames(typeof(Attributes.DebugViewVarying));
debugViewMaterialVaryingStrings = new GUIContent[varyingNames.Length];
debugViewMaterialVaryingValues = new int[varyingNames.Length];
index = 0;
FillWithPropertiesEnum(typeof(Attributes.DebugViewVarying), debugViewMaterialVaryingStrings, debugViewMaterialVaryingValues, "", ref index);
// Properties debug
var propertiesNames = Enum.GetNames(typeof(Attributes.DebugViewProperties));
debugViewMaterialPropertiesStrings = new GUIContent[propertiesNames.Length];
debugViewMaterialPropertiesValues = new int[propertiesNames.Length];
index = 0;
FillWithPropertiesEnum(typeof(Attributes.DebugViewProperties), debugViewMaterialPropertiesStrings, debugViewMaterialPropertiesValues, "", ref index);
// Gbuffer debug
var gbufferNames = Enum.GetNames(typeof(Attributes.DebugViewGbuffer));
debugViewMaterialGBufferStrings = new GUIContent[gbufferNames.Length + bsdfDataDeferredType.GetFields().Length];
debugViewMaterialGBufferValues = new int[gbufferNames.Length + bsdfDataDeferredType.GetFields().Length];
index = 0;
FillWithPropertiesEnum(typeof(Attributes.DebugViewGbuffer), debugViewMaterialGBufferStrings, debugViewMaterialGBufferValues, "", ref index);
FillWithProperties(typeof(Lit.BSDFData), debugViewMaterialGBufferStrings, debugViewMaterialGBufferValues, "", ref index);
isDebugViewMaterialInit = true;
}
}
public int debugViewMaterial { get { return m_DebugViewMaterial; } }
public int debugViewEngine { get { return m_DebugViewEngine; } }
public Attributes.DebugViewVarying debugViewVarying { get { return m_DebugViewVarying; } }
public Attributes.DebugViewProperties debugViewProperties { get { return m_DebugViewProperties; } }
public int debugViewGBuffer { get { return m_DebugViewGBuffer; } }
int m_DebugViewMaterial = 0; // No enum there because everything is generated from materials.
int m_DebugViewEngine = 0; // No enum there because everything is generated from BSDFData
Attributes.DebugViewVarying m_DebugViewVarying = Attributes.DebugViewVarying.None;
Attributes.DebugViewProperties m_DebugViewProperties = Attributes.DebugViewProperties.None;
int m_DebugViewGBuffer = 0; // Can't use GBuffer enum here because the values are actually split between this enum and values from Lit.BSDFData
public int GetDebugMaterialIndex()
{
// This value is used in the shader for the actual debug display.
// There is only one uniform parameter for that so we just add all of them
// They are all mutually exclusive so return the sum will return the right index.
return m_DebugViewGBuffer + m_DebugViewMaterial + m_DebugViewEngine + (int)m_DebugViewVarying + (int)m_DebugViewProperties;
}
public void DisableMaterialDebug()
{
m_DebugViewMaterial = 0;
m_DebugViewEngine = 0;
m_DebugViewVarying = Attributes.DebugViewVarying.None;
m_DebugViewProperties = Attributes.DebugViewProperties.None;
m_DebugViewGBuffer = 0;
}
public void SetDebugViewMaterial(int value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewMaterial = value;
}
public void SetDebugViewEngine(int value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewEngine = value;
}
public void SetDebugViewVarying(Attributes.DebugViewVarying value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewVarying = value;
}
public void SetDebugViewProperties(Attributes.DebugViewProperties value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewProperties = value;
}
public void SetDebugViewGBuffer(int value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewGBuffer = value;
}
public bool IsDebugGBufferEnabled()
{
return m_DebugViewGBuffer != 0;
}
public bool IsDebugDisplayEnabled()
{
return (m_DebugViewEngine != 0 || m_DebugViewMaterial != 0 || m_DebugViewVarying != Attributes.DebugViewVarying.None || m_DebugViewProperties != Attributes.DebugViewProperties.None || m_DebugViewGBuffer != 0);
}
}
}
using System.Collections.Generic;
using UnityEngine;
using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
namespace Attributes
{
// 0 is reserved!
[GenerateHLSL]
public enum DebugViewVarying
{
None = 0,
Texcoord0 = 1,
Texcoord1,
Texcoord2,
Texcoord3,
VertexTangentWS,
VertexBitangentWS,
VertexNormalWS,
VertexColor,
VertexColorAlpha,
Last,
};
// Number must be contiguous
[GenerateHLSL]
public enum DebugViewGbuffer
{
None = 0,
Depth = DebugViewVarying.Last,
BakeDiffuseLightingWithAlbedoPlusEmissive,
BakeShadowMask0,
BakeShadowMask1,
BakeShadowMask2,
BakeShadowMask3,
Last,
}
// Number must be contiguous
[GenerateHLSL]
public enum DebugViewProperties
{
None = 0,
Tessellation = DebugViewGbuffer.Last,
PixelDisplacement,
VertexDisplacement,
TessellationDisplacement,
DepthOffset,
Lightmap,
Last,
}
}
[Serializable]
public class MaterialDebugSettings
{
private static bool isDebugViewMaterialInit = false;
public static GUIContent[] debugViewMaterialStrings = null;
public static int[] debugViewMaterialValues = null;
public static GUIContent[] debugViewEngineStrings = null;
public static int[] debugViewEngineValues = null;
public static GUIContent[] debugViewMaterialVaryingStrings = null;
public static int[] debugViewMaterialVaryingValues = null;
public static GUIContent[] debugViewMaterialPropertiesStrings = null;
public static int[] debugViewMaterialPropertiesValues = null;
public static GUIContent[] debugViewMaterialTextureStrings = null;
public static int[] debugViewMaterialTextureValues = null;
public static GUIContent[] debugViewMaterialGBufferStrings = null;
public static int[] debugViewMaterialGBufferValues = null;
public MaterialDebugSettings()
{
BuildDebugRepresentation();
}
// className include the additional "/"
void FillWithProperties(Type type, GUIContent[] debugViewMaterialStrings, int[] debugViewMaterialValues, string className, ref int index)
{
var attributes = type.GetCustomAttributes(true);
// Get attribute to get the start number of the value for the enum
var attr = attributes[0] as GenerateHLSL;
if (!attr.needParamDebug)
{
return;
}
var fields = type.GetFields();
var localIndex = 0;
foreach (var field in fields)
{
var fieldName = field.Name;
// Check if the display name have been override by the users
if (Attribute.IsDefined(field, typeof(SurfaceDataAttributes)))
{
var propertyAttr = (SurfaceDataAttributes[])field.GetCustomAttributes(typeof(SurfaceDataAttributes), false);
if (propertyAttr[0].displayName != "")
{
fieldName = propertyAttr[0].displayName;
}
}
fieldName = className + fieldName;
debugViewMaterialStrings[index] = new GUIContent(fieldName);
debugViewMaterialValues[index] = attr.paramDefinesStart + (int)localIndex;
index++;
localIndex++;
}
}
void FillWithPropertiesEnum(Type type, GUIContent[] debugViewMaterialStrings, int[] debugViewMaterialValues, string prefix, ref int index)
{
var names = Enum.GetNames(type);
var localIndex = 0;
foreach (var value in Enum.GetValues(type))
{
var valueName = prefix + names[localIndex];
debugViewMaterialStrings[index] = new GUIContent(valueName);
debugViewMaterialValues[index] = (int)value;
index++;
localIndex++;
}
}
public class MaterialItem
{
public String className;
public Type surfaceDataType;
public Type bsdfDataType;
};
void BuildDebugRepresentation()
{
if (!isDebugViewMaterialInit)
{
List<RenderPipelineMaterial> materialList = HDUtils.GetRenderPipelineMaterialList();
// TODO: Share this code to retrieve deferred material with HDRenderPipeline
// Find first material that have non 0 Gbuffer count and assign it as deferredMaterial
Type bsdfDataDeferredType = null;
foreach (RenderPipelineMaterial material in materialList)
{
if (material.GetMaterialGBufferCount() > 0)
{
bsdfDataDeferredType = material.GetType().GetNestedType("BSDFData");
}
}
// TODO: Handle the case of no Gbuffer material
Debug.Assert(bsdfDataDeferredType != null);
List<MaterialItem> materialItems = new List<MaterialItem>();
int numSurfaceDataFields = 0;
int numBSDFDataFields = 0;
foreach (RenderPipelineMaterial material in materialList)
{
MaterialItem item = new MaterialItem();
item.className = material.GetType().Name + "/";
item.surfaceDataType = material.GetType().GetNestedType("SurfaceData");
numSurfaceDataFields += item.surfaceDataType.GetFields().Length;
item.bsdfDataType = material.GetType().GetNestedType("BSDFData");
numBSDFDataFields += item.bsdfDataType.GetFields().Length;
materialItems.Add(item);
}
// Material properties debug
var num = typeof(Builtin.BuiltinData).GetFields().Length * materialList.Count // BuildtinData are duplicated for each material
+ numSurfaceDataFields + 1; // +1 for None case
debugViewMaterialStrings = new GUIContent[num];
debugViewMaterialValues = new int[num];
// Special case for None since it cannot be inferred from SurfaceData/BuiltinData
debugViewMaterialStrings[0] = new GUIContent("None");
debugViewMaterialValues[0] = 0;
var index = 1;
// 0 is a reserved number and should not be used (allow to track error)
foreach (MaterialItem item in materialItems)
{
// BuiltinData are duplicated for each material
FillWithProperties(typeof(Builtin.BuiltinData), debugViewMaterialStrings, debugViewMaterialValues, item.className, ref index);
FillWithProperties(item.surfaceDataType, debugViewMaterialStrings, debugViewMaterialValues, item.className, ref index);
}
// Engine properties debug
num = numBSDFDataFields + 1; // +1 for None case
debugViewEngineStrings = new GUIContent[num];
debugViewEngineValues = new int[num];
// 0 is a reserved number and should not be used (allow to track error)
debugViewEngineStrings[0] = new GUIContent("None");
debugViewEngineValues[0] = 0;
index = 1;
foreach (MaterialItem item in materialItems)
{
FillWithProperties(item.bsdfDataType, debugViewEngineStrings, debugViewEngineValues, item.className, ref index);
}
// Attributes debug
var varyingNames = Enum.GetNames(typeof(Attributes.DebugViewVarying));
debugViewMaterialVaryingStrings = new GUIContent[varyingNames.Length];
debugViewMaterialVaryingValues = new int[varyingNames.Length];
index = 0;
FillWithPropertiesEnum(typeof(Attributes.DebugViewVarying), debugViewMaterialVaryingStrings, debugViewMaterialVaryingValues, "", ref index);
// Properties debug
var propertiesNames = Enum.GetNames(typeof(Attributes.DebugViewProperties));
debugViewMaterialPropertiesStrings = new GUIContent[propertiesNames.Length];
debugViewMaterialPropertiesValues = new int[propertiesNames.Length];
index = 0;
FillWithPropertiesEnum(typeof(Attributes.DebugViewProperties), debugViewMaterialPropertiesStrings, debugViewMaterialPropertiesValues, "", ref index);
// Gbuffer debug
var gbufferNames = Enum.GetNames(typeof(Attributes.DebugViewGbuffer));
debugViewMaterialGBufferStrings = new GUIContent[gbufferNames.Length + bsdfDataDeferredType.GetFields().Length];
debugViewMaterialGBufferValues = new int[gbufferNames.Length + bsdfDataDeferredType.GetFields().Length];
index = 0;
FillWithPropertiesEnum(typeof(Attributes.DebugViewGbuffer), debugViewMaterialGBufferStrings, debugViewMaterialGBufferValues, "", ref index);
FillWithProperties(typeof(Lit.BSDFData), debugViewMaterialGBufferStrings, debugViewMaterialGBufferValues, "", ref index);
isDebugViewMaterialInit = true;
}
}
public int debugViewMaterial { get { return m_DebugViewMaterial; } }
public int debugViewEngine { get { return m_DebugViewEngine; } }
public Attributes.DebugViewVarying debugViewVarying { get { return m_DebugViewVarying; } }
public Attributes.DebugViewProperties debugViewProperties { get { return m_DebugViewProperties; } }
public int debugViewGBuffer { get { return m_DebugViewGBuffer; } }
int m_DebugViewMaterial = 0; // No enum there because everything is generated from materials.
int m_DebugViewEngine = 0; // No enum there because everything is generated from BSDFData
Attributes.DebugViewVarying m_DebugViewVarying = Attributes.DebugViewVarying.None;
Attributes.DebugViewProperties m_DebugViewProperties = Attributes.DebugViewProperties.None;
int m_DebugViewGBuffer = 0; // Can't use GBuffer enum here because the values are actually split between this enum and values from Lit.BSDFData
public int GetDebugMaterialIndex()
{
// This value is used in the shader for the actual debug display.
// There is only one uniform parameter for that so we just add all of them
// They are all mutually exclusive so return the sum will return the right index.
return m_DebugViewGBuffer + m_DebugViewMaterial + m_DebugViewEngine + (int)m_DebugViewVarying + (int)m_DebugViewProperties;
}
public void DisableMaterialDebug()
{
m_DebugViewMaterial = 0;
m_DebugViewEngine = 0;
m_DebugViewVarying = Attributes.DebugViewVarying.None;
m_DebugViewProperties = Attributes.DebugViewProperties.None;
m_DebugViewGBuffer = 0;
}
public void SetDebugViewMaterial(int value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewMaterial = value;
}
public void SetDebugViewEngine(int value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewEngine = value;
}
public void SetDebugViewVarying(Attributes.DebugViewVarying value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewVarying = value;
}
public void SetDebugViewProperties(Attributes.DebugViewProperties value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewProperties = value;
}
public void SetDebugViewGBuffer(int value)
{
if (value != 0)
DisableMaterialDebug();
m_DebugViewGBuffer = value;
}
public bool IsDebugGBufferEnabled()
{
return m_DebugViewGBuffer != 0;
}
public bool IsDebugDisplayEnabled()
{
return (m_DebugViewEngine != 0 || m_DebugViewMaterial != 0 || m_DebugViewVarying != Attributes.DebugViewVarying.None || m_DebugViewProperties != Attributes.DebugViewProperties.None || m_DebugViewGBuffer != 0);
}
}
}

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _ScreenSize = Shader.PropertyToID("_ScreenSize");
public static readonly int _PrevViewProjMatrix = Shader.PropertyToID("_PrevViewProjMatrix");
public static readonly int _FrustumPlanes = Shader.PropertyToID("_FrustumPlanes");
public static readonly int _TaaFrameIndex = Shader.PropertyToID("_TaaFrameIndex");
public static readonly int _TaaFrameIndex = Shader.PropertyToID("_TaaFrameIndex");
public static readonly int _TaaFrameRotation = Shader.PropertyToID("_TaaFrameRotation");
public static readonly int _DepthTexture = Shader.PropertyToID("_DepthTexture");
public static readonly int _CameraColorTexture = Shader.PropertyToID("_CameraColorTexture");

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Deferred.shader


// Include
//-------------------------------------------------------------------------------------
#include "../ShaderPass/ShaderPass.cs.hlsl"
#define SHADERPASS SHADERPASS_DEFERRED_LIGHTING
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "../Debug/DebugDisplay.hlsl"

BSDFData bsdfData;
BakeLightingData bakeLightingData;
DECODE_FROM_GBUFFER(posInput.positionSS, MATERIAL_FEATURE_MASK_FLAGS, bsdfData, bakeLightingData.bakeDiffuseLighting);
DECODE_FROM_GBUFFER(posInput.positionSS, UINT_MAX, bsdfData, bakeLightingData.bakeDiffuseLighting);
#ifdef SHADOWS_SHADOWMASK
DecodeShadowMask(LOAD_TEXTURE2D(_ShadowMaskTexture, posInput.positionSS), bakeLightingData.bakeShadowMask);
#endif

Outputs outputs;
#ifdef OUTPUT_SPLIT_LIGHTING
if ((_EnableSubsurfaceScattering != 0) && HaveSubsurfaceScattering(bsdfData))
if (_EnableSubsurfaceScattering != 0 && PixelHasSubsurfaceScattering(bsdfData))
{
outputs.specularLighting = float4(specularLighting, 1.0);
outputs.diffuseLighting = TagLightingForSSS(diffuseLighting);

76
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl


//-----------------------------------------------------------------------------
float3 EvaluateCookie_Directional(LightLoopContext lightLoopContext, DirectionalLightData lightData,
float3 positionWS)
float3 lightToSample)
float3 lightToSample = positionWS - lightData.positionWS;
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSample, transpose(lightToWorld));

float shadowMask = 1.0;
color = lightData.color;
attenuation = 1.0;
attenuation = 1.0; // Note: no volumetric attenuation along shadow rays for directional lights
[branch] if (lightData.cookieIndex >= 0)
{
float3 lightToSample = positionWS - lightData.positionWS;
float3 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, lightToSample);
color *= cookie;
}
#ifdef SHADOWS_SHADOWMASK
// shadowMaskSelector.x is -1 if there is no shadow mask

#endif
}
// Note: no volumetric attenuation along shadow rays for directional lights.
[branch] if (lightData.cookieIndex >= 0)
{
float3 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, positionWS);
color *= cookie;
}
}
//-----------------------------------------------------------------------------

float4 EvaluateCookie_Punctual(LightLoopContext lightLoopContext, LightData lightData,
float3 positionWS)
float3 lightToSample)
float3 lightToSample = positionWS - lightData.positionWS;
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSample, transpose(lightToWorld));
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSample, transpose(lightToWorld));
float4 cookie;

return cookie;
}
float GetPunctualShapeAttenuation(LightData lightData, float3 L, float distSq)
{
// Note: lightData.invSqrAttenuationRadius is 0 when applyRangeAttenuation is false
float attenuation = GetDistanceAttenuation(distSq, lightData.invSqrAttenuationRadius);
// Reminder: lights are oriented backward (-Z)
return attenuation * GetAngleAttenuation(L, -lightData.forward, lightData.angleScale, lightData.angleOffset);
}
// distances = {d, d^2, 1/d, d_proj}, where d_proj = dot(lightToSample, lightData.forward).
float3 N, float3 L, float dist, float distSq,
float3 N, float3 L, float3 lightToSample, float4 distances,
out float3 color, out float attenuation)
{
float3 positionWS = posInput.positionWS;

color = lightData.color;
attenuation = GetPunctualShapeAttenuation(lightData, L, distSq);
attenuation = SmoothPunctualLightAttenuation(distances, lightData.invSqrAttenuationRadius,
lightData.angleScale, lightData.angleOffset);
#if (SHADEROPTIONS_VOLUMETRIC_LIGHTING_PRESET != 0)
float distVol = (lightData.lightType == GPULIGHTTYPE_PROJECTOR_BOX) ? distances.w : distances.x;
attenuation *= TransmittanceHomogeneousMedium(_GlobalFog_Extinction, distVol);
#endif
// Projector lights always have cookies, so we can perform clipping inside the if().
[branch] if (lightData.cookieIndex >= 0)
{
float4 cookie = EvaluateCookie_Punctual(lightLoopContext, lightData, lightToSample);
color *= cookie.rgb;
attenuation *= cookie.a;
}
#ifdef SHADOWS_SHADOWMASK
// shadowMaskSelector.x is -1 if there is no shadow mask

{
// TODO: make projector lights cast shadows.
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
float4 L_dist = float4(L, dist);
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, N, lightData.shadowIndex, L_dist, posInput.positionSS);
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, N, lightData.shadowIndex, lightData.positionWS, L, posInput.positionSS);
#ifdef SHADOWS_SHADOWMASK
// Note: Legacy Unity have two shadow mask mode. ShadowMask (ShadowMask contain static objects shadow and ShadowMap contain only dynamic objects shadow, final result is the minimun of both value)
// and ShadowMask_Distance (ShadowMask contain static objects shadow and ShadowMap contain everything and is blend with ShadowMask based on distance (Global distance setup in QualitySettigns)).

#endif
}
#if (SHADEROPTIONS_VOLUMETRIC_LIGHTING_PRESET != 0)
[flatten] if (lightData.lightType == GPULIGHTTYPE_PROJECTOR_BOX)
{
float3 lightToSample = positionWS - lightData.positionWS;
dist = dot(-lightToSample, L);
}
shadow *= TransmittanceHomogeneousMedium(_GlobalFog_Extinction, dist);
#endif
// Projector lights always have cookies, so we can perform clipping inside the if().
[branch] if (lightData.cookieIndex >= 0)
{
float4 cookie = EvaluateCookie_Punctual(lightLoopContext, lightData, positionWS);
color *= cookie.rgb;
attenuation *= cookie.a;
}
}

25
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Deferred.compute


// Include
//-------------------------------------------------------------------------------------
#include "../../ShaderPass/ShaderPass.cs.hlsl"
#define SHADERPASS SHADERPASS_DEFERRED_LIGHTING
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "../../Debug/DebugDisplay.hlsl"

StructuredBuffer<uint> g_TileList;
// Indirect
[numthreads(16, 16, 1)]
[numthreads(TILE_SIZE_FPTL, TILE_SIZE_FPTL, 1)]
uint tileIndex = g_TileList[g_TileListOffset + groupId];
uint2 tileCoord = uint2(tileIndex & 0xFFFF, tileIndex >> 16);
uint2 pixelCoord = tileCoord * GetTileSize() + groupThreadId;
uint tileIndex = g_TileList[g_TileListOffset + groupId];
uint2 tileCoord = uint2(tileIndex & ((1 << TILE_SIZE_FPTL) - 1), tileIndex >> TILE_SIZE_FPTL);
uint2 pixelCoord = tileCoord * GetTileSize() + groupThreadId;
uint featureFlags = TileVariantToFeatureFlags(VARIANT);
uint screenWidth = (uint)_ScreenSize.x;
uint numTilesX = (screenWidth + (TILE_SIZE_FPTL) - 1) / TILE_SIZE_FPTL;
uint featureFlags = TileVariantToFeatureFlags(VARIANT, tileCoord.x + tileCoord.y * numTilesX);
[numthreads(16, 16, 1)]
[numthreads(TILE_SIZE_FPTL, TILE_SIZE_FPTL, 1)]
uint2 tileCoord = (16 * groupId) / GetTileSize();
uint2 pixelCoord = dispatchThreadId;
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIAL_FEATURE_MASK_FLAGS;
uint2 tileCoord = (TILE_SIZE_FPTL * groupId) / GetTileSize();
uint2 pixelCoord = dispatchThreadId;
uint featureFlags = UINT_MAX;
#endif

float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeLightingData, featureFlags, diffuseLighting, specularLighting);
if ((_EnableSubsurfaceScattering != 0) && HaveSubsurfaceScattering(bsdfData))
if (_EnableSubsurfaceScattering != 0 && PixelHasSubsurfaceScattering(bsdfData))
{
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = TagLightingForSSS(diffuseLighting);

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


lightData.positionWS = light.light.transform.position;
// Setting 0 for invSqrAttenuationRadius mean we have no range attenuation, but still have inverse square attenuation.
lightData.invSqrAttenuationRadius = additionalLightData.applyRangeAttenuation ? 1.0f / (light.range * light.range) : 0.0f;
bool applyRangeAttenuation = additionalLightData.applyRangeAttenuation && (gpuLightType != GPULightType.ProjectorBox);
lightData.invSqrAttenuationRadius = applyRangeAttenuation ? 1.0f / (light.range * light.range) : 0.0f;
lightData.color = GetLightColor(light);
lightData.forward = light.light.transform.forward; // Note: Light direction is oriented backward (-Z)

if (enableFeatureVariants)
{
cmd.SetComputeBufferParam(deferredComputeShader, kernel, HDShaderIDs.g_TileFeatureFlags, s_TileFeatureFlags);
cmd.SetComputeIntParam(deferredComputeShader, HDShaderIDs.g_TileListOffset, variant * numTiles);
cmd.SetComputeBufferParam(deferredComputeShader, kernel, HDShaderIDs.g_TileList, s_TileList);
cmd.DispatchCompute(deferredComputeShader, kernel, s_DispatchIndirectBuffer, (uint)variant * 3 * sizeof(uint));

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopDef.hlsl


StructuredBuffer<float> g_logBaseBuffer; // don't support Buffer yet in unity
//#endif
#ifdef USE_INDIRECT
StructuredBuffer<uint> g_TileFeatureFlags;
#endif
StructuredBuffer<DirectionalLightData> _DirectionalLightDatas;
StructuredBuffer<LightData> _LightDatas;
StructuredBuffer<EnvLightData> _EnvLightDatas;

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/Shadow.hlsl


// example of overriding punctual lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float4 L )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 lightPositionWS, float3 L)
{
#ifdef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
// example for choosing different algos for point and spot lights

Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_POINT_TEX];
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_POINT_SMP];
uint algo = SHADOW_DISPATCH_POINT_ALG;
return EvalShadow_PointDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_PointDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, lightPositionWS, L );
}
else
{

return EvalShadow_SpotDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_SpotDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, lightPositionWS, L );
}
#else
// example for choosing the same algo

return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, lightPositionWS, L );
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float4 L, float2 positionSS )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 lightPositionWS, float3 L, float2 positionSS )
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, lightPositionWS, L );
}
#endif

20
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/Resources/VolumetricLighting.compute


posInput.positionWS = GetPointAtDistance(ray, t);
float3 lightToSample = posInput.positionWS - light.positionWS;
float dist = sqrt(distSq);
float3 L = -lightToSample * rsqrt(distSq);
float distRcp = rsqrt(distSq);
float dist = distSq * distRcp;
float distProj = dot(lightToSample, light.forward);
float4 distances = float4(dist, distSq, distRcp, distProj);
float3 L = -lightToSample * distRcp;
EvaluateLight_Punctual(context, posInput, light, unused, 0, L, dist, distSq,
color, attenuation);
EvaluateLight_Punctual(context, posInput, light, unused, 0, L, lightToSample,
distances, color, attenuation);
float intensity = attenuation * rcpPdf;

float t = tEntr + tOffset;
posInput.positionWS = GetPointAtDistance(ray, t);
float3 L = -light.forward;
float3 L = -light.forward;
float3 lightToSample = posInput.positionWS - light.positionWS;
float distProj = dot(lightToSample, light.forward);
float4 distances = float4(1, 1, 1, distProj);
EvaluateLight_Punctual(context, posInput, light, unused, 0, L, 1, 1,
color, attenuation);
EvaluateLight_Punctual(context, posInput, light, unused, 0, L, lightToSample,
distances, color, attenuation);
// Note: the 'weight' accounts for transmittance from 'tEntr' to 't'.
float intensity = attenuation * weight;

1001
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl
文件差异内容过多而无法显示
查看文件

290
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


return NUM_FEATURE_VARIANTS - 1;
}
// This function need to return a compile time value, else there is no optimization
uint TileVariantToFeatureFlags(uint variant)
#ifdef USE_INDIRECT
uint TileVariantToFeatureFlags(uint variant, uint tileIndex)
return kFeatureVariantFlags[variant];
if (variant == NUM_FEATURE_VARIANTS - 1)
{
// We don't have any compile-time feature information.
// Therefore, we load the feature classification data at runtime to avoid
// entering every single branch based on feature flags.
return g_TileFeatureFlags[tileIndex];
}
else
{
// Return the compile-time feature flags.
return kFeatureVariantFlags[variant];
}
#endif // USE_INDIRECT
//-----------------------------------------------------------------------------
// Helper functions/variable specific to this material
//-----------------------------------------------------------------------------

// This method allows us to know at compile time what material features should be removed from the code by Tile (Indepenently of the value of material feature flag per pixel).
// This is only useful for classification during lighting, so it's not needed in EncodeIntoGBuffer and ConvertSurfaceDataToBSDFData (where we always know exactly what the material feature is)
bool HasMaterialFeatureFlag(uint featureFlags, uint flag)
bool HasFeatureFlag(uint featureFlags, uint flag)
{
return ((featureFlags & flag) != 0);
}

bsdfData.thickness = _ThicknessRemaps[diffusionProfile].x + _ThicknessRemaps[diffusionProfile].y * thickness;
uint transmissionMode = BitFieldExtract(asuint(_TransmissionFlags), 2u * diffusionProfile, 2u);
bsdfData.useThickObjectMode = transmissionMode != TRANSMISSION_MODE_THIN;
#if SHADEROPTIONS_USE_DISNEY_SSS
bsdfData.transmittance = ComputeTransmittanceDisney( _ShapeParams[diffusionProfile].rgb,

_TransmissionTintsAndFresnel0[diffusionProfile].rgb,
bsdfData.thickness);
#endif
// Apply the transmission mode. Only the thick object mode performs the thickness displacement.
bsdfData.useThickObjectMode = transmissionMode != TRANSMISSION_MODE_THIN;
if (bsdfData.useThickObjectMode)
{
// Compute the thickness in world units along the normal.
float thicknessInMeters = bsdfData.thickness * METERS_PER_MILLIMETER;
float thicknessInUnits = thicknessInMeters * _WorldScales[bsdfData.diffusionProfile].y;
bsdfData.thickness = thicknessInUnits;
}
else
{
// Apply no displacement.
bsdfData.thickness = 0;
}
}
// Assume bsdfData.normalWS is init

bsdfData.materialFeatures = surfaceData.materialFeatures | MATERIALFEATUREFLAGS_LIT_STANDARD; // Not really needed but for consistency with deferred path
// Standard material
bsdfData.specularOcclusion = surfaceData.specularOcclusion;
bsdfData.normalWS = surfaceData.normalWS;
bsdfData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness);
bsdfData.specularOcclusion = surfaceData.specularOcclusion;
bsdfData.normalWS = surfaceData.normalWS;
bsdfData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness);
float metallic = HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE) ?
0.0 : surfaceData.metallic;
float metallic = HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION) ? 0.0 : surfaceData.metallic;
bsdfData.diffuseColor = ComputeDiffuseColor(surfaceData.baseColor, metallic);
bsdfData.fresnel0 = HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR) ? surfaceData.specularColor : ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, DEFAULT_SPECULAR_VALUE);
bsdfData.diffuseColor = ComputeDiffuseColor(surfaceData.baseColor, metallic);
bsdfData.fresnel0 = HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR) ? surfaceData.specularColor : ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, DEFAULT_SPECULAR_VALUE);
bsdfData.diffusionProfile = surfaceData.diffusionProfile;
bsdfData.diffusionProfile = surfaceData.diffusionProfile;
// Note: we have ZERO_INITIALIZE the struct so bsdfData.anisotropy == 0.0
// In forward everything is statically know and we could theorically cumulate all the material features. So the code reflect it.

if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Modify fresnel0 and perceptualRoughness
FillMaterialClearCoatData(surfaceData.coatMask, bsdfData);

// The priority of feature is handled in the code here and reflect in the UI (see LitUI.cs)
// Process SSS and Transmission together as they encode almost the same data, negligible cost
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
metallic15 = GBUFFER_LIT_SSS_OR_TRANSMISSION;
// Special case: For SSS we will store the profile id and the subsurface radius at the location of the specular occlusion (in alpha channel of GBuffer0)

outGBuffer2.rgb = float3(surfaceData.specularOcclusion, surfaceData.thickness, HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING) ? 1.0 : 0.0); // thickness for Transmission
outGBuffer2.rgb = float3(surfaceData.specularOcclusion, surfaceData.thickness, HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING) ? 1.0 : 0.0); // thickness for Transmission
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR))
else if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
else if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
else if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
else if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
{
metallic15 = GBUFFER_LIT_IRIDESCENCE;
outGBuffer2.rgb = float3(0.0, surfaceData.thicknessIrid, 0.0);

}
// Encode coatMask (4bit) / mettalic (4bit)
outGBuffer2.a = PackFloatInt8bit(HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) ? surfaceData.coatMask : 0.0, metallic15, 16.0);
outGBuffer2.a = PackFloatInt8bit(HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) ? surfaceData.coatMask : 0.0, metallic15, 16.0);
void DecodeFromGBuffer(uint2 positionSS, uint featureFlags, out BSDFData bsdfData, out float3 bakeDiffuseLighting, out uint outMaterialFeatures)
// Fills the BSDFData. Also returns the (per-pixel) material feature flags inferred
// from the contents of the G-buffer, which can be used by the feature classification system.
// 'tileFeatureFlags' are compile-time flags provided by the feature classification system.
// If you're not using the feature classification system, pass 0.
uint DecodeFromGBuffer(uint2 positionSS, uint tileFeatureFlags, out BSDFData bsdfData, out float3 bakeDiffuseLighting)
ZERO_INITIALIZE(BSDFData, bsdfData);
// Isolate material features.
tileFeatureFlags &= MATERIAL_FEATURE_MASK_FLAGS;
bsdfData.materialFeatures = tileFeatureFlags; // Only tile-uniform feature evaluation
ZERO_INITIALIZE(BSDFData, bsdfData);
// If any of the flags of featureFlags is not set, it mean we know statically that
// the material feature is not used, so the compiler can optimize related code.
// Else we don't know if the material feature will be use, it is a dynamic condition.
bool enableSpecularColor = (metallic15 == GBUFFER_LIT_SPECULAR_COLOR); // This is always a dynamic test as it is very cheap
outMaterialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD; // It is mandatory to identity ourselve as standard shader, else we are consider as sky/background element
outMaterialFeatures |= (metallic15 == GBUFFER_LIT_SSS_OR_TRANSMISSION && inGBuffer2.g > 0.0) ? featureFlags & MATERIALFEATUREFLAGS_LIT_TRANSMISSION : 0; // Thickness > 0
outMaterialFeatures |= (metallic15 == GBUFFER_LIT_SSS_OR_TRANSMISSION && inGBuffer2.b > 0.0) ? featureFlags & MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING : 0; // TagSSS > 0
outMaterialFeatures |= (metallic15 <= GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND && abs(inGBuffer2.b - 0.5) > 0.01) ? featureFlags & MATERIALFEATUREFLAGS_LIT_ANISOTROPY : 0; // Anisotropy != 0 (small tolerrance as 0.5 can be correctly encoded)
outMaterialFeatures |= (metallic15 == GBUFFER_LIT_IRIDESCENCE) ? featureFlags & MATERIALFEATUREFLAGS_LIT_IRIDESCENCE : 0;
outMaterialFeatures |= coatMask > 0.0 ? featureFlags & MATERIALFEATUREFLAGS_LIT_CLEAR_COAT : 0;
uint pixelFeatureFlags = MATERIALFEATUREFLAGS_LIT_STANDARD; // Only sky/background do not have the Standard material flag
bool pixelHasSpecularColor = (metallic15 == GBUFFER_LIT_SPECULAR_COLOR); // This is always a dynamic test as it is very cheap
bool pixelHasTransmission = (metallic15 == GBUFFER_LIT_SSS_OR_TRANSMISSION && inGBuffer2.g > 0); // Thickness > 0
bool pixelHasSubsurface = (metallic15 == GBUFFER_LIT_SSS_OR_TRANSMISSION && inGBuffer2.b > 0); // TagSSS > 0
bool pixelHasAnisotropy = (metallic15 <= GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND && (inGBuffer2.b - 0.5) >= 1.0/255.0); // Anisotropy > 0
bool pixelHasIridescence = (metallic15 == GBUFFER_LIT_IRIDESCENCE);
bool pixelHasClearCoat = (coatMask > 0);
// Save for material classification
bsdfData.materialFeatures = outMaterialFeatures;
// Disable pixel features disabled by the tile.
pixelFeatureFlags |= tileFeatureFlags & (pixelHasSpecularColor ? MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR : 0);
pixelFeatureFlags |= tileFeatureFlags & (pixelHasTransmission ? MATERIALFEATUREFLAGS_LIT_TRANSMISSION : 0);
pixelFeatureFlags |= tileFeatureFlags & (pixelHasSubsurface ? MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING : 0);
pixelFeatureFlags |= tileFeatureFlags & (pixelHasAnisotropy ? MATERIALFEATUREFLAGS_LIT_ANISOTROPY : 0);
pixelFeatureFlags |= tileFeatureFlags & (pixelHasIridescence ? MATERIALFEATUREFLAGS_LIT_IRIDESCENCE : 0);
pixelFeatureFlags |= tileFeatureFlags & (pixelHasClearCoat ? MATERIALFEATUREFLAGS_LIT_CLEAR_COAT : 0);
// Start decompressing GBuffer
float3 baseColor = inGBuffer0.rgb;

bsdfData.normalWS = UnpackNormalOctEncode(float2(inGBuffer1.r, inGBuffer1.g));
// metallic15 is range [0..12] if mettallic data is needed
float metallic = (metallic15 <= GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND) ? metallic15 * (1.0 / GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND) : 0.0;
// metallic15 is range [0..12] if metallic data is needed
bool pixelHasNoMetallic = HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION);
float metallic = pixelHasNoMetallic ? 0 : metallic15 * (1.0 / GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND);
bsdfData.fresnel0 = enableSpecularColor ? Gamma20ToLinear(inGBuffer2.rgb) : ComputeFresnel0(baseColor, metallic, DEFAULT_SPECULAR_VALUE);
bsdfData.fresnel0 = HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR) ? Gamma20ToLinear(inGBuffer2.rgb) : ComputeFresnel0(baseColor, metallic, DEFAULT_SPECULAR_VALUE);
// Note: we have ZERO_INITIALIZE the struct, so bsdfData.diffusionProfile == DIFFUSION_PROFILE_NEUTRAL_ID, bsdfData.anisotropy == 0.0, bsdfData.SubsurfaceMask == 0.0 etc...
// Note: we have ZERO_INITIALIZE the struct, so bsdfData.diffusionProfile == DIFFUSION_PROFILE_NEUTRAL_ID, bsdfData.anisotropy == 0, bsdfData.subsurfaceMask == 0 etc...
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// First we must extract the diffusion profile

bsdfData.diffusionProfile = sssData.diffusionProfile;
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
// The neutral value of subsurfaceMask is 0 (handled by ZERO_INITIALIZE).
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
// The neutral value of thickness and transmittance is 0 (handled by ZERO_INITIALIZE).
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
FillMaterialTransmission(inGBuffer2.g, bsdfData);
}

// Note that it mean that when we have the worse case, we always use Anisotropy and shader like deferred.shader are always the worst case (but only used for debugging)
if (HasMaterialFeatureFlag(featureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(tileFeatureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
anisotropy = inGBuffer2.b * 2.0 - 1.0;
tangentWS = UnpackNormalOctEncode(inGBuffer2.rg * 2.0 - 1.0);

}
FillMaterialAnisotropy(anisotropy, tangentWS, bsdfData);
// Force the compiler to use the anisotropy path all the time
bsdfData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
// The neutral value of coatMask is 0 (handled by ZERO_INITIALIZE).
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Modify fresnel0 and perceptualRoughness
FillMaterialClearCoatData(coatMask, bsdfData);

ConvertAnisotropyToClampRoughness(bsdfData.perceptualRoughness, bsdfData.anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
bakeDiffuseLighting = inGBuffer3.rgb;
}
void DecodeFromGBuffer(uint2 positionSS, uint featureFlags, out BSDFData bsdfData, out float3 bakeDiffuseLighting)
{
uint unsused;
DecodeFromGBuffer(positionSS, featureFlags, bsdfData, bakeDiffuseLighting, unsused);
return pixelFeatureFlags;
}
// Function call from the material classification compute shader

float3 unused;
// Call the regular function, compiler will optimized out everything not used.
// Note that all material feature flag bellow are in the same GBuffer (inGBuffer2) and thus material classification only sample one Gbuffer
uint materialFeatures;
DecodeFromGBuffer(positionSS, MATERIAL_FEATURE_MASK_FLAGS, bsdfData, unused, materialFeatures);
return materialFeatures;
return DecodeFromGBuffer(positionSS, UINT_MAX, bsdfData, unused);
//-----------------------------------------------------------------------------
// Debug method (use to display values)

preLightData.clampNdotV = NdotV; // Caution: The handling of edge cases where N is directed away from the screen is handled during Gbuffer/forward pass, so here do nothing
preLightData.iblPerceptualRoughness = bsdfData.perceptualRoughness;
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
preLightData.coatPartLambdaV = GetSmithJointGGXPartLambdaV(NdotV, CLEAR_COAT_ROUGHNESS);
preLightData.coatIblR = reflect(-V, N);

// We avoid divergent evaluation of the GGX, as that nearly doubles the cost.
// If the tile has anisotropy, all the pixels within the tile are evaluated as anisotropic.
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);

// to match the reference for rough metals, but further darkens dielectrics.
preLightData.ltcMagnitudeFresnel = bsdfData.fresnel0 * ltcGGXFresnelMagnitudeDiff + (float3)ltcGGXFresnelMagnitude;
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
float2 uv = LTC_LUT_OFFSET + LTC_LUT_SCALE * float2(CLEAR_COAT_PERCEPTUAL_ROUGHNESS, theta * INV_HALF_PI);

// This function require the 3 structure surfaceData, builtinData, bsdfData because it may require both the engine side data, and data that will not be store inside the gbuffer.
float3 GetBakedDiffuseLigthing(SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData, PreLightData preLightData)
{
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
{
bsdfData.diffuseColor = ApplySubsurfaceScatteringTexturingMode(bsdfData.diffuseColor, bsdfData.diffusionProfile);
}

// Subsurface Scattering functions
//-----------------------------------------------------------------------------
bool HaveSubsurfaceScattering(BSDFData bsdfData)
bool PixelHasSubsurfaceScattering(BSDFData bsdfData)
return HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING);
return bsdfData.subsurfaceMask != 0 && HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING);
}
//-----------------------------------------------------------------------------

// BSDF share between directional light, punctual light and area light (reference)
//-----------------------------------------------------------------------------
// This function apply BSDF
void BSDF( float3 V, float3 L, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,
// This function apply BSDF. Assumes that NdotL is positive.
void BSDF( float3 V, float3 L, float NdotL, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
{

// Optimized math. Ref: PBR Diffuse Lighting for GGX + Smith Microsurfaces (slide 114).
float NdotL = saturate(dot(N, L)); // Must have the same value without the clamp
float LdotV = dot(L, V);
float invLenLV = rsqrt(max(2.0 * LdotV + 2.0, FLT_EPS)); // invLenLV = rcp(length(L + V)) - caution about the case where V and L are opposite, it can happen, use max to avoid this

float3 F = F_Schlick(bsdfData.fresnel0, LdotH);
float DV;
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float3 H = (L + V) * invLenLV;
// For anisotropy we must not saturate these values

// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
diffuseLighting = diffuseTerm;
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Apply isotropic GGX for clear coat
// Note: coat F is scalar as it is a dieletric

// Note: The modification of the base roughness and fresnel0 by the clear coat is already handled in FillMaterialClearCoatData
// Very coarse attempt at doing energy conservation for the diffuse layer based on NdotL. No science.
diffuseLighting *= F_Schlick(CLEAR_COAT_F0, NdotL);
diffuseLighting *= lerp(1, F_Schlick(CLEAR_COAT_F0, NdotL), bsdfData.coatMask);
}
}

// OR transmitted (back) lighting, never both at the same time. For transmitted lighting,
// we need to push the shading position back to avoid self-shadowing problems.
// Note: 'bsdfData.thickness' is in world units, and already accounts for the transmission mode.
float displacement = 0;
[flatten] if (bsdfData.useThickObjectMode && NdotL < 0)
{
// Compute the thickness in world units along the normal.
float thicknessInMeters = bsdfData.thickness * METERS_PER_MILLIMETER;
float thicknessInUnits = thicknessInMeters * _WorldScales[bsdfData.diffusionProfile].y;
// Compute the thickness in world units along the light vector.
displacement = thicknessInUnits / -NdotL;
}
// Compute the thickness in world units along the light vector.
// We need a max(x, 0) here, but the saturate() is free,
// and we don't expect the total displacement of over 1 meter.
float displacement = saturate(bsdfData.thickness / -NdotL);
return displacement * L;
}

float3 EvaluateTransmission(BSDFData bsdfData, float NdotL, float NdotV, float attenuation)
{
float wrappedNdotL = ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
float negatedNdotL = saturate(-NdotL);
float negatedNdotL = -NdotL;
// Apply wrapped lighting to better handle thin objects (cards) at grazing angles.
float backNdotL = bsdfData.useThickObjectMode ? negatedNdotL : wrappedNdotL;

#ifdef LIT_DIFFUSE_LAMBERT_BRDF
attenuation *= Lambert();
#else
attenuation *= INV_PI * F_Transm_Schlick(0, 0.5, NdotV) * F_Transm_Schlick(0, 0.5, backNdotL);
attenuation *= INV_PI * F_Transm_Schlick(0, 0.5, NdotV) * F_Transm_Schlick(0, 0.5, abs(backNdotL));
float intensity = attenuation * backNdotL;
float intensity = max(0, attenuation * backNdotL); // Warning: attenuation can be greater than 1
return intensity * bsdfData.transmittance;
}

float3 L = -lightData.forward; // Lights point backward in Unity
float NdotL = dot(N, L); // Note: Ideally this N here should be vertex normal - use for transmisison
// Compute displacement for fake thickObject transmission
posInput.positionWS += ComputeThicknessDisplacement(bsdfData, L, NdotL);
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Compute displacement for fake thickObject transmission
posInput.positionWS += ComputeThicknessDisplacement(bsdfData, L, NdotL);
}
float intensity = attenuation * saturate(NdotL);
float intensity = max(0, attenuation * NdotL); // Warning: attenuation can be greater than 1
BSDF(V, L, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
BSDF(V, L, NdotL, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
[branch] if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
[branch] if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, NdotL, preLightData.clampNdotV, attenuation * lightData.diffuseScale);

float3 lightToSample = posInput.positionWS - lightData.positionWS;
int lightType = lightData.lightType;
float3 unL = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? -lightToSample : -lightData.forward;
float distSq = dot(unL, unL);
float distRcp = rsqrt(distSq);
float dist = distSq * distRcp;
float3 N = bsdfData.normalWS;
float3 L = unL * distRcp;
float NdotL = dot(N, L);
float3 L;
float4 distances; // {d, d^2, 1/d, d_proj}
distances.w = dot(lightToSample, lightData.forward);
// Compute displacement for fake thickObject transmission
posInput.positionWS += ComputeThicknessDisplacement(bsdfData, L, NdotL);
if (lightType == GPULIGHTTYPE_PROJECTOR_BOX)
{
L = -lightData.forward;
distances.xyz = 1; // No distance or angle attenuation
}
else
{
float3 unL = -lightToSample;
float distSq = dot(unL, unL);
float distRcp = rsqrt(distSq);
float dist = distSq * distRcp;
L = unL * distRcp;
distances.xyz = float3(dist, distSq, distRcp);
}
float3 N = bsdfData.normalWS;
float NdotL = dot(N, L);
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Compute displacement for fake thickObject transmission
// Warning: distances computed above are NOT modified!
// This is not correct, of course, but is done for performance reasons.
posInput.positionWS += ComputeThicknessDisplacement(bsdfData, L, NdotL);
}
EvaluateLight_Punctual(lightLoopContext, posInput, lightData, bakeLightingData, N, L, dist, distSq, color, attenuation);
EvaluateLight_Punctual(lightLoopContext, posInput, lightData, bakeLightingData, N, L,
lightToSample, distances, color, attenuation);
float intensity = attenuation * saturate(NdotL);
float intensity = max(0, attenuation * NdotL); // Warning: attenuation can be greater than 1
// Note: We use NdotL here to early out, but in case of clear coat this is not correct. But we are ok with this
[branch] if (intensity > 0.0)

bsdfData.roughnessT = max(bsdfData.roughnessT, lightData.minRoughness);
bsdfData.roughnessB = max(bsdfData.roughnessB, lightData.minRoughness);
BSDF(V, L, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
BSDF(V, L, NdotL, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular);
[branch] if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
[branch] if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, NdotL, preLightData.clampNdotV, attenuation * lightData.diffuseScale);

float invAspectRatio = radius / (radius + (0.5 * len));
// Compute the light attenuation.
float intensity = GetEllipsoidalDistanceAttenuation(unL, lightData.invSqrAttenuationRadius,
axis, invAspectRatio);
float intensity = EllipsoidalDistanceAttenuation(unL, lightData.invSqrAttenuationRadius,
axis, invAspectRatio);
// Terminate if the shaded point is too far away.
if (intensity == 0.0)

// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
[branch] if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
[branch] if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,

lighting.specular = preLightData.ltcMagnitudeFresnel * ltcValue;
// Evaluate the coat part
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
lighting.diffuse *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);
lighting.specular *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);

#ifdef ELLIPSOIDAL_ATTENUATION
// The attenuation volume is an axis-aligned ellipsoid s.t.
// r1 = (r + w / 2), r2 = (r + h / 2), r3 = r.
float intensity = GetEllipsoidalDistanceAttenuation(unL, invHalfDim);
float intensity = EllipsoidalDistanceAttenuation(unL, invHalfDim);
float intensity = GetBoxDistanceAttenuation(unL, invHalfDim);
float intensity = BoxDistanceAttenuation(unL, invHalfDim);
#endif
// Terminate if the shaded point is too far away.

// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
[branch] if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
[branch] if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,

lighting.specular += preLightData.ltcMagnitudeFresnel * ltcValue;
// Evaluate the coat part
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
lighting.diffuse *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);
lighting.specular *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);

R = (positionWS + projectionDistance * R) - lightData.positionWS;
// Test again for clear coat
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
dirLS = mul(coatR, worldToLocal);
projectionDistance = IntersectRaySphereSimple(positionLS, dirLS, sphereOuterDistance);

// TODO: add distance based roughness
// Test again for clear coat
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
dirLS = mul(coatR, worldToLocal);
projectionDistance = IntersectRayAABBSimple(positionLS, dirLS, -boxOuterDistance, boxOuterDistance);

envLighting = F * preLD.rgb;
// Evaluate the Clear Coat component if needed
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// No correction needed for coatR as it is smooth
// Note: coat F is scalar as it is a dieletric

#endif
float3 modifiedDiffuseColor;
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
modifiedDiffuseColor = ApplySubsurfaceScatteringTexturingMode(bsdfData.diffuseColor, bsdfData.diffusionProfile);
else
modifiedDiffuseColor = bsdfData.diffuseColor;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitBuiltinData.hlsl


// It is safe to call this function here as surfaceData have been filled
// We want to know if we must enable transmission on GI for SSS material, if the material have no SSS, this code will be remove by the compiler.
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// For now simply recall the function with inverted normal, the compiler should be able to optimize the lightmap case to not resample the directional lightmap
// however it will not optimize the lightprobe case due to the proxy volume relying on dynamic if (we rely must get right of this dynamic if), not a problem for SH9, but a problem for proxy volume.

528
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitProperties.hlsl


// ===========================================================================
// WARNING:
// On PS4, texture/sampler declarations need to be outside of CBuffers
// Otherwise those parameters are not bound correctly at runtime.
// ===========================================================================
TEXTURE2D(_DistortionVectorMap);
SAMPLER(sampler_DistortionVectorMap);
TEXTURE2D(_EmissiveColorMap);
SAMPLER(sampler_EmissiveColorMap);
#ifndef LAYERED_LIT_SHADER
TEXTURE2D(_DiffuseLightingMap);
SAMPLER(sampler_DiffuseLightingMap);
TEXTURE2D(_BaseColorMap);
SAMPLER(sampler_BaseColorMap);
TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap);
TEXTURE2D(_BentNormalMap); // Reuse sampler from normal map
SAMPLER(sampler_BentNormalMap);
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURE2D(_NormalMapOS);
SAMPLER(sampler_NormalMapOS);
TEXTURE2D(_DetailMap);
SAMPLER(sampler_DetailMap);
TEXTURE2D(_HeightMap);
SAMPLER(sampler_HeightMap);
TEXTURE2D(_TangentMap);
SAMPLER(sampler_TangentMap);
TEXTURE2D(_TangentMapOS);
SAMPLER(sampler_TangentMapOS);
TEXTURE2D(_AnisotropyMap);
SAMPLER(sampler_AnisotropyMap);
TEXTURE2D(_SubsurfaceMaskMap);
SAMPLER(sampler_SubsurfaceMaskMap);
TEXTURE2D(_ThicknessMap);
SAMPLER(sampler_ThicknessMap);
TEXTURE2D(_SpecularColorMap);
SAMPLER(sampler_SpecularColorMap);
TEXTURE2D(_TransmittanceColorMap);
SAMPLER(sampler_TransmittanceColorMap);
#else
// Set of users variables
#define PROP_DECL(type, name) type name##0, name##1, name##2, name##3
// sampler are share by texture type inside a layered material but we need to support that a particualr layer have no texture, so we take the first sampler of available texture as the share one
// mean we must declare all sampler
#define PROP_DECL_TEX2D(name)\
TEXTURE2D(MERGE_NAME(name, 0)); \
SAMPLER(MERGE_NAME(MERGE_NAME(sampler, name), 0)); \
TEXTURE2D(MERGE_NAME(name, 1)); \
SAMPLER(MERGE_NAME(MERGE_NAME(sampler, name), 1)); \
TEXTURE2D(MERGE_NAME(name, 2)); \
SAMPLER(MERGE_NAME(MERGE_NAME(sampler, name), 2)); \
TEXTURE2D(MERGE_NAME(name, 3)); \
SAMPLER(MERGE_NAME(MERGE_NAME(sampler, name), 3))
PROP_DECL_TEX2D(_BaseColorMap);
PROP_DECL_TEX2D(_MaskMap);
PROP_DECL_TEX2D(_BentNormalMap);
PROP_DECL_TEX2D(_NormalMap);
PROP_DECL_TEX2D(_NormalMapOS);
PROP_DECL_TEX2D(_DetailMap);
PROP_DECL_TEX2D(_HeightMap);
PROP_DECL_TEX2D(_SubsurfaceMaskMap);
PROP_DECL_TEX2D(_ThicknessMap);
TEXTURE2D(_LayerMaskMap);
SAMPLER(sampler_LayerMaskMap);
TEXTURE2D(_LayerInfluenceMaskMap);
SAMPLER(sampler_LayerInfluenceMaskMap);
#endif
CBUFFER_START(UnityPerMaterial)
// shared constant between lit and layered lit
float _AlphaCutoff;
float _AlphaCutoffPrepass;
float _AlphaCutoffPostpass;
float4 _DoubleSidedConstants;
float _DistortionScale;
float _DistortionVectorScale;
float _DistortionVectorBias;
float _DistortionBlurScale;
float _DistortionBlurRemapMin;
float _DistortionBlurRemapMax;
float _PPDMaxSamples;
float _PPDMinSamples;
float _PPDLodThreshold;
float3 _EmissiveColor;
float _EmissiveIntensity;
float _AlbedoAffectEmissive;
float _EnableSpecularOcclusion;
// Transparency
float3 _TransmittanceColor;
float _IOR;
float _ATDistance;
float _ThicknessMultiplier;
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.
// In our case we don't use such a mechanism but need to keep the code quiet. We declare the value and always enable it.
// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
float3 _EmissionColor;
float4 _EmissiveColorMap_ST;
float _TexWorldScaleEmissive;
float4 _UVMappingMaskEmissive;
float4 _InvPrimScale; // Only XY are used
// Wind
float _InitialBend;
float _Stiffness;
float _Drag;
float _ShiverDrag;
float _ShiverDirectionality;
#ifndef LAYERED_LIT_SHADER
// Set of users variables
float4 _BaseColor;
float4 _BaseColorMap_ST;
float4 _BaseColorMap_TexelSize;
float4 _BaseColorMap_MipInfo;
float _Metallic;
float _Smoothness;
float _SmoothnessRemapMin;
float _SmoothnessRemapMax;
float _AORemapMin;
float _AORemapMax;
float _NormalScale;
float4 _DetailMap_ST;
float _DetailAlbedoScale;
float _DetailNormalScale;
float _DetailSmoothnessScale;
float4 _HeightMap_TexelSize; // Unity facility. This will provide the size of the heightmap to the shader
float _HeightAmplitude;
float _HeightCenter;
float _Anisotropy;
int _DiffusionProfile;
float _SubsurfaceMask;
float _Thickness;
float4 _ThicknessRemap;
float _CoatMask;
float4 _SpecularColor;
float _TexWorldScale;
float _InvTilingScale;
float4 _UVMappingMask;
float4 _UVDetailsMappingMask;
float _LinkDetailsWithBase;
#else // LAYERED_LIT_SHADER
// Set of users variables
PROP_DECL(float4, _BaseColor);
float4 _BaseColorMap0_ST;
float4 _BaseColorMap1_ST;
float4 _BaseColorMap2_ST;
float4 _BaseColorMap3_ST;
float4 _BaseColorMap0_TexelSize;
float4 _BaseColorMap0_MipInfo;
PROP_DECL(float, _Metallic);
PROP_DECL(float, _Smoothness);
PROP_DECL(float, _SmoothnessRemapMin);
PROP_DECL(float, _SmoothnessRemapMax);
PROP_DECL(float, _AORemapMin);
PROP_DECL(float, _AORemapMax);
PROP_DECL(float, _NormalScale);
float4 _NormalMap0_TexelSize; // Unity facility. This will provide the size of the base normal to the shader
float4 _HeightMap0_TexelSize;
float4 _HeightMap1_TexelSize;
float4 _HeightMap2_TexelSize;
float4 _HeightMap3_TexelSize;
float4 _DetailMap0_ST;
float4 _DetailMap1_ST;
float4 _DetailMap2_ST;
float4 _DetailMap3_ST;
PROP_DECL(float, _UVDetail);
PROP_DECL(float, _DetailAlbedoScale);
PROP_DECL(float, _DetailNormalScale);
PROP_DECL(float, _DetailSmoothnessScale);
PROP_DECL(float, _HeightAmplitude);
PROP_DECL(float, _HeightCenter);
PROP_DECL(int, _DiffusionProfile);
PROP_DECL(float, _SubsurfaceMask);
PROP_DECL(float, _Thickness);
PROP_DECL(float4, _ThicknessRemap);
PROP_DECL(float, _OpacityAsDensity);
float _InheritBaseNormal1;
float _InheritBaseNormal2;
float _InheritBaseNormal3;
float _InheritBaseHeight1;
float _InheritBaseHeight2;
float _InheritBaseHeight3;
float _InheritBaseColor1;
float _InheritBaseColor2;
float _InheritBaseColor3;
PROP_DECL(float, _HeightOffset);
float _HeightTransition;
float4 _LayerMaskMap_ST;
float _TexWorldScaleBlendMask;
PROP_DECL(float, _TexWorldScale);
PROP_DECL(float, _InvTilingScale);
float4 _UVMappingMaskBlendMask;
PROP_DECL(float4, _UVMappingMask);
PROP_DECL(float4, _UVDetailsMappingMask);
PROP_DECL(float, _LinkDetailsWithBase);
#endif // LAYERED_LIT_SHADER
// Tessellation specific
#ifdef TESSELLATION_ON
float _TessellationFactor;
float _TessellationFactorMinDistance;
float _TessellationFactorMaxDistance;
float _TessellationFactorTriangleSize;
float _TessellationShapeFactor;
float _TessellationBackFaceCullEpsilon;
float _TessellationObjectScale;
float _TessellationTilingScale;
#endif
CBUFFER_END
// ===========================================================================
// WARNING:
// On PS4, texture/sampler declarations need to be outside of CBuffers
// Otherwise those parameters are not bound correctly at runtime.
// ===========================================================================
TEXTURE2D(_DistortionVectorMap);
SAMPLER(sampler_DistortionVectorMap);
TEXTURE2D(_EmissiveColorMap);
SAMPLER(sampler_EmissiveColorMap);
#ifndef LAYERED_LIT_SHADER
TEXTURE2D(_DiffuseLightingMap);
SAMPLER(sampler_DiffuseLightingMap);
TEXTURE2D(_BaseColorMap);
SAMPLER(sampler_BaseColorMap);
TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap);
TEXTURE2D(_BentNormalMap); // Reuse sampler from normal map
SAMPLER(sampler_BentNormalMap);
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURE2D(_NormalMapOS);
SAMPLER(sampler_NormalMapOS);
TEXTURE2D(_DetailMap);
SAMPLER(sampler_DetailMap);
TEXTURE2D(_HeightMap);
SAMPLER(sampler_HeightMap);
TEXTURE2D(_TangentMap);
SAMPLER(sampler_TangentMap);
TEXTURE2D(_TangentMapOS);
SAMPLER(sampler_TangentMapOS);
TEXTURE2D(_AnisotropyMap);
SAMPLER(sampler_AnisotropyMap);
TEXTURE2D(_SubsurfaceMaskMap);
SAMPLER(sampler_SubsurfaceMaskMap);
TEXTURE2D(_ThicknessMap);
SAMPLER(sampler_ThicknessMap);
TEXTURE2D(_SpecularColorMap);
SAMPLER(sampler_SpecularColorMap);
TEXTURE2D(_TransmittanceColorMap);
SAMPLER(sampler_TransmittanceColorMap);
#else
// Set of users variables
#define PROP_DECL(type, name) type name##0, name##1, name##2, name##3
// sampler are share by texture type inside a layered material but we need to support that a particualr layer have no texture, so we take the first sampler of available texture as the share one
// mean we must declare all sampler
#define PROP_DECL_TEX2D(name)\
TEXTURE2D(MERGE_NAME(name, 0)); \
SAMPLER(MERGE_NAME(MERGE_NAME(sampler, name), 0)); \
TEXTURE2D(MERGE_NAME(name, 1)); \
SAMPLER(MERGE_NAME(MERGE_NAME(sampler, name), 1)); \
TEXTURE2D(MERGE_NAME(name, 2)); \
SAMPLER(MERGE_NAME(MERGE_NAME(sampler, name), 2)); \
TEXTURE2D(MERGE_NAME(name, 3)); \
SAMPLER(MERGE_NAME(MERGE_NAME(sampler, name), 3))
PROP_DECL_TEX2D(_BaseColorMap);
PROP_DECL_TEX2D(_MaskMap);
PROP_DECL_TEX2D(_BentNormalMap);
PROP_DECL_TEX2D(_NormalMap);
PROP_DECL_TEX2D(_NormalMapOS);
PROP_DECL_TEX2D(_DetailMap);
PROP_DECL_TEX2D(_HeightMap);
PROP_DECL_TEX2D(_SubsurfaceMaskMap);
PROP_DECL_TEX2D(_ThicknessMap);
TEXTURE2D(_LayerMaskMap);
SAMPLER(sampler_LayerMaskMap);
TEXTURE2D(_LayerInfluenceMaskMap);
SAMPLER(sampler_LayerInfluenceMaskMap);
#endif
CBUFFER_START(UnityPerMaterial)
// shared constant between lit and layered lit
float _AlphaCutoff;
float _AlphaCutoffPrepass;
float _AlphaCutoffPostpass;
float4 _DoubleSidedConstants;
float _DistortionScale;
float _DistortionVectorScale;
float _DistortionVectorBias;
float _DistortionBlurScale;
float _DistortionBlurRemapMin;
float _DistortionBlurRemapMax;
float _PPDMaxSamples;
float _PPDMinSamples;
float _PPDLodThreshold;
float3 _EmissiveColor;
float _EmissiveIntensity;
float _AlbedoAffectEmissive;
float _EnableSpecularOcclusion;
// Transparency
float3 _TransmittanceColor;
float _IOR;
float _ATDistance;
float _ThicknessMultiplier;
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.
// In our case we don't use such a mechanism but need to keep the code quiet. We declare the value and always enable it.
// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
float3 _EmissionColor;
float4 _EmissiveColorMap_ST;
float _TexWorldScaleEmissive;
float4 _UVMappingMaskEmissive;
float4 _InvPrimScale; // Only XY are used
// Wind
float _InitialBend;
float _Stiffness;
float _Drag;
float _ShiverDrag;
float _ShiverDirectionality;
#ifndef LAYERED_LIT_SHADER
// Set of users variables
float4 _BaseColor;
float4 _BaseColorMap_ST;
float4 _BaseColorMap_TexelSize;
float4 _BaseColorMap_MipInfo;
float _Metallic;
float _Smoothness;
float _SmoothnessRemapMin;
float _SmoothnessRemapMax;
float _AORemapMin;
float _AORemapMax;
float _NormalScale;
float4 _DetailMap_ST;
float _DetailAlbedoScale;
float _DetailNormalScale;
float _DetailSmoothnessScale;
float4 _HeightMap_TexelSize; // Unity facility. This will provide the size of the heightmap to the shader
float _HeightAmplitude;
float _HeightCenter;
float _Anisotropy;
int _DiffusionProfile;
float _SubsurfaceMask;
float _Thickness;
float4 _ThicknessRemap;
float _CoatMask;
float4 _SpecularColor;
float _TexWorldScale;
float _InvTilingScale;
float4 _UVMappingMask;
float4 _UVDetailsMappingMask;
float _LinkDetailsWithBase;
#else // LAYERED_LIT_SHADER
// Set of users variables
PROP_DECL(float4, _BaseColor);
float4 _BaseColorMap0_ST;
float4 _BaseColorMap1_ST;
float4 _BaseColorMap2_ST;
float4 _BaseColorMap3_ST;
float4 _BaseColorMap0_TexelSize;
float4 _BaseColorMap0_MipInfo;
PROP_DECL(float, _Metallic);
PROP_DECL(float, _Smoothness);
PROP_DECL(float, _SmoothnessRemapMin);
PROP_DECL(float, _SmoothnessRemapMax);
PROP_DECL(float, _AORemapMin);
PROP_DECL(float, _AORemapMax);
PROP_DECL(float, _NormalScale);
float4 _NormalMap0_TexelSize; // Unity facility. This will provide the size of the base normal to the shader
float4 _HeightMap0_TexelSize;
float4 _HeightMap1_TexelSize;
float4 _HeightMap2_TexelSize;
float4 _HeightMap3_TexelSize;
float4 _DetailMap0_ST;
float4 _DetailMap1_ST;
float4 _DetailMap2_ST;
float4 _DetailMap3_ST;
PROP_DECL(float, _UVDetail);
PROP_DECL(float, _DetailAlbedoScale);
PROP_DECL(float, _DetailNormalScale);
PROP_DECL(float, _DetailSmoothnessScale);
PROP_DECL(float, _HeightAmplitude);
PROP_DECL(float, _HeightCenter);
PROP_DECL(int, _DiffusionProfile);
PROP_DECL(float, _SubsurfaceMask);
PROP_DECL(float, _Thickness);
PROP_DECL(float4, _ThicknessRemap);
PROP_DECL(float, _OpacityAsDensity);
float _InheritBaseNormal1;
float _InheritBaseNormal2;
float _InheritBaseNormal3;
float _InheritBaseHeight1;
float _InheritBaseHeight2;
float _InheritBaseHeight3;
float _InheritBaseColor1;
float _InheritBaseColor2;
float _InheritBaseColor3;
PROP_DECL(float, _HeightOffset);
float _HeightTransition;
float4 _LayerMaskMap_ST;
float _TexWorldScaleBlendMask;
PROP_DECL(float, _TexWorldScale);
PROP_DECL(float, _InvTilingScale);
float4 _UVMappingMaskBlendMask;
PROP_DECL(float4, _UVMappingMask);
PROP_DECL(float4, _UVDetailsMappingMask);
PROP_DECL(float, _LinkDetailsWithBase);
#endif // LAYERED_LIT_SHADER
// Tessellation specific
#ifdef TESSELLATION_ON
float _TessellationFactor;
float _TessellationFactorMinDistance;
float _TessellationFactorMaxDistance;
float _TessellationFactorTriangleSize;
float _TessellationShapeFactor;
float _TessellationBackFaceCullEpsilon;
float _TessellationObjectScale;
float _TessellationTilingScale;
#endif
CBUFFER_END

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitReference.hlsl


{
float3 lightDiff, lightSpec;
BSDF(V, L, positionWS, preLightData, bsdfData, lightDiff, lightSpec);
BSDF(V, L, NdotL, positionWS, preLightData, bsdfData, lightDiff, lightSpec);
diffuseLighting += lightDiff * (sinLT / dist2 * NdotL);
specularLighting += lightSpec * (sinLT / dist2 * NdotL);

float cosLNs = saturate(dot(-L, Ns));
// We calculate area reference light with the area integral rather than the solid angle one.
float illuminance = cosLNs * saturate(dot(bsdfData.normalWS, L)) / (sqrDist * lightPdf);
float NdotL = saturate(dot(bsdfData.normalWS, L));
float illuminance = cosLNs * NdotL / (sqrDist * lightPdf);
float3 localDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 localSpecularLighting = float3(0.0, 0.0, 0.0);

BSDF(V, L, positionWS, preLightData, bsdfData, localDiffuseLighting, localSpecularLighting);
BSDF(V, L, NdotL, positionWS, preLightData, bsdfData, localDiffuseLighting, localSpecularLighting);
localDiffuseLighting *= lightData.color * illuminance * lightData.diffuseScale;
localSpecularLighting *= lightData.color * illuminance * lightData.specularScale;
}

{
float3x3 localToWorld;
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS);
}

float weightOverPdf;
// GGX BRDF
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
ImportanceSampleAnisoGGX(u, V, localToWorld, bsdfData.roughnessT, bsdfData.roughnessB, NdotV, L, VdotH, NdotL, weightOverPdf);
}

19
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.compute


#define SSS_USE_LDS_CACHE 1
#define SSS_TAA_INTEGRATION 1 // Smoother results at the cost of a tiny amount of flickering in under-sampled areas
#define SSS_ENABLE_NEAR_FIELD 0 // Greatly increases the number of samples. Comes at a high cost.
#define SSS_SAMPLE_TEST_HTILE 0 // Potential optimization. YMMV.
#define SSS_USE_TANGENT_PLANE 0 // Improves the accuracy of the approximation(0 -> 1st order). High cost. Does not work with back-facing normals.
#define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE.
#define SSS_DEBUG_LOD 0

float3 tangentX, float3 tangentY, float4x4 projMatrix,
inout float3 totalIrradiance, inout float3 totalWeight)
{
float r = _FilterKernels[profileID][i][iR];
float r = _FilterKernels[profileID][i][iR];
float phi = SampleDiskFibonacci(i, n).y;
float phi = SampleDiskFibonacci(i, n).y;
phi += VanDerCorputBase2(_TaaFrameIndex % 4) * TWO_PI;
#endif
float sinPsi = _TaaFrameRotation.x;
float cosPsi = _TaaFrameRotation.y;
// The angle 'psi' is loop-invariant. All the trigonometry is done at compile time.
// cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)
// sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b)
float cosSum = cos(phi) * cosPsi - sin(phi) * sinPsi;
float sinSum = sin(phi) * cosPsi + cos(phi) * sinPsi;
float2 vec = r * float2(cosSum, sinSum);
#else
#endif
// Compute the screen-space position and the squared distance (in mm) in the image plane.
int2 position; float xy2;

72
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Unlit/UnlitProperties.hlsl


TEXTURE2D(_DistortionVectorMap);
SAMPLER(sampler_DistortionVectorMap);
TEXTURE2D(_UnlitColorMap);
SAMPLER(sampler_UnlitColorMap);
TEXTURE2D(_EmissiveColorMap);
SAMPLER(sampler_EmissiveColorMap);
CBUFFER_START(UnityPerMaterial)
float4 _UnlitColor;
float4 _UnlitColorMap_ST;
float4 _UnlitColorMap_TexelSize;
float4 _UnlitColorMap_MipInfo;
float3 _EmissiveColor;
float4 _EmissiveColorMap_ST;
float _EmissiveIntensity;
float _AlphaCutoff;
float _DistortionScale;
float _DistortionVectorScale;
float _DistortionVectorBias;
float _DistortionBlurScale;
float _DistortionBlurRemapMin;
float _DistortionBlurRemapMax;
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.
// In our case we don't use such a mechanism but need to keep the code quiet. We declare the value and always enable it.
// TODO: Fix the code in legacy unity so we can customize the behavior for GI
float3 _EmissionColor;
CBUFFER_END
TEXTURE2D(_DistortionVectorMap);
SAMPLER(sampler_DistortionVectorMap);
TEXTURE2D(_UnlitColorMap);
SAMPLER(sampler_UnlitColorMap);
TEXTURE2D(_EmissiveColorMap);
SAMPLER(sampler_EmissiveColorMap);
CBUFFER_START(UnityPerMaterial)
float4 _UnlitColor;
float4 _UnlitColorMap_ST;
float4 _UnlitColorMap_TexelSize;
float4 _UnlitColorMap_MipInfo;
float3 _EmissiveColor;
float4 _EmissiveColorMap_ST;
float _EmissiveIntensity;
float _AlphaCutoff;
float _DistortionScale;
float _DistortionVectorScale;
float _DistortionVectorBias;
float _DistortionBlurScale;
float _DistortionBlurRemapMin;
float _DistortionBlurRemapMax;
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.
// In our case we don't use such a mechanism but need to keep the code quiet. We declare the value and always enable it.
// TODO: Fix the code in legacy unity so we can customize the behavior for GI
float3 _EmissionColor;
CBUFFER_END

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPass.cs


GBuffer,
Forward,
ForwardUnlit,
DeferredLighting,
DepthOnly,
Velocity,
Distortion,

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPass.cs.hlsl


#define SHADERPASS_GBUFFER (0)
#define SHADERPASS_FORWARD (1)
#define SHADERPASS_FORWARD_UNLIT (2)
#define SHADERPASS_DEPTH_ONLY (3)
#define SHADERPASS_VELOCITY (4)
#define SHADERPASS_DISTORTION (5)
#define SHADERPASS_LIGHT_TRANSPORT (6)
#define SHADERPASS_SHADOWS (7)
#define SHADERPASS_SUBSURFACE_SCATTERING (8)
#define SHADERPASS_VOLUMETRIC_LIGHTING (9)
#define SHADERPASS_DBUFFER (10)
#define SHADERPASS_DEFERRED_LIGHTING (3)
#define SHADERPASS_DEPTH_ONLY (4)
#define SHADERPASS_VELOCITY (5)
#define SHADERPASS_DISTORTION (6)
#define SHADERPASS_LIGHT_TRANSPORT (7)
#define SHADERPASS_SHADOWS (8)
#define SHADERPASS_SUBSURFACE_SCATTERING (9)
#define SHADERPASS_VOLUMETRIC_LIGHTING (10)
#define SHADERPASS_DBUFFER (11)
#endif

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassForward.hlsl


LightLoop(V, posInput, preLightData, bsdfData, bakeLightingData, featureFlags, diffuseLighting, specularLighting);
#ifdef OUTPUT_SPLIT_LIGHTING
if ((_EnableSubsurfaceScattering != 0) && HaveSubsurfaceScattering(bsdfData))
if (_EnableSubsurfaceScattering != 0 && PixelHasSubsurfaceScattering(bsdfData))
{
outColor = float4(specularLighting, 1.0);
outDiffuseLighting = float4(TagLightingForSSS(diffuseLighting), 1.0);

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl


int unity_StereoEyeIndex;
#endif
float3 unity_ShadowColor;
uint _TaaFrameIndex; // [0, 7]
float4 unity_ShadowColor;
float2 _TaaFrameRotation; // {x = sin(_TaaFrameIndex * PI/2), y = cos(_TaaFrameIndex * PI/2), z = unused}
uint _TaaFrameIndex; // [0, 7]
uint _Align128; // Pad for 128-bit alignment
// Volumetric lighting. Should be a struct in 'UnityPerFrame'.
// Unfortunately, structures inside constant buffers are not supported by Unity.
float3 _GlobalFog_Scattering;

1
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/3DObjects/CornelBox/Cornell Box.fbx.meta


2186277476908879422: ImportLogs
2186277476908879424: ImportLogs
2186277476908879426: ImportLogs
2186277476908879428: ImportLogs
externalObjects:
- first:
type: UnityEngine:Material

1
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/3DObjects/Sphere/Sphere.fbx.meta


2186277476908879424: ImportLogs
2186277476908879426: ImportLogs
2186277476908879428: ImportLogs
2186277476908879430: ImportLogs
externalObjects: {}
materials:
importMaterials: 0

1
Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Assets/CommonAssets/Cornell Box.fbx.meta


7400000: Take 001
9500000: //RootNode
2186277476908879412: ImportLogs
2186277476908879414: ImportLogs
externalObjects:
- first:
type: UnityEngine:Material

1
Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/040_UpgradeScene/Models/Environment/Floor.fbx.meta


7400000: Take 001
9500000: //RootNode
2186277476908879412: ImportLogs
2186277476908879414: ImportLogs
externalObjects:
- first:
type: UnityEngine:Material

11
Tests/Scripts/Editor.meta


fileFormatVersion: 2
guid: 0f6887a1ff514ed690ada3786867d216
timeCreated: 1512986333
fileFormatVersion: 2
guid: 2ea8802fb7f2fa641a567a661fb6a58e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/Editor.meta


fileFormatVersion: 2
guid: 0f6887a1ff514ed690ada3786867d216
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/GraphicsTests/Framework.meta


fileFormatVersion: 2
guid: 8305d4811b3aa624ea663e2d7841e470
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Scripts.meta


fileFormatVersion: 2
guid: c1f6eaf19a5d40045818530f57b09da5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/040_UpgradeScene/Scripts.meta


fileFormatVersion: 2
guid: 2c9ce194a1bfc4733b75593a1f4ced22
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

11
Tests/Scripts/Editor/GraphicTests/HDRenderPipeline/DebugViewController_Editor.cs.meta


fileFormatVersion: 2
guid: da59c0df09fb17e4f99a667936fce895
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/ShaderGeneratorTests.meta


fileFormatVersion: 2
guid: 552442937a683d2479830866e050b035
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/GraphicsTests/Framework/Editor.meta


fileFormatVersion: 2
guid: ac919a67e7c764f70a75900c12043d9b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/Scripts/Editor.meta


fileFormatVersion: 2
guid: 129562301394edd45a199c538cda6f8f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/GraphicsTests/RenderPipeline/LightweightPipeline/Scenes/040_UpgradeScene/Scripts/Editor.meta


fileFormatVersion: 2
guid: 8a8e7dc88956341568162060a68f1e7e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Tests/ShaderGeneratorTests/Editor.meta


fileFormatVersion: 2
guid: 76dedef1a7bcc354e900c23b8135d94c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存