浏览代码

Merge branch 'master' into switch-support

/main
GitHub 7 年前
当前提交
32210ac9
共有 38 个文件被更改,包括 1489 次插入2767 次删除
  1. 3
      com.unity.render-pipelines.core/CHANGELOG.md
  2. 22
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/BSDF.hlsl
  3. 6
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Common.hlsl
  4. 33
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/CommonLighting.hlsl
  5. 2
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/CommonMaterial.hlsl
  6. 8
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Macros.hlsl
  7. 5
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Sampling/Sampling.hlsl
  8. 52
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Shadow/ShadowSampling.hlsl
  9. 100
      com.unity.render-pipelines.core/CoreRP/Shadow/Shadow.cs
  10. 2
      com.unity.render-pipelines.core/CoreRP/Shadow/ShadowBase.cs
  11. 1
      com.unity.render-pipelines.core/CoreRP/Shadow/ShadowBase.cs.hlsl
  12. 6
      com.unity.render-pipelines.high-definition/CHANGELOG.md
  13. 12
      com.unity.render-pipelines.high-definition/HDRP/Editor/Material/StackLit/StackLitUI.cs
  14. 2
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template
  15. 57
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightDefinition.cs
  16. 147
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightDefinition.cs.hlsl
  17. 155
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightEvaluation.hlsl
  18. 20
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs
  19. 2
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumeTextureAtlas.cs
  20. 2
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumeVoxelization.compute
  21. 2
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  22. 22
      com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LTCAreaLight.cs
  23. 1
      com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LTCAreaLight.hlsl
  24. 998
      com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LtcData.DisneyDiffuse.cs
  25. 992
      com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LtcData.GGX.cs
  26. 458
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl
  27. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/LitBuiltinData.hlsl
  28. 4
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/LitReference.hlsl
  29. 3
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs
  30. 34
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs.hlsl
  31. 755
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
  32. 33
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.shader
  33. 9
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitData.hlsl
  34. 13
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitProperties.hlsl
  35. 109
      com.unity.render-pipelines.high-definition/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl
  36. 1
      com.unity.render-pipelines.lightweight/CHANGELOG.md
  37. 174
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Shadow/PCSS.hlsl
  38. 9
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Shadow/PCSS.hlsl.meta

3
com.unity.render-pipelines.core/CHANGELOG.md


## [Unreleased]
### Added
- Add PCSS shadow filter
### Improvements
- Improved volume UI & styling

22
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/BSDF.hlsl


}
// Evaluate the reflectance for a thin-film layer on top of a dielectric medum.
real3 EvalIridescence(real eta_1, real cosTheta1, real iridescenceThickness, real3 baseLayerFresnel0)
real3 EvalIridescence(real eta_1, real cosTheta1, real iridescenceThickness, real3 baseLayerFresnel0, real iorOverBaseLayer = 0.0)
{
// iridescenceThickness unit is micrometer for this equation here. Mean 0.5 is 500nm.
real Dinc = 3.0 * iridescenceThickness;

// Force eta_2 -> eta_1 when Dinc -> 0.0
// real eta_2 = lerp(eta_1, eta_2, smoothstep(0.0, 0.03, Dinc));
// Evaluate the cosTheta on the base layer (Snell law)
real cosTheta2 = sqrt(1.0 - Sq(eta_1 / eta_2) * (1.0 - Sq(cosTheta1)));
real sinTheta2 = Sq(eta_1 / eta_2) * (1.0 - Sq(cosTheta1));
// Handle TIR
if (sinTheta2 > 1.0)
return real3(1.0, 1.0, 1.0);
//Or use this "artistic hack" to get more continuity even though wrong (test with dual normal maps to understand the difference)
//if( sinTheta2 > 1.0 ) { sinTheta2 = 2 - sinTheta2; }
real cosTheta2 = sqrt(1.0 - sinTheta2);
// First interface
real R0 = IorToFresnel0(eta_2, eta_1);

real phi21 = PI - phi12;
// Second interface
// The f0 or the base should account for the new computed eta_2 on top.
// This is optionally done if we are given the needed current ior over the base layer that is accounted for
// in the baseLayerFresnel0 parameter:
if (iorOverBaseLayer > 0.0)
{
// Fresnel0ToIor will give us a ratio of baseIor/topIor, hence we * iorOverBaseLayer to get the baseIor
real3 baseIor = iorOverBaseLayer * Fresnel0ToIor(baseLayerFresnel0 + 0.0001); // guard against 1.0
baseLayerFresnel0 = IorToFresnel0(baseIor, eta_2);
}
real3 R23 = F_Schlick(baseLayerFresnel0, cosTheta2);
real phi23 = 0.0;

6
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Common.hlsl


// Misc utilities
// ----------------------------------------------------------------------------
// Simple function to test a bitfield
bool HasFlag(uint bitfield, uint flag)
{
return (bitfield & flag) != 0;
}
// Normalize that account for vectors with zero length
real3 SafeNormalize(real3 inVec)
{

33
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/CommonLighting.hlsl


// Non physically based hack to limit light influence to attenuationRadius.
// SmoothInfluenceAttenuation must be use, InfluenceAttenuation is just for optimization with SmoothQuadraticDistanceAttenuation
real InfluenceAttenuation(real distSquare, real invSqrAttenuationRadius)
real InfluenceAttenuation(real distSquare, real rangeAttenuationScale, real rangeAttenuationBias)
real factor = distSquare * invSqrAttenuationRadius;
return saturate(1.0 - factor * factor);
// Apply the saturate here as we can have negative number
real factor = saturate(distSquare * rangeAttenuationScale + rangeAttenuationBias);
return 1.0 - factor * factor;
real SmoothInfluenceAttenuation(real distSquare, real invSqrAttenuationRadius)
real SmoothInfluenceAttenuation(real distSquare, real rangeAttenuationScale, real rangeAttenuationBias)
real smoothFactor = InfluenceAttenuation(distSquare, invSqrAttenuationRadius);
real smoothFactor = InfluenceAttenuation(distSquare, rangeAttenuationScale, rangeAttenuationBias);
return Sq(smoothFactor);
}

real SmoothQuadraticDistanceAttenuation(real distSquare, real distRcp, real invSqrAttenuationRadius)
real SmoothQuadraticDistanceAttenuation(real distSquare, real distRcp, real rangeAttenuationScale, real rangeAttenuationBias)
attenuation *= InfluenceAttenuation(distSquare, invSqrAttenuationRadius);
attenuation *= InfluenceAttenuation(distSquare, rangeAttenuationScale, rangeAttenuationBias);
real SmoothQuadraticDistanceAttenuation(real3 unL, real invSqrAttenuationRadius)
real SmoothQuadraticDistanceAttenuation(real3 unL, real rangeAttenuationScale, real rangeAttenuationBias)
return SmoothQuadraticDistanceAttenuation(distSquare, distRcp, invSqrAttenuationRadius);
return SmoothQuadraticDistanceAttenuation(distSquare, distRcp, rangeAttenuationScale, rangeAttenuationBias);
}
real AngleAttenuation(real cosFwd, real lightAngleScale, real 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 SmoothPunctualLightAttenuation(real4 distances, real rangeAttenuationScale, real rangeAttenuationBias,
real lightAngleScale, real lightAngleOffset)
{
real distSq = distances.y;

real attenuation = min(distRcp, 1.0 / PUNCTUAL_LIGHT_THRESHOLD);
attenuation *= InfluenceAttenuation(distSq, invSqrAttenuationRadius);
attenuation *= AngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset);
attenuation *= InfluenceAttenuation(distSq, rangeAttenuationScale, rangeAttenuationBias);
attenuation *= AngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset);
return Sq(attenuation);
}

// The transformation is performed along the major axis of the ellipsoid (corresponding to 'r1').
// Both the ellipsoid (e.i. 'axis') and 'unL' should be in the same coordinate system.
// 'unL' should be computed from the center of the ellipsoid.
real EllipsoidalDistanceAttenuation(real3 unL, real invSqRadius,
real EllipsoidalDistanceAttenuation(real3 unL, real rangeAttenuationScale, real rangeAttenuationBias,
real3 axis, real invAspectRatio)
{
// Project the unnormalized light vector onto the axis.

unL -= diff * axis;
real sqDist = dot(unL, unL);
return SmoothInfluenceAttenuation(sqDist, invSqRadius);
return SmoothInfluenceAttenuation(sqDist, rangeAttenuationScale, rangeAttenuationBias);
}
// Applies SmoothInfluenceAttenuation() using the axis-aligned ellipsoid of the given dimensions.

unL *= invHalfDim;
real sqDist = dot(unL, unL);
return SmoothInfluenceAttenuation(sqDist, 1.0);
return SmoothInfluenceAttenuation(sqDist, 1.0, 0.0);
}
// Applies SmoothInfluenceAttenuation() after mapping the axis-aligned box to a sphere.

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

2
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/CommonMaterial.hlsl


//
// avgNormalLength gives the dispersion information for the covered normals.
//
// Note that hw filtering on the normal map should be trilinear to be conservative, while anisotropic
// Note that hw filtering on the normal map should be trilinear to be conservative, while anisotropic
// risk underfiltering. Could also compute average normal on the fly with a proper normal map format,
// like Toksvig.
float TextureNormalVariance(float avgNormalLength)

8
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Macros.hlsl


#define TRANSFORM_TEX(tex, name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
#define GET_TEXELSIZE_NAME(name) (name##_TexelSize)
#if UNITY_REVERSED_Z
# define COMPARE_DEVICE_DEPTH_CLOSER(shadowMapDepth, zDevice) (shadowMapDepth > zDevice)
# define COMPARE_DEVICE_DEPTH_CLOSEREQUAL(shadowMapDepth, zDevice) (shadowMapDepth >= zDevice)
#else
# define COMPARE_DEVICE_DEPTH_CLOSER(shadowMapDepth, zDevice) (shadowMapDepth < zDevice)
# define COMPARE_DEVICE_DEPTH_CLOSEREQUAL(shadowMapDepth, zDevice) (shadowMapDepth <= zDevice)
#endif
#endif // UNITY_MACROS_INCLUDED

5
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Sampling/Sampling.hlsl


//-----------------------------------------------------------------------------
// Sampling function
// Reference : http://www.cs.virginia.edu/~jdl/bib/globillum/mis/shirley96.pdf + PBRT
// Caution: Our light point backward (-Z), these sampling function follow this convention
//-----------------------------------------------------------------------------
// Performs uniform sampling of the unit disk.

