浏览代码

StackLit: proper ambient occlusion, specular occlusion and bentnormals

-Make the AO and SO path clean since we're forward based (no more double occlusion and occlusion on emissive).
-Configurable per-lobe specular occlusion on environment lights and debug options. Also use GTAOMultiBounce tint in the context of vertical layering.
(Enabling SO is orthogonal to bentnormals presence, the choosen algo for the data-based occlusion will use the normal or bentnormal if present)
-Bentnormal map which piggy backs on all normal map parameters (add UI code to allow this too)
-Fix GGX energy compensation term application
-Reuse some Lit shader_feature keywords
/StackLit2
Stephane Laroche 6 年前
当前提交
6a34e975
共有 10 个文件被更改,包括 478 次插入113 次删除
  1. 27
      com.unity.render-pipelines.high-definition/HDRP/Editor/Material/StackLit/BaseMaterialUI.cs
  2. 29
      com.unity.render-pipelines.high-definition/HDRP/Editor/Material/StackLit/StackLitUI.cs
  3. 44
      com.unity.render-pipelines.high-definition/HDRP/Material/MaterialEvaluation.hlsl
  4. 25
      com.unity.render-pipelines.high-definition/HDRP/Material/SphericalCapPivot/SPTDistribution.hlsl
  5. 6
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs
  6. 94
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs.hlsl
  7. 302
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
  8. 29
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.shader
  9. 32
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitData.hlsl
  10. 3
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitProperties.hlsl

27
com.unity.render-pipelines.high-definition/HDRP/Editor/Material/StackLit/BaseMaterialUI.cs


public bool m_IsNormalMap;
public TextureProperty(BaseMaterialGUI parent, string propertyName, string constantPropertyName, string guiText, bool useConstantAsTint, bool isMandatory = true, bool isNormalMap = false, Func<object, bool> isVisible = null)
: this(parent, propertyName, constantPropertyName, guiText, string.Empty, useConstantAsTint, isMandatory, isNormalMap, isVisible)
public bool m_ShowScaleOffset;
public TextureOneLineProperty m_SlaveTexOneLineProp;
public TextureProperty(BaseMaterialGUI parent, string propertyName, string constantPropertyName, string guiText, bool pairConstantWithTexture, bool isMandatory = true, bool isNormalMap = false, bool showScaleOffset = true, TextureOneLineProperty slaveTexOneLineProp = null, Func<object, bool> isVisible = null)
: this(parent, propertyName, constantPropertyName, guiText, string.Empty, pairConstantWithTexture, isMandatory, isNormalMap, showScaleOffset, slaveTexOneLineProp, isVisible)
public TextureProperty(BaseMaterialGUI parent, string propertyName, string constantPropertyName, string guiText, string toolTip, bool useConstantAsTint, bool isMandatory = true, bool isNormalMap = false, Func<object, bool> isVisible = null)
public TextureProperty(BaseMaterialGUI parent, string propertyName, string constantPropertyName, string guiText, string toolTip, bool pairConstantWithTexture, bool isMandatory = true, bool isNormalMap = false, bool showScaleOffset = true, TextureOneLineProperty slaveTexOneLineProp = null, Func < object, bool> isVisible = null)
m_ShowScaleOffset = showScaleOffset;
m_SlaveTexOneLineProp = slaveTexOneLineProp;
if (useConstantAsTint == false)
if (pairConstantWithTexture == false)
m_TextureProperty = new TextureOneLineProperty(parent, propertyName, useConstantAsTint ? constantPropertyName : string.Empty, guiText, toolTip, isMandatory);
m_TextureProperty = new TextureOneLineProperty(parent, propertyName, pairConstantWithTexture ? constantPropertyName : string.Empty, guiText, toolTip, isMandatory);
m_ChannelProperty = new ComboProperty(parent, propertyName + "Channel", "Channel", Enum.GetNames(typeof(Channel)), false);

m_TextureProperty.OnGUI();
if (m_TextureProperty.TextureValue != null)
if (m_TextureProperty.TextureValue != null
|| ((m_SlaveTexOneLineProp != null) && (m_SlaveTexOneLineProp.TextureValue != null)) )
Parent.m_MaterialEditor.TextureScaleOffsetProperty(m_TextureProperty.m_MaterialProperty);
if (m_ShowScaleOffset)
{
Parent.m_MaterialEditor.TextureScaleOffsetProperty(m_TextureProperty.m_MaterialProperty);
}
if (m_UvSetProperty.FloatValue >= (float)UVMapping.PlanarXY)
if (m_UvSetProperty.IsValid && m_UvSetProperty.FloatValue >= (float)UVMapping.PlanarXY)
{
m_LocalOrWorldProperty.OnGUI();
}

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


protected const string k_NormalMapUV = "_NormalMapUV";
protected const string k_NormalScale = "_NormalScale";
protected const string k_BentNormalMap = "_BentNormalMap";
protected const string k_EnableSpecularOcclusion = "_EnableSpecularOcclusion";
protected const string k_AmbientOcclusion = "_AmbientOcclusion";
protected const string k_AmbientOcclusionMap = "_AmbientOcclusionMap";
protected const string k_AmbientOcclusionMapUV = "_AmbientOcclusionMapUV";

private readonly GroupProperty _materialProperties = null;
private Property EnableDetails;
private Property EnableSpecularOcclusion;
private Property EnableDualSpecularLobe;
private Property EnableDualSpecularLobe;
private Property EnableIridescence;
private Property EnableGeometricNormalFiltering;

//
EnableDetails = new Property(this, k_EnableDetails, "Enable Details", "Enable Detail", true);
EnableSpecularOcclusion = new Property(this, k_EnableSpecularOcclusion, "Enable Specular Occlusion", "Enable Specular Occlusion", true);
EnableSSS = new Property(this, k_EnableSubsurfaceScattering, "Enable Subsurface Scattering", "Enable Subsurface Scattering", true);
EnableTransmission = new Property(this, k_EnableTransmission, "Enable Transmission", "Enable Transmission", true);
EnableCoat = new Property(this, k_EnableCoat, "Enable Coat", "Enable coat layer with true vertical physically based BSDF mixing", true);

// All material properties
// All GroupPropery below need to define a
// [HideInInspector] _XXXShow("_XXXShow", Float) = 0.0 parameter in the StackLit.shader to work
var BentNormalTexProp = new TextureProperty(this, k_BentNormalMap, "", "Bent Normal Map", "Bent Normal Map", pairConstantWithTexture: true, isMandatory: false, isNormalMap: true, showScaleOffset: false);
EnableSpecularOcclusion,
EnableDualSpecularLobe,
EnableAnisotropy,
EnableCoat,

