How do I anti-alias my shader graph generated texture?

I’m pretty much a shader graph noob and managed to scrape together quite a sophisticated shader from a few different tutorials that allows me to automatically map a texture onto any object without needing any specific texture mapping from the model.

So far his worked great, however, when using a texture that has very distinct lines it starts looking quite pixelated/jagged when further away. I am assuming it is an anti-aliasing issue where I need to anti-alias the final mapped output texture prior to assigning it to the material’s base color. Can anyone give me pointers on how I could achieve that? :slight_smile:

Below are a few reference pictures on how the shader works and of course the shader graph itself.

The “World Space” parent shader takes a simple diffuse texture, color and tiling parameter.

It utilises the “World Space Texture” sub graph to apply the texture from all 3 axes and then blends it together.

The “Sample Texture World Space” is then used by the “World Space Texture” to apply the blend from all axes.

Here is the shader in action on a few objects. You can see how it blends together, but also the jaggedness on the dark vertical lines.

Here is the shader used on an actual model in my project:

Close up:

Far shot: (You can really see the lines jaggedness here)

Shader can be downloaded here:
https://easyupload.io/nwjmw0

Any help is much appreciated! :smiley:

Sure it’s not just the AA settings of the game?

Normally textures are blurrier (partly due to filtering especially at angles) so they might sample better than math, but the end result is still AA.

Maybe try STP, TAA or something.

I just tried changing the AA settings for textures & objects. Any changes to any AA related settings have no impact on the material itself, only the rendered meshes seem to be rendered smoother. Great idea though!

No no it’s a camera setting, or a setting in the quality settings.

Hi, the reason is that you are using “Sample Texture 2D LOD” instead of just “Sample Texture 2D” in “Sample Texture World Space”. “Sample Texture 2D LOD” only samples one mipmap level and because you did not provide any input to the “LOD” port, it will default to LOD0, which is the full-size texture, and never use any mipmaps, resulting in these aliasing issues, as the texture has to be resized on the fly by the GPU.

Unity - Manual: Mipmaps introduction (unity3d.com)

By the way, have you tried using the “Triplanar”-Node? It pretty much does the same thing as your “World Space Texture”, I believe.

Triplanar Node | Shader Graph | 12.1.15 (unity3d.com)

You’re right, I completely missed that. I assume that when I was recreating the shader I accidentally used the wrong node haha.

It turns out it was a combination of factors that lead to mip maps not working.

  1. I was using the wrong node in the shader always forcing a mip map level to 0.
  2. I was using a runtime-generated texture downloaded from my database. It turns out that directly using the texture you get when using DownloadHandlerTexture.GetContent(request) always returns a texture with no mip maps. I fixed this by adjusting my download method to the below:
public async Task<Texture2D> DownloadTextureFromUrl(string downloadUrl)
{
    using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(downloadUrl))
    {
        var asyncOperation = request.SendWebRequest();

        while (!asyncOperation.isDone)
        {
            await Task.Yield();
        }

        if (request.result == UnityWebRequest.Result.Success)
        {
            var texture = DownloadHandlerTexture.GetContent(request);

            //Generate mip map able texture from downloaded texture.
            var mmTexture = new Texture2D(texture.width, texture.height, texture.format, true);
            mmTexture.SetPixelData(texture.GetRawTextureData<byte>(), 0);
            mmTexture.Apply(true, true);
            Object.Destroy(texture);
            return mmTexture;
        }

        Debug.LogError("Error downloading texture: " + request.error);
        return null;
    }
}

I found the above solution here: Generate mipmaps at runtime for a texture loaded with UnityWebRequest? - #21 by cp1