Hello.
I need a help with 2DArray usings in surface shaders.
I declare 2DArray in Properties part of the shader like this:
Properties
{
_Color (“Color”, Color) = (1,1,1,1)
_MainTex (“Albedo (RGB)”, 2D) = “white” {}
_NormalMap(“NormalMap”, 2D) = “bump” {}
_Tex2DArray(“Tex2DArray (RGB)”, 2DArray) = “” {}
}
Then i passed textures into shader via C# script like on example below:
var texArray = new Texture2DArray(512, 512, Masks.Count, TextureFormat.Alpha8, true);
for (int i = 0; i < Masks.Count; i++)
texArray.SetPixels(Masks*.GetPixels(), i);* CharacterRenderer.sharedMaterial.SetTexture(“_Tex2DArray”, texArray); Now i need to know: 1) How can i know from the inside of the shader how much textures has been passed to it as an array? Something like “length” or “count” fields of the array object should be present i guess… 2) How i can declare this array in Input struct to have uv`s for each array element to be used in surf function? Also, it would be great if anyone will share some count of different surface shaders with a 2DArrays implementation for some reasons.
To the best of my knowledge Unity does not automatically pass this information to shaders. The closest is the _TextureName_TexelSize which is a float4 with the texture dimensions and 1/dimensions for the largest mip. There does not appear to be any equivalent for 3d textures or texture arrays for the texture’s “z” or count. So instead you’ll want to add something like this to your c# code:
You don’t usually have a UV for each element of a texture array. Most commonly you might have a single UV with different UV offsets / scales which you can have as an explicit number of properties on your shader, or pass it in as a vector array (which has to be done via script as you can’t define a vector array as a material property). Picking which texture to use in the array usually falls to some kind of mask texture or textures.
If you really do want / need per-element UVs you can pack them into the mesh’s UVs; you can have up to 8 UVs as all 4 UV sets can internally be float4s, but you would have to set these up in Unity as imported meshes will only use float2 uvs.
I’m new in shaders and i noticed a regularity with textures in shader.
If i will set a 2D texture in Properties of the shader as example
_MainTex (“Albedo (RGB)”, 2D) = “white” {}
i also should declare a variable of the suitable type, in this case it`s:
sampler2D _MainTex;
To apply texture to the model i should use a tex2D function:
o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
but the second parameter should be predeclarated in Input struct with a suitable type again:
struct Input
{
float2 uv_MainTex;
}
My problem is that i dont know what a types of variables i should use in case with 2D array instead of a single 2D textures.
Well, the short version is Surface Shaders aren’t designed to work with Tex2DArray. Doesn’t mean you can’t use them, but they’re lacking some of the automated features of a Surface Shader. I haven’t tried, but you might be able to use the same “float2 uv_MainTex” input struct for getting the mesh’s first UV, but anything additional you’ll have to pass as a custom input.
See “Custom data computed per-vertex” on this page: