【Unity Shaders】学习笔记——Shader和渲染管线


转载请注明出处:http://www.cnblogs.com/-867259206/p/5595924.html

写作本系列文章时使用的是Unity5.3。
写代码之前:

  1. 当然啦,如果Unity都没安装的话肯定不会来学Unity Shaders吧?

  2. 阅读本系列文章之前你需要有一些编程的概念。

  3. 在VS里面,Unity Shaders是没有语法高亮显示和智能提示的,VS党可以参考一下这篇文章使代码高亮显示,也可以下载shaderlabvsNShader之类的插件使代码高亮显示。

  4. 这是针对小白的Unity Shaders的基础知识,如果你已经有了基础或者你是大神,那么这些文章不适合你。

  5. 由于作者水平的局限,文中或许会有谬误之处,恳请指出。


Shader的意思就是着色器,也就是“给物体上色”,所以Shader的作用就是计算物体最终显示的颜色是什么。
GPU这个名词相信大家都不陌生。它是计算机处理图像的元件。GPU是Graphic Processing Unit(图形处理单元)的缩写。由于 GPU 具有高并行结构(highly parallel structure),所以 GPU 在处理图形数据和复杂算法方面拥有比 CPU 更高的效率。我们来看一下下面两段代码的对比,这两段代码都是提取 2D 图像上每个像素点的颜色值,第一段是在CPU上运算的C++代码,第二段是在GPU上运算的Cg代码:

CPU要用for循环语句遍历像素,而GPU只要一行代码就够了。GPU在图形处理方面很强大吧?
而Shader,就是GPU执行的一段针对3D对象进行操作的程序。

Shader开发语言

  • HLSL: 主要用于Direct3D。平台:windows。

  • GLSL: 主要用于OpenGL。 平台:移动平台(iOS,安卓),mac(only use when you target Mac OS X or OpenGL ES 2.0)

  • CG:与DirectX 9.0以上以及OpenGL 完全兼容。运行时或事先编译成GPU汇编代码。
    CG比HLSL、GLSL支持更多的平台,Unity Shader采用CG/HLSL作为开发语言。

Unity3d里CG如何编译

  • Windows:Direct3D GPU汇编代码

  • Mac:OpenGL GPU汇编代码

  • Flash: flash GPU汇编代码

  • Ios/Android: Unity会将CG转换成GLSL代码
    也就是除了移动平台会把CG转换成GLSL代码,其余平台都是转换成汇编代码。

渲染管线

Shader按管线分类一般分为固定渲染管线与可编程渲染管线。
渲染管线(Rendering Pipeline)其实就是GPU渲染流程。你可以这样理解渲染,在一个三维坐标系下,给定一个视点(即摄相机),给定三维物体、光源以及照明模式、纹理等信息,如何绘制一幅呈现在视点画面中的二维图像的过程。
早期GPU遵循的管线叫固定管线(Existing Fixed Function Pipeline)。
                     
(英语不太好的查下图中每个方框里的单词,因为我懒得在图上标注中文了)
图中橙色的部分是用户可以通过GPU配置的。顾名思义,固定管线就是功能固定的管线啦。所谓的功能固定,按照我的理解,就是物体表面与光的反射、折射的算法固定,无法修改,因此物体只能表现出类似塑料的那种质感(如果你用3DMax建过模型,你会理解的),虽然可以用贴图来弥补。固定管线只能配置“是否开启雾效”、“是否开启光照”、“是否开启深度测试”等一些参数,而不能控制物体与光交互的算法。不同质感的物体,比如金属和木头,金属反光强烈,看起来质感坚硬,木头反光较弱,看起来质感较软一些,金属和木头两种材质着色的算法应该是不一样的。总之,固定管线因为功能固定,无法在程序上对物体细节的表现给予更多更自由的控制,无法达到更多更炫酷的效果。
如今已经不再需要学习固定管线了,GPU都已经进入了2.0时代,新的显卡都是可编程渲染管线了。
所谓的可编程,就是上面所说的功能固定的那个部分,变成可以由程序员编程控制了。这样自由度就更大了,可以表现出更多的特效了。
先来看看可编程渲染管线的流程吧。

