浏览代码

Merge pull request #1409 from Unity-Technologies/StackLit2

Add proper specularAA to stacklit
/main
GitHub 6 年前
当前提交
bdf1aae0
共有 8 个文件被更改,包括 91 次插入120 次删除
  1. 56
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/CommonMaterial.hlsl
  2. 25
      com.unity.render-pipelines.high-definition/HDRP/Editor/Material/StackLit/StackLitUI.cs
  3. 6
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs
  4. 38
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs.hlsl
  5. 60
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
  6. 10
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.shader
  7. 12
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitData.hlsl
  8. 4
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitProperties.hlsl

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


return sqrt(2.0 / (variance + 2.0));
}
float FilterPerceptualSmoothness(float perceptualSmoothness, float variance, float threshold)
{
float roughness = PerceptualSmoothnessToRoughness(perceptualSmoothness);
float squaredRoughness = saturate(roughness * roughness + min(2.0 * variance, threshold * threshold)); // threshold can be really low, square the value for easier control
return 1.0 - RoughnessToPerceptualRoughness(sqrt(squaredRoughness));
}
// take perceptualSmoothness and return modified perceptualSmoothness
float GeometricFilterPerceptualSmoothness(float perceptualSmoothness, float3 geometricNormalWS, float screenSpaceVariance, float threshold)
// Specular antialiasing for geometry-induced normal (and NDF) variations: Tokuyoshi / Kaplanyan et al.'s method.
// This is the deferred approximation, which works reasonably well so we keep it for forward too for now.
// screenSpaceVariance should be at most 0.5^2 = 0.25, as that corresponds to considering
// a gaussian pixel reconstruction kernel with a standard deviation of 0.5 of a pixel, thus 2 sigma covering the whole pixel.
float GeometricFilterVariance(float3 geometricNormalWS, float screenSpaceVariance)
float variance = screenSpaceVariance * (dot(deltaU, deltaU) + dot(deltaV, deltaV));
return screenSpaceVariance * (dot(deltaU, deltaU) + dot(deltaV, deltaV));
}
float roughness = PerceptualSmoothnessToRoughness(perceptualSmoothness);
float squaredRoughness = saturate(roughness * roughness + min(2.0 * variance, threshold * threshold)); // threshold can be really low, square the value for easier control
float GeometricFilterPerceptualSmoothness(float perceptualSmoothness, float3 geometricNormalWS, float screenSpaceVariance, float threshold)
{
float variance = GeometricFilterVariance(geometricNormalWS, screenSpaceVariance);
return FilterPerceptualSmoothness(perceptualSmoothness, variance, threshold);
}
return 1.0 - RoughnessToPerceptualRoughness(sqrt(squaredRoughness));
// Normal map filtering based on The Order : 1886 SIGGRAPH course notes implementation.
// Basically Toksvig with an intermediate single vMF lobe induced dispersion (Han et al. 2007)
//
// This returns 2 times the variance of the induced "mesoNDF" lobe (an NDF induced from a section of
// the normal map) from the level 0 mip normals covered by the "current texel".
//
// 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
// risk underfiltering. Could also compute average normal on the fly with a proper normal map format,
// like Toksvig.
float TextureFilteringVariance(float avgNormalLength)
{
if (avgNormalLength < 1.0)
{
float avgNormLen2 = avgNormalLength * avgNormalLength;
float kappa = (3.0 * avgNormalLength - avgNormalLength * avgNormLen2) / (1.0 - avgNormLen2);
// Relationship between gaussian lobe and vMF lobe is 2 * variance = 1 / (2 * kappa) = roughness^2
// so to get variance we must use variance = 1 / (4 * kappa)
return 0.25 * kappa;
}
return 0.0f;
}
float TextureFilterPerceptualSmoothness(float perceptualSmoothness, float avgNormalLength, float threshold)
{
float variance = TextureFilteringVariance(avgNormalLength);
return FilterPerceptualSmoothness(perceptualSmoothness, variance, threshold);
}
// ----------------------------------------------------------------------------

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