new TextureProperty(this, k_MetallicMap, k_Metallic, "Metallic", "Metallic", false, false),
new Property(this, k_DielectricIor, "DieletricIor", "IOR use for dielectric material (i.e non metallic material)", false),
new TextureProperty(this, k_SmoothnessAMap, k_SmoothnessA, "Smoothness", "Smoothness", false, false),
new TextureProperty(this, k_NormalMap, k_NormalScale, "Normal", "Normal Map", true, false, true),
new TextureProperty(this, k_NormalMap, k_NormalScale, "Normal Map", "Normal Map", pairConstantWithTexture:true, isMandatory:false, isNormalMap:true, showScaleOffset:true, slaveTexOneLineProp:BentNormalTexProp.m_TextureProperty),
BentNormalTexProp,
//new TextureProperty(this, k_BentNormalMap, "", "Bent Normal Map", "Bent Normal Map", pairConstantWithTexture:true, isMandatory:false, isNormalMap:true, showScaleOffset:false),
new TextureProperty(this, k_AmbientOcclusionMap, k_AmbientOcclusion, "AmbientOcclusion", "AmbientOcclusion Map", false, false),
}),

new GroupProperty(this, "_Coat", "Coat", new BaseProperty[]
{
new TextureProperty(this, k_CoatSmoothnessMap, k_CoatSmoothness, "Coat smoothness", "Coat smoothness", false),
new TextureProperty(this, k_CoatNormalMap, k_CoatNormalScale, "Coat Normal Map", "Coat Normal Map", true, false, true, _ => EnableCoatNormalMap.BoolValue == true),
new TextureProperty(this, k_CoatNormalMap, k_CoatNormalScale, "Coat Normal Map", "Coat Normal Map",
pairConstantWithTexture:true, isMandatory:false, isNormalMap:true, showScaleOffset:true, slaveTexOneLineProp:null, isVisible: _ => EnableCoatNormalMap.BoolValue == true),
new Property(this, "_CoatIor", "Coat IOR", "Index of refraction", false),
new Property(this, "_CoatThickness", "Coat Thickness", "Coat thickness", false),
new Property(this, "_CoatExtinction", "Coat Absorption", "Coat absorption tint (the thicker the coat, the more that color is removed)", false),

new Property(this, "_DebugEnvLobeMask", "DebugEnvLobeMask", "xyz is Environments Lobe 0 1 2 Enable, w is Enable VLayering", false),
new Property(this, "_DebugLobeMask", "DebugLobeMask", "xyz is Analytical Lobe 0 1 2 Enable", false),
new Property(this, "_DebugAniso", "DebugAniso", "x is Hack Enable, y is factor", false),
new Property(this, "_DebugSpecularOcclusion", "DebugSpecularOcclusion", "eg (2,2,1,0), .x = {0 = fromAO, 1 = conecone, 2 = SPTD} .y = bentao algo {0 = uniform, cos, bent cos}, .z = use hemisphere clipping", false),
}),
});
}

//requireUv3 = requireUv3 || uvIndices[i] == TextureProperty.UVMapping.UV3;
requireTriplanar = requireTriplanar || uvIndices[i] == TextureProperty.UVMapping.Triplanar;
}
CoreUtils.SetKeyword(material, "_USE_TRIPLANAR", requireTriplanar);
CoreUtils.SetKeyword(material, "_MAPPING_TRIPLANAR", requireTriplanar);
CoreUtils.SetKeyword(material, "_USE_DETAILMAP", detailsEnabled);
CoreUtils.SetKeyword(material, "_DETAILMAP", detailsEnabled);
bool bentNormalMapPresent = material.HasProperty(k_BentNormalMap) && material.GetTexture(k_BentNormalMap);
CoreUtils.SetKeyword(material, "_BENTNORMALMAP", bentNormalMapPresent);
bool specularOcclusionEnabled = material.HasProperty(k_EnableSpecularOcclusion) && material.GetFloat(k_EnableSpecularOcclusion) > 0.0f;
CoreUtils.SetKeyword(material, "_ENABLESPECULAROCCLUSION", specularOcclusionEnabled);
bool dualSpecularLobeEnabled = material.HasProperty(k_EnableDualSpecularLobe) && material.GetFloat(k_EnableDualSpecularLobe) > 0.0f;
CoreUtils.SetKeyword(material, "_MATERIAL_FEATURE_DUAL_SPECULAR_LOBE", dualSpecularLobeEnabled);

44
com.unity.render-pipelines.high-definition/HDRP/Material/MaterialEvaluation.hlsl


aoFactor.directAmbientOcclusion = GTAOMultiBounce(directAmbientOcclusion, diffuseColor);
}
// Get screen space ambient occlusion only:
float GetScreenSpaceDiffuseOcclusion(float2 positionSS)
{
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
#ifndef _SURFACE_TYPE_TRANSPARENT
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, positionSS).x;
#else
float indirectAmbientOcclusion = 1.0;
#endif
return indirectAmbientOcclusion;
}
// Get ambient occlusion (indirect) from given data and screenspace one (using high quality GTAOMultiBounce version):
float3 GetDiffuseOcclusion(float3 diffuseColor, float diffuseOcclusionFromData, float screenSpaceDiffuseOcclusion)
{
return GTAOMultiBounce(min(diffuseOcclusionFromData, screenSpaceDiffuseOcclusion), diffuseColor);
}
// Get and Apply screen space diffuse occlusion only from SSAO on direct lighting
// (Note: mostly artistic parameter, also no data-based AO is used):
void GetApplyScreenSpaceDiffuseOcclusionForDirect(float3 diffuseColor, float screenSpaceDiffuseOcclusion, out float3 directAmbientOcclusion, inout AggregateLighting lighting)
{
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directDiffuseOcclusion = lerp(1.0, screenSpaceDiffuseOcclusion, _AmbientOcclusionParam.w);
directAmbientOcclusion = GTAOMultiBounce(directDiffuseOcclusion, diffuseColor);
lighting.direct.diffuse *= directAmbientOcclusion;
}
// Get/fill aoFactor from field values
void GetAmbientOcclusionFactor(float3 indirectAmbientOcclusion, float3 indirectSpecularOcclusion, float3 directAmbientOcclusion, out AmbientOcclusionFactor aoFactor)
{
aoFactor.indirectAmbientOcclusion = indirectAmbientOcclusion;
aoFactor.indirectSpecularOcclusion = indirectSpecularOcclusion;
aoFactor.directAmbientOcclusion = directAmbientOcclusion;
}
// Note: in case of Lit, bakeLightingData.bakeDiffuseLighting contain indirect diffuse + emissive,
// so Ambient occlusion is multiply by emissive which is wrong but not a big deal.
// Note: In case of Lit, bakeLightingData.bakeDiffuseLighting contain indirect diffuse + emissive,
// so ambient occlusion is multiplied by emissive which is wrong but not a big deal.
// Also, we have double occlusion for diffuse lighting:
// The baked diffuse lighting part from builtinData.bakeDiffuseLighting = SampleBakedGI() already
// had precomputed (aka "FromData") AO applied, and will get double occluded from screen space AO

25
com.unity.render-pipelines.high-definition/HDRP/Material/SphericalCapPivot/SPTDistribution.hlsl


