【Unity-Shader脚本】0基础学会通过用Unity-Shader脚本渲染图像数据(NV21,NV12,RGBA数据)详细教程--附demo,NV21测试图像,YUV图像查看器。

这篇具有很好参考价值的文章主要介绍了【Unity-Shader脚本】0基础学会通过用Unity-Shader脚本渲染图像数据(NV21,NV12,RGBA数据)详细教程--附demo,NV21测试图像,YUV图像查看器。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

  最近有一个需求是需要我在Unity中将获取到的图像数据来展示在Unity的界面之中。功能其实很简单,熟悉Unity-Shader的小伙伴可能很快就可以做出来。然而我很少和图像的渲染打交道,基本上是0基础了,在做这个需求之前连Shader是什么都不知道。本文记录了自己做这个需求所学习到的Unity-Shader的基础知识,以及渲染数据的方法和代码。文末会给出测试程序和代码,通过Unity可以直接运行。

  本文适合和我一样的0基础的小伙伴,需要实现在Unity中将图像数据(包括NA21,NV12,RGBA三种数据格式)绘制到Unity界面中。通过本片文章,你会学到以下内容:

  1. 看懂我给出的Unity-Shader的Demo,知道Demo是如何渲染图像数据的。
  2. 能够对Demo进行简单的修改来完成新的功能。(比如你要渲染BGRA的图像,或者你需要将渲染的图像镜像等)
  3. 学习到Unity-Shader最最基础和浅显的知识。

Unity-Shader代码部分讲解

什么是Unity-Shader

  Shader就是一种专门用来渲染图像的技术,通过Shader可以自定义显卡渲染方法,来展示出高大上的炫酷特效。通过Shader可以操作GPU去绘制模型中的每一个像素点的颜色。

  目前有三种Shader语言,他们分别是:

  1. 基于OpenGL的OpenGL Shading Language(GLSL)
  2. 基于DirextX的High Level Shading Language(HLSL)
  3. 基于NVIDIA公司的C for Graphic.(Cg)

  而Unity-Shader,其实Unity对Shader的一层封装。如果在Unity中使用Shader,那你就不用深究使用以上哪三个语言来实现Shader技术,你只用专注于Unity平台中的Shader脚本的规则。
  在Unity平台中,Unity-Shader也有三种不同的书写方法,他们分别是:Surface Shaders 表面着色器(功能最强大);Vertex/Fragment Shaders 顶点/片断着色器(最主流);Fixed Function Shaders 固定管线着色器(已经废弃);
  在三种方法中,Fixed Function Shaders已经被淘汰,完全没有学习的必要了。Surface Shaders 是功能最强大的,Vertex/Fragment Shaders 顶点/片断着色器是最主流的。基本上目前的Unity-Shader的教程都是以Vertex/Fragment Shader来讲解的。当然本文的工程也是使用Vertex/Fragment Shader来实现的。

Unity-Shader中编写格式

  既然是Unity-Shader,那么它的格式既遵循Unity封装的标准,也需要遵循传统的Shader的格式(本例中使用的是Cg语言)。以本例的NV21图像的渲染Shader为例,Unity-Shader的基本格式包含两个部分:第一部分是Shader的名称。第二部分存放了图像像素数组,因为这个Shader是渲染NV21数据的,因此这里的图像属性有两个:分别表示Y通道像素值的数组和UV通道像素值的数组。最有一个部分SubShader就是告诉GPU对于这些数据的渲染的方法。(这里部分是使用Cg语言去实现的)
yuv图片查看器,图像处理,unity,游戏引擎
  第一部分和第二部分很简单了,这里就不做讲解了。最重要的部分就是第三部分,SubShader的编程,下面对这一部分的内容进行讲解。
  举起来说,在Unity-Shader中,Cg程序片段被放在Pass中,Pass又放在SubShader中。在CG程序片段之前,通常需要先使用 #pragma声明编译指令:
yuv图片查看器,图像处理,unity,游戏引擎
  下图是本例NV12-Shader中SubShader的实现。我在重要的部分加上了序号,这样方便讲解。
  第一个部分是Cg的一般规范,定义顶点着色器和片段着色器的名称(后面会讲解这两个东西是干啥的)。我们只用遵循它即可,一般不用修改。

  第二个部分是结构体的一些定义,是我自己写的为了方便数据格式的组织而已。

  最重点的部分就是第三个部分和第四个部分,我们要对程序进行修改,比如对数据格式为RGBA的图像进行渲染,或者图像进行镜像,就是在这里进行修改的。这两个部分也就是要实现两个函数:顶点着色器的实现和片段着色器的实现。这两个函数也分别对应着两个功能:顶点着色器用来定位位置,就是确定我现在要将像素渲染在界面上的哪一个位置。片段着色器用来确定这个点的像素具体是什么颜色的。了解了这些我们可以知道将NV21数据渲染到界面上的一个整体的流程

  1. 首先获取图像的数据,然后将Y通道的数据和UV通道的数据传到Unity-Shader脚本的Properties中(本例中以_YTex和_UVTex)保存。
  2. 通过顶点着色器依次找到界面上需要渲染的每一个像素的位置。
  3. 通过片段着色器,通过Properties中的属性值得到这些像素的颜色RGBA的值,然后进行渲染。
      第三个部分顶点着色器的实现是通过UnityObjectToClipPos函数实现的,这个函数是将这个是把顶点从模型空间直接转化到裁剪空间,也就是进行了M-V-P三次转化。如果只是进行将简单的图像2D数据渲染到界面上,那么我们也不需要进行特殊的修改。
      第四个部分片段着色器的实现。首先我们在顶点着色器中获得到要渲染像素的位置(v2f的数据类型)。然后要找到渲染点对应的_YTex和UVTexture的坐标,再通过这个坐标和properties的属性计算出像素y值,u值和v值,然后通过yuv转rgb的方法进行一个运算,计算出该像素点的rgb的值,进行一个返回。至于这里的寻找_YTex和_UVTexture的坐标的坐标代码为什么是 fixed2 uv = fixed2(i.uv.x, 1 - i.uv.y);在后面的调试方法的章节中会进行讲解。
    yuv图片查看器,图像处理,unity,游戏引擎

Unity-C#代码部分讲解

  上一节我们讲解了在Unity-Shader中是如何对图像进行渲染的。在Unity-Shader进行数据渲染之前,我们在Unity的C#语言中当然还需要将我们的数据传给Unity-Shader了。通过上节的讲解我们现在应该知道,Unity中的NV12数据传入到Unity-Shader中的_YTex和_UVTex了。这里简单讲一下Unity的数据是如何传入的。代码很简单:首先我们要创建一个_dataY和_dataUV,他们分别对应着_YTex和_UVTex。这里需要注意的是new时候的数据的定义。因为对于YUV数据类型来说,Y的数据量是UV数据量的两倍。所以这里创建_UVTex时,宽和长都除以了2.另外因为UV数据类型包含两个值,8位的U值和8位的V值,所以这里对于_YTex来说第三个参数是TextureFormat.R8,而对于_UVTex来说第三个参数是TextureFormat.RG16。
yuv图片查看器,图像处理,unity,游戏引擎
  初始化数组以后,这里通过读文件的方法将数据读到数组中,完成了_dataY和_dataUV的赋值。
yuv图片查看器,图像处理,unity,游戏引擎
  最后,将数据传入到 Texture2D _texY和 Texture2D _texUV中,使用SetTexture就将数据传到Shader脚本的_YTex和_UVTexture两个属性了
yuv图片查看器,图像处理,unity,游戏引擎

Unity-界面部分讲解及Demo使用说明

功能演示

  界面很简单,只包含一个,Scene界面上有一个RawImage,点击Start,就会将NV21数据读到Shader中,Shader接着就会对RawImage进行渲染,将图像输出到界面上。
yuv图片查看器,图像处理,unity,游戏引擎

