- 文档
- 教程
- 游戏开发
【免费下载链接】godot-docs
Godot Engine official documentation
导读
Texture2DArrayRD是 Godot 引擎中面向RenderingDevice(Vulkan 等现代低层图形 API 的抽象层)的 2D 纹理数组资源。它的核心作用是:把你在RenderingDevice上直接创建的 2D 数组纹理(以RID标识)包装成一个可被材质、网格等高层资源直接引用的Texture资源。读完本文,你将掌握其继承关系、texture_rd_rid属性的用法、从RDTextureFormat到texture_create()的完整创建流程,以及它与常规Texture2DArray的取舍差异。
类概览与继承关系
Texture2DArrayRD的定义位于 classes/class_texture2darrayrd.rst,完整继承链如下:
Texture2DArrayRD < TextureLayeredRD # RD 系列分层纹理的抽象基类 < TextureLayered # 多图层纹理的抽象基类 < Texture < Resource < RefCounted < Object从文档描述看,它是「绑定到 RenderingDevice 上创建的纹理对象的 2D 纹理数组」,让你能够把直接在RenderingDevice上生成的 2D 数组纹理用作材质、网格等的纹理。官方文档同时给出了一条明确的注意事项:
Texture2DArrayRD 面向 RenderingDevice 的低层使用场景;绝大多数情况下应使用 Texture2DArray 替代。
这意味着它是一个「桥接型」工具类,服务于需要直连 GPU 资源的渲染管线,而非日常资源导入路径。
在TextureLayeredRD的继承体系中,与它并列的还有两个兄弟类:TextureCubemapRD(Cubemap 纹理)与TextureCubemapArrayRD(Cubemap 数组纹理),三者共享同一套基于 RID 的访问机制。
核心基类 TextureLayeredRD 与 texture_rd_rid 属性
Texture2DArrayRD本身不定义任何新的属性或方法,全部能力来自其直接基类 TextureLayeredRD。该基类是「RD 分层纹理类型的抽象基类」,不能直接使用,但包含访问所有派生资源类型所需的函数。官方文档注明它同样面向RenderingDevice低层使用,常规场景请改用TextureLayered。
基类只暴露一个属性,也是整个 RD 纹理桥接机制的关键:
| 属性 | 类型 | 说明 |
|---|---|---|
texture_rd_rid | RID | 在RenderingDevice上创建的纹理对象的 RID |
对应存取方法:
set_texture_rd_rid(value: RID)get_texture_rd_rid() -> RID
工作机制可以概括为:RenderingDevice.texture_create()返回一个指向 GPU 纹理资源的RID,通过texture_rd_rid将这个 RID 绑定到Texture2DArrayRD实例上,Godot 的材质、网格等渲染管线便可通过该资源间接访问这块 GPU 纹理。
从源码结构看,TextureLayeredRD的兄弟类TextureCubemapRD采用了完全相同的设计(同样仅暴露texture_rd_rid),印证了「RID 包装 + 高层资源桥接」是该系列的统一模式。
从 RenderingDevice 创建 2D 纹理数组
要获得一个可被Texture2DArrayRD引用的 RID,需要走RenderingDevice的完整纹理创建流程。
第一步:获取 RenderingDevice 实例
RenderingDevice是现代低层图形 API(Vulkan、Direct3D 12、Metal、WebGPU 等)的抽象,其类文档位于 classes/class_renderingdevice.rst。获取途径有两种:
- 全局设备:
RenderingServer.get_rendering_device(),负责向屏幕绘制,Godot 启动时自动创建(见 class_renderingserver.rst)。 - 局部设备:
RenderingServer.create_local_rendering_device(),用于在独立线程上执行绘制与 GPU 计算,不能绘制到屏幕,也不能与全局设备共享数据。
根据 compute_shaders 教程,典型写法是:
# 创建局部渲染设备 var rd := RenderingServer.create_local_rendering_device()需要特别留意两个限制(均来自官方文档原文):
RenderingDevice在headless 模式或使用Compatibility 渲染方法时不可用;- 使用 OpenGL 渲染驱动或 headless 模式时,
create_local_rendering_device()始终返回null。
第二步:配置 RDTextureFormat
纹理的创建参数封装在RDTextureFormat对象中(见 classes/class_rdtextureformat.rst),其属性及默认值如下:
| 属性 | 默认值 | 含义 |
|---|---|---|
width | 1 | 纹理宽度(像素) |
height | 1 | 纹理高度(像素) |
depth | 1 | 纹理深度,2D 纹理恒为1 |
array_layers | 1 | 图层数量,仅对 2D 纹理数组有意义 |
mipmaps | 1 | 纹理可用的 mipmap 数量 |
format | 8 | 像素数据格式(RenderingDevice.DataFormat枚举) |
texture_type | 1 | 纹理类型(RenderingDevice.TextureType枚举) |
samples | 0 | 采样时使用的样本数(多重采样) |
usage_bits | 0 | 用途位掩码(TextureUsageBits),决定纹理可被做什么操作 |
is_discardable | false | 内容是否无需跨帧保留(仅作为绘制列表目标时相关) |
is_resolve_buffer | false | 是否用作 resolve 操作的目标 |
关键点:创建 2D 纹理数组时,必须将texture_type设为TEXTURE_TYPE_2D_ARRAY(值5),并通过array_layers指定图层数量。RenderingDevice.TextureType枚举完整定义(见 class_renderingdevice.rst)如下:
| 枚举值 | 值 | 含义 |
|---|---|---|
TEXTURE_TYPE_1D | 0 | 1D 纹理 |
TEXTURE_TYPE_2D | 1 | 2D 纹理 |
TEXTURE_TYPE_3D | 2 | 3D 纹理 |
TEXTURE_TYPE_CUBE | 3 | Cubemap 纹理 |
TEXTURE_TYPE_1D_ARRAY | 4 | 1D 纹理数组 |
TEXTURE_TYPE_2D_ARRAY | 5 | 2D 纹理数组 |
TEXTURE_TYPE_CUBE_ARRAY | 6 | Cubemap 纹理数组 |
TEXTURE_TYPE_MAX | 7 | 枚举大小(哨兵值) |
第三步:指定 usage_bits
usage_bits是决定纹理用途的位掩码(TextureUsageBits,见 class_renderingdevice.rst),常用位如下:
| 位标志 | 值 | 含义 |
|---|---|---|
TEXTURE_USAGE_SAMPLING_BIT | 1 | 可被采样(作为纹理采样) |
TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | 2 | 可作为帧缓冲的颜色附件 |
TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | 4 | 可作为深度/模板附件 |
TEXTURE_USAGE_STORAGE_BIT | 8 | 可作为 storage image(如计算着色器写入) |
TEXTURE_USAGE_STORAGE_ATOMIC_BIT | 16 | 可作为支持原子操作的 storage image |
TEXTURE_USAGE_CPU_READ_BIT | 32 | 可用texture_get_data()回读,数据常驻系统内存 |
TEXTURE_USAGE_CAN_UPDATE_BIT | 64 | 可用texture_update()更新 |
TEXTURE_USAGE_CAN_COPY_FROM_BIT | 128 | 可作为复制操作的源 |
TEXTURE_USAGE_CAN_COPY_TO_BIT | 256 | 可作为复制操作的目标 |
TEXTURE_USAGE_INPUT_ATTACHMENT_BIT | 512 | 可作为输入附件 |
TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT | 4096 | 可作为深度/模板 resolve 附件 |
针对Texture2DArrayRD的典型用途,至少要设置TEXTURE_USAGE_SAMPLING_BIT;如果后续还要更新纹理数据,需追加TEXTURE_USAGE_CAN_UPDATE_BIT;如果需要从 GPU 回读结果(如计算着色器输出),则需追加TEXTURE_USAGE_CPU_READ_BIT。
第四步:调用 texture_create()
RenderingDevice.texture_create()的签名(见 class_renderingdevice.rst):
texture_create(format: RDTextureFormat, view: RDTextureView, data: Array[PackedByteArray] = []) -> RID关于data参数,官方文档有一个容易踩坑的关键说明:
对于
TEXTURE_TYPE_1D、TEXTURE_TYPE_2D、TEXTURE_TYPE_3D类型,data数组只能有一个元素,即包含全部纹理数据的单个PackedByteArray;对于_ARRAY和_CUBE类型,数组长度应与format.array_layers的数量一致。
也就是说,2D 纹理数组的每一层必须作为独立的PackedByteArray传入data,数组长度必须等于array_layers。
综合以上步骤,一个创建 2D 纹理数组并包装为Texture2DArrayRD的完整流程如下(基于官方文档中的 API 签名与 compute_shaders 教程模式组织):
var rd := RenderingServer.create_local_rendering_device() # 1. 配置纹理格式:2D 纹理数组,4 层,每层一张图 var fmt := RDTextureFormat.new() fmt.texture_type = RenderingDevice.TEXTURE_TYPE_2D_ARRAY fmt.width = 256 fmt.height = 256 fmt.array_layers = 4 fmt.mipmaps = 1 fmt.format = RenderingDevice.DATA_FORMAT_R8G8B8A8_UNORM fmt.usage_bits = RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT # 2. 每层准备独立的像素数据(此处示意为空数据) var layers: Array[PackedByteArray] = [] for i in fmt.array_layers: layers.append(PackedByteArray()) # 实际应填充该层的像素字节 # 3. 在 RenderingDevice 上创建纹理,得到 RID var rid := rd.texture_create(fmt, RDTextureView.new(), layers) # 4. 包装为 Texture2DArrayRD 供材质/网格引用 var tex := Texture2DArrayRD.new() tex.texture_rd_rid = rid完成上述步骤后,tex即可赋值给StandardMaterial3D的albedo_texture、Texture2DArray类型的采样器等位置。
纹理数据更新与 GPU 回读
Texture2DArrayRD绑定的是 GPU 上的纹理对象,数据更新与回读均通过RenderingDevice完成。
更新单个图层:texture_update()
texture_update(texture: RID, layer: int, data: PackedByteArray) -> Error(见 class_renderingdevice.rst),它会原地替换已有纹理数据,要求新数据与原有纹理具有相同的尺寸和格式。
官方文档给出三条重要约束:
- 更新后的数据必须与原纹理尺寸、格式一致;
- 在绘制列表或计算列表创建期间禁止更新纹理;
- 纹理必须携带
TEXTURE_USAGE_CAN_UPDATE_BIT位才可更新。
# 更新第 2 层的数据(示例) var new_data := PackedByteArray() # 实际为尺寸/格式匹配的像素字节 rd.texture_update(rid, 1, new_data)从 GPU 回读:texture_get_data() 与异步版本
texture_get_data(texture: RID, layer: int) -> PackedByteArray:同步回读,官方文档明确警告该方法会阻塞 GPU 直到数据取回;texture_get_data_async(texture: RID, layer: int, callback: Callable) -> Error:异步版本,RenderingDevice 会在若干帧后携带请求时刻的纹理数据调用callback,性能更优。
如果希望回读更快,创建纹理时应附带TEXTURE_USAGE_CPU_READ_BIT,因为该位使纹理常驻系统内存。
资源清理与生命周期管理
RenderingDevice是低层 API 抽象,所有创建的 GPU 资源都必须显式释放。texture_create()返回 RID 后,官方文档特别提醒:
用完你的 RID 后,应使用 RenderingDevice 的
free_rid()方法释放该 RID。
free_rid(rid: RID)的定义见 class_renderingdevice.rst。正确的生命周期应该是:RenderingDevice创建 RID → 赋值给Texture2DArrayRD.texture_rd_rid使用 → 不再需要时调用rd.free_rid(rid)释放。这与 Godot 高层Resource的自动引用计数机制不同,属于典型的低层资源管理模式,务必与纹理的创建一一配对,避免 GPU 资源泄漏。
Texture2DArray 与 Texture2DArrayRD 如何选择
两者名字相近但定位截然不同,官方文档给出了明确指引。
常规方案:Texture2DArray(见 classes/class_texture2darray.rst)。它由多个独立Image组成,每个图像尺寸与 mipmap 级别相同;与Texture3D不同,它不支持图像间的三线性插值(无混合);与AtlasTexture不同,它的所有图像相互独立处理,mipmap 链按层单独生成。可通过编辑器导入预设生成,或从代码调用ImageTextureLayered.create_from_images()创建,也可由ResourceLoader.load()加载。日常资源管理、序列化、编辑器中可见的场景都应走这条路。
低层方案:Texture2DArrayRD。它没有内置的数据存储,只是 GPU 纹理 RID 的「包装器」,无法从磁盘资源直接加载,必须在运行时配合RenderingDevice手动创建、更新与释放。适合以下场景:
- 在计算着色器中生成或修改纹理数据后,需要把结果交给材质使用(官方推荐的 Compute Texture demo 即属此类,教程框架参见 compute_shaders.rst);
- 需要对接外部 Vulkan 等低层 API 创建的纹理(
texture_create_from_extension()可包装外部VkImage); - 需要精细控制
usage_bits、mipmap 层级、图层切片等底层细节(如texture_create_shared_from_slice()的layers参数只对 2D 纹理数组等多层纹理有意义,见 class_renderingdevice.rst)。
从TextureLayered基类(见 classes/class_texturelayered.rst)的角度看,两者都满足「所有图层图像尺寸与 mipmap 数一致」这一分层纹理前提,区别只在于数据来源:一个是常规图像数据,一个是 GPU 设备侧资源。
使用注意事项小结
- 适用渲染后端:
RenderingDevice在 headless 模式与 Compatibility 渲染方法下不可用,OpenGL 驱动下create_local_rendering_device()返回null; - 层级概念:2D 纹理数组的「层」对应
RDTextureFormat.array_layers,texture_create()的data数组长度必须等于层数,texture_update()/texture_get_data()也按层索引访问; - 用法标志:采样、更新、回读分别依赖
TEXTURE_USAGE_SAMPLING_BIT、TEXTURE_USAGE_CAN_UPDATE_BIT、TEXTURE_USAGE_CPU_READ_BIT,缺失对应位会导致相应操作失败; - 手动释放:
texture_rd_rid指向的 RID 必须通过rd.free_rid()显式释放,不会随RefCounted自动回收; - 默认选择:非低层定制场景,一律优先使用
Texture2DArray,其导入、加载、编辑器支持更完善。
需要进一步深入时,可对照阅读 class_renderingdevice.rst(texture_create/texture_update/texture_get_data等全部低层 API)、class_rdtextureformat.rst(纹理格式参数)、class_texturelayeredrd.rst(texture_rd_rid属性)以及 compute_shaders.rst(完整的 RenderingDevice 计算管线实践)。
- 文档
- 教程
- 游戏开发
【免费下载链接】godot-docs
Godot Engine official documentation
相关推荐
Godot RenderingDevice 纹理格式完全指南:RDTextureFormat 属性、枚举与创建流程详解
Godot RenderingDevice 纹理格式完全指南:RDTextureFormat 属性、枚举与创建流程详解 导读 :本文以 Godot 官方文档 R
文档教程游戏开发Godot 4 RenderingDevice 纹理视图(RDTextureView)详解:格式覆盖与通道重映射实战
Godot 4 RenderingDevice 纹理视图(RDTextureView)详解:格式覆盖与通道重映射实战 导读 RDTextureView 是 Go
文档教程游戏开发Godot 分层纹理导入器 ResourceImporterLayeredTexture 指南:Texture3D、Cubemap 与纹理数组的导入与压缩配置详解
Godot 分层纹理导入器 ResourceImporterLayeredTexture 指南:Texture3D、Cubemap 与纹理数组的导入与压缩配置详
文档教程游戏开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考