Shadergraph: Normal vector in view space renders black

Unity 2022.3.13f1: Normal vector in view space renders black when passed from vertex shader.
IN-61645

Thanks; it looks like this is a limitation on Apple’s end. The actual node spec doesn’t even list “view” space, so in a way it’s surprising that it does work in the fragment stage. It does, though, so as a workaround, you should be able to get the view space normal in the fragment stage (rather than passing it through an interpolator), or get the object space normal in the vertex stage and use a Transform node to transform it into view space.

We’ll change the implementation so that this works, though (by applying that transform behind the scenes).

1 Like

hi kapolka, I tried this change and the shader comes out completely white. I made a new incident report with a cutdown shader showing the issue, IN-62773

1 Like

Thanks; it looks like this is a coordinate system issue. Unity uses a coordinate system that’s flipped in Z compared to RealityKit, and it looks like we’re emitting the RealityKit coordinates in this case (so the view space normal points to Z+ rather than Z- as it does in Unity). We’ll fix this in a subsequent version; for now, you may be able to get away with multiplying the Z coordinate of the normal by -1 (you can do this for MaterialX only using the built-in MaterialX keyword).

1 Like

Sorry, it turns out I was wrong about this. I missed that your shader uses Render Face: Back, which we don’t support (the material that we use in RealityKit, ShaderGraphMaterial, doesn’t have an option to control the cull face). If I instead use Render Face: Front and add a script that reverses the winding order of all the triangles in the mesh, then I get the same result in Unity and visionOS.

using UnityEngine;

public class ReverseWindingOrder : MonoBehaviour
{
    void Start()
    {
        var meshFilter = GetComponent<MeshFilter>();
        var reversedTriangles = (int[])meshFilter.mesh.triangles.Clone();
        for (var i = 0; i < reversedTriangles.Length; i += 3)
        {
            var tmp = reversedTriangles[i];
            reversedTriangles[i] = reversedTriangles[i + 2];
            reversedTriangles[i + 2] = tmp;
        }
        meshFilter.mesh.triangles = reversedTriangles;
    }
}

just to double check, does that render face problem include disabling it so it draws both?

Yes, I’m afraid so. Only the Render Face: Front option is supported. We’re looking into the possibility of working around this by generating flipped geometry at run time.

1 Like