Android 3D游戏模型纹理处理

时间:2022-10-12 01:33:29

Android 3D游戏模型纹理处理

摘 要 材质是3D模型对真实物体视觉效果的模拟。在使游戏3D场景看起来更真实,纹理就显得异常重要,有了材质和光照后画面效果丰富了许多,但是三维物体的表面只能是光滑的,没有花纹等细节。本文叙述了android3D游戏模型材质与纹理处理过程。

关键词 android;3D;纹理;OPENGL ES

中图分类号:TP391 文献标识码:A 文章编号:1671-7597(2013)11-0000-00

1 3D模型材质与纹理

材质主要用于描述对象如何反射和传播光线,通过材质的设置可以达到模拟对象的置地,表面显示效果。例如我们喜欢的水晶,玻璃等等效果,它提供了模型表面图案、反射、折射效果,通过材质的贴图可以实现多彩多样的材质。材质在模型最终显示效果中占有重要地位。同时高超的贴图技术是制作仿真材质的关键,也是决定最后渲染效果的关键。材质由颜色或贴图组成,并且绝大部分的标准材质是通过4种颜色构成对其进行模拟。

通过public abstract void glMaterialfv(int,int,float[],int)方法可以设置材质的相关属性。高光反射区域,数越大亮区越小、越暗。散射光一般设置为比环境光高,比反射光低,镜面光一般设置较高。

纹理包含众多的多边形,由这些多边形组成场景中看到的实际画面,而且对变形的个数和行装越多越小画面就越细致。纹理定义了物体表面的结构,如花纹,图案,皱纹等等。纹理是一个二维数组,其元素是一些颜色值,每一元素称之为纹理像素。纹理对象是一个内部数据类型,存储着纹理数据。你不能直接访问纹理对象,但是可以通过一个整数的ID来作为其句柄来跟踪。通过此句柄,可以作为当前使用的纹理(称之为纹理绑定),也可以从内存中删除这个纹理对象,还可以为一的纹理赋值(将一些纹理数据加载到关联的纹理中,称之为指定纹理)。一个纹理对象有其自己的一套坐标系,左下角是(0,0)右上角是(1,1):我们要将一个图像的一部分绘制到屏幕上,称之为纹理映射,就是将图像根据上述坐标系计算出要绘制的部分的各个点的纹理坐标,然后一一对应到屏幕上的坐标中去(下图中的坐标系是左上角为原点的)

2 场景中纹理处理

纹理贴图的使用,首先是需要去做的事开启纹理gl.glEnable(GL10.GL_TEXTURE_2d)和允许使用玩纹理数组gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY)方法,使用gl.glDisable(GL10.GL_TEXTURE_2D)方法关闭纹理。多重纹理占用大量内存,所以较好的模型需要的软件支持就更多。用于纹理的图像宽和高必须为乘方即2*n,如32,64,128,256,512等。纹理压缩顾名思义是让纹理数据占用空间更小的一种方法。在保持图片信息的前提下,纹理压缩使纹理占用较少的游戏存储空间,这样游戏本身就有更多的空间可以支配,在加载游戏资源时就可以充分利用局部性原理,提高系统的运行速度,这一点在提高系统运行速度方面至关重要。

纹理映射图的一个纹理元素对应纹理映射对象多边形的一个像素。如果显示的多边形被缩小一半,那么这个衣衣对应就不许做出处理,纹理的纹素就每间隔一个被显示。因此在某些情况下会导致一些视觉上的怪异现象。例如:如果把多边形缩小一半,纹理元素只是每间隔一个被应用,这种情况下所有的斑点或者灰暗点会突然消失。

在使用纹理是,程序会创建一个纹理对象,同时程序会判断是否有足够的内存可以容纳这个纹理,也没有包含诸如纹理边框、mipmap或立方体图纹理等高级技术。纹理绑定指定纹理处于活动状态。一次绑定只能激活一个纹理。活动的纹理是绘制多边形时使用的纹理,所以在提供图像数据前必须绑定纹理。gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);绑定纹理数据,传入指定图片GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bmp,0)。

纹理给整个3D图形真实感带来很大的不同。单一纹理可以实现想要的效果,但是使用多重纹理可以达到更加令人难忘的效果。实现多重纹理效果前,需要先用一个纹理绘制多边形,然后另外一个纹理透明地绘制在多边形上面。这样看起来纹理是在移动,有时可以达到意想不到的效果。另外管理纹理高速缓存是游戏引擎的速度至关重要。在系统性能和速度方面,和任何高速缓存一样,缓存命中很好,而不命中将很糟糕。根据系统局部性原理,如果遇到纹理在图形显示卡内存被频繁地换入换出的情况,这就是纹理高速缓存抖动。如果每一次资源请求,程序都要通过API对内存资源进行置换,一方面增加了交换时间消耗,另方面也说明程序算法不合理,没有体现局部性原理。对玩家来说,当系统重新加载纹理高速缓存时,会导致平均帧速率降低,也就是常常会卡顿。