protected const string kStencilWriteMaskMV = "_StencilWriteMaskMV";
protected const string k_SpecularAntiAliasingEnabled = "_SpecularAntiAliasingEnabled";
protected const string k_NormalCurvatureToRoughnessEnabled = "_NormalCurvatureToRoughnessEnabled";
#endregion

private Property EnableIridescence;
private Property EnableSpecularAA;
private Property EnableNormalCurvatureToRoughness;
public StackLitGUI()
{

EnableDualSpecularLobe = new Property(this, k_EnableDualSpecularLobe, "Enable Dual Specular Lobe", "Enable a second specular lobe, aim to simulate a mix of a narrow and a haze lobe that better match measured material", true);
EnableIridescence = new Property(this, k_EnableIridescence, "Enable Iridescence", "Enable physically based iridescence layer", true);
EnableSpecularAA = new Property(this, k_SpecularAntiAliasingEnabled, k_SpecularAntiAliasingEnabled, k_SpecularAntiAliasingEnabled, true);
EnableNormalCurvatureToRoughness = new Property(this, k_NormalCurvatureToRoughnessEnabled, k_NormalCurvatureToRoughnessEnabled, k_NormalCurvatureToRoughnessEnabled, true);
EnableSpecularAA = new Property(this, k_SpecularAntiAliasingEnabled, "Enable SpecularAA", "Enable specular antialiasing", true);
// All GroupPropery below need to define a
// [HideInInspector] _XXXShow("_XXXShow", Float) = 0.0 parameter in the StackLit.shader to work
_materialProperties = new GroupProperty(this, "_Material", new BaseProperty[]
{
new GroupProperty(this, "_MaterialFeatures", "Material Features", new BaseProperty[]

new Property(this, k_AlbedoAffectEmissive, "Albedo Affect Emissive", "Specifies whether or not the emissive color is multiplied by the albedo.", false),
}),
new GroupProperty(this, "_SpecularAntiAliasing", "SpecularAntiAliasing", new BaseProperty[]
{
EnableSpecularAA,
new Property(this, "_SpecularAntiAliasingScreenSpaceVariance", "Screen Space Variance", "Screen Space Variance (should be less than 0.25)", false, _ => EnableSpecularAA.BoolValue == true),
new Property(this, "_SpecularAntiAliasingThreshold", "Threshold", "Threshold", false, _ => EnableSpecularAA.BoolValue == true),
}),
new GroupProperty(this, "_Debug", "Debug", new BaseProperty[]
{
new Property(this, "_VlayerRecomputePerLight", "Vlayer Recompute Per Light", "", 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),
EnableSpecularAA,
new Property(this, "_SpecularAntiAliasingScreenSpaceVariance", "Specular Aliasing Enable", "Specular Aliasing Enable", false, _ => EnableSpecularAA.BoolValue == true),
new Property(this, "_SpecularAntiAliasingThreshold", "Specular Aliasing Enable", "Specular Aliasing Enable", false, _ => EnableSpecularAA.BoolValue == true),
EnableNormalCurvatureToRoughness,
new Property(this, "_NormalCurvatureToRoughnessScale", "Normal Curvature To Roughness Scale", "Normal Curvature To Roughness Scale", false, _ => EnableNormalCurvatureToRoughness.BoolValue == true),
new Property(this, "_NormalCurvatureToRoughnessBias", "Normal Curvature To Roughness Bias", "Normal Curvature To Roughness Bias", false, _ => EnableNormalCurvatureToRoughness.BoolValue == true),
new Property(this, "_NormalCurvatureToRoughnessExponent", "Normal Curvature To Roughness Exponent", "Normal Curvature To Roughness Exponent", false, _ => EnableNormalCurvatureToRoughness.BoolValue == true),
}),
}),
});
}

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("Average Normal Length A")]
public float averageNormalLengthA;
[SurfaceDataAttributes("Average Normal Length B")]
public float averageNormalLengthB;
[SurfaceDataAttributes("Smoothness A")]
public float perceptualSmoothnessA;

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


