Shader Graph: Choosing Texture2DArray Index by uv.z (727698)

Hi,

I try to achieve the following:
Given a Texture2DArray with different textures I want to draw a specific one. As I’ve done it without shader graph I set

uvs0[index] = new Vector3(uvPosition.x, uvPosition.y, textureArrayIndex);
mesh.SetUVs(0,uvs0);

and use uv.xy as real uv coordinates and uv.z as my index for choosing the Texture out of Texture2DArray.
Somehow I do not get it to work with shader graph.

I use this layout:

It somehow does not pick the correct index but uses some other (constant) index.
I have a functioning workaround using another uv channel, but I suppose it should work as I’ve done above, right?
Here is my workaround using uv2 only for picking the correct index:

uvs0[index] = new Vector2(uvPosition.x, uvPosition.y);
uvs2[index] = new Vector2(textureArrayIndex,0);
mesh.SetUVs(0,uvs0);
mesh.SetUVs(2,uvs2);

With a graph like this:

So, am I doing it wrong or is there a bug?

#################################################
Edit: the reason was found:
Not yet implemented
(Jan. 2019)

The mesh.uvs2 is UV1 in the shader.

The “uvs” properties are 1 based, ie .uvs (1), .uvs2, .uvs3, etc. Internally and in shaders they’re 0 based, ie UV0, UV1, UV2, etc.

Also the .uvs array is limited to a Vector2, so in your first example your Vector3 is being implicitly cast to a Vector2 when assigned. You should be using SetUVs() instead.

1 Like

Thanks for pointing that out.
But I don’t think that I did it wrong. I set Mesh.SetUVs(0,uvs0) and Mesh.SetUVs(2,uvs2).
Using UV0 and UV2 in the shader seem to be correct then.

Edit: I’ve added this to the code above

If you were originally using mesh.uvs, then that’s limited to a Vector2. If you were using SetUVs(0, uvs0) (and uvs0 is a Vector3[ ]) then it should work.

As an extra bit of caution, you may want to store your index with a small offset. Some whole number indices will not interpolate exactly across the face of a triangle leading to artifacts across your surface where the index ends up slightly less than your intended number due to floating point accuracy.

uvs0[index] = new Vector3(uv.x, uv.y, (float)textureArrayIndex + 0.1f);

2 Likes

That’s what I’m doing.

I will try it - but I’m sceptical since it works fine using uv2.x

I’ve tested it - still does not work :frowning:

But I will keep your extra bit of caution for future, thanks so far! :slight_smile:

Strange. This definitely feels like a bug then. Actually, I have a vague memory of something like this already coming up in the past.

Yep:
Feedback Wanted: Shader Graph page-2#post-3349460

No idea what the current state of this is, but it wasn’t supported last year.

1 Like

Great. Thanks!