Unity 渲染教程(二):着色器基础

这篇Unity渲染教程详细介绍了从基础开始编写着色器的过程,包括设置背景颜色、去除无关渲染内容、理解顶点程序和片段程序,以及导入纹理并调整颜色和平铺。通过编写自定义着色器,读者可以深入理解渲染过程和着色器的工作原理。
摘要由CSDN通过智能技术生成

这是关于渲染基础的系列教程的第二部分。这个渲染基础的系列教程的第一部分是有关矩阵的内容。在这篇文章中我们将编写我们的第一个着色器代码并导入纹理。

这个系列教程是使用Unity 5.4.0开发的,这个版本目前还是开放测试版本。我使用的是build 5.4.0b10版本。

对球使用纹理。

1. 默认的场景

当你在Unity中创建新的场景的时候,你将使用默认的相机和定向的光源。  通过GameObject / 3D Object / Sphere这个菜单项来创建一个简单的球体,然后把这个简单的球体放在原点,并把相机放在它的前面。

默认场景中的默认球体。

这是一个非常简单的场景,但是已经有很多复杂的渲染内容了。为了更好地抓住渲染过程,摆脱所有奇怪的东西是非常有帮助的,首先让我们只关心渲染的基础部分。

1.1 剥离那些和渲染无关的内容

通过菜单项Window / Lighting来查看场景的光照设置。 这将打开一个具有三个选项卡的光照窗口。我们只对默认情况下处于激活状态的“场景”选项卡感兴趣。

默认的光照设置。

这是一个关于环境光照的部分,你可以在其中选择天空盒。这个天空盒目前用于场景背景、环境光照和反射。让我们将其设置为none进行关闭。

在你进行设置的时候,你还可以关闭预计算和实时全局光照的面板。我们不会很快使用到这些东西。

不再使用天空盒了。

在没有天空盒的情况下,环境光源会自动切换为纯色。环境光源的默认颜色为深灰色,具有非常浅的蓝色色调。而反射变为纯黑色,如警告框所示。

正如你可能期望的那样,球体会变得更暗,背景会是纯色。但是,得到的结果却是背景是深蓝色。那么这个颜色来自哪里?

简化后的光照

背景颜色是根据摄像机来定义的。它在默认情况下会渲染天空盒,但是它也会回落到纯色状态。

默认的相机设置。

为什么背景颜色的透明通道值为5而不是255?

要进一步简化渲染的话,请取消方向光源对象的激活或将其删除。这将摆脱场景中的直接光照,以及由直接光照所投射的阴影。剩下的就是背景,会用环境颜色显示球体的轮廓。

球体处于黑暗之中。

2. 从物体到二维图像

我们这个非常简单的场景是用两个步骤绘制出来的。 首先,图像用相机的背景颜色进行填充。然后将我们的球体的轮廓绘制在填充颜色的上面。

Unity怎么知道它必须画一个球体? 我们有一个球体对象,这个对象有一个网格渲染器组件。如果此对象位于相机的视图内,那么就应该出现在最终的图像中。 Unity通过检查对象的包围盒否与相机的视锥体相交来验证这一点。

默认的球体。

变换组件用于改变网格和包围盒的位置、方向和大小。实际上,整个变换层次都会被用到,正如第1部分“矩阵”中所描述的那样。如果对象会出现在相机的视图中,则这个物体会被安排进行渲染。

最后,图形处理器负责渲染对象的网格。 特定的渲染指令由对象的材质定义。 材质引用了着色器 - 这是一个图形处理器程序,加上它可能有的任何设置。

每个组件控制着渲染哪些内容。

我们的对象目前有默认材质,它使用Unity的标准着色器。我们要用我们自己的着色器来代替它,我们将从头开始构建它。

2.1 你的第一个着色器程序

通过Assets / Create / Shader / Unlit Shader创建一个新的着色器,并且将它命名为类似My First Shader这样的名字。

你的第一个着色器程序。

打开着色器文件并删除其内容,所以我们可以从头开始。

着色器代码用Shader关键字定义。它后面是一个字符串,描述可用于选择此着色器的着色器菜单项。它不需要匹配文件名。然后跟着的是填充了着色器内容的块。

Shader"Custom/My First Shader"{

}

保存文件。 你将收到不支持这个着色器的警告,因为它没有子着色器或是备选着色器。这是因为它是空的缘故。

