☰
Godot Texture2DArrayRD 详解:将 RenderingDevice 低层纹理数组接入材质与网格
2026/10/14 21:28:20 网站建设 项目流程
  • 文档
  • 教程
  • 游戏开发

【免费下载链接】godot-docs

Godot Engine official documentation

项目地址:https://gitcode.com/GitHub_Trending/go/godot-docs
点击查看免费下载

导读

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_ridRID在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。获取途径有两种:

  1. 全局设备:RenderingServer.get_rendering_device(),负责向屏幕绘制,Godot 启动时自动创建(见 class_renderingserver.rst)。
  2. 局部设备: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),其属性及默认值如下:

属性默认值含义
width1纹理宽度(像素)
height1纹理高度(像素)
depth1纹理深度,2D 纹理恒为1
array_layers1图层数量,仅对 2D 纹理数组有意义
mipmaps1纹理可用的 mipmap 数量
format8像素数据格式(RenderingDevice.DataFormat枚举)
texture_type1纹理类型(RenderingDevice.TextureType枚举)
samples0采样时使用的样本数(多重采样)
usage_bits0用途位掩码(TextureUsageBits),决定纹理可被做什么操作
is_discardablefalse内容是否无需跨帧保留(仅作为绘制列表目标时相关)
is_resolve_bufferfalse是否用作 resolve 操作的目标

关键点:创建 2D 纹理数组时,必须将texture_type设为TEXTURE_TYPE_2D_ARRAY(值5),并通过array_layers指定图层数量。RenderingDevice.TextureType枚举完整定义(见 class_renderingdevice.rst)如下:

枚举值值含义
TEXTURE_TYPE_1D01D 纹理
TEXTURE_TYPE_2D12D 纹理
TEXTURE_TYPE_3D23D 纹理
TEXTURE_TYPE_CUBE3Cubemap 纹理
TEXTURE_TYPE_1D_ARRAY41D 纹理数组
TEXTURE_TYPE_2D_ARRAY52D 纹理数组
TEXTURE_TYPE_CUBE_ARRAY6Cubemap 纹理数组
TEXTURE_TYPE_MAX7枚举大小(哨兵值)

第三步:指定 usage_bits

usage_bits是决定纹理用途的位掩码(TextureUsageBits,见 class_renderingdevice.rst),常用位如下:

位标志值含义
TEXTURE_USAGE_SAMPLING_BIT1可被采样(作为纹理采样)
TEXTURE_USAGE_COLOR_ATTACHMENT_BIT2可作为帧缓冲的颜色附件
TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT4可作为深度/模板附件
TEXTURE_USAGE_STORAGE_BIT8可作为 storage image(如计算着色器写入)
TEXTURE_USAGE_STORAGE_ATOMIC_BIT16可作为支持原子操作的 storage image
TEXTURE_USAGE_CPU_READ_BIT32可用texture_get_data()回读,数据常驻系统内存
TEXTURE_USAGE_CAN_UPDATE_BIT64可用texture_update()更新
TEXTURE_USAGE_CAN_COPY_FROM_BIT128可作为复制操作的源
TEXTURE_USAGE_CAN_COPY_TO_BIT256可作为复制操作的目标
TEXTURE_USAGE_INPUT_ATTACHMENT_BIT512可作为输入附件
TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT4096可作为深度/模板 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),它会原地替换已有纹理数据,要求新数据与原有纹理具有相同的尺寸和格式。

官方文档给出三条重要约束:

  1. 更新后的数据必须与原纹理尺寸、格式一致;
  2. 在绘制列表或计算列表创建期间禁止更新纹理;
  3. 纹理必须携带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 设备侧资源。


使用注意事项小结

  1. 适用渲染后端:RenderingDevice在 headless 模式与 Compatibility 渲染方法下不可用,OpenGL 驱动下create_local_rendering_device()返回null;
  2. 层级概念:2D 纹理数组的「层」对应RDTextureFormat.array_layers,texture_create()的data数组长度必须等于层数,texture_update()/texture_get_data()也按层索引访问;
  3. 用法标志:采样、更新、回读分别依赖TEXTURE_USAGE_SAMPLING_BIT、TEXTURE_USAGE_CAN_UPDATE_BIT、TEXTURE_USAGE_CPU_READ_BIT,缺失对应位会导致相应操作失败;
  4. 手动释放:texture_rd_rid指向的 RID 必须通过rd.free_rid()显式释放,不会随RefCounted自动回收;
  5. 默认选择:非低层定制场景,一律优先使用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

项目地址:https://gitcode.com/GitHub_Trending/go/godot-docs
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询