Text Shader override

I’ve taken the TextSDFSmoothstep shader graph that is included in the Polyspatial package and made some modifications to support outlines, but I can’t find a way to actually use this shader.

It looks like the package replaces any shader on a text mesh pro component with its own shader (TextSDFSmoothstep). Is there a way to stop this override happening?

Alternatively, I’ve tried making a local copy of the Polyspatial package and have made edits directly to TextSDFSmoothstep.shadergraph, but when this is applied at runtime, any new properties I’ve added to the shader are not copied from my old material to the new, generated one.

Any ideas?

Thanks

We are replacing the generated shader in the xcode project, in a build postprocessing step using something like the snippet below.

You need to copy the usd shader that’s generated from your modifications. You can either modify it by hand in Reality Composer Pro, or find it in the xcode assets. If you do a text search in xcode for the shader name you should be able to find the xyz.usda.polyspatial file. This is simply a usd file that’s been renamed.

        List<string> shaderFiles = GetShaderFiles(path);
        ReplaceShader("VisionOS", "USD_TextSDFSmoothstep", shaderFiles);


    private static List<string> GetShaderFiles(string projectPath)
    {
        List<string> shaderFiles = new List<string>();

        string shaderDir = $"{projectPath}/Data/Raw/PolySpatialAssets/VirtualArtifacts/Extra/";
        var dirs = Directory.GetDirectories(shaderDir);
        foreach (var dir in dirs)
        {
            var files = Directory.GetFiles(dir);
            foreach (var f in files)
            {
                if (f.Contains(".usda.polyspatial"))
                {
                    shaderFiles.Add(f);
                }
            }
        }

        foreach (var f in shaderFiles)
        {
            Debug.Log(f);
        }
        return shaderFiles;
    }

    private static string FindShader(string shaderName, List<string> shaderFiles)
    {
        foreach (var f in shaderFiles)
        {
            string data = File.ReadAllText(f);
            if (data.IndexOf($"\"{shaderName}\"") >= 0)
            {
                return f;
            }
        }

        Debug.LogError($"Did not find shader {shaderName}");

        return null;
    }

    private static void ReplaceShader(string shaderPath, string shaderName, List<string> shaderFiles)
    {
        string newData = File.ReadAllText($"{shaderPath}/{shaderName}.usd");
        if (newData.Length < 1)
        {
            Debug.LogError($"ReplaceShader({shaderPath}, {shaderName}, shaderFiles) did not find shader data");
            return;
        }

        string f = FindShader(shaderName, shaderFiles);
        if (f != null)
        {
            string origData = File.ReadAllText(f);
            if (origData != newData)
            {
                File.WriteAllText(f, newData);
                Debug.Log($"{shaderName} in file {f} has been replaced!");
            }
            else
            {
                Debug.Log($"{shaderName} no changes!");
            }
        }
    }

(We are also patching other shaders to get better performance, but that’s a bit more esoteric)

1 Like

Right; we use the TextSDFSmoothstep shader for all UI text at the moment. We can put it on our list to change that so that only the TextMeshPro shaders (TextMeshPro/Mobile/Distance Field, TextMeshPro/Distance Field) are converted to TextSDFSmoothstep, and any other shader (graph) is used as-is. That’s basically how non-UI TextMeshPro objects (ones that use MeshRenderer, rather than CanvasRenderer) work.

1 Like

That would certainly help a lot. Any suggestions for a workaround before launch?

The only workarounds I can think of offhand are using non-UI (MeshRenderer) text or swapping out the shader at build time as Mikkel suggests.