return GetSphereCap(bentNormalWS, cosAv);
}
float GetSpecularOcclusionFromBentAOPivot(float3 V, float3 bentNormalWS, float3 normalWS, float ambientOcclusion, float perceptualRoughness)
float GetSpecularOcclusionFromBentAOPivot(float3 V, float3 bentNormalWS, float3 normalWS, float ambientOcclusion, float perceptualRoughness, int bentconeAlgorithm = BENT_VISIBILITY_FROM_AO_COS,
bool useGivenBasis = false, float3x3 orthoBasisViewNormal = (float3x3)(0), bool useExtraCap = false, SphereCap extraCap = (SphereCap)(0))
SphereCap bentVisibility = GetBentVisibility(bentNormalWS, ambientOcclusion);
SphereCap bentVisibility = GetBentVisibility(bentNormalWS, ambientOcclusion, bentconeAlgorithm);
//float3x3 orthoBasisViewNormal = GetOrthoBasisViewNormal(V, normalWS, dot(normalWS, V), true); // true => avoid singularity when V == N by returning arbitrary tangent/bitangents
float3x3 orthoBasisViewNormal = GetOrthoBasisViewNormal(V, normalWS, dot(normalWS, V));
if (useGivenBasis == false)
{
//orthoBasisViewNormal = GetOrthoBasisViewNormal(V, normalWS, dot(normalWS, V), true); // true => avoid singularity when V == N by returning arbitrary tangent/bitangents
orthoBasisViewNormal = GetOrthoBasisViewNormal(V, normalWS, dot(normalWS, V));
}
false, // true => clip with a second spherical cap, here the visible hemisphere:
GetSphereCap(normalWS, 0.0));
useExtraCap, //false, // true => clip with a second spherical cap, eg here the visible hemisphere:
extraCap); //GetSphereCap(normalWS, 0.0));
// Test: different tweaks to the cone-cone method:
float GetSpecularOcclusionFromBentAOTest(float3 V, float3 bentNormalWS, float3 normalWS, float ambientOcclusion, float perceptualRoughness)
// Different tweaks to the cone-cone method:
float GetSpecularOcclusionFromBentAOConeCone(float3 V, float3 bentNormalWS, float3 normalWS, float ambientOcclusion, float perceptualRoughness, int bentconeAlgorithm = BENT_VISIBILITY_FROM_AO_COS)
SphereCap bentVisibility = GetBentVisibility(bentNormalWS, ambientOcclusion, BENT_VISIBILITY_FROM_AO_COS);
//SphereCap bentVisibility = GetBentVisibility(bentNormalWS, ambientOcclusion, BENT_VISIBILITY_FROM_AO_COS);
SphereCap bentVisibility = GetBentVisibility(bentNormalWS, ambientOcclusion, bentconeAlgorithm);
float cosAv = bentVisibility.cosA;
float roughness = max(PerceptualRoughnessToRoughness(perceptualRoughness), 0.01); // Clamp to 0.01 to avoid edge cases

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


[SurfaceDataAttributes(new string[] {"Coat Normal", "Coat Normal View Space"}, true)]
public Vector3 coatNormalWS;
[SurfaceDataAttributes(new string[] {"Bent Normal", "Bent Normal View Space"}, true)]
public Vector3 bentNormalWS;
[SurfaceDataAttributes("Smoothness A")]
public float perceptualSmoothnessA;

[SurfaceDataAttributes(new string[] {"Coat Normal", "Coat Normal View Space"}, true)]
public Vector3 coatNormalWS;
[SurfaceDataAttributes(new string[] {"Bent Normal", "Bent Normal View Space"}, true)]
public Vector3 bentNormalWS;
public float perceptualRoughnessA;

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


#define DEBUGVIEW_STACKLIT_SURFACEDATA_GEOMETRIC_NORMAL_VIEW_SPACE (1108)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL (1109)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL_VIEW_SPACE (1110)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A (1111)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_B (1112)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_LOBE_MIXING (1113)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_TANGENT (1114)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY (1115)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_IOR (1116)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS (1117)
#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)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_BENT_NORMAL (1111)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_BENT_NORMAL_VIEW_SPACE (1112)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A (1113)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_B (1114)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_LOBE_MIXING (1115)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_TANGENT (1116)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY (1117)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_IOR (1118)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS (1119)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_MASK (1120)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_SMOOTHNESS (1121)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR (1122)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS (1123)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT (1124)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_DIFFUSION_PROFILE (1125)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SUBSURFACE_MASK (1126)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_THICKNESS (1127)
//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+BSDFData: static fields

#define DEBUGVIEW_STACKLIT_BSDFDATA_GEOMETRIC_NORMAL_VIEW_SPACE (1157)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_NORMAL (1158)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_NORMAL_VIEW_SPACE (1159)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_A (1160)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_B (1161)
#define DEBUGVIEW_STACKLIT_BSDFDATA_LOBE_MIX (1162)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TANGENT_WS (1163)
#define DEBUGVIEW_STACKLIT_BSDFDATA_BITANGENT_WS (1164)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AT (1165)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AB (1166)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BT (1167)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BB (1168)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ANISOTROPY (1169)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_ROUGHNESS (1170)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_PERCEPTUAL_ROUGHNESS (1171)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_IOR (1172)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_THICKNESS (1173)
#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_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)
#define DEBUGVIEW_STACKLIT_BSDFDATA_BENT_NORMAL (1160)
#define DEBUGVIEW_STACKLIT_BSDFDATA_BENT_NORMAL_VIEW_SPACE (1161)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_A (1162)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_B (1163)
#define DEBUGVIEW_STACKLIT_BSDFDATA_LOBE_MIX (1164)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TANGENT_WS (1165)
#define DEBUGVIEW_STACKLIT_BSDFDATA_BITANGENT_WS (1166)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AT (1167)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AB (1168)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BT (1169)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BB (1170)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ANISOTROPY (1171)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_ROUGHNESS (1172)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_PERCEPTUAL_ROUGHNESS (1173)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_IOR (1174)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_THICKNESS (1175)
#define DEBUGVIEW_STACKLIT_BSDFDATA_COAT_EXTINCTION (1176)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_IOR (1177)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_THICKNESS (1178)
#define DEBUGVIEW_STACKLIT_BSDFDATA_IRIDESCENCE_MASK (1179)
#define DEBUGVIEW_STACKLIT_BSDFDATA_DIFFUSION_PROFILE (1180)
#define DEBUGVIEW_STACKLIT_BSDFDATA_SUBSURFACE_MASK (1181)
#define DEBUGVIEW_STACKLIT_BSDFDATA_THICKNESS (1182)
#define DEBUGVIEW_STACKLIT_BSDFDATA_USE_THICK_OBJECT_MODE (1183)
#define DEBUGVIEW_STACKLIT_BSDFDATA_TRANSMITTANCE (1184)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.StackLit+SurfaceData
// PackingRules = Exact

float3 normalWS;
float3 geomNormalWS;
float3 coatNormalWS;
float3 bentNormalWS;
float perceptualSmoothnessA;
float perceptualSmoothnessB;
float lobeMix;