{
// Random point at rectangle surface
P = real3((u.x - 0.5) * width, (u.y - 0.5) * height, 0);
Ns = real3(0, 0, -1); // Light point backward (-Z)
Ns = real3(0, 0, -1); // Light down (-Z)
// Transform to world space
P = mul(real4(P, 1.0), localToWorld).xyz;

{
// Random point at disk surface
P = real3(radius * SampleDiskUniform(u.x, u.y), 0);
Ns = real3(0.0, 0.0, -1.0); // Light point backward (-Z)
Ns = real3(0.0, 0.0, -1.0); // Light down (-Z)
// Transform to world space
P = mul(real4(P, 1.0), localToWorld).xyz;

52
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Shadow/ShadowSampling.hlsl


return (z[1] < 0.0 || z[2] > 1.0) ? ShadowMoments_SolveDelta4MSM( z, b, lightLeakBias ) : ShadowMoments_SolveDelta3MSM( z, b.xy, lightLeakBias );
}
#include "PCSS.hlsl"
real SampleShadow_PCSS( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, real4 scaleOffset, real2 sampleBias, float slice, uint texIdx, uint sampIdx )
{
real2 params = asfloat(shadowContext.payloads[payloadOffset].xy);
real shadowSoftnesss = params.x;
int sampleCount = params.y;
payloadOffset++;
real2 sampleJitter = real2(sin(GenerateHashedRandomFloat(tcs.x)),
cos(GenerateHashedRandomFloat(tcs.y)));
//1) Blocker Search
real averageBlockerDepth = 0.0;
real numBlockers = 0.0;
if (!BlockerSearch(averageBlockerDepth, numBlockers, shadowSoftnesss + 0.000001, tcs, sampleJitter, sampleBias, shadowContext, slice, texIdx, sampIdx, sampleCount))
return 1.0;
//2) Penumbra Estimation
real filterSize = shadowSoftnesss * PenumbraSize(tcs.z, averageBlockerDepth);
filterSize = max(filterSize, 0.000001);
//3) Filter
return PCSS(tcs, filterSize, scaleOffset, slice, sampleBias, sampleJitter, shadowContext, texIdx, sampIdx, sampleCount);
}
real SampleShadow_PCSS( ShadowContext shadowContext, inout uint payloadOffset, real3 tcs, real4 scaleOffset, real2 sampleBias, float slice, Texture2DArray tex, SamplerComparisonState compSamp, SamplerState samp )
{
real2 params = asfloat(shadowContext.payloads[payloadOffset].xy);
real shadowSoftnesss = params.x;
int sampleCount = params.y;
payloadOffset++;
real2 sampleJitter = real2(sin(GenerateHashedRandomFloat(tcs.x)),
cos(GenerateHashedRandomFloat(tcs.y)));
//1) Blocker Search
real averageBlockerDepth = 0.0;
real numBlockers = 0.0;
if (!BlockerSearch(averageBlockerDepth, numBlockers, shadowSoftnesss + 0.000001, tcs, slice, sampleJitter, sampleBias, tex, samp, sampleCount))
return 1.0;
//2) Penumbra Estimation
real filterSize = shadowSoftnesss * PenumbraSize(tcs.z, averageBlockerDepth);
filterSize = max(filterSize, 0.000001);
//3) Filter
return PCSS(tcs, filterSize, scaleOffset, slice, sampleBias, sampleJitter, tex, compSamp, sampleCount);
}
//-----------------------------------------------------------------------------------------------------
// helper function to dispatch a specific shadow algorithm
real SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, real3 posTC, real2 sampleBias, uint algorithm, uint texIdx, uint sampIdx )

case GPUSHADOWALGORITHM_PCF_TENT_3X3 : return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_5X5 : return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_7X7 : return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCSS : return SampleShadow_PCSS( shadowContext, payloadOffset, posTC, shadowData.scaleOffset, sampleBias, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_VSM : return SampleShadow_VSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_EVSM_2 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx, false );
case GPUSHADOWALGORITHM_EVSM_4 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, shadowData.slice, texIdx, sampIdx, true );

case GPUSHADOWALGORITHM_PCF_TENT_3X3 : return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_5X5 : return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_7X7 : return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.textureSize, shadowData.texelSizeRcp, posTC, sampleBias, shadowData.slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCSS : return SampleShadow_PCSS( shadowContext, payloadOffset, posTC, shadowData.scaleOffset, sampleBias, shadowData.slice, tex, compSamp, s_point_clamp_sampler );
default: return 1.0;
}

100
com.unity.render-pipelines.core/CoreRP/Shadow/Shadow.cs


readonly ValRange m_DefPCF_DepthBias = new ValRange("Depth Bias", 0.0f, 0.0f, 1.0f, 000.1f);
readonly ValRange m_DefPCF_FilterSize = new ValRange("Filter Size", 1.0f, 1.0f, 10.0f, 1.0f);
readonly ValRange m_DefPCSS_ShadowSoftness = new ValRange("Shadow Softness", 0.0f, 0.5f, 1.0f, 0.01f);
readonly ValRange m_DefPCSS_SampleCount = new ValRange("Sample Count", 1, 32, 64, 1);
public ShadowAtlas(ref AtlasInit init) : base(ref init.baseInit)
{

override protected void Register(GPUShadowType type, ShadowRegistry registry)
{
ShadowPrecision precision = m_ShadowmapBits == 32 ? ShadowPrecision.High : ShadowPrecision.Low;
m_SupportedAlgorithms.Reserve(5);
m_SupportedAlgorithms.Reserve(6);
m_SupportedAlgorithms.AddUniqueUnchecked((int)ShadowUtils.Pack(ShadowAlgorithm.PCSS, ShadowVariant.V0, precision));
ShadowRegistry.VariantDelegate del = (Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock) =>
{

if (dataVariant == ShadowVariant.V1)
m_DefPCF_FilterSize.Slider(ref dataBlock[1]);
};
ShadowRegistry.VariantDelegate pcssDel = (Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataBlock) =>
{
CheckDataIntegrity(dataAlgorithm, dataVariant, dataPrecision, ref dataBlock);
m_DefPCSS_ShadowSoftness.Slider(ref dataBlock[0]);
m_DefPCSS_SampleCount.Slider(ref dataBlock[1]);
dataBlock[1] = ShadowUtils.Asint(Mathf.RoundToInt(ShadowUtils.Asfloat(dataBlock[1])));
};
registry.Register(type, precision, ShadowAlgorithm.PCSS, "Percentage Closer Soft Shadows (PCSS)",
new ShadowVariant[] { ShadowVariant.V0 },
new string[] { "poisson 64" },
new ShadowRegistry.VariantDelegate[] { pcssDel });
if (algorithm != ShadowAlgorithm.PCF ||
if ((algorithm != ShadowAlgorithm.PCF && algorithm != ShadowAlgorithm.PCSS) ||
(variant != ShadowVariant.V0 &&
variant != ShadowVariant.V1 &&
variant != ShadowVariant.V2 &&

const int k_BlockSize = 2;
if (dataBlock == null || dataBlock.Length != k_BlockSize)
switch (algorithm)
// set defaults
dataBlock = new int[k_BlockSize];
dataBlock[0] = m_DefPCF_DepthBias.Default();
dataBlock[1] = m_DefPCF_FilterSize.Default();
return false;
case ShadowAlgorithm.PCF:
const int k_PcfBlockSize = 2;
if (dataBlock == null || dataBlock.Length != k_PcfBlockSize)
{
// set defaults
dataBlock = new int[k_PcfBlockSize];
dataBlock[0] = m_DefPCF_DepthBias.Default();
dataBlock[1] = m_DefPCF_FilterSize.Default();
return false;
}
break;
case ShadowAlgorithm.PCSS:
const int k_PcssBlockSize = 2;
if (dataBlock == null || dataBlock.Length != k_PcssBlockSize)
{
// set defaults
dataBlock = new int[k_PcssBlockSize];
dataBlock[0] = m_DefPCSS_ShadowSoftness.Default();
dataBlock[1] = m_DefPCSS_SampleCount.Default();
return false;
}
break;
}
return true;
}

virtual protected uint ReservePayload(ShadowRequest sr)
{
uint payloadSize = sr.shadowType == GPUShadowType.Directional ? (1 + k_MaxCascadesInShader + ((uint)m_TmpBorders.Length / 4)) : 0;
payloadSize += ShadowUtils.ExtractAlgorithm(sr.shadowAlgorithm) == ShadowAlgorithm.PCF ? 1u : 0;
switch (ShadowUtils.ExtractAlgorithm(sr.shadowAlgorithm))
{
case ShadowAlgorithm.PCF:
payloadSize += 1;
break;
case ShadowAlgorithm.PCSS:
payloadSize += 1;
break;
default:
break;
}
return payloadSize;
}

}
ShadowAlgorithm algo; ShadowVariant vari; ShadowPrecision prec;
ShadowUtils.Unpack(sr.shadowAlgorithm, out algo, out vari, out prec);
if (algo == ShadowAlgorithm.PCF)
if (algo == ShadowAlgorithm.PCF || algo == ShadowAlgorithm.PCSS)
{
AdditionalShadowData asd = lights[sr.index].light.GetComponent<AdditionalShadowData>();
if (!asd)

Debug.Log("Fixed up shadow data for algorithm " + algo + ", variant " + vari);
}
switch (vari)
if (algo == ShadowAlgorithm.PCF)
case ShadowVariant.V0:
case ShadowVariant.V1:
case ShadowVariant.V2:
case ShadowVariant.V3:
case ShadowVariant.V4:
switch (vari)
sp.Set(shadowData[0] | (SystemInfo.usesReversedZBuffer ? 1 : 0), shadowData[1], 0, 0);
payload[payloadOffset] = sp;
payloadOffset++;
case ShadowVariant.V0:
case ShadowVariant.V1:
case ShadowVariant.V2:
case ShadowVariant.V3:
case ShadowVariant.V4:
{
sp.Set(shadowData[0] | (SystemInfo.usesReversedZBuffer ? 1 : 0), shadowData[1], 0, 0);
payload[payloadOffset] = sp;
payloadOffset++;
}
break;
break;
}
else if (algo == ShadowAlgorithm.PCSS)
{
sp.Set(shadowData[0], shadowData[1], 0, 0);
payload[payloadOffset] = sp;
payloadOffset++;
}
}
}

2
com.unity.render-pipelines.core/CoreRP/Shadow/ShadowBase.cs


VSM,
EVSM,
MSM,
PCSS,
Custom = 32
};

EVSM_4 = ShadowAlgorithm.EVSM << 3 | ShadowVariant.V1,
MSM_Ham = ShadowAlgorithm.MSM << 3 | ShadowVariant.V0,
MSM_Haus = ShadowAlgorithm.MSM << 3 | ShadowVariant.V1,
PCSS = ShadowAlgorithm.PCSS << 3 | ShadowVariant.V0,
Custom = ShadowAlgorithm.Custom << 3
}

1
com.unity.render-pipelines.core/CoreRP/Shadow/ShadowBase.cs.hlsl


#define GPUSHADOWALGORITHM_EVSM_4 (17)
#define GPUSHADOWALGORITHM_MSM_HAM (24)
#define GPUSHADOWALGORITHM_MSM_HAUS (25)
#define GPUSHADOWALGORITHM_PCSS (32)
#define GPUSHADOWALGORITHM_CUSTOM (256)
// Generated from UnityEngine.Experimental.Rendering.ShadowData

6
com.unity.render-pipelines.high-definition/CHANGELOG.md


### Fixed
- Fixed a shader preprocessor issue when compiling DebugViewMaterialGBuffer.shader against Metal target
- Added a temporary workaround to Lit.hlsl to avoid broken lighting code with Metal/AMD
- Fixed compilation errors on Nintendo Switch (limited XRSetting support).
- Fixed apply range attenuation option on punctual light
- Fixed issue when using more than one volume mask texture with density volumes.
- Add PCSS shadow filter support (from SRP Core)
- SSS and Transmission code have been refactored to be able to share it between various material. Guidelines are in SubsurfaceScattering.hlsl
- Change code in area light with LTC for Lit shader. Magnitude is now take from FGD texture instead of a separate texture.
### Fixed
- Fix contact shadows applied on transmission

12
com.unity.render-pipelines.high-definition/HDRP/Editor/Material/StackLit/StackLitUI.cs


protected const string k_IridescenceThickness = "_IridescenceThickness";
protected const string k_IridescenceThicknessMap = "_IridescenceThicknessMap";
protected const string k_IridescenceThicknessMapUV = "_IridescenceThicknessMapUV";
protected const string k_IridescenceMask = "_IridescenceMask";
protected const string k_IridescenceMaskMap = "_IridescenceMaskMap";
protected const string k_IridescenceMaskMapUV = "_IridescenceMaskMapUV";
// Stencil is use to control lighting mode (regular, split lighting)
protected const string kStencilRef = "_StencilRef";

new GroupProperty(this, "_Iridescence", "Iridescence", new BaseProperty[]
{
new Property(this, "_IridescenceIor", "IOR", "Index of refraction of iridescence layer", false),
new Property(this, "_IridescenceThickness", "Thickness", "Iridescence thickness (Remap to 0..3000nm)", false),
//just to test: to use the same EvalIridescence as lit, find a good mapping for the top IOR (over the iridescence dielectric film)
//when having iridescence:
//new Property(this, "_IridescenceIor", "TopIOR", "Index of refraction on top of iridescence layer", false),
new TextureProperty(this, k_IridescenceMaskMap, k_IridescenceMask, "Iridescence Mask", "Iridescence Mask", false),
new TextureProperty(this, k_IridescenceThicknessMap, k_IridescenceThickness, "Iridescence thickness (Remap to 0..3000nm)", "Iridescence thickness (Remap to 0..3000nm)", false),
}, _ => EnableIridescence.BoolValue == true),
new GroupProperty(this, "_SSS", "Sub-Surface Scattering", new BaseProperty[]

SetupTextureMaterialProperty(material, k_Thickness);
SetupTextureMaterialProperty(material, k_Anisotropy);
SetupTextureMaterialProperty(material, k_IridescenceThickness);
SetupTextureMaterialProperty(material, k_IridescenceMask);
SetupTextureMaterialProperty(material, k_CoatSmoothness);
// Check if we are using specific UVs.

(TextureProperty.UVMapping)material.GetFloat(k_ThicknessMapUV),
(TextureProperty.UVMapping)material.GetFloat(k_AnisotropyMapUV),
(TextureProperty.UVMapping)material.GetFloat(k_IridescenceThicknessMapUV),
(TextureProperty.UVMapping)material.GetFloat(k_IridescenceMaskMapUV),
(TextureProperty.UVMapping)material.GetFloat(k_CoatSmoothnessMapUV),
(TextureProperty.UVMapping)material.GetFloat(k_CoatNormalMapUV),
};

