Unity Texture2D的 Read/Write 选项

  • 开启 (Read/Write = True) :CPU 可以读写贴图像素数据,贴图会在内存一份、GPU 显存一份。

  • 关闭 (Read/Write = False,默认) :CPU 无法访问贴图像素数据,贴图只存GPU 显存一份。


Read/Write 什么时候开启?

  • 读取像素 :用 GetPixels 获取颜色数据,用于截图保存、地图编辑等

  • 修改像素 :用 SetPixels 运行时动态绘制贴图(如画板功能),修改后需调用 Apply() 上传至 GPU

  • 生成资产 :脚本创建 Texture2D 后调用 EncodeToPNG 保存到本地


Texture2D.Apply()

当你 new Texture2D()后,不会在GPU分配显存, 会首先在**系统内存(CPU侧)**创建纹理对象的数据容器。

  • 内存分配 :构造函数会立即在系统内存中分配像素数据数组(可通过 GetPixels 等直接访问)。

  • 显存分配 :只有当你调用 Apply() 方法后,数据才会被上传到GPU显存 。如果不调用 Apply(),纹理只存在于系统内存中,无法被正确渲染显示。

调用 Apply() 的核心作用,就是将当前系统内存中的像素数据 同步(上传/更新)到 GPU显存中。


问题:为什么 new Texture2D() 后,即使没分配显存,为什么也能在Game窗口中看到?(是纯白的图像)

  1. 理论上的运行时行为 :如果这是一个打包后的游戏 (Build出来的exe),没有调用Apply(),贴图绝对不会显示,或者显示为紫色/黑色错误材质。因为GPU显存里根本没有数据。

  2. 编辑器中的"魔法" :Unity编辑器为了提升开发体验,在某些情况下 会"好心"地帮你自动调用Apply()。当它检测到你将一个未Apply的Texture2D赋值给材质时,编辑器可能会强制同步数据到GPU,让你能在Scene/Game视图里看到效果,方便调试。

new Texture2D()之后,要显示就一定要Apply()。编辑器里的"显示"只是一个为了方便调试的假象。


Read/Write 可以在构建时设定一次,构建出来Texture2D后,Read/Write就不可设定了。

在Apply后释放内存:

直接在 Apply 时将 makeNoLongerReadable 参数设为 true ,Unity会在数据上传至GPU后,立即自动释放系统内存中的那份副本。

cs 复制代码
// 修改像素后,上传数据并立即释放CPU内存
texture2D.Apply(true, true);

参数含义 :第一个 true 是更新Mipmap;第二个 true 就是"不再让CPU读取",上传后丢掉内存副本。


Read / Write 默认设置:

场景 Read / Write 原因
Unity 导入 Assets 不勾选 (False) 省内存:上传到 GPU 后自动丢弃系统内存副本。如果不需要用 CPU 读写像素,保持默认即可。
动态创建 (new Texture2D) 默认开启 (True), 可在构造函数中设定 保功能 :创建时会在系统内存保留数据,方便你随时调用 GetPixelsSetPixels

Read / Write 如果为false,如果硬要读取时怎么办?

如果贴图未开启 Read/Write,官方方案是通过 RenderTexture 间接读取(无需修改原贴图设置):

  1. 创建临时 RenderTexture

  2. Graphics.Blit 将贴图画到 RenderTexture 上

  3. ReadPixels 从 RenderTexture 读取像素到新 Texture2D

⚠️ 此方法有额外性能开销,不适合频繁操作,适合偶发的截图或工具开发。


Texture2D 的 LoadImage 方法:

目的是从 byte\[\]获取像素数据创建出 Texture2D。

有两点需要注意:

① 它会自己调用 Apply,无需手动再调用一次

② LoadImage 方法有一个重载版本:

public bool LoadImage(byte\[\] data, bool markNonReadable);

设为 true → 告诉 Unity 你不需要在 CPU 端读写像素数据 → Unity 可以尝试释放 CPU 端的拷贝

· 设为 false(默认) → Unity 保留 CPU 端可读写拷贝

相关推荐
WiChP14 小时前
【V0.1B11】从零开始的2D游戏引擎开发之路
开发语言·游戏引擎
玖玥拾14 小时前
Cocos学习笔记:武器系统与数据驱动UI联动
游戏引擎·cocos2d
winlife_16 小时前
全程用 AI 做一款商业级手游 · EP1 地基:先搭框架层,不急着写玩法
unity·ai编程·游戏架构·mcp·框架设计·funplay
小贺儿开发17 小时前
Unity VideoPlayer 播放控制器
unity·编辑器·播放器·视频·工具·videoplayer·互动
め.1 天前
UIFramework
ui·unity
fqbqrr1 天前
2606d,用d语言构建游戏引擎
游戏引擎·d
℡枫叶℡1 天前
Unity - Import Activity Window 资源导入诊断信息窗口
unity·资源导入诊断
TO_ZRG2 天前
Unity 证书校验
unity·游戏引擎
mxwin2 天前
Unity Shader 切线空间数据是如何计算出来的
unity·游戏引擎·shader