Search Unity

Writing world space normals in standard surface shader...

Discussion in 'Shaders' started by briank, Feb 3, 2019.

  1. briank

    briank

    Joined:
    Mar 25, 2017
    Posts:
    74
    I'm attempting to use the fragment shader derivative trick to calculate world space normals 'on the fly' to give a flat lighting sort of effect (since the normals from the mesh are smooth).

    Code (CSharp):
    1. // Could also use an object-space position to get an object-space normal...
    2. float3 worldSpaceNormal = normalize(cross(ddx(IN.worldPosition), ddy(IN.worldPosition)));
    The problem is that in a surface shader, o.Normal is expected to be in tangent space.

    Possible options...

    * It would be reallllly awesome if there was some sort of #pragma that could tell Unity's shader generation to treat o.Normal as world space, but I haven't seen such a thing. Correct me if I'm wrong...​

    * Somehow use shader derivatives to calculate the normal in tangent space relative to the smoothed tangent space basis; I'm not sure that even makes sense logically. And the math to do this definitely alludes me.​

    Other than that, I'd either have to recompute the mesh to be flat shaded (would rather not), or live with the smooth shading (not great).
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,339
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,339
    To your actual point, yes, it would be nice if surface shaders could take world space normals as an output from the surf function. It's only one line in the generated surface shader that needs to not exist and it'd work. But I wouldn't expect any more work to be done on Surface Shaders now that they have shader graph.