第一块橙色,是Vertex Shader(顶点着色),第二块橙色是Fragment Shader(片元着色)。这两个部分,就是程序员可以编程的部分了。顶点着色程序,它的作用是逐个对顶点进行变换,得到物体的轮廓,然后对面上的像素进行线性插值。片元着色程序,根据检测不同,来决定是否修正每个像素的color等信息,逐像素处理。Vertex的输出是Fragment的输入。Vertex是顶点变换,输入和输出都需要包含顶点的position信息;Fragment是色深的变化,输出一般只有color信息。如果你是第一次接触这部分的知识,你可能会觉得有些迷惑,不过没关系,随着学习的深入你会渐渐明白。你只要大致明白,定点着色器主要是对顶点进行处理,而片元着色器主要是计算像素的色彩。
其实还有其他的着色程序,但这里不会涉及,所以不会深入说明。

OpenGL渲染管线

 

如图所示,这是OpenGL的工作流程图。
关于图中的各个过程具体都在做些什么工作,可以看看这篇博客,讲得挺详细的,我就不赘述了。
上述的这些过程,初学者可以简单地记为四个部分

顶点变换 → 图元装配和光栅化 → 片元纹理映射和着色 → 写入帧缓存

可编程的部分就是顶点变换和片元着色啦。

Unity3D的四种Shader

Unity的Shader有四种:

  1. Fixed function shader 属于固定渲染管线Shader, 基本用于高级Shader在老显卡无法显示时的备用Shader。

  2. Vertex and Fragment Shader 最强大的Shader类型,属于可编程渲染管线。使用的是CG/HLSL语言。也就是我上面说过的两种。

  3. Surface Shader Unity3d推荐的Shader类型。它是一个代码生成器,帮我们将重复的代码省去了,使得编写Shader更为容易。使用的也是CG/HLSL语言。

  4. Compute Shader 这是Unity3D新增的一种。看下度娘百科对它的介绍:

Compute Shader技术是微软DirectX 11 API新加入的特性,在Compute Shader的帮助下,程序员可直接将GPU作为并行处理器加以利用,GPU将不仅具有3D渲染能力,也具有其他的运算能力,也就是我们说的GPGPU的概念和物理加速运算。

Compute Shader 使用HLSL语言。

接下来我们就要从最简单的Surface Shader学起。