在android游戏中通常使用的3D模型有MD2,OBJ文件。MD2通常实现的是动画,OBJ文件符合android手机3D游戏的要求的模式的只能是包含模型一个部分,如果一个OBJ文件中包含多个模型构件,那么它只能被读到第一个部分,其他的则不能加载到场景对象中去,所以使用OBJ文件需要对模型惊醒拆解,分别存储,然后通过重新构造加载类实现对一个模型的多个部分的加载。加载之后的模型然后对其进行统一的纹理处理。

之后是纹理坐标分配。首先纹理映射允许将制定的纹理素材映射到三维物体指定的多边形面上。当纹理映射启动后绘图时,必须为OpenGL ES提供模型对象数据,即数组中各顶点的纹理坐标。纹理坐标定义了图像的映射关系。要注意的事OpenGl ES中仅支持三角形,因此制定纹理坐标是也要注意这点。物体的没一点对应一组纹理坐标s、t,在对纹理进行黏贴之前要根据去所应用的片段进行排列,对于二维纹理图,纹理坐标在S和T方向上的范围是0.0~1.0,但是物体模型是没有坐标范围限制的。最后使用gl.glTextCoordPointer(2,GL10.GL_FLOAT,0,mTextureBuffer)方法为画笔指定纹理坐标数据,即为定点分配纹理坐标。

渲染之后的场景在显示之前,要进行转换和照明计算,然后进行裁剪。剪裁运算决定哪些三角形完全在场景之内,那些三角形部分在场景之内。因为3D模型必须通过这样的计算才能达到3D到2D屏幕的转换。完全在场景之内的三角形被称为细节接受。对于部分在场景之内的三角形,位于平截头体外面的部分将被剪掉,余下位于内部的多边形部分将重新闭合。场景经过裁剪以后,下一个阶段就是三角形生成阶段(也叫做扫描线转换),场景被映射到2D 屏幕坐标。通过这些处理,要显示的模型数据基本完成,渲染运算也算完成。

3 纹理处理重点细节

3.1 纹理拉伸

当目标很大时,纹理就要进行相应的处理才可以使用。方法如下:纹理拉大,这样的缺点是使纹理显得模糊变形;将目标面分割为多个与纹理大小相似的矩形,再将纹理重复贴到被分割的目标上,这样浪费内存;根据目标的大小自动复制。其中根据目标大小自动复制的方法是最好的方法,这样既节省的内存,又保证了效果,提高了效率。首先将纹理的GL_TEXTURE_WRAP_S与GL_TEXTURE_WRAP_T属性值设置为GL_REPEAT而不是GL_CLAMP_TO_EDGE。然后设置纹理坐标的范围,而此时的取值范围是0-n,n为重复的次数。

3.2 纹理过滤

正常情况下,纹理和实际的模型的坐标也不是完全符合的,要进行放大和缩小,这种情况下会使图像产生不好的效果,所以在不能确定大小的情况下,为避免由于在一个方向进行拉伸另一个方向收缩而产生扭曲,最简单的方式最近点采样,MIN_FILTER采用的就是最近采样gl.glTextParameter(,,)。就近采样是贴图时根据映射目标图像中像素的纹理坐标折算取整从纹理图中提取像素。当纹理的大小和目标大小相近时,这种效果就十分有效快捷。

线性过滤和就近采样是一样的,但是计算方法比较复杂,能取得更平滑的效果。MAG_FILTER采用的就是线性过滤,实现方法为gl.glTexParameterf(,,)。该方法会对靠近像素中心的2*2纹理矩形单元去加权平均值,用于放大和缩小。

4 总结

本文主要论述android 3D模型的纹理处理方法。从材质和纹理的本身的用途和特点介绍,根据android手机对模型的要求,以及在处理过程中的细节要求,说明在显示一个3D模型需要进行纹理处理的过程,以及OPENGL ES针对手机内存有限的优化处理方案,保证画面的真实。

参考文献

[1]android课程3D游戏实现之人物行走(MD2).

[2]吴亚峰.Android__3D游戏开发技术宝典--OpenGL ES2.0[M].2012.

[3]余志龙.Google.Android.SDK开发范例大全[M].2009.

[4]吴亚峰,苏亚光.Android_3D游戏开发技术详解与典型案例[M].2011.

[5]胡浩,温静馨.3D游戏中人物动作的实时渲染[A].计算科学与技术学院,2008(4).

作者简介

夏有新(1990-),男,汉族,河南驻马店人,大学本科,四川大学软件学院软件工程专业。

上一篇:计算机网络信息安全纵深防护模型 下一篇:煤矿电力监控系统的应用