浏览代码

Merge pull request #957 from Unity-Technologies/Adress-iridescence-PR-feedback

Adress iridescence pr feedback
/main
GitHub 7 年前
当前提交
2298dc56
共有 11 个文件被更改,包括 168 次插入184 次删除
  1. 108
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/BSDF.hlsl
  2. 28
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/CommonMaterial.hlsl
  3. 38
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/LitUI.cs
  4. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl
  5. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs
  6. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl
  7. 113
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  8. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.shader
  9. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataIndividualLayer.hlsl
  10. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitProperties.hlsl
  11. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitTessellation.shader

108
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/BSDF.hlsl


// Fresnel dieletric / dielectric
real F_Fresnel(real ior, real u)
{
float g = sqrt(Sq(ior) + Sq(u) - 1.0);
real g = sqrt(Sq(ior) + Sq(u) - 1.0);
return 0.5 * Sq((g - u) / (g + u)) * (1.0 + Sq(((g + u) * u - 1.0) / ((g - u) * u + 1.0)));
}

{
// Note that we could save 2 cycles by inlining the multiplication by INV_PI.
return INV_PI * DiffuseGGXNoPI(albedo, NdotV, NdotL, NdotH, LdotV, roughness);
}
//-----------------------------------------------------------------------------
// Conversion FO/IOR
//-----------------------------------------------------------------------------
// ior is a value between 1.0 and 3.0. 1.0 is air interface
real IorToFresnel0(real transmittedIor, real incidentIor = 1.0)
{
return Sq((transmittedIor - incidentIor) / (transmittedIor + incidentIor));
}
// Assume air interface for top
// Note: Don't handle the case fresnel0 == 1
real Fresnel0ToIor(real fresnel0)
{
real sqrtF0 = sqrt(fresnel0);
return (1.0 + sqrtF0) / (1.0 - sqrtF0);
}
// This function is a coarse approximation of computing fresnel0 for a different top than air (here clear coat of IOR 1.5) when we only have fresnel0 with air interface
// This function is equivalent to IorToFresnel0(Fresnel0ToIor(fresnel0), 1.5)
// mean
// real sqrtF0 = sqrt(fresnel0);
// return Sq(1.0 - 5.0 * sqrtF0) / Sq(5.0 - sqrtF0);
// Optimization: Fit of the function (3 mad) for range [0.04 (should return 0), 1 (should return 1)]
TEMPLATE_1_REAL(ConvertF0ForAirInterfaceToF0ForClearCoat15, fresnel0, return saturate(-0.0256868 + fresnel0 * (0.326846 + (0.978946 - 0.283835 * fresnel0) * fresnel0)))
//-----------------------------------------------------------------------------
// Iridescence
//-----------------------------------------------------------------------------
// Ref: https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html
// Evaluation XYZ sensitivity curves in Fourier space
real3 EvalSensitivity(real opd, real shift)
{
// Use Gaussian fits, given by 3 parameters: val, pos and var
real phase = 2.0 * PI * opd * 1e-6;
real3 val = real3(5.4856e-13, 4.4201e-13, 5.2481e-13);
real3 pos = real3(1.6810e+06, 1.7953e+06, 2.2084e+06);
real3 var = real3(4.3278e+09, 9.3046e+09, 6.6121e+09);
real3 xyz = val * sqrt(2.0 * PI * var) * cos(pos * phase + shift) * exp(-var * phase * phase);
xyz.x += 9.7470e-14 * sqrt(2.0 * PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift) * exp(-4.5282e+09 * phase * phase);
return xyz / 1.0685e-7;
}
// Evaluate the reflectance for a thin-film layer on top of a dielectric medum.
real3 EvalIridescence(real eta_1, real cosTheta1, real iridescenceThickness, real baseLayerFresnel0)
{
// iridescenceThickness unit is micrometer for this equation here. Mean 0.5 is 500nm.
real Dinc = 3.0 * iridescenceThickness;
// Note: Unlike the code provide with the paper, here we use schlick approximation
// Schlick is a very poor approximation when dealing with iridescence to the Fresnel
// term and there is no "neutral" value in this unlike in the original paper.
// We use Iridescence mask here to allow to have neutral value
// Hack: In order to use only one parameter (DInc), we deduced the ior of iridescence from current Dinc iridescenceThickness
// and we use mask instead to fade out the effect
real eta_2 = lerp(2.0, 1.0, iridescenceThickness);
// Following line from original code is not needed for us, it create a discontinuity
// 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)));
// First interface
real R0 = IorToFresnel0(eta_2, eta_1);
real R12 = F_Schlick(R0, cosTheta1);
real R21 = R12;
real T121 = 1.0 - R12;
real phi12 = 0.0;
real phi21 = PI - phi12;
// Second interface
real3 R23 = F_Schlick(baseLayerFresnel0, cosTheta2);
real phi23 = 0.0;
// Phase shift
real OPD = Dinc * cosTheta2;
real phi = phi21 + phi23;
// Compound terms
real3 R123 = R12 * R23;
real3 r123 = sqrt(R123);
real3 Rs = Sq(T121) * R23 / (real3(1.0, 1.0, 1.0) - R123);
// Reflectance term for m = 0 (DC term amplitude)
real3 C0 = R12 + Rs;
real3 I = C0;
// Reflectance term for m > 0 (pairs of diracs)
real3 Cm = Rs - T121;
for (int m = 1; m <= 2; ++m)
{
Cm *= r123;
real3 Sm = 2.0 * EvalSensitivity(m * OPD, m * phi);
//vec3 SmP = 2.0 * evalSensitivity(m*OPD, m*phi2.y);
I += Cm * Sm;
}
// Convert back to RGB reflectance
//I = clamp(mul(I, XYZ_TO_RGB), real3(0.0, 0.0, 0.0), real3(1.0, 1.0, 1.0));
//I = mul(XYZ_TO_RGB, I);
return I;
}
#endif // UNITY_BSDF_INCLUDED