控件的绑定关系

  控件的绑定关系是:首先创建一个RawImage,接着为这个RawImage创建一个Material(图中为DemoMaterial),在Material中选择我们写好的Shader脚本即可。
yuv图片查看器,图像处理,unity,游戏引擎

调试技巧

  在编译器中运行时,在Material中看到传入到Shader脚本中的两个属性(T Texture和UV Texture)。分别表示颜色信息和亮度信息,在图像渲染不正确的时候可以先检查这两个图像通道是否输入正确。
yuv图片查看器,图像处理,unity,游戏引擎

程序扩展

  在本文的Demo中,给出了NV21图像的渲染方法和Demo。对于其它的一些扩展,这里只提供思路,如果大家需要,可以留言评论一下,后面我再将其它的功能也整合到demo中。更多更炫酷的功能还是要大家自己开发啦。

NV12图像数据的渲染

  NV12的图像和NV21的图像非常接近,所以如果需要渲染NV12的图像格式是非常简单的,只需要在Shader脚本中将u,v变量交换即可。
yuv图片查看器,图像处理,unity,游戏引擎

BRG图像数据的渲染

  如果需要渲染BGRA的图像,首先我们数据的输入就不需要两个通道了(之前是Y通道和UV通道),因此我们需要,在properties中我只需要一个_BGRATex即可,然后在顶点着色器中直接取出BGRA四个分量值进行返回即可。
yuv图片查看器,图像处理,unity,游戏引擎

yuv图片查看器,图像处理,unity,游戏引擎
  关于BGRA在C#中对应的Texture2D也需要注意,因为它的数据格式变了,相应的Texture2D的初始化部分也和NV21部分有差异。(TextureFormat变成了RGBA32)
yuv图片查看器,图像处理,unity,游戏引擎
  关于BGRA的Shader脚本我也放在Demo工程中,但是对应的C#部分是缺失的,有需要的同学可以找我要或者自行补充。

图像的镜像

  镜像:其实就是一个图像左右翻转的过程。Shaer脚本的顶点着色器部分中: fixed2 uv = fixed2(i.uv.x, 1 - i.uv.y);这一句话就是控制扫描的方向。如果需要镜像,我们只需要将图像扫描的方式从由左到右变成由右到左。因此控制一下这一句,将代码改成fixed2 uv = fixed2(1- i.uv.x, 1 - i.uv.y);即可。
yuv图片查看器,图像处理,unity,游戏引擎

Demo工程说明

  Demo工程包含一套整体的NV21图像的渲染的工程,包含一张测试图像。另外工程中给出了BRGA图像格式渲染的Shader脚本供参考,对应的C#部分代码需要大家补齐。最后给大家提供了一个YUV格式的图像查看器,大家可以进行辅助测试。
  获取Demo及YUV格式图像查看工具,关注公众号后发送:Unity-Shader即可。
文章来源地址https://www.toymoban.com/news/detail-768192.html

