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

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/Grayscale shader,大部分版本都原生支持16位单通道灰度显示
  • 如果内置shader不符合需求,可以自己写一个极简的shader,采样纹理R通道后直接输出到RGB三个通道即可,采样后可以除以65535把16位值映射到0-1的标准灰度范围,方便做亮度调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:06:00