纹理映射

  • 1 纹理映射
    • 1.1 什么是纹理映射
    • 1.2 纹理的UV坐标
    • 1.3 读取纹理
  • 2 重心坐标
    • 2.1 计算重心坐标
    • 2.2 使用重心坐标做插值运算
  • 3 纹理映射常见问题
    • 3.1 纹理太小
      • 3.1.1 产生原因
      • 3.1.2 解决办法
    • 3.2 纹理太大
      • 3.2.1 纹理太大的影响
      • 3.2.2 走样产生原因
      • 3.2.3 解决办法
        • 3.2.3.1 超采样(MSAA)
        • 3.2.3.2 MipMap
        • 3.2.3.3 MipMap的限制

1 纹理映射

1.1 什么是纹理映射


如上图球的表面贴上一张绘制了地图的二维图片,就变成了地球仪,这张二维的图片就是纹理
把这个图贴到球表面伴随着这纹理的放大缩小以及将纹理中的某个点和球上的某个点对应起来,这个过程就是纹理映射

纹理映射的过程通常是这样的,建模人员给开发人员的模型中通常会有与顶点一一对应的uv坐标,同时提供一张纹理贴图,比如说要对模型的某个顶点着色,这时获取到这个顶点对应的uv坐标,拿着这个坐标从纹理贴图中取色,取到后把值赋给存储顶点颜色的变量

1.2 纹理的UV坐标


如上图左侧是个白模,右侧是使用贴图后的效果,如何准确找到纹理与模型的贴合点,这个就需要用到UV坐标,一张纹理通常会有自己的纹理坐标,如下图,纹理坐标系以左下角为原点,向右为u正方向,向上为v正方向,不论贴图时正方向还是长方形,u和v的取值范围都是[0,1]

1.3 读取纹理

上文中提到着色时,可以获取到每一个顶点对应的纹理坐标,然后从纹理中取色,这样只是为了说明使用纹理的过程,例如处理一个三角形的纹理映射,我只知道三个顶点的坐标和纹理坐标,如何计算三角形内任意一点的纹理坐标呢,答案是做插值,做插值时需要用到重心坐标

2 重心坐标

三角形ABC,该三角形所在平面内任意一点(x,y)可以用该三角形三个顶点坐标的线性组合表示,此时(α,β,γ )所表示的点就是该点的中心坐标
例如三个顶点的中心坐标分别是 A:(1,0,0) 、B:(0,1,0)、C:(0,0,1)
注意:
1.α+β+γ = 1 是将所求的点限定在三角形所在的平面内
2. α、β、γ 的取值必须都大于0,满足都大于0可以将所求的点限定在三角形内

2.1 计算重心坐标

通过面积计算
如下图α的值为A点对面的三角形AA除以三角形总面积;β的值为B点对面的三角形BB除以三角形总面积;γ 的值为C点对面的三角形CC除以三角形总面积

三角形的面积可以通过叉乘的方式获得,这里给出一个已经推导出来的公式,可直接通过该公式来计算重心坐标

2.2 使用重心坐标做插值运算

假设三角形中V点的重心坐标为(α,β,γ),一直三角形的三个顶点的坐标,这时可以通公式V=αA + βB + γ*C来得到V点的坐标
以上是以顶点为例通过插值的方式获取到三角形内任意一点的坐标,还有一些属性同样可以利用重心坐标插值计算获取三角形内任一点的属性值,比如颜色、法线、纹理坐标、深度(z-index)以及自定义的一些材质相关属性

注意:
投影变换前利用重心坐标插值和投影变换后插值结果是不一样的,插值运算是在三维空间中进行的,已经投影到屏幕上的坐标如何变回去?答案是利用投影矩阵的逆矩阵进行逆变换

建议:三维空间的属性需在三维空间中完成插值,然后在映射到二维中去

3 纹理映射常见问题

3.1 纹理太小

