Skip to content

Instantly share code, notes, and snippets.

@aras-p
Last active February 10, 2020 19:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save aras-p/a3aeac5c84ce233f6787 to your computer and use it in GitHub Desktop.
Save aras-p/a3aeac5c84ce233f6787 to your computer and use it in GitHub Desktop.
Possible texture array syntax

Unity shader side:

UNITY_DECLARE_TEX2DARRAY(name)
UNITY_SAMPLE_TEX2DARRAY(name,coord) // coord is float3

On DX11-like systems (DX11, and I'd assume XB1/PS4) the macros expand to:

#define UNITY_DECLARE_TEX2DARRAY(name) Texture2DArray(name); SamplerState sampler##name
#define UNITY_SAMPLE_TEX2DARRAY(name,coord) name.Sample(coord)

On hlsl2glsl-like systems (GL+EXT_texture_array, GLES3, Metal) the macros expand to:

#define UNITY_DECLARE_TEX2DARRAY(name) sampler2DArray name
#define UNITY_SAMPLE_TEX2DARRAY(name,coord) tex2DArray(name,coord)

and hlsl2glslfork has to learn how to parse that & emit proper GLSL. glsl-optimizer might also need minor updates, but concept of "texture arrays" should already be there

Unity code side:

I'd assume that GfxDeviceTypes.h TextureDimension needs to get a new entry for kTexDim2DArray. Review all places that have any tables sized kTexDimCount.

Shader lexer/parser probably needs a keyword for 2D arrays, i.e. shader_lex.lpp.

Shader compiler side needs to emit reflection info for 2D arrays, CompilerHLSL11.cpp etc.

GraphicsCaps needs to get a bool for whether 2D arrays are supported.

Otherwise, probably basing implementation on Texture3D.cpp/h would be good - just like texture arrays, it needs to check for hardware support, has no asset pipeline just yet (only create/fill from code), etc. Expose it to scripts in TextureBindings.txt, similar to 3D textures.

Array uploading/update code added to GfxDevice.h interface, possibly with an empty base implementation (for platforms that can't have them), again probably similar to 3D textures.

@Zicandar
Copy link

Zicandar commented May 5, 2015

Is this in yet? Or has any plans on getting it in?

@lieene
Copy link

lieene commented Jul 19, 2015

Hi Aras, how is this texture2darray thing going. I really need this to work. what I'm doing now is use a native plugin to create texture2dArray dx11 srv like:

extern "C" EXPORT_API void* ApplyTextureArray()
{
    if (!g_D3D11Device)
    {
        OutputDebugStringA("D3D11Device not set!\n");
        return NULL;
    }
    if (g_ArrayCount<=0)
    SAFE_RELEASE(g_pTextureArray);
    D3D11_TEXTURE2D_DESC descTexture;
    g_ppTextures[0]->GetDesc(&descTexture);
    descTexture.ArraySize = g_ArrayCount;
    descTexture.Usage = D3D11_USAGE_DEFAULT;
    descTexture.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    g_D3D11Device->CreateTexture2D(&descTexture, NULL, &g_pTextureArray);
    ID3D11DeviceContext *ctx;
    g_D3D11Device->GetImmediateContext(&ctx);
    for (int _arrayIndex = 0; _arrayIndex < g_ArrayCount; _arrayIndex++)
    {
        for (int _mipIndex = 0; _mipIndex < descTexture.MipLevels; _mipIndex++)
        {
            ctx->CopySubresourceRegion(g_pTextureArray, D3D11CalcSubresource(_mipIndex, _arrayIndex, descTexture.MipLevels), 0, 0, 0,
                g_ppTextures[_arrayIndex], D3D11CalcSubresource(_mipIndex, 0, descTexture.MipLevels), NULL);
        }
    }
    g_D3D11Device->CreateShaderResourceView(g_pTextureArray, NULL, &g_SRV);
    return g_SRV;
}

and apply texture with:

            textureArray = Texture2D.CreateExternalTexture(2048,2048,TextureFormat.DXT1,true,false,ApplyTextureArray());
            GetComponent<Renderer>().material.mainTexture = textureArray;

I tried the texture2dArray in native code shader it all passed, the problem now is the shader compiler cannot go with Texture2DArray. complier give me a "dim is being used without being initialized".

It's almost there! Just let compiler pass this:

Shader "Custom/NativeTexture" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "black" {}
        _Index ("Index", float) = 1
    }
    SubShader {
        Pass {
            CGPROGRAM
            #pragma target 5.0
            #pragma only_renderers d3d11

            #pragma vertex vert_img
            #pragma fragment frag

            #include "UnityCG.cginc"
            float _Index;
            Texture2DArray _MainTex;
            SamplerState sampler_MainTex;
            fixed4 frag(v2f_img i) : SV_Target {
                return _MainTex.Sample(sampler_MainTex,float3(i.uv,_Index));
            }
            ENDCG
        }
    }
}

this shader will work if i change Texture2DArray to Texture2D
But not array sampling just first layer.

and I try the texture2darray with native complied shader:

static const char* kD3D11ShaderText =
    "Texture2DArray mTexture: register(t100);"
    "SamplerState mTextureSampler:register(s15);\n"
    "cbuffer MyCB : register(b0) {\n"
    "   float4x4 worldMatrix;\n"
    "   float4 arrayIdx;\n"
    "}\n"
    "void VS (float3 pos : POSITION, float4 color : COLOR, out float4 ocolor : COLOR, out float4 opos : SV_Position) {\n"
    "   opos = mul (worldMatrix, float4(pos,1));\n"
    "   ocolor = float4(pos.xy,arrayIdx.x,1);\n"
    "}\n"
    "float4 PS (float4 color : COLOR,float4 pos : SV_Position) : SV_TARGET {\n"
    "   return mTexture.Sample(mTextureSampler,float3(color.xyz));\n"
    "}\n";

it works well, of course.

I can handle the creation of texure2darray srv in DX11, I don't need a importer inspector thing.
just let the shader pass compiling.

@darkmavis
Copy link

Support for this would be a huge help for our project too. Thanks!

@bastienstefani
Copy link

Hello,
I'm a bit surprised there isn't more documentation about this.
So i'm leaving a reply if it can helps anymore one day: If i got it correctly from documentation and few tests, in lieene's example, the _Index passed in the float 3 is supposed to be something the index of the last texture to be considered in the array, so if its value is 1, only the first layer will be rendered. Putting it to a higher value allow the sample more textures.
Bastien

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment