美文网首页多媒体和建模Unity Shader分享
Unity Shader学习—入门知识点总结一

Unity Shader学习—入门知识点总结一

作者: 一个有味道的名字 | 来源:发表于2017-11-07 20:53 被阅读72次

    关于 unity shader 的入门知识点网上还是有很多的,那这里进行一下简单的总结,当然只是对语法结构上的总结。

    shader,也叫着色器,是GPU渲染管线中的一部分,只是这部分是可编程的,也就是可以通过编程进行控制。

    而在unity中进行的shader编写与传统意义上的shader还是有一些不同的,因为unity相当于做了一层封装,我们需要按照unity给定的语法结构进行shader编写,如果直接像是OpenGL或者Direct3D那样编写是行不通的。

    当然,这里只对unity shader进行总结,OpenGL与Direct3D可以自行百度。

    OK,对于unity shader而言,更准确的说是unityshaderlab,其有两种常用的结构:

    • 表面着色器,也就是surface shader,这是unity提出来的一种概念,简化了shader的编写难度,而且提供了大量的内置变量,宏,方法等等,unity建议使用表面着色器来编写和光照有关的shader。
    • 顶点片元着色器,也就是vertex and fragment sahder,在OpenGL与Direct3D中也有类似的着色器,基本上没什么区别。顶点片元着色器比着表面着色器更加的自由与强大,当然,对于光照,顶点片元着色器需要自行处理。

    可能有的朋友还听说过固定渲染管线shader,这是一种已经被弃用的shader,但是在一些老式的显卡上还是有这样的shader的。这里不做过多的介绍。

    那么,我们来看一下关于shader的语法结构:

    Paste_Image.png

    整个shader,大致可以分为两个部分:

    • Properties块,用于定义属性,显示在Inspector面板上。
    • SubShader,子着色器,一个shader可以有多个子着色器,当然,重要的是子着色器里面的内容Pass块,一个子着色器可以包含多个Pass块,Pass块中就是shader代码。当有多个Pass块时,除了会根据平台,硬件等因素自动识别第一可以执行的Pass块外,还可以通过代码控制执行具体的Pass块。

    OK,下面是Shader的语法:

    Shader "name"{
          Properties{
            ....
          }
          SubShader{
            Tags{...}
            [CommonState]
            Pass{
                //也可以有Tags{}
                CGPROGRAM
                ...
                ENCG
              }
           // Fallback "name"
          }
    }
    

    大致的语法结构就是这样。
    解释一下:

    • 属性定义:Properties,定义shader的输入,这些输入可以有默认值,且可以在Inspector面板上进行修改调试,还可以通过代码进行修改。
    • 子着色器:一个shader可以有多个子着色器,这些子着色器互不干扰,且只有一个会运行,编写多个子着色器的目的是为了解决平台兼容性问题,unity会自己选择兼容终端平台的shader运行。
    • Pass:一个Pass就是一次绘制,可以看成一个DC(DrawCall),对于表面着色器而言,只有一个Pass,但是顶点片元着色器可以有多个Pass,多个Pass可以实现一些特殊效果。
      而且我们可以在一个shader中使用另一个shader的某一个Pass块,Pass块是可以命名的,使用use "passname"这样的方式可调用,具体方式
    • CG代码:写在CGPROGRAM与ENDCG之间。
    • Fallback:回滚,相当于备胎。

    关于shader的输入:

    • 属性定义变量:属性定义中的变量是Shader参数的主要设置方式。 它是随材质变化的,每个使用该Shader的材质都可以在Inspector或者脚本中设置这些参数。这些参数除了在Shader的Properties段中定义外,还需要在Cg中声明方可使用。

    • 全局变量:Shader有一组SetGlobalXXX方法,可以对Shader的在Cg中定义而没有在属性中定义的uniform变量进行设置。这个设置是全局的,所有定义了该uniform的Shader都会受到影响。例如我们希望场景随着时间变化而改变颜色,就可以给场景所使用到的Shader设置统一的全局颜色变量,然后在脚本中通过设置该颜色来改变场景的颜色。在角色释放技能时场景变黑也可以使用这个方法。

    至于能在shader中定义的属性,有如下几种:

    Paste_Image.png

    下面介绍一些关于SubShader中的知识点:

    • Tags:标签,被用来修饰子着色器,硬件会通过标签来决定什么时候调用该着色器。
      比较常见的Tags有:
      1. Queue 渲染队列
        从名字就可以看出来,这个是决定渲染顺序的,它定义了一个整数,决定了shader的渲染次序,数字越小就越早被渲染,这也就意味着,越早渲染就会被后渲染的物体给覆盖掉。
        unity中预定义的渲染队列有:
    Paste_Image.png
    1. RenderType
      渲染模式,其实它主要是用在处理camera特效上的,ShaderPeplacement是会用到渲染模式的。通常情况下,我们也就会在当渲染透明物体时用 "RenderType"="Transparent",在渲染不透明物体时用"RenderType"="Opaque"。

    2. IgnoreProjector
      忽略投影,在一些特效上,可能需要忽略投影所造成的效果。
      更多关于Tags的内容

    • CommonState:渲染状态,SubShader中可以定义一组Render State,基本上就是一些渲染的开关选项,他们对该SubShader的所有的Pass都有效,所以称Common。当然,这些Render State也可以在每个Pass中分别定义。
      比较常见的有以下几种:
      Cull Back | Front | Off
      多边形表面剔除开关。Back表示背面剔除,Front表示正面剔除,Off表示关闭表面剔除即双面渲染。
      ZWrite On | Off
      控制当前对象的像素是否写入深度缓冲区(depth buffer),默认是开启的。一般来说绘制不透明物体的话ZWrite开启,绘制透明或半透明物体则ZWrite关闭。
      ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
      控制如何进行深度测试,默认是LEqual。
      Blend Off
      关闭混合
      Blend SrcFactor DstFactor
      最终颜色 = Shader产生的颜色 × SrcFactor + 屏幕上原来的颜色 × DstFactor
      Blend SrcAlpha OneMinusSrcAlpha
      透明度混合
      更多参考在此

    OK,第一部分就先介绍到这里。

    相关文章

      网友评论

        本文标题:Unity Shader学习—入门知识点总结一

        本文链接:https://www.haomeiwen.com/subject/mbyjmxtx.html