3.1.1 产生原因

例如要渲染一面墙,它的分辨率1024*1024,但与它对应的纹理大小是256x256,显然纹理相比于墙面过小了,当以墙面上一点去查询纹理时,可能查询到不准确的值,先来说说为什么会查询出不准确的值:
1.墙面的最小单位是像素(pixel),纹理的最小单位为纹素(texel)
2.由于纹理过小,会存在多个像素查询纹理时返回同一个纹素
3.墙面渲染时每个像素取到的纹素不是连续变化的,渲染出来的墙面感觉像是一个个非常细小的格子组成,看上去不自然

3.1.2 解决办法


如上图,红点代表一个像素的中心点的位置,这个4*4的格子代表一个纹理,每个格子中心的黑点表示纹素的中心
一个像素映射到纹理的位置是红点的位置时如何查找出准确的值,正确的方式是使用双线性插值(Bilinear),接下来说说双线性插值的处理过程:

  1. 在纹理上找到与该像素映射位置临近的四个纹素u00、u01、u10、u11

    2.以这四个点创建新的纹理坐标系,以u00到u10方向为u方向,u00到u01为v方向,这时可以指定在该坐标系中红点的位置是(s,t)
  2. 第一次线性插值 (水平方向),线性插值的公式如下

    这次的插值为了得到两个插值结果u0和u1,u0以s为当前值从u00和u10之间插值,u1以s为当前值从u01和u11之间插值
  3. 第二次线性插值 (竖直方向),有了上一步得到的结果u0和u1,在竖直方向以t为当前值从u0和u1之间插值,得到的结果就是我们要求的结果

我们在水平方向做一次插值,在竖直方向做一次插值,因此这个方法叫双线性插值,这样就可以得到任意映射点的准确值,

纹理过小使用双线性插值的办法外,还有精度更高的处理办法叫双三次插值算法(Bicubic) 过程与双线性插值类似,但取的是周围16个texel,同样做竖直的和水平的插值,只不过每次用4个做三次的插值,而非线性的插值,运算量大一些,效果更好,通常高质量伴随高开销,实际双线性插值可以满足大多数需求

3.2 纹理太大

3.2.1 纹理太大的影响

通常纹理过大会引发更严重的问题,例如渲染一个格栅状地面,纹理是一个小格子,在地面的两个方向上重复平铺,远处的一个像素需要装进来更多的纹素,如果按照之前插值的方式处理,渲染出来的结果是远处出现摩尔纹,近处出现锯齿

3.2.2 走样产生原因


如上图,从左到右表示场景中与相机的距离由近到远,当比较近的时候屏幕上一个像素覆盖的面积大概是一个纹素的大小,随着与相机距离的变大,屏幕上一个像素所覆盖的纹理上的面积越来越大,通常每个纹素有自己的颜色,最远距离中覆盖了多个纹素,但只会进行一次采样,采样的结果自然不能代表原理那么多纹素的颜色,所以会出现走样现象

3.2.3 解决办法

3.2.3.1 超采样(MSAA)

例如把采样点增加到512,效果很不错,但是开销太大

3.2.3.2 MipMap

说MipMap前先阐述两个概念点查询和范围查询
点查询:以点为单位去纹理中查询对应位置的值,使用的双线性插值都是点查询
范围查询(Range Query):不需要采样,给你任何一个区域,你立刻可以得到它内部的平均值;这就是范围查询,有很多种类,这里是查询平均值,也有查询范围内的最大值和最小值的范围查询
注意:MipMap 做范围查询时只有近似正方向的范围查询才是准确的
什么是MipMap,如下图,把一张纹理分成若干层,原始纹理为第0层,比如大小为128*128,每增加一层纹理分辨率缩小一半,直到缩小到只剩一个像素,那层数就是log2(纹理的长或宽)