2
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template


// 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(posInput.positionSS.xy, surfaceData);
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFlag(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.

57
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightDefinition.cs


[GenerateHLSL]
public struct DirectionalLightData
{
public Vector3 positionWS;
public int tileCookie; // TODO: make it a bool
// Packing order depends on chronological access to avoid cache misses
public Vector3 positionWS;
public int shadowIndex; // -1 if unused
public int contactShadowIndex; // -1 if unused
public Vector3 forward;
public float volumetricDimmer;
public float specularScale;
public Vector3 up; // Rescaled by (2 / shapeHeight)
public Vector3 forward;
public int tileCookie; // TODO: make it a bool
public int shadowIndex; // -1 if unused
public int contactShadowIndex; // -1 if unused
public Vector3 up; // Rescaled by (2 / shapeHeight)
public float diffuseScale;
public Vector4 shadowMaskSelector; // Use with ShadowMask feature
public float volumetricDimmer;
public Vector4 shadowMaskSelector; // Use with ShadowMask feature
public float diffuseScale;
public float specularScale;
// Packing order depends on chronological access to avoid cache misses
public float invSqrAttenuationRadius;
public int shadowIndex; // -1 if unused
public float rangeAttenuationScale;
public float rangeAttenuationBias;
public int contactShadowIndex; // -1 if unused
public Vector3 forward;
public float angleScale; // Spot light
public float angleOffset; // Spot light
public GPULightType lightType;
public float specularScale;
public float diffuseScale;
public float angleScale; // Spot light
public float angleOffset; // Spot light
public Vector3 forward;
public int shadowIndex; // -1 if unused
public int contactShadowIndex; // -1 if unused
public int nonLightmappedOnly; // Use with ShadowMask feature // TODO: make it a bool
public int nonLightmappedOnly; // Use with ShadowMask feature // TODO: make it a bool
public float minRoughness; // This is use to give a small "area" to punctual light, as if we have a light with a radius.
public float diffuseScale;
public float specularScale;
public GPULightType lightType;
public float minRoughness; // This is use to give a small "area" to punctual light, as if we have a light with a radius.
public float volumetricDimmer; // TODO: improve the cache locality
public float volumetricDimmer;
};

public struct EnvLightData
{
// Packing order depends on chronological access to avoid cache misses
// Caution: The struct need to be align on byte16 (not strictly needed for structured buffer but if we do array later better).
// Proxy properties
public Vector3 capturePositionWS;

147
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightDefinition.cs.hlsl


struct DirectionalLightData
{
float3 positionWS;
int tileCookie;
int shadowIndex;
int contactShadowIndex;
float3 forward;
float volumetricDimmer;
float specularScale;
float diffuseScale;
float volumetricDimmer;
int nonLightmappedOnly;
float3 forward;
int tileCookie;
int shadowIndex;
int contactShadowIndex;
int nonLightmappedOnly;
float diffuseScale;
float specularScale;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.LightData

float3 positionWS;
float invSqrAttenuationRadius;
int shadowIndex;
int contactShadowIndex;
float3 forward;
float rangeAttenuationScale;
float rangeAttenuationBias;
float angleScale;
float angleOffset;
int lightType;
float specularScale;
float diffuseScale;
float angleScale;
float angleOffset;
float3 forward;
int shadowIndex;
int contactShadowIndex;
float4 shadowMaskSelector;
float4 shadowMaskSelector;
float2 size;
int lightType;
float diffuseScale;
float specularScale;
float2 size;
float volumetricDimmer;
};

{
return value.positionWS;
}
int GetTileCookie(DirectionalLightData value)
{
return value.tileCookie;
}
int GetShadowIndex(DirectionalLightData value)
int GetCookieIndex(DirectionalLightData value)
return value.shadowIndex;
return value.cookieIndex;
int GetContactShadowIndex(DirectionalLightData value)
float GetVolumetricDimmer(DirectionalLightData value)
return value.contactShadowIndex;
return value.volumetricDimmer;
float3 GetForward(DirectionalLightData value)
float3 GetRight(DirectionalLightData value)
return value.forward;
return value.right;
int GetCookieIndex(DirectionalLightData value)
float3 GetUp(DirectionalLightData value)
return value.cookieIndex;
return value.up;
float3 GetRight(DirectionalLightData value)
float3 GetForward(DirectionalLightData value)
return value.right;
return value.forward;
float GetSpecularScale(DirectionalLightData value)
int GetTileCookie(DirectionalLightData value)
return value.specularScale;
return value.tileCookie;
float3 GetUp(DirectionalLightData value)
int GetShadowIndex(DirectionalLightData value)
return value.up;
return value.shadowIndex;
float GetDiffuseScale(DirectionalLightData value)
int GetContactShadowIndex(DirectionalLightData value)
return value.diffuseScale;
return value.contactShadowIndex;
float GetVolumetricDimmer(DirectionalLightData value)
float4 GetShadowMaskSelector(DirectionalLightData value)
return value.volumetricDimmer;
return value.shadowMaskSelector;
float4 GetShadowMaskSelector(DirectionalLightData value)
float GetDiffuseScale(DirectionalLightData value)
{
return value.diffuseScale;
}
float GetSpecularScale(DirectionalLightData value)
return value.shadowMaskSelector;
return value.specularScale;
}
//

{
return value.positionWS;
}
float GetInvSqrAttenuationRadius(LightData value)
float3 GetColor(LightData value)
return value.invSqrAttenuationRadius;
return value.color;
float3 GetColor(LightData value)
float GetRangeAttenuationScale(LightData value)
return value.color;
return value.rangeAttenuationScale;
int GetShadowIndex(LightData value)
float GetRangeAttenuationBias(LightData value)
return value.shadowIndex;
return value.rangeAttenuationBias;
int GetContactShadowIndex(LightData value)
float GetAngleScale(LightData value)
return value.contactShadowIndex;
return value.angleScale;
float3 GetForward(LightData value)
float GetAngleOffset(LightData value)
return value.forward;
return value.angleOffset;
}
int GetLightType(LightData value)
{
return value.lightType;
float GetSpecularScale(LightData value)
{
return value.specularScale;
}
float GetDiffuseScale(LightData value)
float3 GetForward(LightData value)
return value.diffuseScale;
return value.forward;
float GetAngleScale(LightData value)
int GetShadowIndex(LightData value)
return value.angleScale;
return value.shadowIndex;
float GetAngleOffset(LightData value)
int GetContactShadowIndex(LightData value)
return value.angleOffset;
return value.contactShadowIndex;
float4 GetShadowMaskSelector(LightData value)
{
return value.shadowMaskSelector;
}
float4 GetShadowMaskSelector(LightData value)
float GetMinRoughness(LightData value)
return value.shadowMaskSelector;
return value.minRoughness;
float2 GetSize(LightData value)
float GetDiffuseScale(LightData value)
return value.size;
return value.diffuseScale;
int GetLightType(LightData value)
float GetSpecularScale(LightData value)
return value.lightType;
return value.specularScale;
float GetMinRoughness(LightData value)
float2 GetSize(LightData value)
return value.minRoughness;
return value.size;
}
float GetVolumetricDimmer(LightData value)
{

155
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightEvaluation.hlsl


// Punctual Light evaluation helper
//-----------------------------------------------------------------------------
// Return L vector for punctual light (normalize surface to light), lightToSample (light to surface non normalize) and distances {d, d^2, 1/d, d_proj}
void GetPunctualLightVectors(float3 positionWS, LightData lightData, out float3 L, out float3 lightToSample, out float4 distances)
{
lightToSample = positionWS - lightData.positionWS;
int lightType = lightData.lightType;
distances.w = dot(lightToSample, lightData.forward);
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);
}
}
float4 EvaluateCookie_Punctual(LightLoopContext lightLoopContext, LightData lightData,
float3 lightToSample)
{

float shadowMask = 1.0;
color = lightData.color;
attenuation = SmoothPunctualLightAttenuation(distances, lightData.invSqrAttenuationRadius,
attenuation = SmoothPunctualLightAttenuation(distances, lightData.rangeAttenuationScale, lightData.rangeAttenuationBias,
lightData.angleScale, lightData.angleOffset);
#if (SHADEROPTIONS_VOLUMETRIC_LIGHTING_PRESET != 0)

weight = Smoothstep01(weight);
weight *= lightData.weight;
}
// ----------------------------------------------------------------------------
// Helper functions to use Transmission with a material
// ----------------------------------------------------------------------------
// For EvaluateTransmission.hlsl file it is required to define a BRDF for the transmission. Defining USE_DIFFUSE_LAMBERT_BRDF use Lambert, otherwise it use Disneydiffuse
#ifdef MATERIAL_INCLUDE_TRANSMISSION
// This function return transmittance to provide to EvaluateTransmission
float3 PreEvaluatePunctualLightTransmission(LightLoopContext lightLoopContext, PositionInputs posInput, float distFrontFaceToLight,
float NdotL, float3 L, BSDFData bsdfData,
inout float3 normalWS, inout LightData lightData)
{
float3 transmittance = bsdfData.transmittance;
// if NdotL is positive, we do one fetch on front face done by EvaluateLight_XXX. Just regular lighting
// If NdotL is negative, we have two cases:
// - Thin mode: Reuse the front face fetch as shadow for back face - flip the normal for the bias (and the NdotL test) and disable contact shadow
// - Mixed mode: Do a fetch on back face to retrieve the thickness. The thickness will provide a shadow attenuation (with distance travelled there is less transmission).
// (Note: EvaluateLight_Punctual discard the fetch if NdotL < 0)
if (NdotL < 0 && lightData.shadowIndex >= 0)
{
if (HasFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS))
{
normalWS = -normalWS; // Flip normal for shadow bias
lightData.contactShadowIndex = -1; // Disable shadow contact
}
else // MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_MIXED_THICKNESS
{
// Recompute transmittance using the thickness value computed from the shadow map.
// Compute the distance from the light to the back face of the object along the light direction.
float distBackFaceToLight = GetPunctualShadowClosestDistance( lightLoopContext.shadowContext, s_linear_clamp_sampler,
posInput.positionWS, lightData.shadowIndex, L, lightData.positionWS);
// Our subsurface scattering models use the semi-infinite planar slab assumption.
// Therefore, we need to find the thickness along the normal.
float thicknessInUnits = (distFrontFaceToLight - distBackFaceToLight) * -NdotL;
float thicknessInMeters = thicknessInUnits * _WorldScales[bsdfData.diffusionProfile].x;
float thicknessInMillimeters = thicknessInMeters * MILLIMETERS_PER_METER;
#if SHADEROPTIONS_USE_DISNEY_SSS
// We need to make sure it's not less than the baked thickness to minimize light leaking.
float thicknessDelta = max(0, thicknessInMillimeters - bsdfData.thickness);
float3 S = _ShapeParams[bsdfData.diffusionProfile].rgb;
// Approximate the decrease of transmittance by e^(-1/3 * dt * S).
#if 0
float3 expOneThird = exp(((-1.0 / 3.0) * thicknessDelta) * S);
#else
// Help the compiler.
float k = (-1.0 / 3.0) * LOG2_E;
float3 p = (k * thicknessDelta) * S;
float3 expOneThird = exp2(p);
#endif
transmittance *= expOneThird;
#else // SHADEROPTIONS_USE_DISNEY_SSS
// We need to make sure it's not less than the baked thickness to minimize light leaking.
thicknessInMillimeters = max(thicknessInMillimeters, bsdfData.thickness);
transmittance = ComputeTransmittanceJimenez(_HalfRcpVariancesAndWeights[bsdfData.diffusionProfile][0].rgb,
_HalfRcpVariancesAndWeights[bsdfData.diffusionProfile][0].a,
_HalfRcpVariancesAndWeights[bsdfData.diffusionProfile][1].rgb,
_HalfRcpVariancesAndWeights[bsdfData.diffusionProfile][1].a,
_TransmissionTintsAndFresnel0[bsdfData.diffusionProfile].rgb,
thicknessInMillimeters);
#endif // SHADEROPTIONS_USE_DISNEY_SSS
// Note: we do not modify the distance to the light, or the light angle for the back face.
// This is a performance-saving optimization which makes sense as long as the thickness is small.
}
}
return transmittance;
}
// This function return transmittance to provide to EvaluateTransmission
float3 PreEvaluateDirectionalLightTransmission(float NdotL, DirectionalLightData lightData, BSDFData bsdfData, inout float3 normalWS, inout int contactShadowIndex)
{
if (NdotL < 0 && lightData.shadowIndex >= 0)
{
if (HasFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS))
{
normalWS = -normalWS; // Flip normal for shadow bias
contactShadowIndex = -1; // Disable shadow contact
}
}
return bsdfData.transmittance;
}
#define TRANSMISSION_WRAP_ANGLE (PI/12) // 15 degrees
#define TRANSMISSION_WRAP_LIGHT cos(PI/2 - TRANSMISSION_WRAP_ANGLE)
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
// Transmitted lighting is computed as follows:
// - we assume that the object is a thick plane (slab);
// - we reverse the front-facing normal for the back of the object;
// - we assume that the incoming radiance is constant along the entire back surface;
// - we apply BSDF-specific diffuse transmission to transmit the light subsurface and back;
// - we integrate the diffuse reflectance profile w.r.t. the radius (while also accounting
// for the thickness) to compute the transmittance;
// - we multiply the transmitted radiance by the transmittance.
// transmittance come from the call to PreEvaluateLightTransmission
// attenuation come from the call to EvaluateLight_Punctual
float3 EvaluateTransmission(BSDFData bsdfData, float3 transmittance, float NdotL, float NdotV, float LdotV, float attenuation)
{
// Apply wrapped lighting to better handle thin objects at grazing angles.
float wrappedNdotL = ComputeWrappedDiffuseLighting(-NdotL, TRANSMISSION_WRAP_LIGHT);
// Apply BSDF-specific diffuse transmission to attenuation. See also: [SSS-NOTE-TRSM]
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
#ifdef USE_DIFFUSE_LAMBERT_BRDF
attenuation *= Lambert();
#else
attenuation *= DisneyDiffuse(NdotV, max(0, -NdotL), LdotV, bsdfData.perceptualRoughness);
#endif
float intensity = attenuation * wrappedNdotL;
return intensity * transmittance;
}
#endif // #ifdef MATERIAL_INCLUDE_TRANSMISSION