28
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/CommonMaterial.hlsl


return sqrt(2.0 / (variance + 2.0));
}
// ior is a value between 1.0 and 2.5
// Assume air interface for top
real IorToFresnel0(real ior)
{
return Sq((ior - 1.0) / (ior + 1.0));
}
real IorToFresnel0(real baseIor, real topIor)
{
return Sq((baseIor - topIor) / (baseIor + topIor));
}
// Assume air interface for top
// Note: Don't handle the case fresnel0 == 1
real Fresnel0ToIor(real fresnel0)
{
real sqrtF0 = sqrt(fresnel0);
return (1.0 + sqrtF0) / (1.0 - sqrtF0);
}
// This function is a coarse approximation of computing fresnel0 for a different top than air (here clear coat of IOR 1.5) when we only have fresnel0 with air interface
// This function is equivalent to IorToFresnel0(Fresnel0ToIor(fresnel0), 1.5)
// mean
// real sqrtF0 = sqrt(fresnel0);
// return Sq(1.0 - 5.0 * sqrtF0) / Sq(5.0 - sqrtF0);
// Optimization: Fit of the function (3 mad) for range [0.04 (should return 0), 1 (should return 1)]
TEMPLATE_1_REAL(ConvertF0ForAirInterfaceToF0ForClearCoat15, fresnel0, return saturate(-0.0256868 + fresnel0 * (0.326846 + (0.978946 - 0.283835 * fresnel0) * fresnel0)) )
// same as regular refract except there is not the test for total internal reflection + the vector is flipped for processing
real3 CoatRefract(real3 X, real3 N, real ieta)
{

38
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/LitUI.cs


// Iridescence
public static GUIContent iridescenceMaskText = new GUIContent("Iridescence Mask", "Control intensity of the iridescence");
public static GUIContent thicknessIridescenceText = new GUIContent("Iridescence Thickness");
public static GUIContent thicknessMapIridescenceText = new GUIContent("Iridescence Thickness map");
public static GUIContent thicknessRemapIridescenceText = new GUIContent("Iridescence Thickness remap");
public static GUIContent iridescenceThicknessText = new GUIContent("Iridescence Thickness");
public static GUIContent iridescenceThicknessMapText = new GUIContent("Iridescence Thickness map");
public static GUIContent iridescenceThicknessRemapText = new GUIContent("Iridescence Thickness remap");
// Clear Coat
public static GUIContent coatMaskText = new GUIContent("Coat Mask", "Attenuate the coating effect (similar to change to IOR of 1");

protected const string kIridescenceMask = "_IridescenceMask";
protected MaterialProperty iridescenceMaskMap = null;
protected const string kIridescenceMaskMap = "_IridescenceMaskMap";
protected MaterialProperty thicknessIridescence = null;
protected const string kThicknessIridescence = "_ThicknessIridescence";
protected MaterialProperty thicknessMapIridescence = null;
protected const string kThicknessMapIridescence = "_ThicknessMapIridescence";
protected MaterialProperty thicknessRemapIridescence = null;
protected const string kThicknessRemapIridescence = "_ThicknessRemapIridescence";
protected MaterialProperty iridescenceThickness = null;
protected const string kIridescenceThickness = "_IridescenceThickness";
protected MaterialProperty iridescenceThicknessMap = null;
protected const string kIridescenceThicknessMap = "_IridescenceThicknessMap";
protected MaterialProperty iridescenceThicknessRemap = null;
protected const string kIridescenceThicknessRemap = "_IridescenceThicknessRemap";
protected MaterialProperty coatMask = null;
protected const string kCoatMask = "_CoatMask";

// Iridescence
iridescenceMask = FindProperty(kIridescenceMask, props);
iridescenceMaskMap = FindProperty(kIridescenceMaskMap, props);
thicknessIridescence = FindProperty(kThicknessIridescence, props);
thicknessMapIridescence = FindProperty(kThicknessMapIridescence, props);
thicknessRemapIridescence = FindProperty(kThicknessRemapIridescence, props);
iridescenceThickness = FindProperty(kIridescenceThickness, props);
iridescenceThicknessMap = FindProperty(kIridescenceThicknessMap, props);
iridescenceThicknessRemap = FindProperty(kIridescenceThicknessRemap, props);
// clear coat
coatMask = FindProperty(kCoatMask, props);

{
m_MaterialEditor.TexturePropertySingleLine(Styles.iridescenceMaskText, iridescenceMaskMap, iridescenceMask);
m_MaterialEditor.TexturePropertySingleLine(Styles.thicknessMapIridescenceText, thicknessMapIridescence);
if (thicknessMapIridescence.textureValue != null)
m_MaterialEditor.TexturePropertySingleLine(Styles.iridescenceThicknessMapText, iridescenceThicknessMap);
if (iridescenceThicknessMap.textureValue != null)
Vector2 remap = thicknessRemapIridescence.vectorValue;
Vector2 remap = iridescenceThicknessRemap.vectorValue;
EditorGUILayout.MinMaxSlider(Styles.thicknessRemapIridescenceText, ref remap.x, ref remap.y, 0.0f, 1.0f);
EditorGUILayout.MinMaxSlider(Styles.iridescenceThicknessRemapText, ref remap.x, ref remap.y, 0.0f, 1.0f);
thicknessRemapIridescence.vectorValue = remap;
iridescenceThicknessRemap.vectorValue = remap;
m_MaterialEditor.ShaderProperty(thicknessIridescence, Styles.thicknessIridescenceText);
m_MaterialEditor.ShaderProperty(iridescenceThickness, Styles.iridescenceThicknessText);
}
}

