Unity3D shader简介

Unity3D shader简介

可以肯定的说Unity3D使得很多开发者开发游戏更容易。毫无疑问,shader(着色器)编码,仍有很长的路要走。shader是一个专门运行在GPU的程序,经常被神秘包围,它最终绘制3D模型的三角形。如果你想给游戏一个特殊的显示,学习如何编写shader是必要的。Unity3D使用shader做后期处理,对2D游戏也是必不可少的。这个系列的文章将逐步介绍shader编程,并面向几乎没有任何shader知识的开发者。

简介

下图大致表示了在Unity3D渲染流程中发挥作用的3个不同实体:

3D模型本质上是,被称为顶点的3D坐标集合。他们连接在一起构成一些三角形。每个顶点包含一些其它的信息,如颜色、点指的方向(法线)、纹理映射坐标(UV数据)。

没有材质模型是不能被渲染的。材质包含一个shader和其属性值的封装。因此,不同材质可以共享相同的shader,赋予不同的数据。

shader剖析

Unity3D支持两种不同的shader:表面shader、片段和顶点shader。还有第三种类型:固定管线shader,但是如今已经过时了,将不包含在本系列文章。无论你需要的是哪种类型,shader的结构都一样:


Shader "MyShader"

{

Properties

{

// The properties of your shaders

// - textures

// - colours

// - parameters

// ...

}

SubShader

{

// The code of your shaders

// - surface shader

//    OR

// - vertex and fragment shader

//    OR

// - fixed function shader

}

}

可以包含多个SubShader,一个接一个。他们包含GPU的实际指令。Unity3D将找到与你显卡兼容的SubShader,并顺序执行他们。这对多平台编码是非常有用,因为你可以在一个文件中编写同一shader的不同版本。

属性

shader的属性在某种程度上相当于C#脚本中的public字段,他们将出现在材质的inspector面板,给你机会来调整。但不像脚本,材质是资源:编辑中游戏运行时修改材质的属性值是永久的。甚至游戏停止后,修改的属性值也是有效的。

下面的代码片段涵盖了你可以在shader中使用的所有基本类型的定义:

3~4行中的2D,表示参数是纹理。他们可以初始化为white、black、gray。你也可以使用bump表示使用法线贴图,这种情况下,它将自动初始为颜色#808080,这用来表示没有任何凸凹。Vector和Color总是有4个元素(分别为xyzw和rgba)。

下图展示了一个shader附着到一个材质上之后,在inspector面板中是如何显示的。

不幸的是,这对我们使用属性还不够。事实上,Properties块被Unity3D用来从inspector访问shader隐藏变量。这些变量仍需定义在shader中,它们包含在SubShader块中。

纹理的类型为sampler2D。向量是float4、颜色一般是half4,分别使用32和16位表示。用来编写shader的语言为Cg/HLSL,很迂腐:参数的名称必须与先前定义的匹配。然而类型不需要,例如把_MyRange声明为half而不是float不会报任何错误。一些令人困惑的是,如果你定一个向量类型的属性,关联到一个float2变量,额外的2个值将被Unity3D忽略。

渲染顺序

正如已提到的,SubShader块包含实际代码,使用Cg/HLSL(非常像C)编写。不严格地说,一个shader为图像的每个像素执行,它的性能非常关键。由于GPU的体系结构,一个shader中能够执行的指令数量有限制。可以通过分割几个部分执行,但本教程不包含这块。

一个SubShader通常看起来像这样:

第8~11行包含实际的Cg代码,通过CGPROGRAM和ENDCG指令示意。

第3行,在实际代码之前,介绍tags的概念。tags用来告诉Unity3D我们写的shader的某些属性。例如,shader渲染的顺序(Queue)和应该如何渲染(RenderType)。

当渲染三角形时,GPU通常根据它们离摄像机的距离,远的先绘制。这在渲染不透明的几何形状时够用了,但是透明物体将失败。这也是为什么Unity3D运行指定Queue标签,可以控制每个材质的渲染顺序。Queue接受正整数(越小越先绘制),预定义(mnemonic)的标签也可以使用:

l  Background(1000):用于背景和天空盒

l  Geometry(2000):默认标签,用于大部分不透明物体

l  Transparent(3000):用于包含透明属性的材质,例如玻璃、火、粒子、水

l  Overlay(4000):用于镜头耀斑,GUI元素和文本

Unity3D还允许指定相关顺序,例如Background+2,表示1002队列值。搞乱了Queue值会导致恶劣的情况,一个对象总是被绘制,即使它应该被其他模型遮挡住了。

Ztest

记住,一个包含透明属性(Transparent)的对象并不总是显示在不透明(Geometry)对象上面。默认情况下,GPU执行ZTest避免隐藏的对象被绘制。原理是,它使用了一个额外的缓冲区,其大小与屏幕渲染的相同。每个像素包含绘制对象在该像素的深度(离相机的距离)。如果我们要绘制一个像素比当前深度更大,像素就被丢弃。ZTest剪裁被其它对象遮挡住的像素,无论他们绘制到屏幕上的顺序。

