Unity3D中如何将16位单通道红外数据填充到R16格式纹理
实现方案
该需求完全可以落地,你创建的R16格式纹理本身就和ushort类型的红外数据完全匹配,只需要解决数据传递的问题即可,有两种常用实现方式:
方案1:直接通过指针传递(性能最优,无额外内存拷贝)
不需要把ushort数组转成byte数组,直接通过GCHandle获取数组内存指针调用对应重载即可,不需要开启项目unsafe编译选项:
// infraredRawData为你拿到的原始ushort格式红外数据 ushort[] infraredRawData = /* 你的源数据 */; // 钉住数组防止GC移动内存 GCHandle dataHandle = GCHandle.Alloc(infraredRawData, GCHandleType.Pinned); try { IntPtr dataPtr = dataHandle.AddrOfPinnedObject(); // 第二个参数为总字节长度,ushort占2字节,所以总长度为数组长度*2 infraredTexture.LoadRawTextureData(dataPtr, infraredRawData.Length * sizeof(ushort)); // 提交更新到GPU infraredTexture.Apply(); } finally { // 必须释放句柄,否则会造成内存泄漏 dataHandle.Free(); }
方案2:转byte数组传递(兼容性最好,适合需要预处理数据的场景)
如果需要先对红外数据做裁剪、阈值过滤等预处理,也可以显式转成byte数组再传递:
ushort[] infraredRawData = /* 你的源数据 */; // 每个ushort占2字节,所以byte数组长度是ushort数组的2倍 byte[] rawByteData = new byte[infraredRawData.Length * 2]; // 直接拷贝内存块,比逐元素转换效率高很多 Buffer.BlockCopy(infraredRawData, 0, rawByteData, 0, rawByteData.Length); infraredTexture.LoadRawTextureData(rawByteData); infraredTexture.Apply();
显示适配注意事项
R16格式纹理无法直接用默认的Unlit/Texture shader正常显示,需要做适配:
- 优先选择Unity内置的
Unlit/Grayscaleshader,大部分版本都原生支持16位单通道灰度显示 - 如果内置shader不符合需求,可以自己写一个极简的shader,采样纹理R通道后直接输出到RGB三个通道即可,采样后可以除以
65535把16位值映射到0-1的标准灰度范围,方便做亮度调整。
内容的提问来源于stack exchange,提问作者link
相关产品推荐
相关产品推荐

