You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中Compute Shader读取Texture2DArray单张纹理报错及实现问询

解决方案

一、修复回读数据错误

1. 匹配Texture2D格式

相机画面为R16格式(16位无符号整数灰度图),但默认创建的Texture2D是RGBA32格式,会导致数据量不匹配。创建时必须指定TextureFormat.R16:

Texture2D extractedTexture = new Texture2D(
    cam.Key.VideoTexture.width, 
    cam.Key.VideoTexture.height, 
    TextureFormat.R16, 
    false // 无需生成mipmap
);

2. 正确读取数据类型

R16格式对应的数据类型是ushort(16位无符号整数),而非float。GetData<float>()会将每个像素视为4字节的float,导致数据量仅为预期的一半。改用GetData<ushort>():

extractedTexture.LoadRawTextureData(result.GetData<ushort>());

3. 移除无用代码

AsyncGPUReadback已直接读取指定切片的数据,无需设置RenderTexture.active,可删除该行代码。

4. 优化AsyncGPUReadback参数

若cameraOutputTexturesArray是RenderTexture类型的Tex2DArray,可省略第三个纹理格式参数,让Unity自动匹配:

AsyncGPUReadback.Request(cameraOutputTexturesArray, index2, result => { ... });

二、Compute Shader中按索引访问纹理切片

在Compute Shader中,通过texture.Load(int3(x, y, sliceIndex))访问Texture2DArray的指定切片:

RWTexture2DArray<float4> OutputArray;
Texture2DArray<float4> InputArray;

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // 替换为目标相机索引
    int sliceIndex = 2;
    float4 color = InputArray.Load(int3(id.x, id.y, sliceIndex));
    
    // 处理逻辑...
    
    OutputArray[id.xyz] = color;
}

若需处理整个数组,可在Dispatch时将z维度设为相机数量,或在Shader中循环遍历切片索引。

三、更优实现建议

  1. 复用Texture2D:当前代码每次回读都创建新Texture2D,会产生GC开销。可提前为每个相机创建对应Texture2D,后续回读时复用。
  2. 批处理Dispatch:相机数量较多时,合并Compute Shader的Dispatch调用,减少GPU状态切换。
  3. GPU端直接渲染:若无需将数据读回CPU,可自定义Shader让RawImage直接采样Texture2DArray的指定切片,避免CPU-GPU数据拷贝开销。

内容的提问来源于stack exchange,提问作者Lilly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:57:36