笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题。
在游戏中,我们除了能看到游戏物体的形体轮廓,还能看到物体的一些具体外观,包括颜色,凹凸等。而实现这一步的就是使用 纹理。与纹理相对应的技术就是 纹理映射技术 ,相当于把一张图贴在物体表面,然后 逐纹素 地控制颜色。
纹理映射坐标:纹理映射坐标定义了一个顶点在纹理中对应的2D坐标。由于常用 U 来表示横向坐标, V 来表示纵向坐标,所以纹理映射坐标也是我们常常见到的 UV坐标。 顶点 UV 坐标通常会被归一化至 【0,1】范围内。当然纹理采样时使用的坐标也不一定在这个范围内。
另外值得注意的是,OpenGL 与 DirectX 的二维坐标系是不一样的,OpenGL中原点位于左下角,DirectX原点位于左上角。当然 Unity 会帮我们处理这个差异,同时一般情况下,Unity 采用的纹理空间是符合 OpenGL传统的。
需要注意的是:本文着重讲述纹理采样的原理,由于实现的shader中的光照模型计算如同上文中,并不完整。所以不能直接运用于项目
目录
一. 单张纹理
先看一下我们要实现的效果
shader 的一些书写方式本文便不再赘述,同时本文的计算光照的方式都能够在上一篇文章中找到,如果忘了,可以先复习一下
【Unity Shader】(三) ------ 漫反射和高光反射的实现
1.1. 实现单张纹理
新建一个场景,去掉天空盒子;新建一个 Capsule 与 Material,命名为 SingleTexture;
I. 先定义 Properties 语义块
其中 _MainTex 的纹理用来表示纹理贴图,这里我们用这张纹理贴图来代替物体的漫反射颜色。
II. 为了控制 Properties 中的属性,我们在CG代码片中定义与之相匹配
在Unity中,一般使用 纹理名_ST 来代表某个纹理的属性
_MainTex_ST 代表 _MainTex 这个纹理的属性:S(Scale)缩放,T(Translation)平移。
_MainTex_ST.xy 代表 缩放值;_MainTex_ST.zw 代表 偏移值
III. 定义输入输出结构体
uv 变量存储了纹理坐标,以便在片元着色器中进行采样
IV. 顶点着色器
黄色框中,我们使用了 _MainTex_ST 对顶点纹理坐标进行变换,得到最终的纹理坐标。先使用 _MainTex_ST.xy 对顶点纹理坐标进行缩放,然后使用 _MainTex_ST.zw 进行偏移。而 TRANSFORM_TEX 则是封装了这个计算方式的内置函数,我们可以在 UnityCG.cginc 中找到它的定义
很显然,参数一为顶点纹理坐标,参数二为纹理名
V. 片元着色器