CoreUtils.SetKeyword(material, "_DETAIL_MAP", material.GetTexture(kDetailMap));
CoreUtils.SetKeyword(material, "_SUBSURFACE_MASK_MAP", material.GetTexture(kSubsurfaceMaskMap));
CoreUtils.SetKeyword(material, "_THICKNESSMAP", material.GetTexture(kThicknessMap));
CoreUtils.SetKeyword(material, "_THICKNESSMAP_IRIDESCENCE", material.GetTexture(kThicknessMapIridescence));
CoreUtils.SetKeyword(material, "_IRIDESCENCE_THICKNESSMAP", material.GetTexture(kIridescenceThickness));
CoreUtils.SetKeyword(material, "_SPECULARCOLORMAP", material.GetTexture(kSpecularColorMap));
bool needUV2 = (UVDetailMapping)material.GetFloat(kUVDetail) == UVDetailMapping.UV2 || (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV2;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl


surfaceData.anisotropy = 0.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
surfaceData.coatMask = 0.0;
surfaceData.thicknessIridescence = 0.0;
surfaceData.iridescenceThickness = 0.0;
surfaceData.iridescenceMask = 0.0;
// Transparency parameters

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs


public float anisotropy; // anisotropic ratio(0->no isotropic; 1->full anisotropy in tangent direction, -1->full anisotropy in bitangent direction)
// Iridescence
[SurfaceDataAttributes("Thickness of Iridescence")]
public float thicknessIridescence;
[SurfaceDataAttributes("Iridescence Thickness")]
public float iridescenceThickness;
[SurfaceDataAttributes("Iridescence Mask")]
public float iridescenceMask;

public float anisotropy;
// Iridescence
public float thicknessIridescence;
public float iridescenceThickness;
public float iridescenceMask;
// ClearCoat

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl


#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS (1012)
#define DEBUGVIEW_LIT_SURFACEDATA_TANGENT (1013)
#define DEBUGVIEW_LIT_SURFACEDATA_ANISOTROPY (1014)
#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS_OF_IRIDESCENCE (1015)
#define DEBUGVIEW_LIT_SURFACEDATA_IRIDESCENCE_THICKNESS (1015)
#define DEBUGVIEW_LIT_SURFACEDATA_IRIDESCENCE_MASK (1016)
#define DEBUGVIEW_LIT_SURFACEDATA_INDEX_OF_REFRACTION (1017)
#define DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_COLOR (1018)

#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_T (1045)
#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_B (1046)
#define DEBUGVIEW_LIT_BSDFDATA_ANISOTROPY (1047)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS_IRIDESCENCE (1048)
#define DEBUGVIEW_LIT_BSDFDATA_IRIDESCENCE_THICKNESS (1048)
#define DEBUGVIEW_LIT_BSDFDATA_IRIDESCENCE_MASK (1049)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_ROUGHNESS (1050)
#define DEBUGVIEW_LIT_BSDFDATA_IOR (1051)

float thickness;
float3 tangentWS;
float anisotropy;
float thicknessIridescence;
float iridescenceThickness;
float iridescenceMask;
float ior;
float3 transmittanceColor;

float roughnessT;
float roughnessB;
float anisotropy;
float thicknessIridescence;
float iridescenceThickness;
float iridescenceMask;
float coatRoughness;
float ior;

case DEBUGVIEW_LIT_SURFACEDATA_ANISOTROPY:
result = surfacedata.anisotropy.xxx;
break;
case DEBUGVIEW_LIT_SURFACEDATA_THICKNESS_OF_IRIDESCENCE:
result = surfacedata.thicknessIridescence.xxx;
case DEBUGVIEW_LIT_SURFACEDATA_IRIDESCENCE_THICKNESS:
result = surfacedata.iridescenceThickness.xxx;
break;
case DEBUGVIEW_LIT_SURFACEDATA_IRIDESCENCE_MASK:
result = surfacedata.iridescenceMask.xxx;

case DEBUGVIEW_LIT_BSDFDATA_ANISOTROPY:
result = bsdfdata.anisotropy.xxx;
break;
case DEBUGVIEW_LIT_BSDFDATA_THICKNESS_IRIDESCENCE:
result = bsdfdata.thicknessIridescence.xxx;
case DEBUGVIEW_LIT_BSDFDATA_IRIDESCENCE_THICKNESS:
result = bsdfdata.iridescenceThickness.xxx;
break;
case DEBUGVIEW_LIT_BSDFDATA_IRIDESCENCE_MASK:
result = bsdfdata.iridescenceMask.xxx;

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


// Helper functions/variable specific to this material
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Iridescence
//-----------------------------------------------------------------------------
// Ref: https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html
// Evaluation XYZ sensitivity curves in Fourier space
float3 EvalSensitivity(float opd, float shift)
{
// Use Gaussian fits, given by 3 parameters: val, pos and var
float phase = 2.0 * PI * opd * 1e-6;
float3 val = float3(5.4856e-13, 4.4201e-13, 5.2481e-13);
float3 pos = float3(1.6810e+06, 1.7953e+06, 2.2084e+06);
float3 var = float3(4.3278e+09, 9.3046e+09, 6.6121e+09);
float3 xyz = val * sqrt(2.0 * PI * var) * cos(pos * phase + shift) * exp(-var * phase * phase);
xyz.x += 9.7470e-14 * sqrt(2.0 * PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift) * exp(-4.5282e+09 * phase * phase);
return xyz / 1.0685e-7;
}
// Evaluate the reflectance for a thin-film layer on top of a dielectric medum.
float3 EvalIridescence(float eta_1, float cosTheta1, BSDFData bsdfData)
{
// thicknessIridescence unit is micrometer for this equation here. Mean 0.5 is 500nm.
float Dinc = 3.0 * bsdfData.thicknessIridescence;
// Note: Unlike the code provide with the paper, here we use schlick approximation
// Schlick is a very poor approximation when dealing with iridescence to the Fresnel
// term and there is no "neutral" value in this unlike in the original paper.
// We use Iridescence mask here to allow to have neutral value
// Hack: In order to use only one parameter (DInc), we deduced the ior of iridescence from current Dinc thicknessIridescence
// and we use mask instead to fade out the effect
float eta_2 = lerp(2.0, 1.0, bsdfData.thicknessIridescence);
// Following line from original code is not needed for us, it create a discontinuity
// Force eta_2 -> eta_1 when Dinc -> 0.0
// float eta_2 = lerp(eta_1, eta_2, smoothstep(0.0, 0.03, Dinc));
// Evaluate the cosTheta on the base layer (Snell law)
float cosTheta2 = sqrt(1.0 - Sq(eta_1 / eta_2) * (1.0 - Sq(cosTheta1)));
// First interface
float R0 = IorToFresnel0(eta_2, eta_1);
float R12 = F_Schlick(R0, cosTheta1);
float R21 = R12;
float T121 = 1.0 - R12;
float phi12 = 0.0;
float phi21 = PI - phi12;
// Second interface
float3 R23 = F_Schlick(bsdfData.fresnel0, cosTheta2);
float phi23 = 0.0;
// Phase shift
float OPD = Dinc * cosTheta2;
float phi = phi21 + phi23;
// Compound terms
float3 R123 = R12 * R23;
float3 r123 = sqrt(R123);
float3 Rs = Sq(T121) * R23 / (float3(1.0, 1.0, 1.0) - R123);
// Reflectance term for m = 0 (DC term amplitude)
float3 C0 = R12 + Rs;
float3 I = C0;
// Reflectance term for m > 0 (pairs of diracs)
float3 Cm = Rs - T121;
for (int m = 1; m <= 2; ++m)
{
Cm *= r123;
float3 Sm = 2.0 * EvalSensitivity(m * OPD, m * phi);
//vec3 SmP = 2.0 * evalSensitivity(m*OPD, m*phi2.y);
I += Cm * Sm;
}
// Convert back to RGB reflectance
//I = clamp(mul(I, XYZ_TO_RGB), float3(0.0, 0.0, 0.0), float3(1.0, 1.0, 1.0));
//I = mul(XYZ_TO_RGB, I);
return I;
}
#if HAS_REFRACTION
# include "CoreRP/ShaderLibrary/Refraction.hlsl"

void FillMaterialIridescence(float mask, float thickness, inout BSDFData bsdfData)
{
bsdfData.iridescenceMask = mask;
bsdfData.thicknessIridescence = thickness;
bsdfData.iridescenceThickness = thickness;
}
// Note: this modify the parameter perceptualRoughness and fresnel0, so they need to be setup

bsdfData.thickness = max(thickness, 0.0001);
}
// Remap IOR in range 1..2.5 to 0..1
float RemapIor25to01(float ior)
{
return saturate((ior - 1.0) / 1.5);
}
float RemapIor01to25(float ior)
{
return ior * 1.5 + 1.0;
}
// For image based lighting, a part of the BSDF is pre-integrated.
// This is done both for specular and diffuse (in case of DisneyDiffuse)
void GetPreIntegratedFGD(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 specularFGD, out float diffuseFGD, out float reflectivity)

