前两篇笔记整理学习了下光照模型,用代码体会了下实现原理,有不足的地方是相关的计算都是在代码中计算的,没有使用Unity内置的方法,在笔记(八)中有介绍过Unity在UnityCG.cginc文件中是有内置的计算方法函数的,而且也没有直接使用表面着色器的形式去写,都是手写顶点函数和片元函数。其实这里有多方面的因素考量的,一方面是因为笔者也是UnityShader Beginner,知晓其原理可以方便后续的学习和拓展,另一方面就是好明确属于自己的学习线。因为UnityShader本身是面向多平台的,虽然本身针对多个图形接口有良好的对接但是也不能面面俱到,深入学习后就会发现这些接口只是从比较浅显的层面满足了大多数开发者,对于一些特定的需求和优化就需要自己去写代码实现。再加上UnityShader本身也在不断的更新,因此笔者认为基础部分很重要。有基础的就可以跳过了。
下面就上篇笔记做一下结尾部分,这次用UnityShader内置的函数来改写Blinn加强版计算高光的代码,之所以要用内置的函数,一方面当然是方便,另一方面也是为了避免自己写计算的时候出错。首先还是先附上一部分内置函数说明,还有更多具体的可以去看UnityCG.cginc文件,另外笔者看的资料也有一定年头了,为了验证代码的可用性笔者用的Unity版本为2019.3.11f1,可能有些函数已经不适用了,笔者会标明的。 改动的地方不多,只是将部分计算的代码用Unity内置的函数代替,我们打开Blinn加强版计算光照的代码,在顶点着色器中使用内置的UnityObjectToWorldNormal函数来计算世界空间下的法线方向,在片元着色器中,使用内置的UnityWorldSpaceLightDir函数和UnityWoldSpaceViewDir函数来分别计算世界空间的光照方向和视角方向,有一点要备注的是通过内置函数得到的方向都没有归一化,因此得需要normalize函数进行归一化,最后在进行计算。完整代码如下,主要看注释部分:


光照模型部分就暂时总结到这里,后续有新知识点会相应的补充。接下来就开始基础纹理的学习整理。 在3D建模的时候,最终都会给模型分UV,这个分UV的过程就是将模型展开,把纹理映射坐标存储在模型的每个顶点上,这个纹理映射坐标就是定义了模型顶点在纹理中的2D(u,v)坐标,u代表横坐标,v代表纵坐标。另外还有一点,纹理也有尺寸,比如256x256,512x512..,对应到uv的时候往往是通过了normalize到[0,1]的范围内,纹理采样的时候使用的纹理坐标不一定是在[0,1]的范围内,另外还涉及到纹理的平铺模式。这么说可能比较抽象,慢慢一点点去理解吧。我们先来看一下一个纯粹的模型文件到底包含什么,我们知道导入Unity的模型文件格式是FBX,其实是包含了动画灯光等等一系列信息的格式。笔者是用的3DS Max,其他3D软件也可以,我们从max中建立一个box,也就是Cube,导出为.obj格式,之后用文本打开,这时你就能看到一个单纯的模型文件所包含的信息,比如顶点,顶点法线等等,如下图:





之后也是用图来解释下之前说的模型到UV到纹理的一个过程,也是在max中简单的建立一个box,之后分好uv,在附上贴图,从通常3D建模的流程上来体验一下这个过程如下图: 通过以上流程应该对模型和纹理的关系有一定的了解了,接下来我们用代码再来体会一下这个过程,在此之前将纹理导入到Unity里,纹理随便找一张,为了比较好的效果最好是清晰,四方连续,边的尺寸是2的幂次的纹理最佳,笔者用的纹理如下图: 将图导入到Unity后,点击图片,在Inspector面板会看到图片属性面板: 这里参数我们先暂时不理会,后面在做解释说明,我们还是先代码走起,不用写太多,我们直接改上面Blinn高光的代码,在Properties块中将diffuse改成Color,因为要用到纹理,因此添加一个纹理属性,如下图: 之后在CG代码块中属性重申明部分加入纹理的重申明,另外还需新加一个float4类型变量_MainTex_ST,用来存放纹理的缩放平移值,这个变量的命名有严格规定,必须为"纹理名_ST",其中S为scale缩放,T为translation平移。如下图: 之后,我们在输入a2v结构体中加入新的变量texcoord,用TEXCOORD0语义声明,这样Unity会将模型的第一组纹理坐标存储到该变量中。在输出结构体v2f中加入新变量uv,以便在片元着色器中使用该坐标进行纹理采样。如下图: 接着我们来完成顶点函数,我们使用纹理属性值_MainTex_ST来对顶点纹理坐标进行变换,先对顶点纹理进行缩放,之后再进行平移,以上的操作对应Unity内置函数TRANSFORM_TEX,代码如下: 最后我们来完成片元函数,计算高光,纹理,环境光,最后叠加返回结果,设置好Fallback完成代码编写,如下图: 如果是按照流程做下来的话可以发现球体的shader上可以添加纹理,选择前面导入Unity的纹理,调节Tiling和Offset,可以看到球体表面纹理的变化,如下图:











未完接下篇
Unity Shader纹理映射与光照
本文探讨Unity Shader中纹理映射与光照处理,详细解析如何利用Unity内置函数改进光照模型,实现Blinn加强版高光计算,并通过代码实例展示纹理在模型上的应用过程。
1460

被折叠的 条评论
为什么被折叠?



