maximum ps_5_0 sampler register index

so seeing this error in my shadergraph using LWRP,I’m guessing I’ve hit a limit on how many textures I can use in my shader. I’m just staring to work with shaders so my understanding is next to noting but I’ve seen shader that can take 256 textures , how can I use more than 16 textures in my shadergraph,please help

You’re limited to 16 sampler states per shader, not 16 textures. By default each texture gets its own sampler state, which means you hit the 16 sampler limit after 16 textures. You can work around this by defining a sampler state and reusing it to sample multiple textures. I believe Shader Graph has the Sampler State Node for this. However that only gets you to 128 textures. The real solution to get past that is using a texture array, which is how those shaders that advertise 256 textures work. And those shaders really have a limit of 256 texture sets, which includes the diffuse, normal, and smoothness textures. A texture array is a special kind of texture which the shader sees as a single texture, and the 256 limit has more to do with the way the texture stores which texture layer to sample. Really you could have 65536 textures in a single shader by using 128 texture arrays with 512 layers each, but that’s overkill.

If all you need is to get a few more textures, a shared sampler state is the easier option.

6 Likes
// https://github.com/przemyslawzaworski/Unity3D-CG-programming/blob/master/texture_mapping.shader

//Shader shows configuration of using 24 textures per shader in single pass.

Shader "Texture Mapping"
{
    Properties
    {
        _Texture01 ("Texture 01", 2D) = "black" {}
        _Texture02 ("Texture 02", 2D) = "black" {}
        _Texture03 ("Texture 03", 2D) = "black" {}
        _Texture04 ("Texture 04", 2D) = "black" {}
        _Texture05 ("Texture 05", 2D) = "black" {}
        _Texture06 ("Texture 06", 2D) = "black" {}
        _Texture07 ("Texture 07", 2D) = "black" {}
        _Texture08 ("Texture 08", 2D) = "black" {}
        _Texture09 ("Texture 09", 2D) = "black" {}
        _Texture10 ("Texture 10", 2D) = "black" {}
        _Texture11 ("Texture 11", 2D) = "black" {}
        _Texture12 ("Texture 12", 2D) = "black" {}
        _Texture13 ("Texture 13", 2D) = "black" {}
        _Texture14 ("Texture 14", 2D) = "black" {}
        _Texture15 ("Texture 15", 2D) = "black" {}
        _Texture16 ("Texture 16", 2D) = "black" {}
        _Texture17 ("Texture 17", 2D) = "black" {}
        _Texture18 ("Texture 18", 2D) = "black" {}
        _Texture19 ("Texture 19", 2D) = "black" {}
        _Texture20 ("Texture 20", 2D) = "black" {}
        _Texture21 ("Texture 21", 2D) = "black" {}
        _Texture22 ("Texture 22", 2D) = "black" {}
        _Texture23 ("Texture 23", 2D) = "black" {}
        _Texture24 ("Texture 24", 2D) = "black" {}       
    }
    Subshader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vertex_shader
            #pragma fragment pixel_shader
            #pragma target 5.0

            Texture2D _Texture01,_Texture02,_Texture03,_Texture04,_Texture05,_Texture06,_Texture07,_Texture08;
            Texture2D _Texture09,_Texture10,_Texture11,_Texture12,_Texture13,_Texture14,_Texture15,_Texture16;
            Texture2D _Texture17,_Texture18,_Texture19,_Texture20,_Texture21,_Texture22,_Texture23,_Texture24;

            SamplerState sampler_linear_repeat;

            struct structure
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            structure vertex_shader (float4 vertex:POSITION,float2 uv:TEXCOORD0)
            {
                structure vs;
                vs.vertex = UnityObjectToClipPos (vertex);
                vs.uv = uv;
                return vs;
            }

            float4 pixel_shader (structure ps ) : SV_TARGET
            {
                float2 uv = ps.uv.xy;
                float2 scale = uv/float2(0.25,0.1666);
                if (uv.x<0.25 && uv.y<0.1666)
                    return  _Texture01.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.25 && uv.y<0.3333)
                    return  _Texture02.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.25 && uv.y<0.4999)
                    return  _Texture03.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.25 && uv.y<0.6666)
                    return  _Texture04.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.25 && uv.y<0.8333)
                    return  _Texture05.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.25 && uv.y<=1.0)
                    return  _Texture06.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.5 && uv.y<0.1666)
                    return  _Texture07.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.5 && uv.y<0.3333)
                    return  _Texture08.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.5 && uv.y<0.4999)
                    return  _Texture09.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.5 && uv.y<0.6666)
                    return  _Texture10.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.5 && uv.y<0.8333)
                    return  _Texture11.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.5 && uv.y<=1.0)
                    return  _Texture12.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.75 && uv.y<0.1666)
                    return  _Texture13.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.75 && uv.y<0.3333)
                    return  _Texture14.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.75 && uv.y<0.4999)
                    return  _Texture15.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.75 && uv.y<0.6666)
                    return  _Texture16.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.75 && uv.y<0.8333)
                    return  _Texture17.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<0.75 && uv.y<=1.0)
                    return  _Texture18.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<=1.0 && uv.y<0.1666)
                    return  _Texture19.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<=1.0 && uv.y<0.3333)
                    return  _Texture20.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<=1.0 && uv.y<0.4999)
                    return  _Texture21.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<=1.0 && uv.y<0.6666)
                    return  _Texture22.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<=1.0 && uv.y<0.8333)
                    return  _Texture23.Sample(sampler_linear_repeat, scale);
                else
                if (uv.x<=1.0 && uv.y<=1.0)
                    return  _Texture24.Sample(sampler_linear_repeat, scale);
                else
                    return 1;
            }
            ENDCG
        }
    }
}

