《Unity着色器和屏幕特效》——2.2 进阶的透明效果

简介:

本节书摘来自华章计算机《Unity着色器和屏幕特效》一书中的第2章,第2.2节,作者[美]杰米·迪恩(Jamie Dean),译 周翀,张薇,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.2 进阶的透明效果

在第1章里宇航员头盔的半透明材质使用了标准着色器所支持的透明特性。但是这样做有一个问题:由于创建头盔模型时,几何体上的所有三角形都正面朝外,因此使用标准着色器时,只有外表面的正面会产生高光(specularity)效果。但是头盔是半透明的,实际上其内表面也应当接受光照从而产生高光效果。

这个问题可以通过创建自定义着色器解决。我们将在2.1节学习的基础上创建一个结构类似,但能够显示更真实的光照效果的自定义着色器。

2.2.1 创建自定义透明着色器

首先创建一个新的自定义着色器。

1.在项目(Project)面板上单击PACKT_Shaders文件夹,使它的内容显示在资源(Assets)面板上。

2.右键单击资源(Assets)面板上的任一空白位置,在弹出的菜单上单击创建(Create) | 着色器(Shader)| 标准表面着色器(Standard Surface Shader)命令。

3.将新产生的着色器重命名为“Glass”。

再次提醒:在这里为着色器设定的名称不同于材质的着色器选单中的名称,后者在着色器代码中指定。

接着将新建的着色器应用于宇航员头盔的材质,以便当我们继续修改着色器时,能够随时观察到头盔外观的变化。

1.在项目(Project)面板上找到并单击PACKT_Materials文件夹,使文件夹内容显示在资源(Assets)面板上。

2.找到并单击“Helmet”材质。

第1章曾为宇航员的头盔创建并设置过这个材质,因此对该材质的任何修改都会直接反映在场景中。这其中也包括该材质所使用的着色器。

3.在检阅(Inspector)面板上,单击着色器(Shader)下拉选单,并选择Custom/Glass。

screenshot

在场景中,宇航员的头盔应当重新变为不透明,因为自定义着色器的默认效果是不透明的。这个问题将在后续步骤中修正。

2.2.2 编辑透明着色器

当新着色器创建后,默认生成的代码里定义了着色器名称。该名称由资源面板上的名称加上Custom文件夹名组成。Custom即自定义,用于和标准着色器区分。

1.在项目(Project)面板上单击PACKT_Shaders文件夹,并在资源(Assets)面板上找到并双击“Glass”着色器。着色器的代码将在MonoDevelop中打开。

这一次我们将要仔细看一看默认生成的代码,并在其基础上做修改。

2.第一行代码定义了着色器在材质中的名称。将其改为

screenshot

末尾的花括号用于括起着色器的其他内容。

3.保存修改。

自定义着色器的默认代码已经具有光照效果,但不支持透明。接下来修改代码以实现透明。

4.在SubShader下面,找到Tags一行,并将Opaque关键字改为Transparent。

在SubShader里面的着色器编译指令代码中,可以指定使用Alpha通道或者其他属性来定义透明度。

在SubShader关键字下面不远处是品红色的Cg代码开始标识。

5.找到着色器的编译指令代码:

screenshot

6.在上面代码的最后面添加关键字alpha,并用一个空格与前面的关键字分隔。

alpha关键字使得着色器支持透明。

7.再次保存修改,并返回Unity界面。

在场景中可以看到宇航员头盔现在已经变为透明。

screenshot

透明度由着色器的颜色属性的alpha通道决定。

8.在PACKT_Materials文件夹里找到Helmet材质,在检阅(Inspector)面板上单击颜色(Color)右侧的矩形,弹出颜色选择器窗口。

9.在颜色选择器窗口中将A通道的值改为128,然后关闭颜色选择器窗口。

10.在检阅(Inspector)面板上将平滑度(Smoothness)值改为0.9以使头盔表面具有高光效果。

11.将金属光泽(Metallic)值改为0.188以使头盔表面更加闪亮。

现在如果拉近镜头仔细观察头盔表面,会发现只有外表面有高光效果。我们将继续修改着色器代码以使内表面可见。

screenshot

创建头盔的内表面

出于对运行效率的考虑,Unity默认忽略物体的背面,只渲染正面。

可以通过修改一行代码来改变这个默认行为,令Unity对物体的正面和背面都进行渲染。

1.回到MonoDevelop窗口。找到Glass着色器的SubShader代码块。