【Unity Shaders】学习笔记——渲染管线的更多相关文章

  1. Unity Shader学习笔记-1

    本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github 如果有什么说的不正确的请批评指正 目录 渲染流水线 流程图 Shader作用 屏幕映射 三角形遍历 两大 ...

  2. 【Unity Shader学习笔记】Unity基础纹理-法线贴图

    1 高度纹理 使用一张纹理改变物体表面法线,为模型提供更多细节. 有两种主要方法: 1.高度映射:使用一张高度纹理(height map)来模拟表面位移(displacement).得到一个修改后的法 ...

  3. 【Unity Shader学习笔记】Unity光照基础-高光反射

    1.原理 1.1.Phong模型 计算高光反射需要表面法线.视角方向.光源方向.反射方向等. 在这四个矢量中,我们实际上只需要知道其中3个矢量即可,而第4个矢量(反射方向r)可以通过其他信息计算得到: ...

  4. 【Unity Shader学习笔记】Unity光照基础-半兰伯特光照

    在光照无法达到的区域,模型的外观通常是全黑的,没有任何明暗变化,这会使模型的背光区域看起来就像一个平面. 使用半兰伯特光照可以解决这个问题. 逐顶点光照技术也被称为兰伯特光照模型.因为它符合兰伯特定律 ...

  5. 从0开始学习Unity的学习笔记(I 界面学习和简单模型拼装)

    先给一个大致今天学习的图,然后后面是细节 1.下载Unity :官网下载需要版本 2.Unity安装:一定不要有中文路径:一台电脑可以安装不同版本的Unity,但是要安装在不同的文件夹下: 3. 新建 ...

  6. 【Unity Shader学习笔记】Unity基础纹理-单张纹理

    1 单张纹理 1.1 纹理 使用纹理映射(Texture Mapping)技术,我们把一张图片逐纹素(Texel)地控制模型的颜色. 美术人员建模时,会在建模软件中利用纹理展开技术把纹理映射坐标(Te ...

  7. Unity sqlite学习笔记一

    1.SQLITE的常识 SQLite是一个开源免费的数据库,一般用于嵌入系统或者小规模的应用软件开发中,你可以像使用Access一样使用它. sqlite的主要优点:零配置(Zero Configur ...

  8. unity 3D 学习笔记

    1.父对象的初始位置设,即刚开始的空对象的根节点位置应当设置成(0,0,0) 这样设置可以避免以后出现奇怪的坐标. GameObject实际上就是一些组件的容器. unity 使用公用变量原因是,在U ...

  9. Unity Shader学习笔记 - 用UV动画实现沙滩上的泡沫

    这个泡沫效果来自远古时代的Unity官方海岛Demo, 原效果直接复制3个材质球在js脚本中做UV动画偏移,这里尝试在shader中做动画并且一个pass中完成: // Upgrade NOTE: r ...

随机推荐

  1. winform 承载 WCF 注意,可能不是工作在多线程模式下

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMo ...

  2. Spring实战6:利用Spring和JDBC访问数据库

    主要内容 定义Spring的数据访问支持 配置数据库资源 使用Spring提供的JDBC模板 写在前面:经过上一篇文章的学习,我们掌握了如何写web应用的控制器层,不过由于只定义了SpitterRep ...

  3. php提高效率

    1. foreach效率更高,尽量用foreach代替while和for循环. 2. 循环内部不要声明变量,尤其是对象这样的变量. 3. 在多重嵌套循环中,如有可能,应当将最长的循环放在内层,最短循环 ...

  4. android学习笔记42——图形图像处理2——绘图

    绘图 android的绘图应该继承View组件,并重写onDraw(Canvas canvas)方法即可. 重写onDraw(Canvas canvas)方法时涉及一个绘图API:Canvas,Can ...

  5. android学习笔记13——ExpandableListView

    ExpandableListView==>可展开的列表组件 ==> ExpandableListView是ListView的子类,对其进行了扩展,其将应用中的列表项分为几组,每组中又包含多 ...

  6. win7下vs2008编译出现C1859错误的处理办法

    昨天,电脑上安装的vs2008 sp1版本编译工程时候出了这样的错了:fatal error C1859: 'Debug\**.pch'.清理并重新编译会临时解决问题,但问题仍然会频发.后面上网找资料 ...

  7. HTTP协议与HTTPS的区别

    permike 原文 HTTP协议与HTTPS的区别 HTTP协议 HTTP协议主要应用是在服务器和客户端之间,客户端接受超文本. HTTP是在七层网络模型中的应用层的协议,由发送请求和接受响应构成, ...

  8. 2.Could not open Selected VM debug port (8700). Make sure you do not have another instance of DDMS or of the eclipse plugin running

    在eclipse.ini配置文件最后加上:-Djava.net.preferIPv4Stack=true 其他类似

  9. 跨浏览器复制神器 ZeroClipboard 2.x快速入门详解

    有些时候,我们希望让用户在网页上完成某个操作就能自动将指定的内容复制到用户计算机的剪贴板中.但是出于安全原因,大多数现代浏览器都未提供通用的剪贴板复制接口(或即便有,也默认被禁用).只有IE浏览器可以 ...

  10. NSSet类型 以及与NSArray区别

    NSSet到底什么类型,其实它和NSArray功能性质一样,用于存储对象,属于集合: NSSet  , NSMutableSet类声明编程接口对象,无序的集合,在内存中存储方式是不连续的,不像NSAr ...