20
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs


lightData.lightType = gpuLightType;
lightData.positionWS = light.light.transform.position;
// Setting 0 for invSqrAttenuationRadius mean we have no range attenuation, but still have inverse square attenuation.
lightData.invSqrAttenuationRadius = applyRangeAttenuation ? 1.0f / (light.range * light.range) : 0.0f;
// In the shader we do range remapping: (x - start) / (end - start) = (dist^2 * rangeAttenuationScale + rangeAttenuationBias)
if (applyRangeAttenuation)
{
// start = 0.0f, end = range^2
lightData.rangeAttenuationScale = 1.0f / (light.range * light.range);
lightData.rangeAttenuationBias = 0.0f;
}
else // Don't apply any attenuation but do a 'step' at range
{
// start = range^2 - epsilon, end = range^2
lightData.rangeAttenuationScale = 1.0f / 0.01f;
lightData.rangeAttenuationBias = - (light.range * light.range - 0.01f) / 0.01f;
}
lightData.forward = light.light.transform.forward; // Note: Light direction is oriented backward (-Z)
lightData.forward = light.light.transform.forward;
lightData.up = light.light.transform.up;
lightData.right = light.light.transform.right;

2
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumeTextureAtlas.cs


{
if (textures.Contains(volumeTexture))
{
textures.Add(volumeTexture);
textures.Remove(volumeTexture);
needTextureUpdate = true;
}

2
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumeVoxelization.compute


// Express the voxel center in the local coordinate system of the box.
float3 voxelCenterBS = mul(voxelCenterWS - obb.center, transpose(obbFrame));
float3 voxelCenterUV = (voxelCenterBS / obbExtents) * 0.5 + 0.5;
float3 voxelCenterUV = (voxelCenterBS / obbExtents);
#if SOFT_VOXELIZATION
// We need to determine which is the face closest to 'voxelCenterBS'.

2
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


if (volumeAtlas != null)
{
volumeAtlasDimensions.x = volumeAtlas.width / volumeAtlas.depth; // 1 / number of textures
volumeAtlasDimensions.x = (float)volumeAtlas.width / volumeAtlas.depth; // 1 / number of textures
volumeAtlasDimensions.y = 1.0f / volumeAtlas.width;
volumeAtlasDimensions.z = volumeAtlas.width;
}

22
com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LTCAreaLight.cs


int m_refCounting;
// For area lighting - We pack all texture inside a texture array to reduce the number of resource required
Texture2DArray m_LtcData; // 0: m_LtcGGXMatrix - RGBA, 2: m_LtcDisneyDiffuseMatrix - RGBA, 3: m_LtcMultiGGXFresnelDisneyDiffuse - RGB, A unused
Texture2DArray m_LtcData; // 0: m_LtcGGXMatrix - RGBA, 1: m_LtcDisneyDiffuseMatrix - RGBA
const int k_LtcLUTMatrixDim = 3; // size of the matrix (3x3)
const int k_LtcLUTResolution = 64;

tex.SetPixels(pixels, arrayElement);
}
// Special-case function for 'm_LtcMultiGGXFresnelDisneyDiffuse'.
void LoadLUT(Texture2DArray tex, int arrayElement, TextureFormat format, float[] LtcGGXMagnitudeData, float[] LtcGGXFresnelData, float[] LtcDisneyDiffuseMagnitudeData)
{
const int count = k_LtcLUTResolution * k_LtcLUTResolution;
Color[] pixels = new Color[count];
for (int i = 0; i < count; i++)
{
// We store the result of the subtraction as a run-time optimization.
// See the footnote 2 of "LTC Fresnel Approximation" by Stephen Hill.
pixels[i] = new Color(LtcGGXMagnitudeData[i] - LtcGGXFresnelData[i], LtcGGXFresnelData[i], LtcDisneyDiffuseMagnitudeData[i], 1);
}
tex.SetPixels(pixels, arrayElement);
}
public void Build()
{
Debug.Assert(m_refCounting >= 0);

hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Bilinear,
name = CoreUtils.GetTextureAutoName(k_LtcLUTResolution, k_LtcLUTResolution, TextureFormat.RGBAHalf, depth: 3, dim: TextureDimension.Tex2DArray, name: "LTC_LUT")
name = CoreUtils.GetTextureAutoName(k_LtcLUTResolution, k_LtcLUTResolution, TextureFormat.RGBAHalf, depth: 2, dim: TextureDimension.Tex2DArray, name: "LTC_LUT")
// TODO: switch to RGBA64 when it becomes available.
LoadLUT(m_LtcData, 2, TextureFormat.RGBAHalf, s_LtcGGXMagnitudeData, s_LtcGGXFresnelData, s_LtcDisneyDiffuseMagnitudeData);
m_LtcData.Apply();
}

1
com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LTCAreaLight.hlsl


#define LTC_GGX_MATRIX_INDEX 0 // RGBA
#define LTC_DISNEY_DIFFUSE_MATRIX_INDEX 1 // RGBA
#define LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX 2 // RGB, A unused
#define LTC_LUT_SIZE 64
#define LTC_LUT_SCALE ((LTC_LUT_SIZE - 1) * rcp(LTC_LUT_SIZE))

998
com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LtcData.DisneyDiffuse.cs
文件差异内容过多而无法显示
查看文件

992
com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LtcData.GGX.cs
文件差异内容过多而无法显示
查看文件

458
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl


//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "../SubsurfaceScattering/SubsurfaceScattering.hlsl"
#include "../NormalBuffer.hlsl"
// Those define allow to include desired SSS/Transmission functions
#define MATERIAL_INCLUDE_SUBSURFACESCATTERING
#define MATERIAL_INCLUDE_TRANSMISSION
#include "HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl"
#include "HDRP/Material/NormalBuffer.hlsl"
// Configuration
//-----------------------------------------------------------------------------
// Choose between Lambert diffuse and Disney diffuse (enable only one of them)
// #define USE_DIFFUSE_LAMBERT_BRDF
#define LIT_USE_GGX_ENERGY_COMPENSATION
// Enable reference mode for IBL and area lights
// Both reference define below can be define only if LightLoop is present, else we get a compile error
#ifdef HAS_LIGHTLOOP
// #define LIT_DISPLAY_REFERENCE_AREA
// #define LIT_DISPLAY_REFERENCE_IBL
#endif
// In forward we can chose between reading the normal from the normalBufferTexture or computing it again
// This is tradeoff between performance and quality. As we store the normal conpressed, recomputing again is higher quality.
// Uncomment this to get speed (to measure), let it comment to get quality
// #define FORWARD_MATERIAL_READ_FROM_WRITTEN_NORMAL_BUFFER
//-----------------------------------------------------------------------------
// Texture and constant buffer declaration
//-----------------------------------------------------------------------------

TEXTURE2D(_GBufferTexture2);
TEXTURE2D(_GBufferTexture3);
#include "../LTCAreaLight/LTCAreaLight.hlsl"
#include "../PreIntegratedFGD/PreIntegratedFGD.hlsl"
#include "HDRP/Material/LTCAreaLight/LTCAreaLight.hlsl"
#include "HDRP/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl"
//-----------------------------------------------------------------------------
// Definition

#define CLEAR_COAT_PERCEPTUAL_ROUGHNESS RoughnessToPerceptualRoughness(CLEAR_COAT_ROUGHNESS)
//-----------------------------------------------------------------------------
// Configuration
//-----------------------------------------------------------------------------
// Choose between Lambert diffuse and Disney diffuse (enable only one of them)
// #define LIT_DIFFUSE_LAMBERT_BRDF
#define LIT_USE_GGX_ENERGY_COMPENSATION
// Enable reference mode for IBL and area lights
// Both reference define below can be define only if LightLoop is present, else we get a compile error
#ifdef HAS_LIGHTLOOP
// #define LIT_DISPLAY_REFERENCE_AREA
// #define LIT_DISPLAY_REFERENCE_IBL
#endif
// In forward we can chose between reading the normal from the normalBufferTexture or computing it again
// This is tradeoff between performance and quality. As we store the normal conpressed, recomputing again is higher quality.
// Uncomment this to get speed (to measure), let it comment to get quality
// #define FORWARD_MATERIAL_READ_FROM_WRITTEN_NORMAL_BUFFER
//-----------------------------------------------------------------------------
// Ligth and material classification for the deferred rendering path
// Light and material classification for the deferred rendering path
// Configure what kind of combination is supported
//-----------------------------------------------------------------------------

