目录
UV
1.为什么需要UV座标?
使用纹理映射(texture mapping)技术,即把2D图像映射到3D模型三角形表面。
ex:左边是两个三角面,右边是一个贴图,把一张图片映射到2个三角形上。
2.什么是UV座标?
在纹理映射过程中,我们使用纹理座标的方式(或称u、v座标),把纹理进行划分。UV(纹理映射座标)它定义了图片上每个点的位置的信息,将图像上每一个点精确对应到模型表面。无论模型贴图大小如何,UV纹理一般都被归一化到[0,1]。
UV座标算法 ex: 模型贴图1024 * 1024,贴图某个点的UV座标 = (x/1024,y/1024) 例如(512,512) UV座标= (0.5,0.5)。
3.为什么UV座标要归一化到[0,1]?
这样不管纹理大小如何,通过模型顶点的UV座标都能正确找到相对应的纹素。
4.UV座标存在哪?怎么获取?
UV座标存储在模型顶点中,通过代码可获取 Vector2[] tempUv = this.GetComponent<Mesh>().uv;
Unity Shader中 输入结构体中,通过语义 half2 uv : TEXCOORD0获得。
5.建3D模型时候,展UV什么意思?
将建好的模型展开成平面,别人就可以在那平面上绘制贴图。
例如一个3D正方体模型,展完UV将它分成6个面,然后就可以在这些2D面上绘制贴图了。
https://blog.csdn.net/hihozoo/article/details/53302586
纹素(Texel)
1.纹素定义
纹理的基本单位。如同屏幕中图像由多个像素构成,纹理由很多个纹素组成。纹素包含ARGB值。例如8*8的纹理,有64个纹素。
2.纹素获取
使用纹理,通过UV座标定位,就能取到纹理的纹素。例如一个256x256大小的二维纹理,UV座标(0.5,1.0)对应的纹素座标(128,256)。
3.纹理中的纹素怎么形成屏幕空间显示的像素?
使用纹理映射(texture mapping)技术。
- Magnification 纹理放大
纹理大小为256*256,但我们的两个三角形组成的quad却是512*512,则一个纹理单元(纹素)要对应quad上的四个像素,一个纹理单元对应多个光栅化后的像素的情况通常称作Magnification。
在magnification情况下如何进行纹理映射呢?通常是用双线性插值的方式,比如下面左边的图中红色的pixel,没有对应的纹理texel,则它的颜色值用它的上下左右的pixel颜色插值得到,当然我们也可以选择最接近的纹理单元颜色做为其颜色,
具体要视Filter Mode纹理滤波中设置的MAG值。
- Minification 纹理缩小
和Magnification相反,三角面小,纹理大。例如128 * 128的面片大小,纹理大小 256 * 256。
这时可以选择最接近的纹理单元,也可以把上下左右纹理单元进行双线性插值,再和pixel映射起来。
具体要视Filter Mode纹理滤波中设置的MAG值。
- Mipmap 多级渐远纹理技术
选择创建mipmp层,系统就自动创建一系列采样的图像,每个图像都是前面一个图像的1/4(如下图所示)。
比如纹理原始大小是256*256,我们的三角形是178*178,那么这时会做三线性插值,四边形先和128*128纹理执行magnificaiton插值得到一个结果,再和256*256纹理做minification插值得到一个结果,最后再对这2个结果进行线性插值,得到的颜色为最终的pixel颜色。
Material Tiling 和 Offset
1.含义
Offet:指明使用贴图的起始位置,取值一般范围为0-1。(UV座标偏移量)
Tiling:指明从offset位置处的大小区域,区域的一般取值范围一般为(-1,1)。
正常显示纹理 offset为(0,0),tilling为(1,1)。
Tiling(2,1) Offset(0,0) 由于x轴方向为2。2 * 1 = 2。超过UV座标x最大值1值。此处纹理Wrap Mode = Repeat。
因此效果如下。
Tiling(1,1) Offset(0,0.5) 由于y轴方向UV偏移了0.5,因此下半部分显示纹理的上半部分。上半部分由于此处纹理Wrap Mode = Repeat。重复采样纹理的下半部分填充上半部分。
2.怎么获取Tiling,Offset?
2.1 c#代码获取:
//GetComponent<Renderer>().sharedMaterial.mainTextureOffset;
//GetComponent<Renderer>().sharedMaterial.mainTextureScale;
2.2 Shader中获取:
申明 纹理名称+ "_ST" 的变量。变量中包含了材质球中面板中的Offset,Tiling。
例如 纹理 _MainTex 申明 _MainTex_ST变量,变量_MainTex_ST.xy 为Tiling。_MainTex_ST.zw 为Offset。
一般用“UnityCG.cginc” 的宏定义TRANSFORM_TEX计算材质球中的值,以确保采样得到预期效果。TRANSFORM_TEX等同:
(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
计算真正的UV,用于后边的纹理采样: o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);