if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
{
FillMaterialIridescence(surfaceData.iridescenceMask, surfaceData.thicknessIridescence, bsdfData);
FillMaterialIridescence(surfaceData.iridescenceMask, surfaceData.iridescenceThickness, bsdfData);
}
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))

{
materialFeatureId = GBUFFER_LIT_IRIDESCENCE;
outGBuffer2.rgb = float3(surfaceData.iridescenceMask, surfaceData.thicknessIridescence,
outGBuffer2.rgb = float3(surfaceData.iridescenceMask, surfaceData.iridescenceThickness,
PackFloatInt8bit(surfaceData.metallic, 0, 8));
}
else // Standard

result = (surfaceData.materialFeatures.xxx) / 255.0; // Aloow to read with color picker debug mode
break;
case DEBUGVIEW_LIT_SURFACEDATA_INDEX_OF_REFRACTION:
result = RemapIor25to01(surfaceData.ior).xxx;
result = saturate((surfaceData.ior - 1.0) / 1.5).xxx;
break;
}
}

result = (bsdfData.materialFeatures.xxx) / 255.0; // Aloow to read with color picker debug mode
break;
case DEBUGVIEW_LIT_BSDFDATA_IOR:
result = RemapIor25to01(bsdfData.ior).xxx;
result = saturate((bsdfData.ior - 1.0) / 1.5).xxx;
break;
}
}