到了这里,关于【Unity-Shader脚本】0基础学会通过用Unity-Shader脚本渲染图像数据(NV21,NV12,RGBA数据)详细教程--附demo,NV21测试图像,YUV图像查看器。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity - Stencil Test 开关,无法通过脚本或是 shader lab 开关来控制

    查看过 shader lab 文档: ShaderLab command: Stencil,没有看到 stencil test 关闭的功能,我真的无语。。。 只能开,不能关,意思一个 shader lab 一旦编写了 stencil { } 的内容,就必须开启。。。 好 low 的设计 在网上同样搜索到对应的 unity 论坛贴图: how to disable the Stencil block via shader pr

    2024年02月16日
    浏览(28)
  • 【unity shader】水体渲染基础-基于texture distortion的流体流动材质

    当液体静止时,它在视觉上与固体没有太大区别。 但大多数时候,我们的性能不一定支持去实现特别复杂的水物理模拟, 需要的只是在常规的静态材料的表面上让其运动起来。我们可以对网格的 UV 坐标实现动态变化,从而让表面的纹理效果实现变形的动态变化。 1.1. uv实时

    2024年02月03日
    浏览(44)
  • 【Unity Shader】Unity前向渲染

    ForwardBase Pass(优先渲染),渲染一个逐像素平行光和所有的顶点/球面调和光,阴影只和平行光有关系,那阴影应该是这个Pass中实现的 ForwardAdd Pass(需要和Base配合使用,否则不生效),渲染剩余全部逐像素灯光 Unity会根据场景中各个光源的设置以及这些光源对物体的影响程

    2024年02月08日
    浏览(46)
  • Unity中Shader编译目标渲染器

    Unity中Shader编译到目标渲染器 #pragma only_renderers 仅编译指定平台的Shader d3d11 - Direct3D 11/12 glcore - OpenGL 3.x/4.x gles - OpenGL ES 2.0 gles3 - OpenGL ES 3.x metal - iOS/Mac Metal vulkan - Vulkan d3d11_9x - Direct3D 11 9.x功能级别,通常在WSA平台上使用 xboxone - Xbox One ps4 - PlayStation 4 psp2 - PlayStation Vita n3ds -

    2024年02月05日
    浏览(35)
  • Unity shader 入门之渲染管线一、总览

     如下示意图 应用阶段(ApplicationStage):准备场景信息(视景体,摄像机参数)、粗粒度剔除、定义每个模型的渲染命令(材质,shader)——由开发者定义,不做讨论。 几何阶段(GemetryStage):顶点着色器、曲面细分着色器、几何着色器、裁剪、屏幕映射; 光栅化阶段(Rasterizer

    2024年02月11日
    浏览(30)
  • 【Unity大气渲染】Unity Shader中实现大气散射(半成品)

    写在前面 这是之前在做天空盒的时候同步写的分析博客,结果后面写到一半就忘了继续了,这里先贴出当时写的半成品,有小伙伴问我怎么做的,这里只能尽力把之前的半成品先放出来了(写得很乱,勿怪orz),,后面有机会会完善好的!希望能帮到大家~ 前置知识学习 【

    2024年02月08日
    浏览(34)
  • unity build-in 渲染管线升级urp渲染 shader篇

            由于工作原因需要对项目进行升级,从build-in渲染管线升级到urp渲染管线,我自己对应的unity版本是2018.版本升级到2021.3.2版本,由于最近几年unity版本升级比较快,个体版本差异有所不同,如遇与版本不一致问题敬请谅解。以下是根据官网等系列网站整理的内容

    2023年04月16日
    浏览(42)
  • Unity大面积草地渲染——1、Shader控制一棵草的渲染

    目录 1、Shader控制一棵草的渲染 2、草地的动态交互 3、使用GPUInstancing渲染大面积的草 4、对大面积草地进行区域剔除和显示等级设置 大家好,我是阿赵。 这里开始讲大面积草地渲染的第一个部分,一棵草的渲染。按照惯例,完整shader在最后。前面是原理的介绍。 这里我自己

    2024年02月12日
    浏览(33)
  • Unity Shader从内置渲染管线迁移到URP

    Unity 在URP中将shader更新为了HLSL语言,使用build-in shader 无法直接在URP中使用 这里讲一下关于shader的更新方法 参考 From Built-in to URP Tags 添加 \\\"RenderPipeline\\\" = \\\"UniversalPipeline\\\" CGPROGRAM ENDCG 改变为 HLSLPROGRAM ENDHLSL #include \\\"UnityCG.cginc\\\" 更改为 #include \\\"Packages/com.unity.render-pipelines.universal/Sh

    2024年02月05日
    浏览(31)
  • Unity中的渲染优化技术 -- Shader入门精要学习(15)

    本章中,我们将阐述一些 Unity 中常见的优化技术。这些优化技术都是和渲染相关的,例如,使用批处理、LOD 技术等。 游戏优化不仅是程序员的工作,更需要美工人员在游戏的美术上进行一定的权衡。例如,避免使用全屏的屏幕特效,避免使用计算复杂的 Shader,减少透明混合

    2024年01月18日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包