#define DEBUGVIEW_STACKLIT_SURFACEDATA_GEOMETRIC_NORMAL_VIEW_SPACE (1308)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL (1309)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL_VIEW_SPACE (1310)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_AVERAGE_NORMAL_LENGTH_A (1311)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_AVERAGE_NORMAL_LENGTH_B (1312)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A (1313)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_B (1314)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_LOBE_MIXING (1315)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_TANGENT (1316)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY (1317)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_IOR (1318)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS (1319)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_SMOOTHNESS (1320)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR (1321)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS (1322)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT (1323)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_DIFFUSION_PROFILE (1324)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SUBSURFACE_MASK (1325)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_THICKNESS (1326)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A (1311)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_B (1312)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_LOBE_MIXING (1313)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_TANGENT (1314)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY (1315)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_IOR (1316)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_IRIDESCENCE_THICKNESS (1317)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_SMOOTHNESS (1318)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR (1319)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS (1320)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT (1321)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_DIFFUSION_PROFILE (1322)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SUBSURFACE_MASK (1323)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_THICKNESS (1324)
//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+BSDFData: static fields

float3 normalWS;
float3 geomNormalWS;
float3 coatNormalWS;
float averageNormalLengthA;
float averageNormalLengthB;
float perceptualSmoothnessA;
float perceptualSmoothnessB;
float lobeMix;

break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_NORMAL_VIEW_SPACE:
result = surfacedata.coatNormalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_AVERAGE_NORMAL_LENGTH_A:
result = surfacedata.averageNormalLengthA.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_AVERAGE_NORMAL_LENGTH_B:
result = surfacedata.averageNormalLengthB.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A:
result = surfacedata.perceptualSmoothnessA.xxx;

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


return sssData;
}
// Specular antialiasing
float NormalCurvatureToRoughness(float3 n)
{
float3 dNdx = ddx(n);
float3 dNdy = ddy(n);
float curvature = pow(max(dot(dNdx, dNdx), dot(dNdy, dNdy)), _NormalCurvatureToRoughnessExponent);
return saturate(curvature * _NormalCurvatureToRoughnessScale + _NormalCurvatureToRoughnessBias);
}
float FilterRoughness_TOKUYOSHI(float3 n, float r)
{
float3 deltaU = ddx(n);
float3 deltaV = ddy(n);
float variance = _SpecularAntiAliasingScreenSpaceVariance * (dot(deltaU, deltaU) + dot(deltaV, deltaV));
return variance;
}
// Based on The Order : 1886 SIGGRAPH course notes implementation.
float AdjustRoughness(float avgNormalLength)
{
if (avgNormalLength < 1.0)
{
float avgNormLen2 = avgNormalLength * avgNormalLength;
float kappa = (3 * avgNormalLength - avgNormalLength * avgNormLen2) / (1 - avgNormLen2);
return 1.0 / (2.0 * kappa);
}
return 0.0f;
}
float FilterRoughness(float r, float3 geomNormalWS, float averageNormalLength)
{
// Specular AA: NormalCurvatureToRoughness
r = lerp(r, max(NormalCurvatureToRoughness(geomNormalWS), r), _NormalCurvatureToRoughnessEnabled);
// Specular AA: Tokuyoshi Filtering + 1866 normal filtering.
float varianceGeom = FilterRoughness_TOKUYOSHI(geomNormalWS, r);
float varianceNorm = AdjustRoughness(averageNormalLength);
float filteredRoughness = sqrt(saturate(r * r + min(2.0 * (varianceGeom + varianceNorm), _SpecularAntiAliasingThreshold)));
return lerp(r, filteredRoughness, _SpecularAntiAliasingEnabled);
}
//-----------------------------------------------------------------------------
// conversion function for forward
//-----------------------------------------------------------------------------

bsdfData.perceptualRoughnessA = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothnessA);
bsdfData.perceptualRoughnessB = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothnessB);
// Specular AA / Filtering.
bsdfData.perceptualRoughnessA = FilterRoughness(bsdfData.perceptualRoughnessA, bsdfData.geomNormalWS, surfaceData.averageNormalLengthA);
bsdfData.perceptualRoughnessB = FilterRoughness(bsdfData.perceptualRoughnessB, bsdfData.geomNormalWS, surfaceData.averageNormalLengthB);
bsdfData.lobeMix = surfaceData.lobeMix;
// There is no metallic with SSS and specular color mode