if (bsdfData.iridescenceMask > 0.0)
{
bsdfData.fresnel0 = lerp(bsdfData.fresnel0, EvalIridescence(topIor, viewAngle, bsdfData), bsdfData.iridescenceMask);
bsdfData.fresnel0 = lerp(bsdfData.fresnel0, EvalIridescence(topIor, viewAngle, bsdfData.iridescenceThickness, bsdfData.fresnel0), bsdfData.iridescenceMask);
}
}

float NdotV = ClampNdotV(preLightData.NdotV);
float3 F = F_Schlick(bsdfData.fresnel0, LdotH);
// Note: Here we are suppose to call EvalIridescence with LdotH
// This is to expensive for our need, so instead we use the NdotV
// Moreover, the bsdfData.fresnel0 here already contain the evaluation of F_Schlick
// in the context of iridescence, so if iridescence is enabled, don't apply schlick a second time
// Remark: Fresnel must be use with LdotH angle. But Fresnel for iridescence is expensive to compute at each light.
// 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))
{
F = lerp(F, bsdfData.fresnel0, bsdfData.iridescenceMask);

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.shader


_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessIridescence("Thickness sridescence", Range(0.0, 1.0)) = 1.0
_ThicknessMapIridescence("Thickness Map Iridescence", 2D) = "white" {}
_ThicknessRemapIridescence("Thickness Remap Iridescence", Vector) = (0, 1, 0, 0)
_IridescenceThickness("Thickness sridescence", Range(0.0, 1.0)) = 1.0
_IridescenceThicknessMap("Iridescence Thickness Map", 2D) = "white" {}
_IridescenceThicknessRemap("Iridescence Thickness Remap", Vector) = (0, 1, 0, 0)
_IridescenceMask("Iridescence Mask", Range(0.0, 1.0)) = 1.0
_IridescenceMaskMap("Iridescence Mask Map", 2D) = "white" {}

// Transparency
[Enum(None, 0, Plane, 1, Sphere, 2)]_RefractionMode("Refraction Mode", Int) = 0
_Ior("Indice Of Refraction", Range(1.0, 2.5)) = 1.0
_Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)
_TransmittanceColorMap("TransmittanceColorMap", 2D) = "white" {}

