--- tags: - Texture - Texture2D - RenderTexture --- # 总结 - **RenderTexture 的像素数据 100% 在显存(GPU Memory)中**,不是在 CPU 内存中。 - 除非**触发回读CPU**,也就是ReadPixel,才会在内存中有数据 - 内存中有RT对象、Unity C++中的handle 下面分层说明其放在哪里、为什么、以及哪些部分可能在 CPU。 --- # 1. **RenderTexture 的核心像素存储位置:显存 (VRAM)** Unity 调用底层 API(DX11/12、Metal、Vulkan、GLES)时,创建 RenderTarget Texture 一定会将纹理 Allocation 放在: - **VRAM(GPU local memory)** - 或在某些平台(集显)上在**统一显存 UMA**区域(但本质也属于 GPU 可直接访问的物理内存) 因为: ### RenderTexture 必须支持: - GPU 作为 RenderTarget 写入 - GPU 作为 Shader 资源读 - ComputeShader random write(开启 enableRandomWrite 时) 这些都要求纹理在 GPU 可直接寻址的专用显存中。 **所以 RenderTexture 不会放在 CPU 内存(System RAM)。** --- # 2. 那系统内存会占用吗? 会,但只是**少量管理结构**: |类型|是否在 CPU RAM|说明| |---|---|---| |RenderTexture 对象(C# wrapper)|✔|占用极小(几十字节)| |Unity 内部 RenderTexture handle|✔|也非常小| |像素数据|✖|全在显存| **像素数据绝不会放在 System RAM。** 除非你用 `ReadPixels` 强制拷贝。 --- # 3. 特殊情况(集显、移动设备) 即便 CPU 和 GPU 共用物理内存(如 Intel 集显、移动 SOC),Unity 仍然会: - 将 RenderTexture 创建成 **GPU 访问区域的纹理资源** - 不会放到 CPU 那边的缓冲区 因此逻辑上它依然属于“显存”。 --- # 4. 如果你读取 RenderTexture,会发生什么? 例如: `RenderTexture.active = rt; tex.ReadPixels(...);` **这会把 RenderTexture 从 GPU → CPU 进行一次拷贝** 代价巨大,会 stall GPU → CPU pipeline。 但这只是“做了 CPU 副本”,RenderTexture 仍然在显存中。 --- # 5. Unity Profiler 中的 Attrib Profiler 中 GPU Memory 的 **RenderTexture** 项目,就是 VRAM 占用。 CPU Memory 中不会出现它。 如果你看到 CPU Memory 涨,是你创建了大量 Texture2D Readback 副本。