浏览代码

Update specularAA handling in stacklit

/main
Sebastien Lagarde 6 年前
当前提交
2871eb29
共有 5 个文件被更改,包括 74 次插入95 次删除
  1. 56
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/CommonMaterial.hlsl
  2. 6
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs
  3. 38
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.cs.hlsl
  4. 60
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
  5. 9
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLitData.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);
}
// ----------------------------------------------------------------------------

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

9
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;
float geometricVariance = GeometricFilterVariance(input.worldToTangent[2], _SpecularAntiAliasingScreenSpaceVariance);
float textureFilteringVariance = TextureFilteringVariance(gradient.w);
float coatTextureFilteringVariance = TextureFilteringVariance(coatGradient.w);
FilterPerceptualSmoothness(surfaceData.perceptualSmoothnessA, geometricVariance + textureFilteringVariance, _SpecularAntiAliasingThreshold);
FilterPerceptualSmoothness(surfaceData.perceptualSmoothnessB, geometricVariance + textureFilteringVariance, _SpecularAntiAliasingThreshold);
FilterPerceptualSmoothness(surfaceData.coatPerceptualSmoothness, geometricVariance + coatTextureFilteringVariance, _SpecularAntiAliasingThreshold);
// TODO: decal etc.

正在加载...
取消
保存