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 “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.
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.
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);