Search Unity

Geometric Specular AA

Discussion in 'Shaders' started by Avol, Jan 25, 2018.

  1. Avol

    Avol

    Joined:
    May 27, 2016
    Posts:
    95
    Hallo, I've been implementing a geometric specular aa as described in some Valve's doc and somewhere on unity forums:
    Code (CSharp):
    1.  
    2. inline half4 LightingStandardDefaultGI(SurfaceOutputStandard s, half3 viewDir, UnityGI gi)
    3.         {
    4.             float3 ddxN = ddx(s.Normal.xyz);
    5.             float3 ddyN = ddy(s.Normal.xyz);
    6.  
    7.             float geoRoughness = pow(saturate(max(dot(ddxN.xyz, ddxN.xyz), dot(ddyN.xyz, ddyN.xyz))), 0.333);
    8.             s.Smoothness = min(s.Smoothness, 1.0f - geoRoughness);
    9.  
    10.             return LightingStandard(s, viewDir, gi);
    11.         }
    And I've noticed a blocky artifact that it produces as seen in the attachment. This happens when I reach a smoothness of 0.9 or higher, any possible solutions to solving this problem? Normalizing ddx and ddy values completely removes specular hightlight.
     

    Attached Files:

  2. Avol

    Avol

    Joined:
    May 27, 2016
    Posts:
    95
    changing it to this, removes the blockines, but also increases specular intensity and aliasing, though still reduces on most parts.
    s.Smoothness = min(s.Smoothness, 1.0f - pow(geoRoughness, 2.0f));
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Derivative functions like ddx and ddy are giving you the rate of change of a value between pixels. In the case of derivative of an interpolated vertex variable, the value is linearly interpolated across a polygon, so the rate of change is constant across the entire polygon. You might then expect all polygons on a sphere to have essentially the same derivative, and they do, in object space. But ddx/ddy are in screen space, so as the polygon gets "squished" on screen due to being viewed edge on, the rate of change increases.

    The result is the geometric roughness is blocky, and unfortunately it is working as intended.

    It would be possible to convert the screen space rate of change into world space, which would remove some of the blocky-ness, but it wouldn't be as effective at anti-aliasing, and it would be more expensive to calculate.

    The issue comes down to you are calculating values based off of the actual geometry, the result being you start to see the actual geometry. The solution would be to use a high poly sphere.
     
    olli_vrcoaster likes this.
  4. IgnisIncendio

    IgnisIncendio

    Joined:
    Aug 16, 2017
    Posts:
    223