相比原始图片的存储量,MipMap只增加了1/3的存储量
通常MipMap是在渲染前通过预计算完成的,生成对应层级的纹理,经过计算后MipMap变成如下图的结构,称为图像金字塔

MipMap需要在方形区域内做范围查询,如何确定需要查询的区域呢

如上图,三角形覆盖了一些采样点,以红色点和蓝色点为例,它们会投影到纹理空间上,可以观察到它们围成的区域不在是正方形了

如上图,例如我们要确定红色点左下角的采样点(粉色区域)在纹理坐标上查询范围的大小,在纹理空间中以这个点为中心,连接上面和右面的采样点,求出距离,并取最大值,假设最大的长度是L

如上图,求出的长度L基本近似采样点(粉红色区域)映射在纹理上的正方向的长度
有了正方向的长度就可以通过公式来确定去那一层查询

直接利用层级去MinMap中查询出来的结果,会发现层级之间过渡非常生硬,不是平滑过渡,如下图(不同颜色代表不同层级)

这有什么好办法吗,答案是肯定的,还是插值,例如你需要查询1.3层,那先查询1层和2层,然后拿两个结果在做一次插值

首先在D层使用双线性插值查询该点的值,然后继续使用双线性插值查询出D+1层的值,最后层与层之间做一次插值,我们把这种方法称为三线性插值

三线性插值需要做两次查询,一次插值,开销很小,并且效果也非常好如下图

3.2.3.3 MipMap的限制


如上图,使用MipMap处理的结果中会发现远处的细节全部都模糊掉了,这种现象称为模糊过度,问题出在哪了,在处理过程中,它只能查询方块区域,而我们查询的方块是近似得到的,所以是不完全准确的,既然问题出现如何解决,答案是使用各项异性过滤(Anisotropic Filtering)

各向异性过滤也就是RipMap,它和MipMap的不同之处就是它可以支持矩形区域的查询,生成出来的纹理如下


上图中, 沿着对角线上的图,水平方向和竖直方向上各缩小一半,称为各项同性,其实也就是MipMap
其余的有的只在水平方向发生压缩,有的只在竖直方向发生压缩,也有的在水平和竖直方向同时发生压缩且压缩比例可能会不一样,像这样在不同方向上它的表现各不相同称为各项异性。各向异性额外的开销是原本的三倍,造成较大的显存开销,能解决部分问题,只能满足矩形区域的范围查询,针对斜着的矩形区域(下图右侧中类似平行四边形)的查询也无能为力


对于上述这类情况我们可以使用EWA Filtering来解决,不规则的形状都可以拆成很多个不同的圆形去覆盖,当然运算量又会增加。