虽然这个着色器没有什么功能,但是我们可以将它分配给一个材质。因此,通过Assets / Create / Material来创建一个新材质,并从着色器菜单中选择我们的着色器。

使用了你的着色器的材质。

更改我们的球体对象,使我们的球体对象使用我们自己的材质,而不是默认材质。 球体将变为洋红色。发生这种情况是因为Unity会切换到一个错误的着色器,它使用这种颜色来引起你对问题的注意。

使用了你的着色器的材质。

着色器的错误提示信息中提到子着色器。你可以使用这些子着色器将多个着色器变量组合在一起。这允许你为不同的构建平台或者LOD值不同的情况下提供不同的子着色器。让我们举个简单的例子来说,你可以为桌面电脑上运行的那个应用使用一个子着色器,而为移动设备上运行的应用使用另一个子着色器。

Shader"Custom/My First Shader"{

SubShader

{

}

}

子着色器里面必须包含至少一个通道。着色器通道是对象实际被渲染的地方。 我们将使用一个通道,但着色器里面可以有多个。具有多个通道意味着对象被多次渲染,这是很多效果所需要的。

Shader"Custom/My First Shader"{

SubShader

{

Pass

{

}

}

}

我们的球体现在可能变成白色,因为我们使用的是一个空通道的默认行为。如果发生这种情况,这意味着我们不再收到任何着色器错误的提示信息。但是,你可能仍然在控制台中看到旧的错误提示信息。编辑器倾向于坚持提示错误信息,因为当着色器重新编译而没有错误的时候,这些错误提示信息是不会被清除的。

一个白色的球体。

2.2 着色器程序

现在是时候来编写我们自己的着色器程序了。我们用Unity的着色语言来做这个功能,这是HLSL和CG着色语言的变体。我们必须用CGPROGRAM关键字指示我们的代码开始。我们必须以ENDCG关键字来指示我们的代码终止。

Pass

{

CGPROGRAM

ENDCG

}

着色器编译器现在会发出警告,警告我们的着色器里面没有顶点程序和片段程序。着色器由两个程序组成,也就是顶点程序和片段程序。顶点程序负责处理网格的顶点数据。 这包括从对象空间到显示空间的转换,就像我们在第1部分“矩阵”中所做的那样。片段程序负责对位于网格三角形内的单个像素进行渲染。

顶点程序和片段程序。

我们必须通过pragma指令告诉编译器使用哪些程序。

CGPROGRAM

#pragma vertex MyVertexProgram

#pragma fragment MyFragmentProgram

ENDCG

编译器会再次发出警告,这次因为它找不到我们指定的程序。这是因为我们还没有定义这些程序的缘故。

定义顶点程序和片段程序就像定义方法一样,非常像C#里面的做法,虽然它们通常被称为函数。让我们简单地创建两个空的返回void的方法,并给它们适当的名称。

CGPROGRAM

#pragma vertex MyVertexProgram

#pragma fragment MyFragmentProgram

voidMyVertexProgram () {

}

voidMyFragmentProgram () {

}

ENDCG

此时,着色器将编译,球体将消失。或者你仍然会得到错误信息提示。这取决于你的编辑器使用的是哪个渲染平台。如果你使用的是Direct3D 9渲染平台,你可能会得到错误信息提示。

2.3 着色器的编译

Unity的着色器编译器接受我们的代码,并将其转换为不同的程序,具体如何转换取决于目标平台。不同的平台需要不同的解决方案。 例如,如果是Windows 平台的话,需要的是Direct3D,如果是Mac平台的话,需要的是OpenGL ,如果是移动平台的话,需要的是OpenGL ES,等等。 我们不是在这里处理单个编译器,而是处理多个编译器。

你最终使用哪个编译器取决于你的定位。由于这些编译器并不相同,因此每个平台可能会产生不同的结果。举个简单的例子来说,我们的空程序使用OpenGL和Direct3D 11的话,就能正常工作,但在如果使用的是Direct3D 9,就会失败。

在编辑器中选择着色器,并查看检查器窗口。它会显示有关着色器的一些信息,包括当前的编译器错误。还有一个带有“编译和显示代码”按钮和下拉菜单的“编译代码”项。 如果单击“编译和显示代码”按钮,Unity将编译着色器代码并在编辑器中打开着色器代码的输出,因此你可以检查生成的代码具体是什么。

</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农老K

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值