#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _SUBSURFACE_MASK_MAP
#pragma shader_feature _THICKNESSMAP
#pragma shader_feature _THICKNESSMAP_IRIDESCENCE
#pragma shader_feature _IRIDESCENCE_THICKNESSMAP
#pragma shader_feature _SPECULARCOLORMAP
#pragma shader_feature _TRANSMITTANCECOLORMAP

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataIndividualLayer.hlsl


#endif
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
#ifdef _THICKNESSMAP_IRIDESCENCE
surfaceData.thicknessIridescence = SAMPLE_UVMAPPING_TEXTURE2D(_ThicknessMapIridescence, sampler_ThicknessMapIridescence, layerTexCoord.base).r;
surfaceData.thicknessIridescence = _ThicknessRemapIridescence.x + _ThicknessRemapIridescence.y * surfaceData.thicknessIridescence;
#ifdef _IRIDESCENCE_THICKNESSMAP
surfaceData.iridescenceThickness = SAMPLE_UVMAPPING_TEXTURE2D(_IridescenceThicknessMap, sampler_IridescenceThicknessMap, layerTexCoord.base).r;
surfaceData.iridescenceThickness = _IridescenceThicknessRemap.x + _IridescenceThicknessRemap.y * surfaceData.iridescenceThickness;
surfaceData.thicknessIridescence = _ThicknessIridescence;
surfaceData.iridescenceThickness = _IridescenceThickness;
surfaceData.thicknessIridescence = 0.0;
surfaceData.iridescenceThickness = 0.0;
surfaceData.iridescenceMask = 0.0;
#endif

