Where is the anisotropic sampler?

I’ve been working on a Texture2DArray based shader, but for some reason I am not able to enable anisotropic filtering for it. I’ve tried setting Texture2DArray.anisoLevel to both 9 (as is the documented max) and 16 (as a helpful forum user pointed out is the real max ), and I tried forcing anisotropic filtering on all textures in the quality settings to no avail.

Yes, I do have mipmaps enabled on both the textures, and trilinear filtering. (because for some reason Unity decides anisotropic isn’t a separate type of filtering but one that piggybacks off of trilinear) I have gotten anisotropic filtering to work on regular texture/shaders just fine.

I would believe that anisotropic filtering would be a sampler state you would set directly in the shader, as is documented by Microsoft. But Unity doesn’t recognize any such thing as seen in their docs.

How are you sampling your texture in the shader?

Hey, you’re the helpful user I mentioned that I was hoping would reply! You seem to know a lot about anisotropic filters, helped me get to where I am now. Sorry for the lateness, I was away from my machine.
But back to the point, I setup the SamplerState

Texture2DArray _MainTex : register(t0);
float4 _MainTex_ST;
float4 _MainTex_TexelSize;
SamplerState sampler_trilinear_repeat;

And then I sample the texture like so

float4 frag(float4 vertex:POSITION, float3 uv : TEXCOORD0) : SV_TARGET
{
    float2 uvPixels = float2(uv.x, uv.y) * _MainTex_TexelSize.zw;

    float2 uvPixels_fwidth = min(float2(1.0, 1.0), fwidth(uvPixels));
    float2 uvPixels_floor = floor(uvPixels);
    float2 uvPixels_frac = frac(uvPixels);
    // magic ...
    float2 uvPixels_aa = (1.0 - saturate((1.0 - abs(uvPixels_frac * 2.0 - 1.0)) / uvPixels_fwidth)) * sign(uvPixels_frac - 0.5) * 0.5 + 0.5;
    float2 new_uv = (floor(uvPixels) + uvPixels_aa) * _MainTex_TexelSize.xy;

    return _MainTex.SampleGrad(sampler_trilinear_repeat, float3(new_uv.x, new_uv.y, uv.z), ddx(uv), ddy(uv));
}

I assume the only relevant bit is the final return statement, the lines before just clean up the pixels from the trilinear filter.

Here’s a visual if needed, right side is what I want, left side is what I have so far.

There’s your problem.

You’re not using the texture’s sampler state, ie: the one that the settings on the texture asset control. Instead you’re using one that’s hardcoded to use trilinear filtering. Instead you want to use:
SamplerState sampler_MainTex;

Annoyingly, there’s not actually a way to specify an inline sampler state (what you are using) with anisotropic filtering enabled, but luckily for your use case you can just use the one defined by the texture property.

Also, happy to see someone use my pixel AA code.

1 Like

Holy cripes it worked! Thank you so much mang, I had a feeling the SamplerState was overriding it, but the screwy way Unity handles anisotropic filtering tricked me.

Yeah, I was banging my head against the wall with that… I think it’s actually a bug and should be implemented.

Noted :wink:

2 Likes

Wow. Someone from Unity ACTUALLY LISTEN TO US! :smile:

1 Like

Lots of people at Unity listen. Legitimately too, not just “thanks for your feedback, we’ll keep that under advisement” then tossed into the suggestion oubliette. I know talking to some Unity devs they’re often just as frustrated with stuff as users are.

Doesn’t always mean things will get fixed / added / changed. Unity is a massive company with a lot of internal processes that have to get past for getting stuff approved, both in terms of giving a person or a team the time to spend to fix something over other tasks, or even once finished get into a shipping product we see.

Usually the best way to get something fixed is to report it as a bug. That way they have a way to track it internally, and get it moved through the proper processes.

Though, to be brutally honest, not a single thing I’ve reported that way has ever been fixed through that path … I can’t entirely blame Unity for that since my issues are usually fairly esoteric or misrepresented in the bug report as I’m still trying to figure out what the issue is when I report it. I usually get things fixed by knowing people internally high enough up that can push things through. Also Twitter.

2 Likes

Yes please do add anisotropic filtering controls to the sampler naming convention!
I been forced into the sampler naming method for a few reasons and surprised MaxAnisotropy was missed from the hlsl sampler reference.

The macros themselves that borrow the main texture sampler makes it hard to debug, for example a early return of results before all sampler macros are hit break the compiler, i basically got feed up and force the quality as i wished for every sampler. The lack of MaxAnisotropy gives really bad mip map blurring unless a user forces project quality settings high or override anisotropic quality in the GPU.