【Unity Shaders】学习笔记——渲染管线
【Unity Shaders】学习笔记——Shader和渲染管线
转载请注明出处:http://www.cnblogs.com/-867259206/p/5595924.html
写作本系列文章时使用的是Unity5.3。
写代码之前:
当然啦,如果Unity都没安装的话肯定不会来学Unity Shaders吧?
阅读本系列文章之前你需要有一些编程的概念。
在VS里面,Unity Shaders是没有语法高亮显示和智能提示的,VS党可以参考一下这篇文章使代码高亮显示,也可以下载
shaderlabvs或NShader之类的插件使代码高亮显示。这是针对小白的Unity Shaders的基础知识,如果你已经有了基础或者你是大神,那么这些文章不适合你。
由于作者水平的局限,文中或许会有谬误之处,恳请指出。
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有四种:
Fixed function shader 属于固定渲染管线Shader, 基本用于高级Shader在老显卡无法显示时的备用Shader。
Vertex and Fragment Shader 最强大的Shader类型,属于可编程渲染管线。使用的是CG/HLSL语言。也就是我上面说过的两种。
Surface Shader Unity3d推荐的Shader类型。它是一个代码生成器,帮我们将重复的代码省去了,使得编写Shader更为容易。使用的也是CG/HLSL语言。
Compute Shader 这是Unity3D新增的一种。看下度娘百科对它的介绍:
Compute Shader技术是微软DirectX 11 API新加入的特性,在Compute Shader的帮助下,程序员可直接将GPU作为并行处理器加以利用,GPU将不仅具有3D渲染能力,也具有其他的运算能力,也就是我们说的GPGPU的概念和物理加速运算。
Compute Shader 使用HLSL语言。
接下来我们就要从最简单的Surface Shader学起。
【Unity Shaders】学习笔记——渲染管线的更多相关文章
- Unity Shader学习笔记-1
本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github 如果有什么说的不正确的请批评指正 目录 渲染流水线 流程图 Shader作用 屏幕映射 三角形遍历 两大 ...
- 【Unity Shader学习笔记】Unity基础纹理-法线贴图
1 高度纹理 使用一张纹理改变物体表面法线,为模型提供更多细节. 有两种主要方法: 1.高度映射:使用一张高度纹理(height map)来模拟表面位移(displacement).得到一个修改后的法 ...
- 【Unity Shader学习笔记】Unity光照基础-高光反射
1.原理 1.1.Phong模型 计算高光反射需要表面法线.视角方向.光源方向.反射方向等. 在这四个矢量中,我们实际上只需要知道其中3个矢量即可,而第4个矢量(反射方向r)可以通过其他信息计算得到: ...
- 【Unity Shader学习笔记】Unity光照基础-半兰伯特光照
在光照无法达到的区域,模型的外观通常是全黑的,没有任何明暗变化,这会使模型的背光区域看起来就像一个平面. 使用半兰伯特光照可以解决这个问题. 逐顶点光照技术也被称为兰伯特光照模型.因为它符合兰伯特定律 ...
- 从0开始学习Unity的学习笔记(I 界面学习和简单模型拼装)
先给一个大致今天学习的图,然后后面是细节 1.下载Unity :官网下载需要版本 2.Unity安装:一定不要有中文路径:一台电脑可以安装不同版本的Unity,但是要安装在不同的文件夹下: 3. 新建 ...
- 【Unity Shader学习笔记】Unity基础纹理-单张纹理
1 单张纹理 1.1 纹理 使用纹理映射(Texture Mapping)技术,我们把一张图片逐纹素(Texel)地控制模型的颜色. 美术人员建模时,会在建模软件中利用纹理展开技术把纹理映射坐标(Te ...
- Unity sqlite学习笔记一
1.SQLITE的常识 SQLite是一个开源免费的数据库,一般用于嵌入系统或者小规模的应用软件开发中,你可以像使用Access一样使用它. sqlite的主要优点:零配置(Zero Configur ...
- unity 3D 学习笔记
1.父对象的初始位置设,即刚开始的空对象的根节点位置应当设置成(0,0,0) 这样设置可以避免以后出现奇怪的坐标. GameObject实际上就是一些组件的容器. unity 使用公用变量原因是,在U ...
- Unity Shader学习笔记 - 用UV动画实现沙滩上的泡沫
这个泡沫效果来自远古时代的Unity官方海岛Demo, 原效果直接复制3个材质球在js脚本中做UV动画偏移,这里尝试在shader中做动画并且一个pass中完成: // Upgrade NOTE: r ...
随机推荐
- objective-c 下面int 和 NSData数据 互相转换的方法
抄自这里 ; NSData *data = [NSData dataWithBytes: &i length: sizeof(i)]; int i; [data getBytes: & ...
- 判断是否含有中文,包含返回true,不包含返回false
/** * 功能:判断是否含有中文,包含返回true,不包含返回false */ function isChina(s) { var patrn = /[\u4E00-\u9FA5]|[\uFE30- ...
- 从1970年1月1日00:00:00 GMT以来此时间对象表示的毫秒数转化为Datetime
1970年1月1日(00:00:00 GMT)Unix 时间戳(Unix Timestamp)对时间转换 将Long类型转换为DateTime类型 /// <summary> /// 将L ...
- ASP.NET运行机制原理
ASP.NET运行机制原理 一.浏览器和服务器的交互原理 (一).浏览器和服务器交互的简单描述: 1.通俗描述:我们平时通过浏览器来访问网站,其实就相当于你通过浏览器去另一台电脑上访问文件一样,只不过 ...
- 用radio控制<tr>的隐藏和显示问题
jsp页面代码 <tr> <th nowrap="nowrap" width="10%" height="50px" st ...
- 一个优秀的C#开源绘图软件 DrawTools
1.Extensions to DrawTools Author Mark Miller I develop software for a leading healthcare system in N ...
- spring和springmvc之间的整合
一.springmvc就是运行在spring的环境下,这两者是否需要进行整合,即:是不是要把service .dao . 事务 .和其它框架的整合放在springmvc的配置文件中.这样子在技术层面上 ...
- 使用mustache.js 模板引擎输出html
看了https://mustache.github.io/你就知道mustache是非常强大的模板引擎,支持多种语言,下面是个简单入门例子: MVC Model public class Studen ...
- PostgreSQL在Ubuntu上安装指南
安装环境: Ubuntu 10.04-desktop-i386 PostgreSQL 8.4 1. 安装PostgreSQL 输入如下命令 sudo apt-get install postgresq ...
- C++primer 练习13.44
13.44:编写标准库string类的简化版本,命名为String.你的类应该至少有一个默认构造函数和一个接受C 风格字符串指针参数的构造函数.使用allocator为你的String类分配所需内存 ...