表面 VS 顶点和片段

shader代码的最后一部分。在渲染之前,需要决定使用那种类型的shader。本节将给出shader效果惊鸿一瞥的样子,但不会深入解释。表面、顶点和片段shader将在本教材的下一部分覆盖。

表面shader

当材质需要根据光照模拟实际效果时,那么你就需要一个表面shader。表面shader在函数surf中隐藏光线如何被反射的计算,并允许指定“直观”的属性,如反照率、法线、反射率等。然后将这些值插入到光照模型,将输出每个像素的最终RGB值。或者,当需要非常高级的效果是,你也可以编写自己的光照模型。

一个典型的表面shader的Cg代码如下所示:

第5行指定输入的纹理,然后在第12行将指定Albedo属性。第3行指定使用Lambertian光照模型,这个是非常典型光照如何影响对象的模型。shader仅使用反照率属性通常称为漫反射(diffuse)。

顶点和片段shader

顶点和片段shader的工作贴近GPU渲染三角形的方式,并没有光照如何表现的概念。模型的几何形状首先通过一个调用函数vert,改变他的顶点。然后各个三角形通过另一个调用函数frag,这决定了最终每个像素的RGB颜色。这对2D效果非常有用,后期处理和特殊的3D效果非常付出需要使用表面shader。

下面的顶点和片段shader简单只是使用红色,没有光照:

第15~17行,将原始的3D空间顶点转换到最终的2D屏幕位置。Unity3D使用UNITY_MATRIX_MVP实现,隐藏了底层的实现数学运算。在此之后,第22行,给定每个像素为红色。只需要记住,顶点和片段shader的Cg部分需要封装到Pass块中。它跟简单的表面shader不一样。

结论

本篇文章逐渐引入了两种类型的Unity3D shader,并说明何时需要使用。接下来四篇文章,将介绍实现它们的细节。还有一个附加篇,将介绍屏幕shader,用于2D图像的后期处理。

时间: 2024-10-12 17:36:10

Unity3D shader简介的相关文章

【译】Unity3D Shader 新手教程(1/6)

刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D Shader编程望而却步.该系列教程的第一篇文章(译者注:即本文,后续还有5篇文章)详细介绍了Unity3D中的表面着色器(Surface Shader)的,为学习更复杂的Shader编程打下基础. 动机 如果你是刚刚接触Shader编程的新手,你可能不知道从何开始踏出Shader编程的第一步.本教程将带你一步步完成一个表面着色器(Surface Shader)和片段着色器(Fra

【浅墨Unity3D Shader编程】之六 暗黑城堡篇: 表面着色器(Surface Shader)的写法(一)

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/plus/view.php?aid=165 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文主要讲解了Unity中SurfaceShader的具体写法,以及几个常用的CG函数的用法. 在这里先说明一下,表面着色器将分为

【淡墨Unity3D Shader计划】五 圣诞用品: Unity在Shader三种形式的控制&混合操作编译

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/42060963 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 文章开头,先给自己诚求个游戏研发实习的好去处. 浅墨今年1月.明年上半年有近半年的空暇时间可供实习. 近5年游戏编程经验,能够胜任全职的游戏开发工作.仅仅拿实习生的工资(性价比非常高有

【浅墨Unity3D Shader编程】之七 静谧之秋篇: 表面着色器的写法(二)——自定义光照模式

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/plus/view.php?aid=183 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文主要讲解了Unity中SurfaceShader的自定义光照模式的写法. 上篇文章中我们已经说到,表面着色器将分为两次讲解,上

【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色、光照与材质

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 本篇文章中,我们学习了Unity Shader的基本写法框架,以及学习了Shader中Properties(属性)的详细写法,光照.材质与颜色的具体写法.写了6个Shader作为本文S

【浅墨Unity3D Shader编程】之三 光之城堡篇:子着色器、通道与标签的写法 & 纹理混合

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/41175585 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 本文介绍了Unity中子着色器.通道和标签相关的详细概念与写法,以及纹理的设置方法,基本的纹理混合写法,写了5个Shader作为本文Shader讲解的实战内容,最后创建了一个梦幻的光之

unity3d shader 学习

[浅墨Unity3D Shader编程] 着色器参考 [Unity Shaders]

【浅墨Unity3D Shader编程】之五 圣诞夜篇: Unity中Shader的三种形态对比&混合操作合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处.  文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/164.html 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文算是固定功能Shader的最后一篇,下一次更新应该就会开始讲解表面Shader,而

【浅墨Unity3D Shader编程】之四 热带雨林篇: 剔除、深度测试、Alpha测试以及基本雾效合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/163.html 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文介绍了Unity中Shader书写中会用到的剔除.深度测试.Alpha测试以及基