计算机图形学(八)-纹理映射、计算重心坐标、UV插值、双线性插值、MipMap相关推荐

  1. TIT 计算机图形学 实验三 使用重心坐标算法绘制颜色渐变的正六面体

    TIT 计算机图形学 实验三 使用重心坐标算法绘制颜色渐变的正六面体 前言 参考视频计算机图形学全套算法讲解和C++编码实现(共23讲配套源码),计算机图形学案例视频讲解以及主页相关算法.孔老师是我的 ...

  2. 计算机图形学与可视化计算OPENGL 个人作业一

    计算机图形学与可视化计算OPENGL 个人作业一     关键词:OpenGL绘制线.点.球,世界的旋转     背景信息     这是2022年春季学期,北京理工大学,计算机学院,软件工程,开设的一 ...

  3. 计算机图形学三(补充):重心坐标(barycentric coordinates)详解及其作用

    重心坐标(Barycentric Coordinates) 1 重心坐标的定义及求解 1.1 基础定义 1.2 几何面积角度求解 1.3 坐标系角度求解 2 重心坐标的运用 Reference (本篇 ...

  4. 计算机图形学八连通区域名词解释,计算机图形学名词解释

    1.图形与图像的区别 图形是用数学方法来描述一幅图,强调图形的几何表示,图形是由场景的几何模型和景物的物理属性共同组成的. 图像是把彩色图分成许许多多的象素,每个象素用若干个二进制位来指定该象素的颜色 ...

  5. 【12月学习进度3/31—计算机图形学期末准备01】拉格朗日插值 + 三次Hermite插值

    相关概念 型值点:事先给定的离散点 插值:得到的曲线通过所有的型值点 逼近:不要求通过给定的所有型值点,用给定型值点控制曲线形状 Hermite多项式 拉格朗日插值 拉格朗日插值是当 j=0j=0j= ...

  6. Games101--现代计算机图形学入门 作业3笔记(渲染管线、着色模型、双线性插值)

    一.渲染管线 一.作业要求 在这次编程任务中,我们会进一步模拟现代图形技术.我们在代码中添加了ObjectLoader(用于加载三维模型),VertexShader与FragmentShader,并且 ...

  7. 计算机图形学在现实中的应用,计算机图形学在实际中的应用

    计算机图形学在实际中的应用 计算机图形学在实际中的应用 1963年,伊凡•苏泽兰在麻省理工学院发表了名为<画板>的博士论文,它标志着计算机图形学的正式诞生.至今已有四十多年的历史.此前的计 ...

  8. 图形学笔记(八)着色2 —— 纹理映射、重心坐标、双线性插值、Mipmap、三线性插值、各向异性过滤、纹理的应用(环境贴图、法线贴图等)

    图形学笔记(七)着色 -- Blinn-Phone 反射模型.着色频率.渲染管线.GPU 图形学笔记(九)几何 --几何表示方法(CSG.距离函数.水平集 .点云.网格(obj格式)).贝塞尔曲线(面 ...

  9. 7、计算机图形学——图形管线渲染与纹理映射

    一.图形渲染管线 管线渲染其实就是将三维物体如何呈现到计算机屏幕上的过程,图形渲染管线的整体大致流程如下 顶点处理过程就是进行MVP变换,最终得到一系列的二维坐标点.而三角化就是将这一系列的二维坐标点 ...

最新文章

  1. VTK:vtkCubeAxesActor用法实战
  2. Swift之深入解析异步函数async/await的使用与运行机制
  3. 说说我的ID:fxh7622
  4. Windows 恢复环境(Windows RE模式)
  5. wxpython界面切换_wxpython中的图形用户界面
  6. 全新玖五社区系统整站源码
  7. Oracle默认的用户名和密码
  8. linux fls函数,Linux学习笔记- find 命令详解
  9. SQL SERVER 2005 安装报错
  10. matlab 图形对称,Matlab关于直线为轴对称与点为中心对称的图形代码
  11. 验证是不是合法的18位身份证号码代码
  12. openwrt 中 WiFi探针的三种实现办法
  13. 【python入门】循环语句
  14. Android 高级面试
  15. 3D人体姿态估计论文汇总(CVPR/ECCV/ACCV/AAAI)
  16. word转PDF图片消失问题
  17. 解决ubuntu18.04打不开网易云音乐(亲测可行!
  18. 日常安全运营工作的一些思考
  19. 互联网协会与IDGVC发布Web2.0 100(附名单)
  20. 计算机加密恢复,系统小技巧:BitLocker密钥恢复二三事

热门文章

  1. HTML隐藏属性的使用(前端标签)
  2. 陪我长大歌曲计算机,网易云音乐里的故事:陪你温暖同行,伴你成长。
  3. 铅酸电池IEC61056报告测试
  4. 【区块链】 区块链哈希算法
  5. tidb-读热点造成的单kv负载高
  6. VBA写入公式(6):排名不重复
  7. Excel-多条件排名时间排名
  8. 商业模式得到肯定 投资ofo朱啸虎信心满满
  9. 微商们如何在微信朋友圈正确发广告刷屏?
  10. cmd使用chcp提示不是内部或外部命令,也不是可运行的程序或批处理文件