float3 normalWS;
float3 geomNormalWS;
float3 coatNormalWS;
float3 bentNormalWS;
float perceptualRoughnessA;
float perceptualRoughnessB;
float lobeMix;

case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL_VIEW_SPACE:
result = surfacedata.coatNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_BENT_NORMAL:
result = surfacedata.bentNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_BENT_NORMAL_VIEW_SPACE:
result = surfacedata.bentNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A:
result = surfacedata.perceptualSmoothnessA.xxx;
break;

break;
case DEBUGVIEW_STACKLIT_BSDFDATA_COAT_NORMAL_VIEW_SPACE:
result = bsdfdata.coatNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_BENT_NORMAL:
result = bsdfdata.bentNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_BENT_NORMAL_VIEW_SPACE:
result = bsdfdata.bentNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_A:
result = bsdfdata.perceptualRoughnessA.xxx;

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


#include "HDRP/Material/LTCAreaLight/LTCAreaLight.hlsl"
#include "HDRP/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl"
#include "HDRP/Material/SphericalCapPivot/SPTDistribution.hlsl"
#include "HDRP/Material/MaterialEvaluation.hlsl"
//-----------------------------------------------------------------------------
// Definition

#ifdef _STACKLIT_DEBUG
# define IF_DEBUG(a) a
# define VLAYERED_DEBUG
# define STACKLIT_DEBUG
#else
# define IF_DEBUG(a)
#endif

float GetCoatEta(in BSDFData bsdfData)
{
float eta = bsdfData.coatIor / 1.0;
//float eta = 1.5 / 1.0;
//ieta = 1.0 / eta;
return eta;
}

// Two lobe base material
bsdfData.normalWS = surfaceData.normalWS;
bsdfData.bentNormalWS = surfaceData.bentNormalWS;
bsdfData.perceptualRoughnessA = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothnessA);
bsdfData.perceptualRoughnessB = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothnessB);

float3x3 orthoBasisViewNormal[NB_NORMALS]; // Right-handed view-dependent orthogonal basis around the normal
float3x3 ltcTransformDiffuse; // Inverse transformation for Lambertian or Disney Diffuse
float3x3 ltcTransformSpecular[TOTAL_NB_LOBES]; // Inverse transformation for GGX
// Occlusion data:
float screenSpaceAmbientOcclusion; // Keep a copy of the screen space occlusion texture fetch between
// PreLightData and GetBakedDiffuseLighting.
float3 hemiSpecularOcclusion[TOTAL_NB_LOBES]; // Specular occlusion calculated from roughness and for an unknown
// (the less sparse / more uniform the better) light structure
// potentially covering the whole hemisphere.
};

float r = (perceptualRoughness)/(newPerceptualRoughness+FLT_MIN*2);
//r = sqrt(r);
float factor = 1000.0;
#ifdef VLAYERED_DEBUG
#ifdef STACKLIT_DEBUG
factor = _DebugAniso.y;
#endif
float newAniso = anisotropy * (r + (1-r) * clamp(factor*roughness*roughness,0,1));

// _cti should be NdotV if calledPerLight == false and no independent coat normal map is used (ie single normal map), V is unused in this case.
// _cti should be (coatNormalWS dot V) if calledPerLight == false and we have a coat normal map. V is used in this case
#ifdef VLAYERED_DEBUG
#ifdef STACKLIT_DEBUG
preLightData.vLayerEnergyCoeff[COAT_LOBE_IDX] = 0.0 * F_Schlick(IorToFresnel0(bsdfData.coatIor), _cti);
preLightData.vLayerEnergyCoeff[TOP_VLAYER_IDX] = 0.0 * F_Schlick(IorToFresnel0(bsdfData.coatIor), _cti);
preLightData.vLayerEnergyCoeff[BASE_LOBEA_IDX] = 1.0 * F_Schlick(bsdfData.fresnel0, _cti);
preLightData.vLayerEnergyCoeff[BASE_LOBEB_IDX] = 1.0 * F_Schlick(bsdfData.fresnel0, _cti);
preLightData.vLayerEnergyCoeff[BOTTOM_VLAYER_IDX] = 1.0 * F_Schlick(bsdfData.fresnel0, _cti);
preLightData.layeredRoughnessT[0] = ClampRoughnessForAnalyticalLights(bsdfData.roughnessAT);
preLightData.layeredRoughnessB[0] = ClampRoughnessForAnalyticalLights(bsdfData.roughnessAB);

//-------------------------------------------------------------
// Post compute:
//-------------------------------------------------------------
// TODO: dual lobe feature option
//
// Works because we're the last "layer" and all variables touched
// above are in a state where these calculations will be valid:

{
// First, if we're not called per light, always (regardless of perLightOption) calculate
// roughness for top lobe: no adding( ) modifications, just conversion + clamping for
// analytical lights. For these we also don't need to recompute these, but only the Fresnel
// analytical lights. For these we also don't need to recompute the following, but only the Fresnel
// or FGD term are necessary in ComputeAdding, see BSDF().
preLightData.iblPerceptualRoughness[COAT_LOBE_IDX] = bsdfData.coatPerceptualRoughness;
preLightData.layeredCoatRoughness = ClampRoughnessForAnalyticalLights(bsdfData.coatRoughness);

preLightData.layeredRoughnessB[1] = ClampRoughnessForAnalyticalLights(LinearVarianceToRoughness(_s_r0m));
}
}
// ...Non scalar treatment of anisotropy to have the option to remove some anisotropy
// --------------------------------------------------------------------------------
#endif // #ifdef VLAYERED_ANISOTROPY_SCALAR_ROUGHNESS