Thanks for the info, looks like I will need to use a texture array. Have you done texture arrays in shadergraph I would know where to start, so I need to create a texture array or can I just plug textures in as I go

Unity’s editor doesn’t help with creating texture arrays at all. You have to construct them entirely on your own from script, or download something from the asset store which can help. Once they’ve been setup, they can be plugged into a sample 2d array node.

Ok , thanks again for all your help

Is this what im looking for

Hi there, I have the same problem but I am using ASE. I am doing a terrain shader and I just need a few more than 16 textures, 20 in fact. Is there an equivalent of this Sampler State Node in Amplify?

No idea, you should ask that in the official thread for that asset.

Ive used a textureArray in Amplify, seems like this is what you need. I used over 50 textures that way in a single sampler

Thanks Bgolus, using the Sampler State node worked perfectly to have more than 16 textures at once in a shader. Now is it optimized? Time will tell… :slight_smile:

1 Like

@Horus_Sungod42 How did you use SamplerState node? Just attaching its output to sampler input ok?

1 Like

Yes

2 Likes

@Horus_Sungod42 I don´t know how using the samplerState node resolve this issue. I´m using 12 textures and one SamplerState node and Unity is having problem to render preview for material. You can post the schemas of how you work with this issue? Thanks

I’m getting this error on Shaders made by Unity URP, only while building, which is extremely weird (Unity 2021.2.7f1 - URP 12.1.2):

Does anybody know why? And the solution to it? The build somehow does get completed but the errors worry me a great deal.

I have exact same errors when I build my project or my addressables groups. I am using Unity 2021.2.14.

I’m not 100% sure about this, but if you work for Unity perhaps you have a way of testing this.

We managed to build the game by removing all the shaders (we added them all into a Shader Variant) and then build again with all the shaders.

It makes no sense but we figure (because we tried this in a couple of PCs) it’s something related to a Unity cache bug (not project cache because we re-generated the project like 5 times and even updated it).

That’s it.

Our weird process was like:

Build with all the shaders - Fail.
Build with 0 shaders - Success.
Build with all the shaders - Success.

¯_(ツ)_/¯

1 Like

Getting this in 2021.3.2f1 with built-in terrain shader:

Shader error in 'Nature/Terrain/Standard': maximum ps_5_0 sampler register index (16) exceeded at Files/Unity/Hub/Editor/2021.3.2f1/Editor/Data/CGIncludes/TerrainSplatmapCommon.cginc(62) (on gles3)

Compiling Subshader: 0, Pass: FORWARD, Vertex program with DIRECTIONAL DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON INSTANCING_ON LIGHTMAP_ON SHADOWS_SCREEN SHADOWS_SHADOWMASK _ALPHATEST_ON _NORMALMAP
Platform defines: SHADER_API_GLES30 SHADER_API_MOBILE UNITY_COLORSPACE_GAMMA UNITY_ENABLE_REFLECTION_BUFFERS UNITY_FRAMEBUFFER_FETCH_AVAILABLE UNITY_HARDWARE_TIER1 UNITY_LIGHTMAP_DLDR_ENCODING UNITY_NO_CUBEMAP_ARRAY UNITY_NO_DXT5nm UNITY_NO_FULL_STANDARD_SHADER UNITY_NO_RGBM UNITY_NO_SCREENSPACE_SHADOWS UNITY_PASS_FORWARDBASE UNITY_PBS_USE_BRDF3
Disabled keywords: FOG_EXP FOG_EXP2 FOG_LINEAR LIGHTMAP_SHADOW_MIXING LIGHTPROBE_SH UNITY_ASTC_NORMALMAP_ENCODING UNITY_ENABLE_DETAIL_NORMALMAP UNITY_ENABLE_NATIVE_SHADOW_LOOKUPS UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3 UNITY_LIGHTMAP_FULL_HDR UNITY_LIGHTMAP_RGBM_ENCODING UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_METAL_SHADOWS_USE_POINT_FILTERING UNITY_PBS_USE_BRDF1 UNITY_PBS_USE_BRDF2 UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION UNITY_SPECCUBE_BLENDING UNITY_SPECCUBE_BOX_PROJECTION UNITY_UNIFIED_SHADER_PRECISION_MODEL UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_VIRTUAL_TEXTURING VERTEXLIGHT_ON
1 Like

Same - got it after upgrading to 2021.3.2 looks like we got LTS release with a breaking bug… I think if the tech bubble bursts we might lose Unity altogether if they keep working like this.

How do you build without the shaders? I do not understand what you did