Unity 工具之 YUV(YUV420 :I420,YV12,NV12,NV21)使用 shader 转为 RGB 显示 封装 YUV420ToRGBWrapper

Unity 工具之  YUV(YUV420 :I420,YV12,NV12,NV21)使用 shader 转为 RGB 显示 封装 YUV420ToRGBWrapper

 

目录

Unity 工具之  YUV(YUV420 :I420,YV12,NV12,NV21)使用 shader 转为 RGB 显示 封装 YUV420ToRGBWrapper

一、简单介绍

二、YUV相关知识

1、什么是 YUV

2、YUV 数据格式解析(YUV420 I420)

3、YUV 分类

4、YUV 转 RGB 公式

三、实现原理

四、注意实现

五、效果预览

六、实现步骤

1、打开 Unity,新建一个空工程

2、在工程中,新建几个脚本和shader(以及对应的Material),并导入yuv 数据资源

3、编写脚本,YUV420ToRGBWrapper 脚本是对应 YUV 格式拆分 YUV 数据,YUV420ToRGB 脚本shader 把 YUV 转为 RGB,Test_YUV420ToRGBWrapper 脚本是获取资源测试 YUV420ToRGBWrapper  接口

4、搭建场景,新建plane ,添加 3D Text,布置场景如图

5、把shader  材质赋给 plane,并把脚本挂载游戏物体上

6、运行场景,分别按下 N 键,或 I 键,就会解析 yuv 为 rgb,效果如上

七、关键代码

1、YUV420ToRGBWrapper

2、Test_YUV420ToRGBWrapper

3、YUV420ToRGB shader

参考资料:

参考文章:


 

 

一、简单介绍

Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。

本节介绍如果把对应的YUV数据转为RGB,然后再 Unity中显示出来。

 

二、YUV相关知识

1、什么是 YUV

YUV是被欧洲电视系统所采用的一种颜色编码方法(属于PAL),是PAL和SECAM模拟彩色电视制式采用的颜色空间。在现代彩色电视系统中,通常采用三管彩色摄影机或彩色CCD摄影机进行取像,然后把取得的彩色图像信号经分色、分别放大校正后得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号B-Y(即U)、R-Y(即V),最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。这种色彩的表示方法就是所谓的YUV色彩空间表示。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。

Y分量主管亮度的(其实就是灰度图),U和V分量主管色彩的。所以即使没有U和V分量,一样可以看到图像,只是没有颜色罢了(只有黑白色)。如果不理解,想想我们小时候的黑白电视机和彩电,黑白电视机就是只有Y分量的图像,而彩电就是有三个分量的图像。所以YUV格式的视频数据也是当时美国用来适配黑白电视机和彩电的一种方案。

 

2、YUV 数据格式解析(YUV420 I420)

由图可见,I420格式的YUV数据的三个分量Y/U/V被分离在了3个连续的内存块中,而每个Y都会对应一个像素,每4个像素共用一组UV。所以一张 s = width x height 的图片,就会有 s 个像素,s 个Y,s / 4 个U和V这张图片占用的内存 m = width * height * 1.5 byte 。
 

3、YUV 分类

这里以 YUV420 为例:

主要分为I420 , YV12,,NV12,,NV21,具体布局如下:

I420: YYYYYYYY UU VV =>YUV420P

YV12: YYYYYYYY VV UU =>YUV420P

NV12: YYYYYYYY UV UV =>YUV420SP

NV21: YYYYYYYY VU VU =>YUV420SP

 

I420 图示:

 

YV12 图示:

 

NV12 图示:

 

NV21 图示:

 

4、YUV 转 RGB 公式

R = Y + 1.4022 *(V-128)

G = Y – 0.3456 *(U –128) –0.7145 *(V –128)

B = Y + 1.771 *(U – 128)

YUV2RGB的转换公式本身是很简单的,但是牵涉到浮点运算,所以,如果要实现快速算法,算法结构本身没什么好研究的了,主要是采用整型运算或者查表来加快计算速度。以上是在CPU里做的转换,本文将会把这种转换放到GPU里去做,毕竟GPU很擅长并行计算,对于这种粗鲁的运算,GPU是很快的。

在Unity 的 shader 中 RGB 表示范围是 [0,1],而不是[0,255],所以上面公式略作修改

R = Y + 1.4022 *(V-0.5)

G = Y –0.3456 *(U –0.5) – 0.7145 *(V –0.5)

B = Y + 1.771 *(U – 0.5)

 

三、实现原理

1、首先根据 YUV 对应格式的 YUV 的排列方式,拆分 YUV;

2、然后,在通过 YUV 与 RGB 转换对应公式,进行转换;

3、最后,shader 方式显示出来;

4、调用接口,YUV420ToRGBWrapper.YUV420ToRGB(YUV420 yuv420_Format, byte[] data, int width, int height, Renderer renderer),设定YUV 格式,数据,宽、高、以及目标的渲染的 Renderer ,即可实现 YUV 转 RGB

 

四、注意实现

1、如果解析出来的画面翻转颠倒,可以直接在shader 中调整 uv 的 x y 转正;

2、注意区分 YUV 的格式,每种YUV 排列会略有不同,对应解析才能出来画面原版本效果;

3、在Uni

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙魁XAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值