/* 26 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIAL_FEATURE_MASK_FLAGS, // Catch all case with MATERIAL_FEATURE_MASK_FLAGS is needed in case we disable material classification
};
// Additional bits set in 'bsdfData.materialFeatures' to save registers and simplify feature tracking.
#define MATERIAL_FEATURE_FLAGS_SSS_OUTPUT_SPLIT_LIGHTING ((MATERIAL_FEATURE_MASK_FLAGS + 1) << 0)
#define MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET FastLog2((MATERIAL_FEATURE_MASK_FLAGS + 1) << 1) // 2 bits
#define MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_MIXED_THICKNESS ((MATERIAL_FEATURE_MASK_FLAGS + 1) << 3)
// Flags used as a shortcut to know if we have thin mode transmission
#define MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS ((MATERIAL_FEATURE_MASK_FLAGS + 1) << 4)
uint FeatureFlagsToTileVariant(uint featureFlags)
{
for (int i = 0; i < NUM_FEATURE_VARIANTS; i++)

#endif
#endif
// 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 HasFeatureFlag(uint featureFlags, uint flag)
{
return ((featureFlags & flag) != 0);
}
// Assume that bsdfData.diffusionProfile is init
void FillMaterialSSS(uint diffusionProfile, float subsurfaceMask, inout BSDFData bsdfData)
{
bsdfData.diffusionProfile = diffusionProfile;
bsdfData.fresnel0 = _TransmissionTintsAndFresnel0[diffusionProfile].a;
bsdfData.subsurfaceMask = subsurfaceMask;
bsdfData.materialFeatures |= MATERIAL_FEATURE_FLAGS_SSS_OUTPUT_SPLIT_LIGHTING;
bsdfData.materialFeatures |= GetSubsurfaceScatteringTexturingMode(bsdfData.diffusionProfile) << MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET;
}
// Assume that bsdfData.diffusionProfile is init
void FillMaterialTransmission(uint diffusionProfile, float thickness, inout BSDFData bsdfData)
{
bsdfData.diffusionProfile = diffusionProfile;
bsdfData.fresnel0 = _TransmissionTintsAndFresnel0[diffusionProfile].a;
bsdfData.thickness = _ThicknessRemaps[diffusionProfile].x + _ThicknessRemaps[diffusionProfile].y * thickness;
// The difference between the thin and the regular (a.k.a. auto-thickness) modes is the following:
// * in the thin object mode, we assume that the geometry is thin enough for us to safely share
// the shadowing information between the front and the back faces;
// * the thin mode uses baked (textured) thickness for all transmission calculations;
// * the thin mode uses wrapped diffuse lighting for the NdotL;
// * the auto-thickness mode uses the baked (textured) thickness to compute transmission from
// indirect lighting and non-shadow-casting lights; for shadowed lights, it calculates
// the thickness using the distance to the closest occluder sampled from the shadow map.
// If the distance is large, it may indicate that the closest occluder is not the back face of
// the current object. That's not a problem, since large thickness will result in low intensity.
bool useThinObjectMode = IsBitSet(asuint(_TransmissionFlags), diffusionProfile);
bsdfData.materialFeatures |= useThinObjectMode ? MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS : MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_MIXED_THICKNESS;
// Compute transmittance using baked thickness here. It may be overridden for direct lighting
// in the auto-thickness mode (but is always be used for indirect lighting).
#if SHADEROPTIONS_USE_DISNEY_SSS
bsdfData.transmittance = ComputeTransmittanceDisney(_ShapeParams[diffusionProfile].rgb,
_TransmissionTintsAndFresnel0[diffusionProfile].rgb,
bsdfData.thickness);
#else
bsdfData.transmittance = ComputeTransmittanceJimenez(_HalfRcpVariancesAndWeights[diffusionProfile][0].rgb,
_HalfRcpVariancesAndWeights[diffusionProfile][0].a,
_HalfRcpVariancesAndWeights[diffusionProfile][1].rgb,
_HalfRcpVariancesAndWeights[diffusionProfile][1].a,
_TransmissionTintsAndFresnel0[diffusionProfile].rgb,
bsdfData.thickness);
#endif
}
// Assume bsdfData.normalWS is init
void FillMaterialAnisotropy(float anisotropy, float3 tangentWS, float3 bitangentWS, inout BSDFData bsdfData)
{

#endif
// There is no metallic with SSS and specular color mode
float metallic = HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION) ? 0.0 : surfaceData.metallic;
float metallic = HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION) ? 0.0 : surfaceData.metallic;
bsdfData.fresnel0 = HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR) ? surfaceData.specularColor : ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, DEFAULT_SPECULAR_VALUE);
bsdfData.fresnel0 = HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR) ? surfaceData.specularColor : ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, DEFAULT_SPECULAR_VALUE);
// Note: we have ZERO_INITIALIZE the struct so bsdfData.anisotropy == 0.0
// Note: DIFFUSION_PROFILE_NEUTRAL_ID is 0

// The UI is in charge of setuping the constrain, not the code. So if users is forward only and want unleash power, it is easy to unleash by some UI change
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Modify perceptualRoughness
FillMaterialClearCoatData(surfaceData.coatMask, bsdfData);

// RT2 - 8:8:8:8
uint materialFeatureId;
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Reminder that during GBuffer pass we know statically material materialFeatures
if ((surfaceData.materialFeatures & (MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION)) == (MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))

// It allows us to delay reading the G-Buffer 0 until the end of the deferred lighting shader.
outGBuffer2.rgb = float3(surfaceData.specularOcclusion, surfaceData.thickness, outGBuffer0.a);
}
else if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
else if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
materialFeatureId = GBUFFER_LIT_ANISOTROPIC;

sinOrCos,
PackFloatInt8bit(surfaceData.metallic, storeSin | quadrant, 8));
}
else if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
else if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
{
materialFeatureId = GBUFFER_LIT_IRIDESCENCE;

float3 diffuseColor = surfaceData.baseColor;
float3 fresnel0 = surfaceData.specularColor;
if (!HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR))
if (!HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR))
{
// Convert from the metallic parametrization.
diffuseColor = ComputeDiffuseColor(surfaceData.baseColor, surfaceData.metallic);

}
// Ensure that surfaceData.coatMask is 0 if the feature is not enabled
float coatMask = HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) ? surfaceData.coatMask : 0.0;
float coatMask = HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) ? surfaceData.coatMask : 0.0;
// Note: no need to store MATERIALFEATUREFLAGS_LIT_STANDARD, always present
outGBuffer2.a = PackFloatInt8bit(coatMask, materialFeatureId, 8);

bakeDiffuseLighting = inGBuffer3.rgb;
// Decompress feature-specific data from the G-Buffer.
bool pixelHasMetallic = HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE);
bool pixelHasMetallic = HasFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE);
if (pixelHasMetallic)
{

bsdfData.fresnel0 = FastSRGBToLinear(inGBuffer2.rgb); // Later possibly overwritten by SSS
}
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
SSSData sssData;

// in case one feature is enabled and not the other.
// The neutral value of subsurfaceMask is 0 (handled by ZERO_INITIALIZE).
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
FillMaterialTransmission(sssData.diffusionProfile, inGBuffer2.g, bsdfData);
}

// Special handling for anisotropy: When anisotropy is present in a tile, the whole tile will use anisotropy to avoid divergent evaluation of GGX that increase the cost
// 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 (HasFeatureFlag(tileFeatureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFlag(tileFeatureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
anisotropy = inGBuffer2.r * 2.0 - 1.0;

}
// The neutral value of iridescenceMask is 0 (handled by ZERO_INITIALIZE).
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFeatureFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFlag(pixelFeatureFlags, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Modify perceptualRoughness
FillMaterialClearCoatData(coatMask, bsdfData);

float energyCompensation;
// IBL
float3 iblR; // Dominant specular direction, used for IBL in EvaluateBSDF_Env()
float3 iblR; // Reflected specular direction, used for IBL in EvaluateBSDF_Env()
float3 specularFGD; // Store preconvoled BRDF for both specular and diffuse
float3 specularFGD; // Store preintegrated BSDF for both specular and diffuse
float diffuseFGD;
// Area lights (17 VGPRs)

float3x3 ltcTransformSpecular; // Inverse transformation for GGX (4x VGPRs)
float ltcMagnitudeDiffuse;
float3 ltcMagnitudeFresnel;
// Clear coat
float coatPartLambdaV;

float ltcMagnitudeCoatFresnel;
#if HAS_REFRACTION
// Refraction

float NdotV = ClampNdotV(preLightData.NdotV);
// We modify the bsdfData.fresnel0 here for iridescence
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
topIor = lerp(1.0, CLEAR_COAT_IOR, bsdfData.coatMask);
// HACK: Use the reflected direction to specify the Fresnel coefficient for pre-convolved envmaps

}
// We modify the bsdfData.fresnel0 here for clearCoat
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Fresnel0 is deduced from interface between air and material (Assume to be 1.5 in Unity, or a metal).
// but here we go from clear coat (1.5) to material, we need to update fresnel0

preLightData.coatIblF = F_Schlick(CLEAR_COAT_F0, NdotV) * bsdfData.coatMask;
}
float3 iblN, iblR;
float3 iblN;
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);

// IBL
// Handle IBL + multiscattering
// Handle IBL + multiscattering. Note FGD texture is also use for area light
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
#ifdef USE_DIFFUSE_LAMBERT_BRDF
iblR = reflect(-V, iblN);
// Corretion of reflected direction for better handling of rough material
preLightData.iblR = iblR;
preLightData.iblR = reflect(-V, iblN);
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
// Ref: Practical multiple scattering compensation for microfacet models.

float2 uv = LTC_LUT_OFFSET + LTC_LUT_SCALE * float2(bsdfData.perceptualRoughness, theta * INV_HALF_PI);
// Note we load the matrix transpose (avoid to have to transpose it in shader)
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
#ifdef USE_DIFFUSE_LAMBERT_BRDF
preLightData.ltcTransformDiffuse = k_identity3x3;
#else
// Get the inverse LTC matrix for Disney Diffuse

preLightData.orthoBasisViewNormal[2] = N;
preLightData.orthoBasisViewNormal[1] = cross(preLightData.orthoBasisViewNormal[2], preLightData.orthoBasisViewNormal[0]);
float3 ltcMagnitude = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX, 0).rgb;
float ltcGGXFresnelMagnitudeDiff = ltcMagnitude.r; // The difference of magnitudes of GGX and Fresnel
float ltcGGXFresnelMagnitude = ltcMagnitude.g;
float ltcDisneyDiffuseMagnitude = ltcMagnitude.b;
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
preLightData.ltcMagnitudeDiffuse = 1;
#else
preLightData.ltcMagnitudeDiffuse = ltcDisneyDiffuseMagnitude;
#endif
// TODO: the fit seems rather poor. The scaling factor of 0.5 allows us
// to match the reference for rough metals, but further darkens dielectrics.
preLightData.ltcMagnitudeFresnel = bsdfData.fresnel0 * ltcGGXFresnelMagnitudeDiff + (float3)ltcGGXFresnelMagnitude;
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
preLightData.ltcTransformCoat = 0.0;
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
preLightData.ltcTransformCoat = 0.0;
ltcMagnitude = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX, 0).rgb;
ltcGGXFresnelMagnitudeDiff = ltcMagnitude.r; // The difference of magnitudes of GGX and Fresnel
ltcGGXFresnelMagnitude = ltcMagnitude.g;
preLightData.ltcMagnitudeCoatFresnel = (CLEAR_COAT_F0 * ltcGGXFresnelMagnitudeDiff + ltcGGXFresnelMagnitude) * bsdfData.coatMask;
}
else
{
preLightData.ltcTransformCoat = 0.0;
preLightData.ltcMagnitudeCoatFresnel = 0.0;
}
// refraction (forward only)

// 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 GetBakedDiffuseLighting(SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData, PreLightData preLightData)
{
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
{
uint texturingMode = (bsdfData.materialFeatures >> MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET) & 3;
bsdfData.diffuseColor = ApplySubsurfaceScatteringTexturingMode(texturingMode, bsdfData.diffuseColor);
}
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER)
{

#endif
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING)) // This test is static as it is done in GBuffer or forward pass, will be remove by compiler
{
bsdfData.diffuseColor = GetModifiedDiffuseColorForSSS(bsdfData); // local modification of bsdfData
}
// Premultiply bake diffuse lighting information with DisneyDiffuse pre-integration
return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor;
}

}
//-----------------------------------------------------------------------------
// Subsurface Scattering functions
//-----------------------------------------------------------------------------
bool ShouldOutputSplitLighting(BSDFData bsdfData)
{
return HasFeatureFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_SSS_OUTPUT_SPLIT_LIGHTING);
}
//-----------------------------------------------------------------------------
// LightLoop related function (Only include if required)
// HAS_LIGHTLOOP is define in Lighting.hlsl
//-----------------------------------------------------------------------------

#ifndef _SURFACE_TYPE_TRANSPARENT
// For /Lighting/LightEvaluation.hlsl:
#define USE_DEFERRED_DIRECTIONAL_SHADOWS // Deferred shadows are always enabled for opaque objects
#endif

// Instead we use the incorrect angle NdotV as an approximation for LdotH for Fresnel evaluation.
// The Fresnel with iridescence and NDotV angle is precomputed ahead and here we jsut reuse the result.
// Thus why we shouldn't apply a second time Fresnel on the value if iridescence is enabled.
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float3 H = (L + V) * invLenLV;

}
specularLighting = F * DV;
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
#ifdef USE_DIFFUSE_LAMBERT_BRDF
float diffuseTerm = Lambert();
#else
// A note on subsurface scattering: [SSS-NOTE-TRSM]

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

}
}
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
// Transmitted lighting is computed as follows:
// - we assume that the object is a thick plane (slab);
// - we reverse the front-facing normal for the back of the object;
// - we assume that the incoming radiance is constant along the entire back surface;
// - we apply BSDF-specific diffuse transmission to transmit the light subsurface and back;
// - we integrate the diffuse reflectance profile w.r.t. the radius (while also accounting
// for the thickness) to compute the transmittance;
// - we multiply the transmitted radiance by the transmittance.
float3 EvaluateTransmission(BSDFData bsdfData, float3 transmittance, float NdotL, float NdotV, float LdotV, float attenuation)
{
// Apply wrapped lighting to better handle thin objects at grazing angles.
float wrappedNdotL = ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// Apply BSDF-specific diffuse transmission to attenuation. See also: [SSS-NOTE-TRSM]
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
attenuation *= Lambert();
#else
attenuation *= DisneyDiffuse(NdotV, max(0, -NdotL), LdotV, bsdfData.perceptualRoughness);
#endif
float intensity = attenuation * wrappedNdotL;
return intensity * transmittance;
}
//-----------------------------------------------------------------------------
// EvaluateBSDF_Directional
//-----------------------------------------------------------------------------

DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 N = bsdfData.normalWS;
float3 L = -lightData.forward; // Lights point backward in Unity
float NdotV = ClampNdotV(preLightData.NdotV);
float NdotL = dot(N, L);
float LdotV = dot(L, V);
float3 color;
float attenuation;
float3 L = -lightData.forward;
float3 N = bsdfData.normalWS;
float NdotL = dot(N, L);
// When using thin transmission mode we don't fetch shadow map for back face, we reuse front face shadow
// However we flip the normal for the bias (and the NdotL test) and disable contact shadow
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS) && NdotL < 0)
float3 transmittance = float3(0.0, 0.0, 0.0);
if (HasFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS))
// Disable shadow contact in case of transmission and backface shadow
N = -N;
lightData.contactShadowIndex = -1; // This is only modify for the scope of this function
// Caution: This function modify N and contactShadowIndex
transmittance = PreEvaluateDirectionalLightTransmission(NdotL, lightData, bsdfData, N, lightData.contactShadowIndex); // contactShadowIndex is only modify for the code of this function
float3 color;
float attenuation;
EvaluateLight_Directional(lightLoopContext, posInput, lightData, bakeLightingData, N, L, color, attenuation);
float intensity = max(0, attenuation * NdotL); // Warning: attenuation can be greater than 1 due to the inverse square attenuation (when position is close to light)

}
// The mixed thickness mode is not supported by directional lights due to poor quality and high performance impact.
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS))
if (HasFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS))
float NdotV = ClampNdotV(preLightData.NdotV);
float LdotV = dot(L, V);
lighting.diffuse += EvaluateTransmission(bsdfData, bsdfData.transmittance, NdotL, NdotV, LdotV, attenuation * lightData.diffuseScale);
lighting.diffuse += EvaluateTransmission(bsdfData, transmittance, NdotL, NdotV, LdotV, attenuation * lightData.diffuseScale);
}
// Save ALU by applying light and cookie colors only once.

DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 lightToSample = posInput.positionWS - lightData.positionWS;
int lightType = lightData.lightType;
float3 lightToSample;
distances.w = dot(lightToSample, lightData.forward);
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);
}
GetPunctualLightVectors(posInput.positionWS, lightData, L, lightToSample, distances);
float NdotV = ClampNdotV(preLightData.NdotV);
float LdotV = dot(L, V);
float3 color;
float attenuation;
// When using thin transmission mode we don't fetch shadow map for back face, we reuse front face shadow
// However we flip the normal for the bias (and the NdotL test) and disable contact shadow
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS) && NdotL < 0)
float3 transmittance = float3(0.0, 0.0, 0.0);
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
// Disable shadow contact in case of transmission and backface shadow
N = -N;
lightData.contactShadowIndex = -1; // This is only modify for the scope of this function
// Caution: This function modify N and lightData.contactShadowIndex
transmittance = PreEvaluatePunctualLightTransmission(lightLoopContext, posInput, distances.x, NdotL, L, bsdfData, N, lightData);
float3 color;
float attenuation;
EvaluateLight_Punctual(lightLoopContext, posInput, lightData, bakeLightingData, N, L,
lightToSample, distances, color, attenuation);

lighting.specular *= intensity * lightData.specularScale;
}
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
float3 transmittance = bsdfData.transmittance;
// Note that if NdotL is positive, we have one fetch on front face done by EvaluateLight_Punctual, otherwise we have only one fetch
// done by transmission code here (EvaluateLight_Punctual discard the fetch if NdotL < 0)
bool mixedThicknessMode = HasFeatureFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_MIXED_THICKNESS)
&& NdotL < 0 && lightData.shadowIndex >= 0;
if (mixedThicknessMode)
{
// Recompute transmittance using the thickness value computed from the shadow map.
// Compute the distance from the light to the back face of the object along the light direction.
float distBackFaceToLight = GetPunctualShadowClosestDistance(lightLoopContext.shadowContext, s_linear_clamp_sampler,
posInput.positionWS, lightData.shadowIndex, L, lightData.positionWS);
// Our subsurface scattering models use the semi-infinite planar slab assumption.
// Therefore, we need to find the thickness along the normal.
float distFrontFaceToLight = distances.x;
float thicknessInUnits = (distFrontFaceToLight - distBackFaceToLight) * -NdotL;
float thicknessInMeters = thicknessInUnits * _WorldScales[bsdfData.diffusionProfile].x;
float thicknessInMillimeters = thicknessInMeters * MILLIMETERS_PER_METER;
#if SHADEROPTIONS_USE_DISNEY_SSS
// We need to make sure it's not less than the baked thickness to minimize light leaking.
float thicknessDelta = max(0, thicknessInMillimeters - bsdfData.thickness);
float3 S = _ShapeParams[bsdfData.diffusionProfile].rgb;
// Approximate the decrease of transmittance by e^(-1/3 * dt * S).
#if 0
float3 expOneThird = exp(((-1.0 / 3.0) * thicknessDelta) * S);
#else
// Help the compiler.
float k = (-1.0 / 3.0) * LOG2_E;
float3 p = (k * thicknessDelta) * S;
float3 expOneThird = exp2(p);
#endif
transmittance *= expOneThird;
#else // SHADEROPTIONS_USE_DISNEY_SSS
// We need to make sure it's not less than the baked thickness to minimize light leaking.
thicknessInMillimeters = max(thicknessInMillimeters, bsdfData.thickness);
transmittance = ComputeTransmittanceJimenez(_HalfRcpVariancesAndWeights[bsdfData.diffusionProfile][0].rgb,
_HalfRcpVariancesAndWeights[bsdfData.diffusionProfile][0].a,
_HalfRcpVariancesAndWeights[bsdfData.diffusionProfile][1].rgb,
_HalfRcpVariancesAndWeights[bsdfData.diffusionProfile][1].a,
_TransmissionTintsAndFresnel0[bsdfData.diffusionProfile].rgb,
thicknessInMillimeters);
#endif // SHADEROPTIONS_USE_DISNEY_SSS
}
// Note: we do not modify the distance to the light, or the light angle for the back face.
// This is a performance-saving optimization which makes sense as long as the thickness is small.
float NdotV = ClampNdotV(preLightData.NdotV);
float LdotV = dot(L, V);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, transmittance, NdotL, NdotV, LdotV, attenuation * lightData.diffuseScale);
}

// We define the ellipsoid s.t. r1 = (r + len / 2), r2 = r3 = r.
// TODO: This could be precomputed.
float radius = rsqrt(lightData.invSqrAttenuationRadius);
float radius = rsqrt(lightData.rangeAttenuationScale); // // rangeAttenuationScale is inverse Square Radius
float intensity = EllipsoidalDistanceAttenuation(unL, lightData.invSqrAttenuationRadius,
float intensity = EllipsoidalDistanceAttenuation(unL, lightData.rangeAttenuationScale, lightData.rangeAttenuationBias,
axis, invAspectRatio);
// Terminate if the shaded point is too far away.

ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse);
ltcValue *= lightData.diffuseScale;
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
UNITY_BRANCH if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
// See comment for specular magnitude, it apply to diffuse as well
lighting.diffuse = preLightData.diffuseFGD * ltcValue;
UNITY_BRANCH if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,

// Evaluate the specular part
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular);
ltcValue *= lightData.specularScale;
lighting.specular = preLightData.ltcMagnitudeFresnel * ltcValue;
// We need to multiply by the magnitude of the integral of the BRDF
// ref: http://advances.realtimerendering.com/s2016/s2016_ltc_fresnel.pdf
// This value is what we store in specularFGD, so reuse it
lighting.specular = preLightData.specularFGD * ltcValue;
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
lighting.diffuse *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);
lighting.specular *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);
lighting.specular += preLightData.ltcMagnitudeCoatFresnel * ltcValue;
// For clear coat we don't fetch specularFGD we can use directly the perfect fresnel coatIblF
lighting.diffuse *= (1.0 - preLightData.coatIblF);
lighting.specular *= (1.0 - preLightData.coatIblF);
lighting.specular += preLightData.coatIblF * ltcValue;
}
// Save ALU by applying 'lightData.color' only once.

}
//-----------------------------------------------------------------------------
// EvaluateBSDF_Area - Approximation with Linearly Transformed Cosines
// EvaluateBSDF_Rect - Approximation with Linearly Transformed Cosines
//-----------------------------------------------------------------------------
// #define ELLIPSOIDAL_ATTENUATION

// Define the dimensions of the attenuation volume.
// TODO: This could be precomputed.
float radius = rsqrt(lightData.invSqrAttenuationRadius);
float radius = rsqrt(lightData.rangeAttenuationScale); // rangeAttenuationScale is inverse Square Radius
float3 invHalfDim = rcp(float3(radius + halfWidth,
radius + halfHeight,
radius));

ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformDiffuse));
ltcValue *= lightData.diffuseScale;
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
// See comment for specular magnitude, it apply to diffuse as well
lighting.diffuse = preLightData.diffuseFGD * ltcValue;
UNITY_BRANCH if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
UNITY_BRANCH if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,

// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformSpecular));
ltcValue *= lightData.specularScale;
lighting.specular += preLightData.ltcMagnitudeFresnel * ltcValue;
// We need to multiply by the magnitude of the integral of the BRDF
// ref: http://advances.realtimerendering.com/s2016/s2016_ltc_fresnel.pdf
// This value is what we store in specularFGD, so reuse it
lighting.specular += preLightData.specularFGD * ltcValue;
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
lighting.diffuse *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);
lighting.specular *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);
lighting.specular += preLightData.ltcMagnitudeCoatFresnel * ltcValue;
// For clear coat we don't fetch specularFGD we can use directly the perfect fresnel coatIblF
lighting.diffuse *= (1.0 - preLightData.coatIblF);
lighting.specular *= (1.0 - preLightData.coatIblF);
lighting.specular += preLightData.coatIblF * ltcValue;
}
// Save ALU by applying 'lightData.color' only once.

// TODO: handle clear coat
// #ifdef LIT_DIFFUSE_LAMBERT_BRDF
// #ifdef USE_DIFFUSE_LAMBERT_BRDF
// envLighting += IntegrateLambertIBLRef(lightData, V, bsdfData);
// #else
// envLighting += IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);

// Don't do clear coating for refraction
float3 coatR = preLightData.coatIblR;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
float unusedWeight = 0.0;
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, coatR, unusedWeight);

envLighting = F * preLD.rgb;
// Evaluate the Clear Coat component if needed
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFlag(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

#else
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, 1.0, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
#endif
// Subsurface scattering mdoe
uint texturingMode = (bsdfData.materialFeatures >> MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET) & 3;
float3 modifiedDiffuseColor = ApplySubsurfaceScatteringTexturingMode(texturingMode, bsdfData.diffuseColor);
// Subsurface scattering mode
float3 modifiedDiffuseColor = GetModifiedDiffuseColorForSSS(bsdfData);
// Apply the albedo to the direct diffuse lighting (only once). The indirect (baked)
// diffuse lighting has already had the albedo applied in GetBakedDiffuseLighting().

2
com.unity.render-pipelines.high-definition/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(input.positionSS.xy, surfaceData);
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (HasFlag(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.

4
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/LitReference.hlsl


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

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

3
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs


public float iridescenceIor;
[SurfaceDataAttributes("IridescenceThickness")]
public float iridescenceThickness;
[SurfaceDataAttributes("Iridescence Mask")]
public float iridescenceMask;
// Top interface and media (clearcoat)
[SurfaceDataAttributes("Coat Smoothness")]

// iridescence
public float iridescenceIor;
public float iridescenceThickness;
public float iridescenceMask;
// SSS
public uint diffusionProfile;

34
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs.hlsl


#define DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY (1115)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_IOR (1116)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS (1117)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_SMOOTHNESS (1118)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR (1119)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS (1120)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT (1121)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_DIFFUSION_PROFILE (1122)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SUBSURFACE_MASK (1123)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_THICKNESS (1124)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_MASK (1118)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_SMOOTHNESS (1119)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR (1120)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS (1121)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT (1122)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_DIFFUSION_PROFILE (1123)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SUBSURFACE_MASK (1124)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_THICKNESS (1125)
//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+BSDFData: static fields

#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_EXTINCTION (1174)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_IOR (1175)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_THICKNESS (1176)
#define DEBUGVIEW_STACKLIT_BSDFDATA_DIFFUSION_PROFILE (1177)
#define DEBUGVIEW_STACKLIT_BSDFDATA_SUBSURFACE_MASK (1178)
#define DEBUGVIEW_STACKLIT_BSDFDATA_THICKNESS (1179)
#define DEBUGVIEW_STACKLIT_BSDFDATA_USE_THICK_OBJECT_MODE (1180)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TRANSMITTANCE (1181)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_MASK (1177)
#define DEBUGVIEW_STACKLIT_BSDFDATA_DIFFUSION_PROFILE (1178)
#define DEBUGVIEW_STACKLIT_BSDFDATA_SUBSURFACE_MASK (1179)
#define DEBUGVIEW_STACKLIT_BSDFDATA_THICKNESS (1180)
#define DEBUGVIEW_STACKLIT_BSDFDATA_USE_THICK_OBJECT_MODE (1181)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TRANSMITTANCE (1182)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.StackLit+SurfaceData
// PackingRules = Exact

float anisotropy;
float iridescenceIor;
float iridescenceThickness;
float iridescenceMask;
float coatPerceptualSmoothness;
float coatIor;
float coatThickness;

float3 coatExtinction;
float iridescenceIor;
float iridescenceThickness;
float iridescenceMask;
uint diffusionProfile;
float subsurfaceMask;
float thickness;

break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS:
result = surfacedata.iridescenceThickness.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_MASK:
result = surfacedata.iridescenceMask.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_SMOOTHNESS:
result = surfacedata.coatPerceptualSmoothness.xxx;

break;
case DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_THICKNESS:
result = bsdfdata.iridescenceThickness.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_MASK:
result = bsdfdata.iridescenceMask.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_DIFFUSION_PROFILE:
result = GetIndexColor(bsdfdata.diffusionProfile);

755
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
文件差异内容过多而无法显示
查看文件

33
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.shader


[HideInInspector] _ThicknessRange("Thickness Range", Vector) = (0, 1, 0, 0)
[ToggleUI] _EnableIridescence("Enable Iridescence", Float) = 0.0 // UI only
_IridescenceIor("Coat IOR", Range(1.0, 2.0)) = 1.5
_IridescenceThickness("_IridescenceThickness", Range(0.0, 1.0)) = 0.0
_IridescenceThicknessMap("IridescenceThickness Color Map", 2D) = "black" {}
_IridescenceIor("TopIOR over iridescent layer", Range(1.0, 2.0)) = 1.5
[HideInInspector] _IridescenceThicknessMapShow("IridescenceThickness Map Show", Float) = 0
_IridescenceThickness("IridescenceThickness", Range(0.0, 1.0)) = 0.0
_IridescenceThicknessMap("IridescenceThickness Map", 2D) = "black" {}
_IridescenceThicknessMapChannel("IridescenceThickness Mask Map Channel", Float) = 0.0
_IridescenceThicknessMapChannelMask("IridescenceThickness Mask Map Channel Mask", Vector) = (1, 0, 0, 0)
_IridescenceThicknessMapChannel("IridescenceThickness Map Channel", Float) = 0.0
_IridescenceThicknessMapChannelMask("IridescenceThickness Map Channel Mask", Vector) = (1, 0, 0, 0)
_IridescenceThicknessRemap("IridescenceThickness Remap", Vector) = (0, 1, 0, 0)
[ToggleUI] _IridescenceThicknessRemapInverted("Invert IridescenceThickness Remap", Float) = 0.0
[HideInInspector] _IridescenceMaskMapShow("Iridescence Mask Map Show", Float) = 0
_IridescenceMask("Iridescence Mask", Range(0.0, 1.0)) = 1.0
_IridescenceMaskMap("Iridescence Mask Map", 2D) = "black" {}
_IridescenceMaskUseMap("Iridescence Mask Use Map", Float) = 0
_IridescenceMaskMapUV("Iridescence Mask Map UV", Float) = 0.0
_IridescenceMaskMapUVLocal("Iridescence Mask UV Local", Float) = 0.0
_IridescenceMaskMapChannel("Iridescence Mask Map Channel", Float) = 0.0
_IridescenceMaskMapChannelMask("Iridescence Mask Map Channel Mask", Vector) = (1, 0, 0, 0)
_IridescenceMaskRemap("Iridescence Mask Remap", Vector) = (0, 1, 0, 0)
[HideInInspector] _IridescenceMaskRange("Iridescence Mask Range", Vector) = (0, 1, 0, 0)
_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
[ToggleUI] _DistortionEnable("Enable Distortion", Float) = 0.0

#pragma multi_compile _ DEBUG_DISPLAY
//NEWLITTODO
//#pragma multi_compile _ LIGHTMAP_ON
//#pragma multi_compile _ DIRLIGHTMAP_COMBINED
//#pragma multi_compile _ DYNAMICLIGHTMAP_ON
//#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ DYNAMICLIGHTMAP_ON
#pragma multi_compile _ SHADOWS_SHADOWMASK
// #include "../../Lighting/Forward.hlsl" : nothing left in there.
//#pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS

9
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitData.hlsl


surfaceData.iridescenceThickness = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_IridescenceThicknessMap), _IridescenceThicknessMapChannelMask);
surfaceData.iridescenceThickness = lerp(_IridescenceThicknessRange.x, _IridescenceThicknessRange.y, surfaceData.iridescenceThickness);
surfaceData.iridescenceThickness = lerp(_IridescenceThickness, surfaceData.iridescenceThickness, _IridescenceThicknessUseMap);
surfaceData.iridescenceMask = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_IridescenceMaskMap), _IridescenceMaskMapChannelMask);
surfaceData.iridescenceMask = lerp(_IridescenceMaskRange.x, _IridescenceMaskRange.y, surfaceData.iridescenceMask);
surfaceData.iridescenceMask = lerp(_IridescenceMask, surfaceData.iridescenceMask, _IridescenceMaskUseMap);
surfaceData.iridescenceMask = 0.0;
#endif
#if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) || defined(_MATERIAL_FEATURE_TRANSMISSION)

surfaceData.normalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], gradient.xyz);
surfaceData.coatNormalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], coatGradient.xyz);
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
if ((_GeometricNormalFilteringEnabled + _TextureNormalFilteringEnabled) > 0.0)
{
float geometricVariance = _GeometricNormalFilteringEnabled ? GeometricNormalVariance(input.worldToTangent[2], _SpecularAntiAliasingScreenSpaceVariance) : 0.0;

// 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(input.positionSS.xy, surfaceData);
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_TRANSMISSION))
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_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.

13
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitProperties.hlsl


TEXTURE2D(_IridescenceThicknessMap);
SAMPLER(sampler_IridescenceThicknessMap);
TEXTURE2D(_IridescenceMaskMap);
SAMPLER(sampler_IridescenceMaskMap);
TEXTURE2D(_SubsurfaceMaskMap);
SAMPLER(sampler_SubsurfaceMaskMap);

float4 _IridescenceThicknessMapChannelMask;
float4 _IridescenceThicknessRange;
float _IridescenceIor;
float _IridescenceMask;
float _IridescenceMaskUseMap;
float _IridescenceMaskMapUV;
float _IridescenceMaskMapUVLocal;
float4 _IridescenceMaskMap_ST;
float4 _IridescenceMaskMap_TexelSize;
float4 _IridescenceMaskMap_MipInfo;
float4 _IridescenceMaskMapChannelMask;
float4 _IridescenceMaskRange;
int _DiffusionProfile;
float _SubsurfaceMask;

109
com.unity.render-pipelines.high-definition/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl


#include "../DiffusionProfile/DiffusionProfileSettings.cs.hlsl"
#include "../DiffusionProfile/DiffusionProfile.hlsl"
// Subsurface scattering constant
#define SSS_WRAP_ANGLE (PI/12) // 15 degrees
#define SSS_WRAP_LIGHT cos(PI/2 - SSS_WRAP_ANGLE)
// constant buffer declaration
CBUFFER_START(UnitySSSAndTransmissionParameters)
// Warning: Unity is not able to losslessly transfer integers larger than 2^24 to the shader system.

{
return subsurfaceLighting.b > 0;
}
// ----------------------------------------------------------------------------
// Helper functions to use SSS/Transmission with a material
// ----------------------------------------------------------------------------
// Following function allow to easily setup SSS and transmission inside a material.
// User can request either SSS functions, or Transmission functions, or both, by defining MATERIAL_INCLUDE_SUBSURFACESCATTERING and/or MATERIAL_INCLUDE_TRANSMISSION
// before including this file.
// + It require that the material follow naming convention for properties inside BSDFData
// struct BSDFData
// {
// (...)
// // Share for SSS and Transmission
// uint materialFeatures;
// uint diffusionProfile;
// // For SSS
// float3 diffuseColor;
// float3 fresnel0;
// float subsurfaceMask;
// // For transmission
// float thickness;
// bool useThickObjectMode;
// float3 transmittance;
// perceptualRoughness; // Only if user chose to support DisneyDiffuse
// (...)
// }
// Note: Transmission functions for light evaluation are included in LightEvaluation.hlsl file also based on the MATERIAL_INCLUDE_TRANSMISSION
// For LightEvaluation.hlsl file it is required to define a BRDF for the transmission. Defining USE_DIFFUSE_LAMBERT_BRDF use Lambert, otherwise it use Disneydiffuse
#define MATERIAL_FEATURE_SSS_TRANSMISSION_START (1 << 16) // It should be safe to start these flags
#define MATERIAL_FEATURE_FLAGS_SSS_OUTPUT_SPLIT_LIGHTING ((MATERIAL_FEATURE_SSS_TRANSMISSION_START) << 0)
#define MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET FastLog2((MATERIAL_FEATURE_SSS_TRANSMISSION_START) << 1) // Note: The texture mode is 2bit, thus go from '<< 1' to '<< 3'
#define MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_MIXED_THICKNESS ((MATERIAL_FEATURE_SSS_TRANSMISSION_START) << 3)
// Flags used as a shortcut to know if we have thin mode transmission
#define MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS ((MATERIAL_FEATURE_SSS_TRANSMISSION_START) << 4)
#ifdef MATERIAL_INCLUDE_SUBSURFACESCATTERING
void FillMaterialSSS(uint diffusionProfile, float subsurfaceMask, inout BSDFData bsdfData)
{
bsdfData.diffusionProfile = diffusionProfile;
bsdfData.fresnel0 = _TransmissionTintsAndFresnel0[diffusionProfile].a;
bsdfData.subsurfaceMask = subsurfaceMask;
bsdfData.materialFeatures |= MATERIAL_FEATURE_FLAGS_SSS_OUTPUT_SPLIT_LIGHTING;
bsdfData.materialFeatures |= GetSubsurfaceScatteringTexturingMode(diffusionProfile) << MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET;
}
bool ShouldOutputSplitLighting(BSDFData bsdfData)
{
return HasFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_SSS_OUTPUT_SPLIT_LIGHTING);
}
float3 GetModifiedDiffuseColorForSSS(BSDFData bsdfData)
{
// Subsurface scattering mode
uint texturingMode = (bsdfData.materialFeatures >> MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET) & 3;
return ApplySubsurfaceScatteringTexturingMode(texturingMode, bsdfData.diffuseColor);
}
#endif
#ifdef MATERIAL_INCLUDE_TRANSMISSION
// Assume that bsdfData.diffusionProfile is init
void FillMaterialTransmission(uint diffusionProfile, float thickness, inout BSDFData bsdfData)
{
bsdfData.diffusionProfile = diffusionProfile;
bsdfData.fresnel0 = _TransmissionTintsAndFresnel0[diffusionProfile].a;
bsdfData.thickness = _ThicknessRemaps[diffusionProfile].x + _ThicknessRemaps[diffusionProfile].y * thickness;
// The difference between the thin and the regular (a.k.a. auto-thickness) modes is the following:
// * in the thin object mode, we assume that the geometry is thin enough for us to safely share
// the shadowing information between the front and the back faces;
// * the thin mode uses baked (textured) thickness for all transmission calculations;
// * the thin mode uses wrapped diffuse lighting for the NdotL;
// * the auto-thickness mode uses the baked (textured) thickness to compute transmission from
// indirect lighting and non-shadow-casting lights; for shadowed lights, it calculates
// the thickness using the distance to the closest occluder sampled from the shadow map.
// If the distance is large, it may indicate that the closest occluder is not the back face of
// the current object. That's not a problem, since large thickness will result in low intensity.
bool useThinObjectMode = IsBitSet(asuint(_TransmissionFlags), diffusionProfile);
bsdfData.materialFeatures |= useThinObjectMode ? MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS : MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_MIXED_THICKNESS;
// Compute transmittance using baked thickness here. It may be overridden for direct lighting
// in the auto-thickness mode (but is always used for indirect lighting).
#if SHADEROPTIONS_USE_DISNEY_SSS
bsdfData.transmittance = ComputeTransmittanceDisney(_ShapeParams[diffusionProfile].rgb,
_TransmissionTintsAndFresnel0[diffusionProfile].rgb,
bsdfData.thickness);
#else
bsdfData.transmittance = ComputeTransmittanceJimenez( _HalfRcpVariancesAndWeights[diffusionProfile][0].rgb,
_HalfRcpVariancesAndWeights[diffusionProfile][0].a,
_HalfRcpVariancesAndWeights[diffusionProfile][1].rgb,
_HalfRcpVariancesAndWeights[diffusionProfile][1].a,
_TransmissionTintsAndFresnel0[diffusionProfile].rgb,
bsdfData.thickness);
#endif
}
#endif

1
com.unity.render-pipelines.lightweight/CHANGELOG.md


- GLES2 shader compiler error in IntegrationTests
- Can't set RenderScale and ShadowDistance by script
- VR Single Pass Instancing shadows
- Fixed compilation errors on Nintendo Switch (limited XRSetting support).
## [2.0.0-preview]

174
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Shadow/PCSS.hlsl


#include "CoreRP/ShaderLibrary/Common.hlsl"
static const float2 poissonDisk64[64] =
{
float2 ( 0.1187053, 0.7951565),
float2 ( 0.1173675, 0.6087878),
float2 (-0.09958518, 0.7248842),
float2 ( 0.4259812, 0.6152718),
float2 ( 0.3723574, 0.8892787),
float2 (-0.02289676, 0.9972908),
float2 (-0.08234791, 0.5048386),
float2 ( 0.1821235, 0.9673787),
float2 (-0.2137264, 0.9011746),
float2 ( 0.3115066, 0.4205415),
float2 ( 0.1216329, 0.383266),
float2 ( 0.5948939, 0.7594361),
float2 ( 0.7576465, 0.5336417),
float2 (-0.521125, 0.7599803),
float2 (-0.2923127, 0.6545699),
float2 ( 0.6782473, 0.22385),
float2 (-0.3077152, 0.4697627),
float2 ( 0.4484913, 0.2619455),
float2 (-0.5308799, 0.4998215),
float2 (-0.7379634, 0.5304936),
float2 ( 0.02613133, 0.1764302),
float2 (-0.1461073, 0.3047384),
float2 (-0.8451027, 0.3249073),
float2 (-0.4507707, 0.2101997),
float2 (-0.6137282, 0.3283674),
float2 (-0.2385868, 0.08716244),
float2 ( 0.3386548, 0.01528411),
float2 (-0.04230833, -0.1494652),
float2 ( 0.167115, -0.1098648),
float2 (-0.525606, 0.01572019),
float2 (-0.7966855, 0.1318727),
float2 ( 0.5704287, 0.4778273),
float2 (-0.9516637, 0.002725032),
float2 (-0.7068223, -0.1572321),
float2 ( 0.2173306, -0.3494083),
float2 ( 0.06100426, -0.4492816),
float2 ( 0.2333982, 0.2247189),
float2 ( 0.07270987, -0.6396734),
float2 ( 0.4670808, -0.2324669),
float2 ( 0.3729528, -0.512625),
float2 ( 0.5675077, -0.4054544),
float2 (-0.3691984, -0.128435),
float2 ( 0.8752473, 0.2256988),
float2 (-0.2680127, -0.4684393),
float2 (-0.1177551, -0.7205751),
float2 (-0.1270121, -0.3105424),
float2 ( 0.5595394, -0.06309237),
float2 (-0.9299136, -0.1870008),
float2 ( 0.974674, 0.03677348),
float2 ( 0.7726735, -0.06944724),
float2 (-0.4995361, -0.3663749),
float2 ( 0.6474168, -0.2315787),
float2 ( 0.1911449, -0.8858921),
float2 ( 0.3671001, -0.7970535),
float2 (-0.6970353, -0.4449432),
float2 (-0.417599, -0.7189326),
float2 (-0.5584748, -0.6026504),
float2 (-0.02624448, -0.9141423),
float2 ( 0.565636, -0.6585149),
float2 (-0.874976, -0.3997879),
float2 ( 0.9177843, -0.2110524),
float2 ( 0.8156927, -0.3969557),
float2 (-0.2833054, -0.8395444),
float2 ( 0.799141, -0.5886372)
};
real PenumbraSize(real Reciever, real Blocker)
{
return abs((Reciever - Blocker) / Blocker);
}
bool BlockerSearch(inout real averageBlockerDepth, inout real numBlockers, real lightArea, real3 coord, real2 sampleJitter, real2 sampleBias, ShadowContext shadowContext, float slice, uint texIdx, uint sampIdx, int sampleCount)
{
real blockerSum = 0.0;
for (int i = 0; i < sampleCount; ++i)
{
real2 offset = real2(poissonDisk64[i].x * sampleJitter.y + poissonDisk64[i].y * sampleJitter.x,
poissonDisk64[i].x * -sampleJitter.x + poissonDisk64[i].y * sampleJitter.y) * lightArea;
real shadowMapDepth = SampleShadow_T2DA(shadowContext, texIdx, sampIdx, coord.xy + offset, slice).x;
if (COMPARE_DEVICE_DEPTH_CLOSER(shadowMapDepth, coord.z + dot(sampleBias, offset)))
{
blockerSum += shadowMapDepth;
numBlockers += 1.0;
}
}
averageBlockerDepth = blockerSum / numBlockers;
return numBlockers >= 1;
}
bool BlockerSearch(inout real averageBlockerDepth, inout real numBlockers, real lightArea, real3 coord, float slice, real2 sampleJitter, real2 sampleBias, Texture2DArray shadowMap, SamplerState PointSampler, int sampleCount)
{
real blockerSum = 0.0;
for (int i = 0; i < sampleCount; ++i)
{
real2 offset = real2(poissonDisk64[i].x * sampleJitter.y + poissonDisk64[i].y * sampleJitter.x,
poissonDisk64[i].x * -sampleJitter.x + poissonDisk64[i].y * sampleJitter.y) * lightArea;
real shadowMapDepth = SAMPLE_TEXTURE2D_ARRAY_LOD(shadowMap, PointSampler, coord.xy + offset, slice, 0.0).x;
if (COMPARE_DEVICE_DEPTH_CLOSER(shadowMapDepth, coord.z + dot(sampleBias, offset)))
{
blockerSum += shadowMapDepth;
numBlockers += 1.0;
}
}
averageBlockerDepth = blockerSum / numBlockers;
return numBlockers >= 1;
}
real PCSS(real3 coord, real filterRadius, real4 scaleOffset, float slice, real2 sampleBias, real2 sampleJitter, ShadowContext shadowContext, uint texIdx, uint sampIdx, int sampleCount)
{
real UMin = scaleOffset.z;
real UMax = scaleOffset.z + scaleOffset.x;
real VMin = scaleOffset.w;
real VMax = scaleOffset.w + scaleOffset.y;
real sum = 0.0;
for(int i = 0; i < sampleCount; ++i)
{
real2 offset = real2(poissonDisk64[i].x * sampleJitter.y + poissonDisk64[i].y * sampleJitter.x,
poissonDisk64[i].x * -sampleJitter.x + poissonDisk64[i].y * sampleJitter.y) * filterRadius;
real U = coord.x + offset.x;
real V = coord.y + offset.y;
//NOTE: We must clamp the sampling within the bounds of the shadow atlas.
// Overfiltering will leak results from other shadow lights.
//TODO: Investigate moving this to blocker search.
if (U <= UMin || U >= UMax || V <= VMin || V >= VMax)
sum += SampleCompShadow_T2DA(shadowContext, texIdx, sampIdx, real3(coord.xy, coord.z), slice).r;
else
sum += SampleCompShadow_T2DA(shadowContext, texIdx, sampIdx, real3(U, V, coord.z + dot(sampleBias, offset)), slice).r;
}
return sum / sampleCount;
}
real PCSS(real3 coord, real filterRadius, real4 scaleOffset, float slice, real2 sampleBias, real2 sampleJitter, Texture2DArray shadowMap, SamplerComparisonState compSampler, int sampleCount)
{
real UMin = scaleOffset.z;
real UMax = scaleOffset.z + scaleOffset.x;
real VMin = scaleOffset.w;
real VMax = scaleOffset.w + scaleOffset.y;
real sum = 0.0;
for(int i = 0; i < sampleCount; ++i)
{
real2 offset = real2(poissonDisk64[i].x * sampleJitter.y + poissonDisk64[i].y * sampleJitter.x,
poissonDisk64[i].x * -sampleJitter.x + poissonDisk64[i].y * sampleJitter.y) * filterRadius;
real U = coord.x + offset.x;
real V = coord.y + offset.y;
//NOTE: We must clamp the sampling within the bounds of the shadow atlas.
// Overfiltering will leak results from other shadow lights.
//TODO: Investigate moving this to blocker search.
if (U <= UMin || U >= UMax || V <= VMin || V >= VMax)
sum += SAMPLE_TEXTURE2D_ARRAY_SHADOW(shadowMap, compSampler, real3(coord.xy, coord.z), slice).r;
else
sum += SAMPLE_TEXTURE2D_ARRAY_SHADOW(shadowMap, compSampler, real3(U, V, coord.z + dot(sampleBias, offset)), slice).r;
}
return sum / sampleCount;
}

9
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/Shadow/PCSS.hlsl.meta


fileFormatVersion: 2
guid: 24c12fe97ac0c9240af12fb1ed0c9275
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存