《计算机图形学_15 纹理映射》由会员分享,可在线阅读,更多相关《计算机图形学_15 纹理映射(93页珍藏版)》请在金锄头文库上搜索。
1、纹理映射基本内容n介绍各种映射方法n纹理映射(texture mapping)n环境映射(environmental mapping)n凹凸映射(bump mapping)n考虑基本策略n正向映射和逆向映射n点取样与区域平均几何建模的局限n虽然图形显示卡可以每秒钟显示多达一千万个多边形,但这个速度并不能满足模拟任何现象的要求云草地貌树皮毛发水波与火焰桔子的模型n考虑如何建立桔子(或其它水果)的模型n用着色的球表示桔子n太简单n用更复杂形状代替球n并没有强调曲面的特征(微凹, dimples)n为了模拟所有的微凹,需要相当多的多边形桔子的模型(续)n获取真实桔子的照片,扫描后把结果“粘贴”到简单
2、的球模型上n这个过程就是纹理映射n可能结果仍然不令人满意,因为所得曲面是光滑的n需要改变局部形状n凹凸映射三种映射方法n纹理映射n利用图像填充多边形n环境映射(反射映射)n利用环境的图像进行纹理映射n可以模拟高度镜面曲面n凹凸映射n在生成显示结果的过程中可以改变法向量纹理映射环境映射凹凸映射映射在什么地方进行?n映射技术是在输出流水线的最后阶段实现的n非常有效,因为在经过所有的操作后,减少了许多不必要的映射很容易吗?n虽然映射的想法很简单,即把图像映射到曲面上,但由于这时要用到三四个坐标系,因此实现起来并不容易坐标系n参数坐标系n可以用来建立曲面n纹理坐标系n用来区别要被映射的图像上的点n世界
3、坐标系n从概念上说,就是映射发生的地方n屏幕坐标系n最终图像生成的地方纹理映射框架映射函数n基本问题就是如何定义映射n考虑从纹理坐标到曲面上一点的映射n直观地看,因当需要三个函数n终必定用到上述的函数,但实际采用的是却是间接的方法逆映射n我们需要的是逆向操作n给定一个像素,我们想知道它对应于对象上的哪个点n给定对象上的一个点,我们想知道它对应于纹理中的哪个点n此时需要如下形式的映射ns = s(x,y,z), t=t(x,y,z)n这样的函数一般是很难求出来的实际困难n假设要计算中心在(xs, ys)的一个矩形像素的颜色,中心点对应于对象上的点(x,y,z)n如果对象是弯曲的,那么矩形像素的原
4、像是一个曲边四边形n这个曲边四边形在n纹理上的原像才是n对当前矩形像素的n颜色有贡献的纹理n元素解决方法n先不管如何定义逆映射,只考虑如何确定当前像素的颜色(或者说明暗效果)n一种方法是用当前像素块的原像的中心对应的纹理元素的颜色n走样(aliasing)Moir效果n当不考虑像素是有一定的大小时,在图像中会导致moir效果,即出现波纹“更好”的方法n用在纹理原像上对应区域的明暗效果的平均赋给当前像素n很难实现n也不是完美的n右图经上述处理后n也得不到所需要的结果n但这个问题来自于低分辨率的局限n对于规则纹理,这种效果非常明显映射的确定n考虑由参数方程定义的曲面p(u,v)=(x(u,v),y
5、(u,v),z(y,v)n此时通常采用如下形式从纹理元素对应到曲面上的点u = as + bt+ c, v = ds+ et + f只要aebd, 上述映射是可逆的方法的特点n很容易应用n没有考虑曲面的弯曲n为了填充曲面,纹理在不同方向进行了不同拉伸两步映射n解决映射问题的另外一种方法n首先把纹理映射到一个简单的中间曲面上n例如:映射到圆柱上圆柱映射n假设纹理坐标在单位正方形0,12内变化,圆柱高h, 半径rn那么圆柱的参数方程为n适合于构造与无底的圆柱面拓朴同构的曲面上的纹理球映射n球的参数方程nx = r cos(2s), y = r sin(2s) cos(2t), z = r sin(
6、2s) sin (2t)n类似于地图绘制中的映射n肯定有变形n用在环境映射中立方体映射n适合应用于正交投影n也用在环境映射中两步映射中的第二个映射n从中间对象到实际对象的映射n从中间形状的法向到实际对象n从实际对象的法向到中间形状n从中间形状的中心开始的向量其它类型的纹理n立体纹理程序生成的纹理nProcedural textureOpenGL中的纹理映射基本内容n介绍OpenGL中的纹理函数以及相应的选项OpenGL与纹理nOpenGL支持许多纹理映射选项n第一版包含了把一维或二维纹理映射到一维至四维图形对象的函数n现在的版本提供了三维纹理,但需要高端硬件的支持n本节只讨论从二维纹理到曲面的
7、映射基本策略n应用纹理需要下面三个步骤n指定纹理n读入或生成图像n赋给纹理n激活纹理映射功能n给每个顶点赋纹理坐标n由应用程序建立适当的映射函数n指定纹理参数n包装(wrapping), 过滤(filtering)纹理映射纹理示例n纹理(下方)是256 256 的图像,它被映射到一个矩形上,经透视投影后的结果显示在上方纹理映射与OpenGL流水线n图像与几何分别经过不同的流水线,在光栅化时合二为一n复杂纹理并不影响几何的复杂性指定纹理图像n利用CPU内存中的纹理元素数组定义纹理图像nGLubyte my_texels512512;n 定义纹理图像所用的像素图n扫描图像n由应用程序代码创建n激活
8、纹理映射nglEnable(GL_TEXTURE_2D);nOpenGL支持一至四维纹理映射定义纹理所用的图像glTexImage2D(target,level,components,w,h,border,format,type,texels);target:纹理的类型,例如:GL_TEXTURE_2Dlevel:用于mipmapping(稍后讨论)components: 每个纹理元素的分量数w,h:texels中以像素为单位的宽度与高度border:用于光滑处理(稍后讨论)format与type: 描述纹理元素texels: 指向纹理元素数组的指针glTexImage2D(GL_TEXTUR
9、E_2D,0,3,512,512,0,GL_RGB,GL_UNSIGNED_BYTE,my_texels);转化纹理图像nOpenGL需要纹理的尺寸为2的幂次n如果图像的尺寸不是2的幂次,用下述函数进行转化gluScaleImage(format,w_in,h_in,type_in,*data_in,w_out,h_out,type_out,*data_out);ndata_in 源图像ndata_out 目标图像n当放缩时图像被插值和过滤映射纹理n基于参数纹理坐标nglTexCoord*()指定每个顶点对应的纹理坐标典型代码glBegin(GL_POLYGON);glColor3f(r0,g
10、0,b0);glNormal3f(u0,v0,w0);glTexCoord2f(s0,t0);glVertex3f(x0,y0,z0);glColor3f(r1,g1,b1);glNormal3f(u1,v1,w1);glTexCoord2f(s1,t1);glVertex3f(x1,y1,z1);.glEnd();注意为了提高效率,可以采用顶点数组插值nOpenGL应用双线性插值从给定的纹理坐标中求出适当的纹理元素n可以只应用纹理的一部分n方法是只应用纹理坐标的一部分,如最大纹理坐标为(0.5,0.5)变形n对于四边形,从纹理坐标到纹理元素的对应是比较直接的n对于一般的多边形,OpenGL需
11、要确定一种方法,确定纹理坐标与纹理元素的对应n可能会出现变形纹理参数nOpenGL中有许多办法确定纹理的使用方式nWrapping参数确定当s, t的值超出0,1区间后的处理方法n应用filter模式就会不采用点取样方法,而是采用区域平均方法nMimmapping技术使得能以不同的分辨率应用纹理n环境参数确定纹理映射与明处理的交互作用Wrapping模式n截断:若s,t1就取1,若s,t0就取0n重复:应用s,t模1的值放大与缩小n可以是多个纹理元素覆盖一个像素(缩小),也可以是多个像素覆盖一个纹理元素(放大)解决方法n可以应用点取样(最近纹理元素)或者线性滤波(2x2滤波)得到纹理值滤波模式
12、n模式指定nglTexParameteri(target, type, mode)nglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);nglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);n注意在线性滤波中为滤波边界需要纹理元素具有额外的边界(border=1)纹理的MipmapnMipmap对纹理位图进行预先滤波,降低分辨率n 可以减小对于非常小的要加纹理的对象的插值误差n在纹理定义时声明mipmap的层次nglTexImage2D(GL
13、_TEXTURE_*D, level, );n GLU中提供了mipmap建立界面,可以从给定图像建立起所有的mipmap纹理ngluBuild*DMipmaps()示例纹理函数n控制纹理的应用方式nglTexEnvfiv(GL_TEXTURE_ENV, mode,param);nGL_TEXTURE_ENV_MODE 设置模式nGL_MODULATE: 与计算的明暗效果调制在一起nGL_BLEND: 与环境颜色融合在一起nGL_REPLACE: 只应用纹理的颜色nGL_DECAL: 与GL_REPLACE相同n应用GL_TEXTURE_ENV_COLOR设置融合颜色透视校正提示n纹理坐标与颜
14、色插值n要么是关于屏幕空间线性确定的n或者要应用深度/透视值(较慢)n对于在边界上的多边形,效果非常明显nglHint(GL_PERSPECTIVE_CORRECTION_HINT, hint)n其中hint可取值GL_DONT_CARE,GL_NICEST, GL_FASTEST纹理坐标的生成nOpenGL可以自动生成纹理坐标nglTexGenifdv(GLenum c, GLenum pn, pv)nc: 纹理坐标,可取GL_S, GL_T, GL_R, GL_Qnpn: 纹理坐标的生成函数,可取GL_TEXTURE_GEN_MODE,GL_OBJECT_PLANE, GL_EYE_PLA
15、NEnpv: 参数值,当pn=GL_TEXTURE_GEN_MODE时,可取GL_OBJECT_LINEAR, GL_EYE_LINEAR,GL_SPHERE_MAP;否则应为数组,由生成函数的系数组成纹理对象n纹理也是状态的一部分n如果不同的对象具有不同的纹理,那么OpenGL需要从处理器内存向纹理内存传送大量数据n最新版本的OpenGL提供了纹理对象功能n每个纹理对象是一个图像n纹理内存可以保存多个纹理对象综述:应用纹理框架n在纹理对象中指定纹理n设置纹理滤波函数n设置纹理函数n设置纹理的wrap模式n设置可省的透视校正提示n结合纹理对象n激活纹理映射功能n为每个顶点指定纹理坐标n坐标可以
16、自动生成多重纹理n通常一个几何对象上只有一个纹理n有许多渲染效果需要多次应用纹理n例:已有纹理的表面上有其它物体的阴影n此时需要给阴影加上纹理n多重纹理的工作流程纹理生成n纹理的主要一个应用就是不必应用几何建模方法,而提供几何对象上的细节n高端图形系统可以实时生成三维纹映射n对于每一帧图像,纹理被映射到对象上,几乎与不进行纹理映射的对象显示频率相同n 现在的微机显卡也包含了大量纹理内存,从而可以使得游戏开发人员应用纹理映射的方法创建复杂的动画效果其它类型的纹理映射基本内容n环境映射n 凹凸映射高度反射表面n具有完美反射特征的表面会形成周围环境的影像n这种影像具有变形n它是全局效果n如果不知道周
17、围的信息,无法得到花瓶上各点的最终状态解决方法n基于物理模型的渲染方法可以得到这种效果n例如:光线跟踪但太耗时,无法用于实时程序中n需要对场景进行完整建模n拓展纹理映射方法n环境映射,也称为反射映射基本想法n考虑场景中的镜子n形状为多边形,表面为光滑的镜面反射材料n从视点来看,观察者的位置和镜面法向已知,因此反射角确定: r = 2(vn)n vn如果沿这个反射方向跟踪,它必环境交于某一点n因此可以分两步进行两步策略n第一步:假设场景中没有表面镜子的多边形,照相机放在镜子的中心,指向镜子的法向n如此得到环境的图像n这个图像并不是完全正确的n 第二步:把上述图像贴到镜子多边形上困难n第一步中得到
18、的图像并不是很正确n因为它是在场景中缺少一个对象(即镜子)的情形下得到的n必须处理映射中的问题n在第一步中应当把场景投影到哪种曲面上?n照相机应当放在哪儿?n有时我们会移动镜子,那么就需要多次投影经典解决方法n经典的方法是把场景投影到一个球上,球的中心就是COPn注意在COP的观察者分不清到底看到的是原来的对象,还是投影后的对象n早期的环境映射中接着就利用经纬线把球面上的图像对应到矩形上n极点的变形很大n也不保持面积n大量应用三角运算球面映射nOpenGL支持上述方法的变体,即球面映射n应用程序提供一个圆形图像,它来自于环境映射到其上的球的正交投影n好处:从反射向量到圆上二维纹理坐标的对应非常
19、简单,易于硬件或软件实现n缺陷:需要圆形图像,可以用宽角镜头进行透视投影来近似构造,或者从其它结果转化过来OpenGL代码n假设纹理用glTexImage2D定义,下述代码自动生成纹理坐标nglTexGeni(GL_S, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);nglTexGeni(GL_T, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);nglEnable(GL_TEXTURE_GEN_S);nglEnable(GL_TEXTURE_GEN_T);改进n如果应用图形系统计算纹理映射,那么就应当采用图形系统支持的标准投影方式n如果在屋子里,
20、那么自然的中间曲面应当是一个立方体n应用虚拟的照相机计算六次投影,分别对应于四面墙、地板和天花板n每次投影中照相机的指向不同示例从中间曲面的映射n把六个图像组合成一个环境映射,然后如图构造映射凹凸映射n仍然考虑桔子的模型n借用纹理映射的思路,可以把一个真实桔子的照片贴到球面上模拟桔子n但如果移动了光源或者旋转对象,就会发现我们有的还是桔子模型的图像,而不是真实桔子的图像n因为真实桔子的特征是在表面上有很多小形状变化,但不是颜色的变化n 纹理映射不能模拟形状变化n因此采用凹凸映射基本想法n在生成图像时的光照模型中对曲面的法向进行随机扰动n如此得到的图像就会显现出形状变化的错觉法向n曲面上一点的法
21、向量刻划曲面在该点的形状n 如果用小量扰动曲面法向,那么就会得到具有小变化的曲面n如果在生成图像时进行这种扰动,那么就会从光滑的模型得到具有复杂表面模型的图像法向扰动方法n可以有多种方法对法向进行扰动n下述法向适用于参数曲面n设曲面方程为S(u,v)n在一点的单位法向为n = SuSv/| SuSv |n假设曲面在法向移位d(u,v) (|d(u,v)|1)n那么变化后的法向近似为 n = n + du n Su + dv n Sv结果示例计算方法n曲面表示的偏导数计算n基于曲面的表示解析计算,或者n在当前点让u与v改变很小,找到四个最近点用差商代替微商n位移函数的偏导数计算n根据定义方式解析
22、计算斜面效应n沿几何图形的边界应当显示出明显的边界效果n描述斜面(bevelling)的参数n脊与平坦区域的宽度n在脊的顶部与底部的斜率噪音函数n移位函数d也称为噪音函数n它打破了正则性n可以模拟非规则现象白噪(white noise)n为一串随机数n均匀分布n完全不相关n两个相邻值之间没有任何关联n在纹理生成中并不希望采用这种噪音n对于取样操作的精度非常敏感n噪音频率太高适于纹理生成的理想噪音n在输入固定时,生成的随机数可以重复范围在 1, 1n带宽有限(最高频率大约为1)n没有明显的周期性n静态而且各向同性n在平移和旋转变换下统计属性不变网格噪音n最常见的纹理生成所用的噪音n白噪的低通滤波
23、n在噪音空间中随机数与整数位置关联在一起n中间值根据某种形式的插值计算出来n频率由网格间距限制网格噪音的生成n在纹理坐标为整数的地方生成一个或多个均匀分布的随机数n这些点称为整数格点代码示例值噪音n创建另外一个由介于 1, 1之间随机数构成的表格n根据前面给出的INDEX函数索引表格插值方法n线性插值n不够光滑n二次或三次样条插值n可能仍有网格布局所导致的人为痕迹n与一个径向对称的滤波函数做卷积一维与二维值噪音梯度噪音n在每个格点处存贮方向向量n在格点处的噪音值为零n中间值的计算方法:n对于每个相邻的格点,计算沿指定方向的位移n基于8个最近点的位移线性插值得到最终的值一维与二维梯度噪音值噪音与梯度噪音的对比n两种噪音都具有有限频率n值噪音的计算稍微简单一些n梯度噪音的绝大多数能量集中在高频处n强迫在整数点为零n梯度噪音具有一点的规则性值梯度噪音n值噪音与梯度噪音的加权和示例:纹理的扰动