//preLightData.ltcTransformDiffuse._m22 = 1.0;
//preLightData.ltcTransformDiffuse._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_DISNEY_DIFFUSE_MATRIX_INDEX, 0);
#endif
}
} // PreLightData_SetupAreaLights
#define SPECULAR_OCCLUSION_FROM_AO 0
#define SPECULAR_OCCLUSION_CONECONE 1
#define SPECULAR_OCCLUSION_SPTD 2
float3 PreLightData_GetSpecularOcclusion(BSDFData bsdfData, // PreLightData preLightData,
int specularOcclusionAlgorithm,
float screenSpaceSpecularOcclusion,
float3 V, float3 normalWS, float NdotV /* clamped */,
float perceptualRoughness, float3x3 orthoBasisViewNormal,
int bentVisibilityAlgorithm, bool useHemisphereClip, float3 fresnel0)
{
SphereCap hemiSphere = GetSphereCap(normalWS, 0.0);
float ambientOcclusionFromData = bsdfData.ambientOcclusion;
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
float3 debugCoeff = float3(1.0,1.0,1.0);
float specularOcclusionFromData;
switch(specularOcclusionAlgorithm)
{
case SPECULAR_OCCLUSION_FROM_AO:
specularOcclusionFromData = GetSpecularOcclusionFromAmbientOcclusion(NdotV, ambientOcclusionFromData, roughness);
break;
case SPECULAR_OCCLUSION_CONECONE:
IF_DEBUG( if (_DebugSpecularOcclusion.w == -1.0) { debugCoeff = float3(1.0,0.0,0.0); } )
specularOcclusionFromData = GetSpecularOcclusionFromBentAOConeCone(V, bsdfData.bentNormalWS, normalWS, ambientOcclusionFromData, roughness, bentVisibilityAlgorithm);
break;
case SPECULAR_OCCLUSION_SPTD:
IF_DEBUG( if (_DebugSpecularOcclusion.w == -1.0) { debugCoeff = float3(0.0,1.0,0.0); } )
specularOcclusionFromData = GetSpecularOcclusionFromBentAOPivot(V, bsdfData.bentNormalWS, normalWS,
ambientOcclusionFromData,
perceptualRoughness,
bentVisibilityAlgorithm,
/* useGivenBasis */ true,
orthoBasisViewNormal,
useHemisphereClip,
hemiSphere);
break;
}
float3 specularOcclusion = debugCoeff * GTAOMultiBounce(min(specularOcclusionFromData, screenSpaceSpecularOcclusion), fresnel0);
return specularOcclusion;
} // PreLightData_GetSpecularOcclusion
// Call after LTC so orthoBasisViewNormal[] are setup along with other preLightData fields:
//
// Makes use of ComputeAdding modified iblPerceptualRoughness, vLayerEnergyCoeff (if vlayered)
// and fresnelIridforCalculatingFGD (if not vlayered) if iridescence is enabled.
void PreLightData_SetupOcclusion(PositionInputs posInput, BSDFData bsdfData, float3 V, float3 N[NB_NORMALS], float NdotV[NB_NORMALS] /* clamped */, inout PreLightData preLightData)
{
float screenSpaceSpecularOcclusion[TOTAL_NB_LOBES];
float3 bottomF0;
preLightData.screenSpaceAmbientOcclusion = GetScreenSpaceDiffuseOcclusion(posInput.positionSS);
#ifdef _ENABLESPECULAROCCLUSION
// -We have 3 lobes with different roughnesses, and these have been placed unclamped and modified by vlayering in
// iblPerceptualRoughness[].
// -We might have 2 different shading normals to consider.
// -Bentnormal is always considered if the algorithm permits it, but it might trivially be the normal if no bent
// normals were given by the user.
//
// -Finally, our pre-calculated specular occlusion will serve for IBL for now, which have unknown structure so the
// whole hemisphere around the normal is taken as potential light visibility region, that's why the pre-calculated
// values are identified as "hemiSpecularOcclusion". This would potentially need to be different per light type,
// or even per light:
// eg. for eventual LTC spherical area lights, we can have perfect 3 terms (geometric factor, BSDF, incoming radiance)
// integration with pivot-transformed spherical cap integration domain, our SPTD GGX proxy for BSDF and LTC GGX proxy
// analytic sphere irradiance.
int specularOcclusionAlgorithm = SPECULAR_OCCLUSION_SPTD; // = 2
int bentVisibilityAlgorithm = BENT_VISIBILITY_FROM_AO_COS_BENT_CORRECTION; // = 2
bool useHemisphereClip = true;
IF_DEBUG(specularOcclusionAlgorithm = clamp((int)(_DebugSpecularOcclusion.x), 0, SPECULAR_OCCLUSION_SPTD));
IF_DEBUG(bentVisibilityAlgorithm = clamp((int)(_DebugSpecularOcclusion.y), 0, BENT_VISIBILITY_FROM_AO_COS_BENT_CORRECTION));
IF_DEBUG(useHemisphereClip = (_DebugSpecularOcclusion.z == 1.0) );
// For fresnel0 to use with GTAOMultiBounce for the bottom interface, since it's already a hack on an empirical fit
// (empirical fit done for diffuse), we will try to use something we already calculated and should offer a proper tint:
if( IsVLayeredEnabled(bsdfData) )
{
bottomF0 = preLightData.vLayerEnergyCoeff[BOTTOM_VLAYER_IDX];
}
else
{
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_IRIDESCENCE))
{
bottomF0 = preLightData.fresnelIridforCalculatingFGD;
}
else
{
bottomF0 = bsdfData.fresnel0;
}
}
// Screen space derived SO: one per lobe. Will be min( , ) with data-based calculated SO.
// TODO: Like in Lit, for screen space AO based SO, we don't offer the more advanced algorithms but we could.
screenSpaceSpecularOcclusion[BASE_LOBEA_IDX] = GetSpecularOcclusionFromAmbientOcclusion(NdotV[BASE_NORMAL_IDX],
preLightData.screenSpaceAmbientOcclusion,
preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX]);
screenSpaceSpecularOcclusion[BASE_LOBEB_IDX] = GetSpecularOcclusionFromAmbientOcclusion(NdotV[BASE_NORMAL_IDX],
preLightData.screenSpaceAmbientOcclusion,
preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX]);
preLightData.hemiSpecularOcclusion[BASE_LOBEA_IDX] = PreLightData_GetSpecularOcclusion(bsdfData,
specularOcclusionAlgorithm,
screenSpaceSpecularOcclusion[BASE_LOBEA_IDX],
V,
N[BASE_NORMAL_IDX],
NdotV[BASE_NORMAL_IDX] /* clamped */,
preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX],
preLightData.orthoBasisViewNormal[BASE_NORMAL_IDX],
bentVisibilityAlgorithm,
useHemisphereClip,
bottomF0);
preLightData.hemiSpecularOcclusion[BASE_LOBEB_IDX] = PreLightData_GetSpecularOcclusion(bsdfData,
specularOcclusionAlgorithm,
screenSpaceSpecularOcclusion[BASE_LOBEB_IDX],
V,
N[BASE_NORMAL_IDX],
NdotV[BASE_NORMAL_IDX] /* clamped */,
preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX],
preLightData.orthoBasisViewNormal[BASE_NORMAL_IDX],
bentVisibilityAlgorithm,
useHemisphereClip,
bottomF0);
if( IsVLayeredEnabled(bsdfData) )
{
screenSpaceSpecularOcclusion[COAT_LOBE_IDX] = GetSpecularOcclusionFromAmbientOcclusion(NdotV[COAT_NORMAL_IDX],
preLightData.screenSpaceAmbientOcclusion,
preLightData.iblPerceptualRoughness[COAT_LOBE_IDX]);
preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX] = PreLightData_GetSpecularOcclusion(bsdfData,
specularOcclusionAlgorithm,
screenSpaceSpecularOcclusion[COAT_LOBE_IDX],
V,
N[COAT_NORMAL_IDX],
NdotV[COAT_NORMAL_IDX] /* clamped */,
preLightData.iblPerceptualRoughness[COAT_LOBE_IDX],
preLightData.orthoBasisViewNormal[COAT_NORMAL_IDX],
bentVisibilityAlgorithm,
useHemisphereClip,
IorToFresnel0(bsdfData.coatIor));
}
#else
preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX] =
preLightData.hemiSpecularOcclusion[BASE_LOBEA_IDX] =
preLightData.hemiSpecularOcclusion[BASE_LOBEB_IDX] = float3(1.0, 1.0, 1.0);
#endif // _ENABLESPECULAROCCLUSION
} // PreLightData_SetupOcclusion
PreLightData GetPreLightData(float3 V, PositionInputs posInput, inout BSDFData bsdfData)
{

preLightData.layeredRoughnessT[1] = bsdfData.roughnessBT;
preLightData.layeredRoughnessB[1] = bsdfData.roughnessBB;
// Also important: iblPerceptualRoughness[] is used for specular occlusion
preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX] = bsdfData.perceptualRoughnessA;
preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX] = bsdfData.perceptualRoughnessB;
preLightData.iblAnisotropy[0] = bsdfData.anisotropy;

