You can pass array elements such as vectors and floats using SetVectorArray and SetFloatArray, but I need to pass textures to an array. How? I use GLSL, so my texture array is defined like this: Code (CSharp): uniform sampler2D textureSlot[16];
GPUs don’t actually support arrays of textures. GLSL has a funny quirk in that it sometimes lets you use the above code, but it’s doesn’t actually compile to an array, but rather expands out to multiple texture entries. Code (csharp): uniform sampler2D textureSlot[16]; I’d really short hand for: Code (csharp): sampler2D textureSlot1; sampler2D textureSlot2; sampler2D textureSlot3; //etc If you want an array of textures you need to use the Texture2DArray texture type, which is a texture object with multiple layers.
Thank you, this is very useful information! So does this mean I can use this in Unity, when declaring the textureSlot as an array in GLSL: Code (csharp): int textureIndex=1; material.setTexture("textureSlot"+textureIndex,texture2D); And, if I understand this correctly, on the GLSL side Code (csharp): uniform sampler2D textureSlot[4]; ... Sampler2D currentSampler=textureSlot[textureIndex]; would actually expand to Code (csharp): if (textureIndex== 1) currentSampler = textureSlot1; else if (textureIndex== 2) currentSampler = textureSlot2; else if (textureIndex== 3) currentSampler = textureSlot3; else if (textureIndex== 4) currentSampler = textureSlot4; Do you know if there are any performance benefits letting the compiler expand the code for you rather than manually write the if else as above? I think i would still like to use the array statement, as it looks cleaner and I might have quite a lot of samplers. Unfortunately I cannot use the Texture2DArray texture type as the textures might have different resolutions.
Honestly not sure. Possibly? Before Unity 5.4 or so there weren’t even Set_Array material functions and all array values were set like the c# example code you posted. Those don’t work anymore for proper arrays as there are now those material functions. I don’t know how smart Unity is at handling that kind of GLSL since it’s technically not valid code per the spec, just some compilers will handle it the way I described. Possibly even worse. It’ll probably be more like: Code (CSharp): fixed4 col = 0; fixed4 colTemp0 = tex2D(textureSlot0, uv); if (textureIndex == 0) col = colTemp0; fixed4 colTemp1 = tex2D(textureSlot1, uv); if (textureIndex == 1) col = colTemp1; // etc You will most likely pay for the actual texture sampling. You’d have to look at the compiled shader from your target device to find out what it actually does though.
No, I already looked into this. This is a rendering editor tool, it has to be flexible and I cannot limit what type of textures the artist can use. The way Unity loads texture arrays is also slow and cumbersome, which would slow down the rendering preview system too much.
I tried and it looks like Unity has its own system for setting those uniform variables, and it is not compatible with texture array unrolling you described. I will probably have to do this in a plugin. I hoped to avoid that as working with DLLs is so tedious in Unity, you actually have to reboot your whole project every time you change the DLL as the editor hooks into it so it cannot be overwritten. Also, loads of overhead to execute even a single OpenGL command in the correct way. Probably easier to write my own unroll script that puts the code into the shader itself...