if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT))
{
FillMaterialCoatData(PerceptualSmoothnessToPerceptualRoughness(surfaceData.coatPerceptualSmoothness),
surfaceData.coatIor, surfaceData.coatThickness, surfaceData.coatExtinction, bsdfData);
FillMaterialCoatData(PerceptualSmoothnessToPerceptualRoughness(surfaceData.coatPerceptualSmoothness),
surfaceData.coatIor, surfaceData.coatThickness, surfaceData.coatExtinction, bsdfData);
// vlayering:
// We can't calculate final roughnesses including anisotropy right away in this case: we will either do it

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


[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8
[ToggleUI] _SpecularAntiAliasingEnabled("Specular Anti Aliasing Enabled", Float) = 0.0
_SpecularAntiAliasingScreenSpaceVariance("SpecularAntiAliasingScreenSpaceVariance", Range(0.0, 1.0)) = 1.0
_SpecularAntiAliasingThreshold("SpecularAntiAliasingThreshold", Range(0.0, 1.0)) = 0.18
[ToggleUI] _NormalCurvatureToRoughnessEnabled("_NormalCurvatureToRoughnessEnabled", Float) = 0.0
_NormalCurvatureToRoughnessScale("_NormalCurvatureToRoughnessScale", Range(0.0, 2.0)) = 1.0
_NormalCurvatureToRoughnessBias("_NormalCurvatureToRoughnessBias", Range(-1.0, 1.0)) = 0.0
_NormalCurvatureToRoughnessExponent("_NormalCurvatureToRoughnessExponent", Range(0.05, 20.0)) = 0.333
_SpecularAntiAliasingScreenSpaceVariance("SpecularAntiAliasingScreenSpaceVariance", Range(0.0, 1.0)) = 0.1
_SpecularAntiAliasingThreshold("SpecularAntiAliasingThreshold", Range(0.0, 1.0)) = 0.2
[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleUI] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0

[HideInInspector] _AnisotropyShow("_AnisotropyShow", Float) = 0.0
[HideInInspector] _TransmissionShow("_TransmissionShow", Float) = 0.0
[HideInInspector] _IridescenceShow("_IridescenceShow", Float) = 0.0
[HideInInspector] _SpecularAntiAliasingShow("_SpecularAntiAliasingShow", Float) = 0.0
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.

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


surfaceData.normalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], gradient.xyz);
surfaceData.coatNormalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], coatGradient.xyz);
surfaceData.averageNormalLengthA = gradient.w;
surfaceData.averageNormalLengthB = coatGradient.w;
if (_SpecularAntiAliasingEnabled > 0.0)
{
float geometricVariance = GeometricFilterVariance(input.worldToTangent[2], _SpecularAntiAliasingScreenSpaceVariance);
float textureFilteringVariance = TextureFilteringVariance(gradient.w);
float coatTextureFilteringVariance = TextureFilteringVariance(coatGradient.w);
surfaceData.perceptualSmoothnessA = FilterPerceptualSmoothness(surfaceData.perceptualSmoothnessA, geometricVariance + textureFilteringVariance, _SpecularAntiAliasingThreshold);
surfaceData.perceptualSmoothnessB = FilterPerceptualSmoothness(surfaceData.perceptualSmoothnessB, geometricVariance + textureFilteringVariance, _SpecularAntiAliasingThreshold);
surfaceData.coatPerceptualSmoothness = FilterPerceptualSmoothness(surfaceData.coatPerceptualSmoothness, geometricVariance + coatTextureFilteringVariance, _SpecularAntiAliasingThreshold);
}
// TODO: decal etc.

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


float _SpecularAntiAliasingEnabled;
float _SpecularAntiAliasingScreenSpaceVariance;
float _SpecularAntiAliasingThreshold;
float _NormalCurvatureToRoughnessEnabled;
float _NormalCurvatureToRoughnessScale;
float _NormalCurvatureToRoughnessBias;
float _NormalCurvatureToRoughnessExponent;
float _AlphaCutoff;
float4 _DoubleSidedConstants;

正在加载...
取消
保存