// Area Lights:
PreLightData_SetupAreaLights(bsdfData, V, N, NdotV, preLightData);
// Diffuse and specular occlusion pre-calculations:
PreLightData_SetupOcclusion(posInput, bsdfData, V, N, NdotV /* array, clamped */, /* inout */ preLightData);
return preLightData;
}

// Premultiply bake diffuse lighting information
// preLightData.diffuseEnergy will be 1,1,1 if no vlayering or no VLAYERED_DIFFUSE_ENERGY_HACKED_TERM
return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * preLightData.diffuseEnergy * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor;
//return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * preLightData.diffuseEnergy * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor;
//
// In our case, we want to avoid the tradeoffs of deferred with ambientOcclusion:
//
// We don't want to apply (screen space based) ambient occlusion on baked emissive light
// and we don't want to apply double occlusion to indirect diffuse light that we return here
// to the ShaderPassForward and will get fed back to use in evaluateBSDF (and the postEval)
// functions via
// BakeLightingData.bakeDiffuseLighting
// but these functions mainly use the bakeShadowMask fields of BakeLightingData.
//
// These errors happen in deferred because we don't want to store the separate ambient occlusion,
// in the GBuffer as we're already storing the bakeDiffuseLighting, so we apply data based AO on
// the bakediffuse here, but then, at PostEvaluateBSDF time, ie in some the lighting shader variant,
// we apply the screen space AO on all indirect diffuse lighting which will include emissive and be applied
// on builtinData.bakeDiffuseLighting * surfaceData.ambientOcclusion instead of these later terms
// getting min(ss AO, data based AO).
//
// Here we are called after PreLightData but before lighting.
// So we have choices: regardless of what we return as bakeDiffuseLighting here, we could store a separate
// copy of the lighting itself to split out emissive and apply indirect AO later, or calculate
// AO here (combined screen space based + data based) and apply it on the indirect diffuse as we don't deal
// with such lighting later anyway (data-based direct diffuse occlusion can be applied later - the direct
// diffuse is an artistic choice configured by the .w component of the AO parameters, the color of
// the later being ignored when using GTAOMultiBounce.)
//
// We decide on the later option as principle since BakeLightingData.bakeDiffuseLighting will be correct
// and not duplicated and again here in forward we can do it as the screen space occlusion texture should
// be ready too. The lobe specific specular occlusion data, along with the result of the screen space occlusion
// sampling, will already be computed in PreLightData.
// bsdfData.diffuseColor is not appropriate to use when vlayered when doing GTAOMultiBounce here, but we can
// try something with (bsdfData.diffuseColor * bsdfData.coatExtinction) (for specular occlusion with f0, it's
// even worse but both are a hack anyway) We could also try "renormalizing diffuseEnergy" to the luminance of
// diffuseColor.
// For now, we use (bsdfData.diffuseColor * preLightData.diffuseEnergy) directly:
float3 GTAOMultiBounceTintBase = (bsdfData.diffuseColor * preLightData.diffuseEnergy);
float3 diffuseOcclusion = GetDiffuseOcclusion(GTAOMultiBounceTintBase, surfaceData.ambientOcclusion, preLightData.screenSpaceAmbientOcclusion);
//float3 diffuseOcclusion = GTAOMultiBounce(min(surfaceData.ambientOcclusion, preLightData.screenSpaceAmbientOcclusion), bsdfData.diffuseColor);
return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * preLightData.diffuseEnergy * diffuseOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor;
}

#define USE_DEFERRED_DIRECTIONAL_SHADOWS // Deferred shadows are always enabled for opaque objects
#endif
#include "HDRP/Material/MaterialEvaluation.hlsl"
//#include "HDRP/Material/MaterialEvaluation.hlsl"
#include "HDRP/Lighting/LightEvaluation.hlsl"
#include "HDRP/Lighting/Reflection/VolumeProjection.hlsl"

specularLighting = max(0, NdotL[0]) * F * lerp(DV[0]*preLightData.energyCompensationFactor[BASE_LOBEA_IDX],
DV[1]*preLightData.energyCompensationFactor[BASE_LOBEB_IDX],
bsdfData.lobeMix);
//...and energy compensation is applied at PostEvaluateBSDF when no vlayering.
}

IF_DEBUG( if ( _DebugLobeMask.y != 0.0) )
{
ltcValue = LTCEvaluate(localP1, localP2, B, preLightData.ltcTransformSpecular[BASE_LOBEA_IDX]);
lighting.specular += preLightData.specularFGD[BASE_LOBEA_IDX] * ltcValue;
// See EvaluateBSDF_Env TODOENERGY:
lighting.specular += preLightData.energyCompensationFactor[BASE_LOBEA_IDX] * preLightData.specularFGD[BASE_LOBEA_IDX] * ltcValue;
lighting.specular += preLightData.specularFGD[BASE_LOBEB_IDX] * ltcValue;
lighting.specular += preLightData.energyCompensationFactor[BASE_LOBEB_IDX] * preLightData.specularFGD[BASE_LOBEB_IDX] * ltcValue;
}
if (IsVLayeredEnabled(bsdfData))

IF_DEBUG( if ( _DebugLobeMask.x != 0.0) )
{
ltcValue = LTCEvaluate(localP1, localP2, B, preLightData.ltcTransformSpecular[COAT_LOBE_IDX]);
lighting.specular += preLightData.specularFGD[COAT_LOBE_IDX] * ltcValue;
lighting.specular += preLightData.energyCompensationFactor[COAT_LOBE_IDX] * preLightData.specularFGD[COAT_LOBE_IDX] * ltcValue;
}
}
lighting.specular *= lightData.specularScale;

{
// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(localLightVerts, preLightData.ltcTransformSpecular[BASE_LOBEA_IDX]));
lighting.specular += preLightData.specularFGD[BASE_LOBEA_IDX] * ltcValue;
// See EvaluateBSDF_Env TODOENERGY:
lighting.specular += preLightData.energyCompensationFactor[BASE_LOBEA_IDX] * preLightData.specularFGD[BASE_LOBEA_IDX] * ltcValue;
lighting.specular += preLightData.specularFGD[BASE_LOBEB_IDX] * ltcValue;
lighting.specular += preLightData.energyCompensationFactor[BASE_LOBEB_IDX] * preLightData.specularFGD[BASE_LOBEB_IDX] * ltcValue;
}
if (IsVLayeredEnabled(bsdfData))

