Hello! Today I will tell you how to use a texture array for 3D in Godot.
First of all, you need to understand that if you want to use an array of textures, you will have to abandon imported materials that have textures, as this will cause errors and spontaneous copying of textures. Maybe there are ways to avoid this, but I have not found them.
-
Import the mesh without materials into Godot, you don’t need to adjust the UV unwrap.
-
Manually transfer the atlas with any textures to your texture folder. The main thing is that the textures in this atlas should be the same size.
-
Select the texture atlas that you moved to the folder and perform the following actions in the import tab:
1)Select Texture2DArray;
2)Set the compression mode. This is a controversial issue, since in theory, you should select VRAM Compressed, but on my PC, it either closes Godot or causes interface artifacts, so I use VRAM Uncompressed;
3)Set how your atlas will be divided. Focus on the size of the atlas by textures, if your atlas is 4 textures long and 2 textures high, then set these values;
4)Click the Reimport button.
-
Next, open the material and enable Normal Map, even if you don’t need it. Just let it be.
-
Convert the material to a shader.
-
Open the shader and replace the generated code with this:
// NOTE: Shader automatically converted from Godot Engine 4.3.stable's StandardMaterial3D.
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
uniform vec4 albedo : source_color;
uniform sampler2DArray texture_albedo : source_color, filter_linear_mipmap, repeat_enable;
uniform float point_size : hint_range(0.1, 128.0, 0.1);
uniform float roughness : hint_range(0.0, 1.0);
uniform sampler2DArray texture_metallic : hint_default_white, filter_linear_mipmap, repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2DArray texture_roughness : hint_roughness_r, filter_linear_mipmap, repeat_enable;
uniform float specular : hint_range(0.0, 1.0, 0.01);
uniform float metallic : hint_range(0.0, 1.0, 0.01);
uniform sampler2DArray texture_normal : hint_roughness_normal, filter_linear_mipmap, repeat_enable;
uniform float normal_scale : hint_range(-16.0, 16.0);
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;
uniform vec3 uv2_scale;
uniform vec3 uv2_offset;
void vertex() {
UV = UV * uv1_scale.xy + uv1_offset.xy;
}
void fragment() {
vec2 base_uv = UV;
vec4 albedo_tex = texture(texture_albedo, vec3(base_uv, float(uv1_scale.z)));
ALBEDO = albedo.rgb * albedo_tex.rgb;
float metallic_tex = dot(texture(texture_metallic, vec3(base_uv, float(uv1_scale.z))), metallic_texture_channel);
METALLIC = metallic_tex * metallic;
SPECULAR = specular;
vec4 roughness_texture_channel = vec4(1.0, 0.0, 0.0, 0.0);
float roughness_tex = dot(texture(texture_roughness, vec3(base_uv, float(uv1_scale.z))), roughness_texture_channel);
ROUGHNESS = roughness_tex * roughness;
// Normal Map: Enabled
NORMAL_MAP = texture(texture_normal, vec3(base_uv, float(uv1_scale.z))).rgb;
NORMAL_MAP_DEPTH = normal_scale;
}
If your shader code is generated in some other way, here are the key points:
1)Replace all “sampler2D” with “sampler2DArray”;
2)In lines like “vec4 albedo_tex = texture(texture_albedo, base_uv);”, replace “base_uv” with “vec3(base_uv, float(uv1_scale.z))”.
-
After that, new fields will appear in Shader Parameters. Specifically here, you need to insert the textures that were re-imported into the Texture Array
-
And here you need to set some values:
1)x — repeat texture along the x axis;
2)y — repeat texture along the y axis;
3)z — index of the layer in which the texture you need is stored, in my case it is 5.
You can improve this code, make it more automated and efficient, it has potential for development.
I also want to note that this is not the only way to use Texture Array in Godot, but it is one of them.
To consolidate your knowledge of using Texture Array in Godot, check out the continuation of this topic, where Texture Array is used in practice:
If you don’t want to bother with Texture Array, but still need repeating textures from a texture atlas, then this might help:
Bye!