surfaceData.tangentWS = float3(0.0, 0.0, 0.0);
surfaceData.anisotropy = 0.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
surfaceData.thicknessIridescence = 0.0;
surfaceData.iridescenceThickness = 0.0;
surfaceData.iridescenceMask = 0.0;
surfaceData.coatMask = 0.0;

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


TEXTURE2D(_ThicknessMap);
SAMPLER(sampler_ThicknessMap);
TEXTURE2D(_ThicknessMapIridescence);
SAMPLER(sampler_ThicknessMapIridescence);
TEXTURE2D(_IridescenceThicknessMap);
SAMPLER(sampler_IridescenceThicknessMap);
TEXTURE2D(_IridescenceMaskMap);
SAMPLER(sampler_IridescenceMaskMap);

float4 _ThicknessRemap;
float _ThicknessIridescence;
float4 _ThicknessRemapIridescence;
float _IridescenceThickness;
float4 _IridescenceThicknessRemap;
float _IridescenceMask;
float _CoatMask;

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitTessellation.shader


_ThicknessMap("Thickness Map", 2D) = "white" {}
_ThicknessRemap("Thickness Remap", Vector) = (0, 1, 0, 0)
_ThicknessIridescence("Thickness sridescence", Range(0.0, 1.0)) = 1.0
_ThicknessMapIridescence("Thickness Map Iridescence", 2D) = "white" {}
_ThicknessRemapIridescence("Thickness Remap Iridescence", Vector) = (0, 1, 0, 0)
_IridescenceThickness("Thickness sridescence", Range(0.0, 1.0)) = 1.0
_IridescenceThicknessMap("Iridescence Thickness Map", 2D) = "white" {}
_IridescenceThicknessRemap("Iridescence Thickness Remap", Vector) = (0, 1, 0, 0)
_CoatMask("Coat Mask", Range(0.0, 1.0)) = 0.0
_CoatMaskMap("CoatMaskMap", 2D) = "white" {}

// Transparency
[Enum(None, 0, Plane, 1, Sphere, 2)]_RefractionMode("Refraction Mode", Int) = 0
_Ior("Indice Of Refraction", Range(1.0, 2.5)) = 1.0
_Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)
_TransmittanceColorMap("TransmittanceColorMap", 2D) = "white" {}

#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _SUBSURFACE_MASK_MAP
#pragma shader_feature _THICKNESSMAP
#pragma shader_feature _THICKNESSMAP_IRIDESCENCE
#pragma shader_feature _IRIDESCENCE_THICKNESSMAP
#pragma shader_feature _SPECULARCOLORMAP
#pragma shader_feature _TRANSMITTANCECOLORMAP

正在加载...
取消
保存