IF_DEBUG( if ( _DebugLobeMask.x != 0.0) )
{
ltcValue = PolygonIrradiance(mul(localLightVerts, preLightData.ltcTransformSpecular[COAT_LOBE_IDX]));
lighting.specular += preLightData.specularFGD[COAT_LOBE_IDX] * ltcValue;
lighting.specular += preLightData.energyCompensationFactor[COAT_LOBE_IDX] * preLightData.specularFGD[COAT_LOBE_IDX] * ltcValue;
}
}
lighting.specular *= lightData.specularScale;

{
float3 L;
#ifdef VLAYERED_DEBUG
#ifdef STACKLIT_DEBUG
IF_FEATURE_COAT( if( (i == 0) && _DebugEnvLobeMask.x == 0.0) continue; )
if( (i == (0 IF_FEATURE_COAT(+1))) && _DebugEnvLobeMask.y == 0.0) continue;
if( (i == (1 IF_FEATURE_COAT(+1))) && _DebugEnvLobeMask.z == 0.0) continue;

tempWeight[i] *= preLD.a;
L = preLD.rgb * preLightData.specularFGD[i];
if( IsVLayeredEnabled(bsdfData) )
{
// TODOENERGY: should be done in ComputeAdding with FGD formulation for IBL.
// Note that when we're not vlayered, we apply it not at each light sample but at the end,
// at PostEvaluateBSDF.
// Incorrect, but just for now:
L *= preLightData.energyCompensationFactor[i];
}
// TODOENERGY: If vlayered, should be done in ComputeAdding with FGD formulation for IBL. Same for LTC actually
// Incorrect, but just for now:
L *= preLightData.energyCompensationFactor[i];
L *= preLightData.hemiSpecularOcclusion[i];
envLighting += L;
}

PreLightData preLightData, BSDFData bsdfData, BakeLightingData bakeLightingData, AggregateLighting lighting,
out float3 diffuseLighting, out float3 specularLighting)
{
float3 N;
float unclampedNdotV;
EvaluateBSDF_GetNormalUnclampedNdotV(bsdfData, preLightData, V, N, unclampedNdotV);
// Indirect diffuse occlusion has already been applied in GetBakedDiffuseLighting() and specular occlusion
// has been pre-computed in GetPreLightData() and applied on indirect specular light.
// We apply the artistic diffuse occlusion on direct lighting here:
float3 directAmbientOcclusion; // for debug below
AmbientOcclusionFactor aoFactor;
// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the baseColor)
//GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix), bsdfData.ambientOcclusion, 1.0, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, unclampedNdotV, lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix), bsdfData.ambientOcclusion, 1.0, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
ApplyAmbientOcclusionFactor(aoFactor, bakeLightingData, lighting);
// bsdfData.diffuseColor is not appropriate to use when vlayered when doing GTAOMultiBounce here, but we can
// try something with (bsdfData.diffuseColor * bsdfData.coatExtinction) (for specular occlusion with f0, it's
// even worse but both are a hack anyway) We could also try "renormalizing diffuseEnergy" to the luminance of
// diffuseColor.
// For now, we use (bsdfData.diffuseColor * preLightData.diffuseEnergy) directly:
float3 GTAOMultiBounceTintBase = (bsdfData.diffuseColor * preLightData.diffuseEnergy);
GetApplyScreenSpaceDiffuseOcclusionForDirect(GTAOMultiBounceTintBase, preLightData.screenSpaceAmbientOcclusion, directAmbientOcclusion, lighting);
// Subsurface scattering mode
float3 modifiedDiffuseColor = GetModifiedDiffuseColorForSSS(bsdfData);

specularLighting = lighting.direct.specular + lighting.indirect.specularReflected;
#ifdef DEBUG_DISPLAY
// Recompute diffuseOcclusion for debug display here (see comments about GTAOMultiBounceTintBase above).
// For specularOcclusion we display red to indicate there's not one value possible here.
float3 diffuseOcclusion = GetDiffuseOcclusion(GTAOMultiBounceTintBase, bsdfData.ambientOcclusion, preLightData.screenSpaceAmbientOcclusion);
AmbientOcclusionFactor aoFactor;
float3 specularOcclusion = float3(1.0,0.0,0.0);
#ifdef STACKLIT_DEBUG
IF_FEATURE_COAT( if (_DebugSpecularOcclusion.w == 1.0) { specularOcclusion = preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; } )
if (_DebugSpecularOcclusion.w == 2.0) { specularOcclusion = preLightData.hemiSpecularOcclusion[BASE_LOBEA_IDX]; }
if (_DebugSpecularOcclusion.w == 3.0) { specularOcclusion = preLightData.hemiSpecularOcclusion[BASE_LOBEB_IDX]; }
if (_DebugSpecularOcclusion.w == 4.0) { specularOcclusion = float3(0.0,0.0,1.0) * preLightData.screenSpaceAmbientOcclusion; }
#endif
GetAmbientOcclusionFactor(diffuseOcclusion, specularOcclusion, directAmbientOcclusion /* not used for now in PostEvaluateBSDFDebugDisplay */ , aoFactor);
PostEvaluateBSDFDebugDisplay(aoFactor, bakeLightingData, lighting, bsdfData.diffuseColor, diffuseLighting, specularLighting);
#endif
}

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


_DebugEnvLobeMask("DebugEnvLobeMask", Vector) = (1, 1, 1, 1)
_DebugLobeMask("DebugLobeMask", Vector) = (1, 1, 1, 1)
_DebugAniso("DebugAniso", Vector) = (1, 0, 0, 1000.0)
_DebugSpecularOcclusion("DebugSpecularOcclusion", Vector) = (2, 2, 1, 2)
// .x = {0 = fromAO, 1 = conecone, 2 = SPTD} .y = bentao algo {0 = uniform, cos, bent cos}, .z = use hemisphere clipping,
// .w = {-1.0 => show SO algo used with tint,
// 1.0 to 4.0 => used with DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION
// 1.0, 2.0, 3.0 show SO for COAT LOBE, BASE LOBEA and BASE LOBEB,
// 4.0 show the source screen space occlusion instead of specular occlusion.}
// TODO: TangentMap, AnisotropyMap and CoatIorMap (SmoothnessMap ?)

