初识Unity Shader

前言:我能想到最浪漫的事,就是敲一行代码,给你一个五光十色的完美世界。虽然现实中一行代码是远远不够的,但是能够利用代码创造出那些出色的画面、炫酷的特效仍是让人着迷其中。要想实现如上所述,我们不妨走进Shader的世界,其中Unity作为一个上手方便的游戏引擎,自然也提供了可编写的Unity Shader文件来帮助我们实现。

作为刚刚入门、仍是学习在线的萌新的我,希望能将这一段时间的学习记录下来,以达对知识的巩固及分享当下学习的心得与感悟之效,下面就让我们一起踏上学习Unity Shader之旅吧!

Shader能起到什么作用?我们不妨先来看看GLSL Sandbox Gallery网站上的一些例子。
链接入口:http://www.glslsandbox.com/

是否被那些绚丽的效果所震撼?这就是我们的Shader所能做的,当然它能做的不仅仅这些。

要想学好Shader,不管是目前三大主流编程语言HLSL/GLSL/Cg,还是Unity的ShaderLab,我们首先都该了解一些渲染原理与工作机制,只有这样我们才能更好理解Shader的编写。

Shader,翻译过来即着色器,与之紧密关联的就是渲染流水线,实际上Shader只是渲染流水线中的一个环节。渲染流水线的工作即从一个虚拟的三维场景出发,最终渲染出一张我们可见的二维图像,这个工作通常由CPU和GPU共同完成。

通过CPU将数据加载到显存中,设置好渲染状态,之后调用Draw Call就会给GPU下达一个渲染命令,GPU收到命令后便会进行一系列流水线操作,最终把图元渲染到屏幕上。

GPU流水线过程大致如下(括号内为该阶段所做工作):

输入顶点数据顶点着色器(坐标变换:由模型空间→齐次裁剪空间;逐顶点光照;计算顶点颜色等)→曲面细分着色器(细分图元)→几何着色器(逐图元着色)→裁剪(舍弃单位立方体外图元,裁剪相交部分图元)→屏幕映射(将三维坐标转化为窗口坐标)→三角形设置(由顶点数据计算三角网格表示数据)→三角形遍历(根据三角网格覆盖像素生成片元)→片元着色器(纹理采样;着色)→逐片元操作(对片元模板测试(限制渲染区域)→深度测试(舍弃被遮挡片元)→混合(处理透明物体)→写入颜色缓冲区)→输出屏幕图像

GPU流水线阶段图: GPU流水线

除屏幕映射、三角形设置、三角形遍历外,其余阶段都是可编程控制/可配置的。由上可见Shader所在阶段只是渲染流水线的一部分,依靠它我们可以控制流水线中的一些渲染细节,但要得到出色的画面,必须要所有过程共同参与才可完成,仅仅只考虑Shader是不够的,我们还要设置适当的渲染状态,使用合适的混合函数,以及决定是否关闭深度测试/写入等。

Unity Shader能够让我们更加轻松地管理着色器代码与渲染的设置,我们可以将它和材质一起搭配使用,以达到我们想要的效果。在Unity中,我们需要创建一个材质,将写好的Unity Shader赋给这个材质,再将材质赋给需要渲染的对象,之后可以通过在材质面板上调整属性来达到预期渲染效果。

Unity 5.2及以上版本提供了4种Unity Shader模板:
Standard Surface Shader(包含了标准光照模型的表面着色器模板)、Unlit Shader(不包含光照(但包含雾效)的基本的顶点/片元着色器)、Image Effect Shader(实现各种屏幕后处理效果提供基本模板)、Compute Shader(利用GPU并行性进行一些与常规渲染流水线无关的计算)

我们通常使用Unlit Shader来生成一个基本顶点/片元着色器

Unity Shader文件使用ShaderLab来编写。下面是一些常用ShaderLab语义的作用:

Shader:指定该Unity Shader的名字及在材质面板中出现位置

Properties:设置材质面板上显示的属性

SubShader:定义Pass及可选的状态和标签设置;每个Pass定义了一次完整的渲染流程

Fallback:设置最低级的Unity Shader

我们真正意义上的Shader代码都包含在SubShader语义块中。 它是使用Unity经封装后提供的Cg/HLSL编写的,语法和标准的Cg/HLSL几乎一样,只是有些原生的函数和用法,Unity没有提供支持。

以上我们已经初步了解了渲染的大体流程以及Unity Shader的一些语义。在本次的最后,将以一个最简单的Shader编写例子作为收尾。

一个简单例子代码如下: A simple example

它的输出结果: Result

把编写好的Shader代码赋给一个材质,再赋到新建的一个球体上,没错,我的结果就只是一个普通的白色小球。不过它已经可以让我们基本了解一个顶点/片元着色器内部要编写哪些内容了。

由代码部分,结合GPU流水线所讲,我们可以看到顶点着色器的最基本作用就是顶点转换,它通过把模型空间顶点与一个变换矩阵相乘来得到裁剪空间中的坐标(这里直接利用了Unity内置函数);而片元着色器则是主要负责决定之后的渲染着色,这里仅简单的输出白色。当然,通常我们的顶点着色器输入参数与输出不会这么简单,往往会是一个结构体的形式,以包含更多的信息。

胡溢钧

河海大学常州校区学生,一只很蠢很蠢的新人。

Changzhou,Jiangsu,China

Subscribe to CG-HHU

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!