2.在LOD一行的后面添加下面代码。

screenshot

3.保存修改并且返回Unity窗口。

现在宇航员头盔的正面和背面都会被渲染出来。但是由于正面和背面属于同一个头盔模型,所以它们会在同一道渲染过程中被绘制,这有时也会造成一些错误的渲染效果。

screenshot

可以通过用两块Cg代码分两次渲染头盔的正面和背面来提高画面质量。这就是本章开始时提到的多遍渲染。

正面和背面分开渲染

为了增强真实感,可以在着色器里将头盔渲染两遍,一遍渲染背面,另一遍渲染正面。并且在其中一遍渲染时,略微放大模型,以便模拟表面的厚度感,产生内、外表面的区分。

1.回到MonoDevelop窗口。

2.在Properties代码块内的_Metallic行后面添加如下一行代码。

screenshot

上面代码为着色器增加一个厚度(_Thickness)属性,用来控制在其中一遍渲染中,模型被放大或缩小的程度。

3.找到Cull Off一行,将其改为

screenshot

4.向下找到品红色的Cg代码块结束标识ENDCG一行。

5.在该行下面添加如下代码:

screenshot

这是一个用于渲染背面的附加着色过程,即前面所说的第二遍渲染。

Cull Front(剔除正面)语句指定这一遍渲染只处理背面,以避免与前一遍只处理正面的渲染过程冲突。当然也可以将这两遍渲染过程混合在一起。本书的后面章节将介绍这种更复杂的着色器。

前面曾介绍过以#pragma关键字开头的着色器编译指令行。这一行可以指定着色器的很多特性。附加着色器过程使用了与原着色器相似的编译指令,但是增加了一个新指令:vertex:vert,这使得我们可以向着色器插入自定义的顶点处理代码。

在顶点处理代码中,以_Thickness属性的值作为移动距离,将模型的每一个顶点沿着表面的法线方向移动,从而便可实现模型的缩放。

经过两遍渲染,玻璃表面便可获得一定厚度感的。其厚度可以由检阅(Inspector)面板上的Thickness属性设置。

6.保存着色器代码的修改并返回Unity界面。

7.在项目(Project)面板上点击PACKT_Materials文件夹,并在资源(Assets)面板上找到并点击“Helmet”材质。

8.在检阅(Inspector)面板上将厚度(Thickness)值设置为-0.2。

这一技巧只适合于模拟轻薄的小块玻璃物体,如头盔、护目镜和眼镜,但它难以模拟需要折射效果的厚玻璃物体,或是其他密度较大的透明物体(例如水池)。

screenshot

在2.3节中,我们将使用类似的方法来模拟星球的大气层。

相关文章
|
C# 图形学
Unity零基础到进阶 ✨ 使用 Vectrosity 插件 像德芙一样丝滑的画线
Vectrosity画线插件 ☀️ Unity画线插件Vectrosity 🔥 在使用Unity进行开发的过程中,我们在某些时候需要使用到划线功能,使用Unity中的几种划线方法自然可行,但是我们可以用一种更方便的方式来进行划线操作,那就是我们的主角:Vectrosity插件👍!
Unity零基础到进阶 ✨ 使用 Vectrosity 插件 像德芙一样丝滑的画线
|
开发框架 图形学
Unity进阶之ET网络游戏开发框架 02-ET的客户端启动流程分析
Unity进阶之ET网络游戏开发框架 02-ET的客户端启动流程分析 万物起源:Init.cs打开范例场景init.unity,可以发现其场景层级如下: 其中唯一重要的就是Global对象上挂在的init.
1979 0
|
图形学
Unity进阶技巧 - RectTransform详解
一、Pivot属性详解首先为了让大家更好的理解内容,我在Unity中创建了两个UI控件,一个Plane控件,作为父对象,一个Image控件,作为子对象。 然后我们选中子对象,来看看它的RectTransform组件的属性,会看到有一堆的数据,那么这些数据是如何最终决定UI在屏幕中的位置和大小的呢?我们首先来看第一个重要的属性Pivot,因为它理解RectTransform这套UI布局方案的第一个关键。
2165 0
|
4月前
|
C# 图形学
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
50 0
|
4月前
|
人工智能 自然语言处理 区块链
【Unity 3D】元宇宙概念、应用前景、价值链等概述
【Unity 3D】元宇宙概念、应用前景、价值链等概述
52 0