_NormalMapUVLocal("NormalMapUV Local", Float) = 0.0
_NormalMapObjSpace("NormalMapObjSpace", Float) = 0.0
_NormalScale("Normal Scale", Range(0.0, 2.0)) = 1
[HideInInspector] _BentNormalMapShow("Bent NormalMap Show", Float) = 0.0
_BentNormalMap("Bent NormalMap", 2D) = "bump" {} // Tangent space bent normal map
//_BentNormalMapUV("Bent NormalMapUV", Float) = 0.0
//_BentNormalMapUVLocal("Bent NormalMapUV Local", Float) = 0.0
//_BentNormalMapObjSpace("Bent NormalMap ObjSpace", Float) = 0.0
//_BentNormalScale("Bent NormalMap Scale", Range(0.0, 2.0)) = 1
// Bent normal should reuse the mapping and scale of the normal map as their direction
// should be intimately tied on the user's (generation/artist pipeline) side
// This will control SO whether bent normals are there or not (cf Lit where only bent normals have effect with the associated keyword)
[ToggleUI] _EnableSpecularOcclusion("Enable Specular Occlusion", Float) = 0.0
[HideInInspector] _AmbientOcclusionMapShow("AmbientOcclusion Map Show", Float) = 0
_AmbientOcclusion("AmbientOcclusion", Range(0.0, 1.0)) = 1

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _USE_DETAILMAP
#pragma shader_feature _USE_UV2
#pragma shader_feature _USE_UV3
#pragma shader_feature _USE_TRIPLANAR
#pragma shader_feature _DETAILMAP
#pragma shader_feature _BENTNORMALMAP
#pragma shader_feature _ENABLESPECULAROCCLUSION // This will control SO whether bent normals are there or not (cf Lit where only bent normals have effect with this keyword)
//#pragma shader_feature _REQUIRE_UV2
//#pragma shader_feature _REQUIRE_UV3
#pragma shader_feature _MAPPING_TRIPLANAR // This shader makes use of TRIPLANAR mapping, we reuse the Lit keyword _MAPPING_TRIPLANAR
// Keyword for transparent
#pragma shader_feature _SURFACE_TYPE_TRANSPARENT

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


struct TextureUVMapping
{
float2 texcoords[TEXCOORD_INDEX_COUNT][2];
#ifdef _USE_TRIPLANAR
#ifdef _MAPPING_TRIPLANAR
float3 triplanarWeights[2];
#endif

uvMapping.texcoords[TEXCOORD_INDEX_PLANAR_YZ][1] = uvZY;
uvMapping.texcoords[TEXCOORD_INDEX_PLANAR_ZX][1] = uvXZ;
#ifdef _USE_TRIPLANAR
#ifdef _MAPPING_TRIPLANAR
float3 vertexNormal = input.worldToTangent[2].xyz;
uvMapping.triplanarWeights[0] = ComputeTriplanarWeights(vertexNormal);
// If we use local planar mapping, convert to local space

// If we use triplanar on any of the properties, then we enable the triplanar path
float4 SampleTexture2DTriplanarScaleBias(TEXTURE2D_ARGS(textureName, samplerName), float textureNameUV, float textureNameUVLocal, float4 textureNameST, TextureUVMapping uvMapping)
{
#ifdef _USE_TRIPLANAR
#ifdef _MAPPING_TRIPLANAR
if (textureNameUV == TEXCOORD_INDEX_TRIPLANAR)
{
float4 val = float4(0.0, 0.0, 0.0, 0.0);

}
else
{
#endif // _USE_TRIPLANAR
#endif // _MAPPING_TRIPLANAR
#ifdef _USE_TRIPLANAR
#ifdef _MAPPING_TRIPLANAR
}
#endif
}

}
else
{
#ifdef _USE_TRIPLANAR
#ifdef _MAPPING_TRIPLANAR
if (textureNameUV == TEXCOORD_INDEX_TRIPLANAR)
{
float2 derivXplane;

#define SAMPLE_TEXTURE2D_SCALE_BIAS(name) SampleTexture2DTriplanarScaleBias(name, sampler##name, name##UV, name##UVLocal, name##_ST, uvMapping)
#define SAMPLE_TEXTURE2D_NORMAL_SCALE_BIAS(name, scale, objSpace) SampleTexture2DTriplanarNormalScaleBias(name, sampler##name, name##UV, name##UVLocal, name##_ST, objSpace, uvMapping, scale)
#define SAMPLE_TEXTURE2D_NORMAL_PROPNAME_SCALE_BIAS(name, propname, scale, objSpace) SampleTexture2DTriplanarNormalScaleBias(name, sampler##propname, propname##UV, propname##UVLocal, propname##_ST, objSpace, uvMapping, scale)
//...permits referencing all properties from another texture name
//-----------------------------------------------------------------------------
// GetSurfaceAndBuiltinData

{
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal.
TextureUVMapping uvMapping;
TextureUVMapping uvMapping; // Note this identifier is directly referenced in the SAMPLE_TEXTURE2D_* macros above
InitializeMappingData(input, uvMapping);
// -------------------------------------------------------------

surfaceData.baseColor = SAMPLE_TEXTURE2D_SCALE_BIAS(_BaseColorMap).rgb * _BaseColor.rgb;
float4 gradient = SAMPLE_TEXTURE2D_NORMAL_SCALE_BIAS(_NormalMap, _NormalScale, _NormalMapObjSpace);
//TODO: bentNormalTS
float4 bentGradient = float4(0.0, 0.0, 0.0, 1.0f);
// ...last value is for normal map filtering (average normal length). Unused for bent normal for now, but
// could be used to tilt back the bent normal to the normal and/or enlarge the visibility cone as bent visibility
// can alias like everything else.
// TODO
#ifdef _BENTNORMALMAP
bentGradient = SAMPLE_TEXTURE2D_NORMAL_PROPNAME_SCALE_BIAS(_BentNormalMap, _NormalMap, _NormalScale, _NormalMapObjSpace);
#endif
surfaceData.perceptualSmoothnessA = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_SmoothnessAMap), _SmoothnessAMapChannelMask);
surfaceData.perceptualSmoothnessA = lerp(_SmoothnessAMapRange.x, _SmoothnessAMapRange.y, surfaceData.perceptualSmoothnessA);

surfaceData.thickness = 1.0;
#endif
#ifdef _USE_DETAILMAP
#ifdef _DETAILMAP
bentGradient += detailGradient * detailMask;
bentGradient.w *= 0.5; // Take mean of average normal length
float detailPerceptualSmoothness = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_DetailSmoothnessMap), _DetailSmoothnessMapChannelMask);
detailPerceptualSmoothness = lerp(_DetailSmoothnessMapRange.x, _DetailSmoothnessMapRange.y, detailPerceptualSmoothness);

surfaceData.geomNormalWS = input.worldToTangent[2];
// Convert back to world space normal
surfaceData.normalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], gradient.xyz);
surfaceData.bentNormalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], bentGradient.xyz);
surfaceData.coatNormalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], coatGradient.xyz);
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);

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


TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURE2D(_BentNormalMap); // reuses the normal map sampler
TEXTURE2D(_CoatNormalMap);
SAMPLER(sampler_CoatNormalMap);

float4 _DebugEnvLobeMask;
float4 _DebugLobeMask;
float4 _DebugAniso;
float4 _DebugSpecularOcclusion;
float _NormalScale;
float _NormalMapUV;

正在加载...
取消
保存