WebGL入门教程5 - 详解纹理滤镜(Texture Filter)
WebGL中使用纹理贴图来实现细腻的物体表面观感,其中一个重要的参数是纹理滤镜(Texture Filter)。
这个参数用来处理当对象出现缩放时,纹理如何处理中间点或被压缩的点。
我们知道纹理在使用中一个经典问题是会出现走样,滤波器就是用来实现纹理反走样的技术。
gl.bindTexture(gl.TEXTURE_2D, textures[0]); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textures[0].image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.bindTexture(gl.TEXTURE_2D, textures[1]); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textures[1].image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.bindTexture(gl.TEXTURE_2D, textures[2]); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textures[2].image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); gl.generateMipmap(gl.TEXTURE_2D);
上面的代码使用了3个纹理,分别设置了不同的参数。
最近滤镜(Nearest Filter)
第1个纹理的gl.TEXTURE_MAG_FILTER 和 gl.TEXTURE_MIN_FILTER 参数都被设置为gl.NEAREST。它表示当纹理被放大或缩小时(通常是通过缩放一个3D对象),WebGL需要使用一个滤镜(filter)来决定缩放后的一个给定点的颜色,在设定颜色时取原图中距离最近的点。如果纹理没有缩放,这个当然没问题,缩小时也还行。但是当放大时,会因为不连续而出现块状效应。但这个滤镜最简单,因此性能最好。
线性滤镜(Linear filter)
第2个纹理缩小和放大滤镜参数均设置为gl.LINEAR。对于纹理放大而言,线性滤镜取原图中相邻像素并使用线性插值获得中间值来填充新点的颜色,比如黑白像素之间插入灰度颜色点,这样显然会获得更好的平滑过滤。当然只要是图像放大,都会产生一定的模糊感,因为无论你怎么处理,都不可能和原图一样清晰。线性滤镜对于纹理缩小处理效果不佳。
多级纹理图(Mipmaps)
第3个纹理gl.TEXTURE_MAG_FILTER取值gl.LINEAR 而 gl.TEXTURE_MIN_FILTER取值gl.LINEAR_MIPMAP_NEAREST。
上述的线性滤镜能很好的处理纹理放大的情况,但对于纹理缩小的处理和最近滤镜是半斤八两。
假如WebGL场景中的一个立方体被放到较远的地方,只有当前窗口的1/10,最近滤镜和线性滤镜将使用原图中的10个像素来生成新的像素点,假如这是一个条纹质地的对象,那么就有1/10的几率会出现条纹色,而9/10的机率不出现条纹色。这就会导致纹理缩小后,有些条纹仍然显示,有些不显示,而且随着缩小比率的变化(持续缩小对象时),条纹也会随机变化呈现闪烁不定的视觉效果。
你可以观察一下这个教程示例作品:
通过pageDown按键让它缩小,pageUp按键让它放大。默认使用纹理1,按“F”字母键,将切换到纹理2,再按“F”,切换到纹理3。
我们可能想通过计算原图周边10*10像素来获得新的纹理像素点,这样将会平滑得多,但实时执行这样的计算是昂贵的。这就是为什么我们要使用纹理3中的Mipmaps滤镜。
Mipmap滤镜通过预先生成一系列平滑过渡的辅助图像(称之为多级纹理图Mip Levels),比如1/2,1/4,1/8原图等等。每个mip level是上一级大图的平滑平均版本(即通过像素矩阵求平均)。当gl.TEXTURE_MIN_FILTER参数的值被设置为gl.LINEAR_MIPMAP_NEAREST时,我们告诉WebGL选择最接近的mip level并在它上面执行线性过滤得到新的纹理像素。
最后一行代码 gl.generateMipmap(gl.TEXTURE_2D);
告诉WebGL来生成多级纹理图(mipmap)。
最新评论
- 相关文章
2019年NodeJS框架Koa和Express选型比较
Koa和Express都是NodeJS的主流应用开发框架。
Express是一个完整的nodejs应用框架。Koa是由Express团队开发的,但是它有不同的关注点。Koa致力于核心中间件...OpenGL/WebGL顶点坐标变换过程简介
世界坐标是按照笛卡尔坐标系定义出来的绝对坐标系,下面的各种坐标系都建立在世界坐标的基础上。对象坐标系对象被应用于任何...
增强现实引擎ARToolKit工作原理简介
ARToolkit是一个基于CV(计算机视觉)和Marker(标识)的开源增强现实引擎。其具备如下功能特性:A. 鲁棒跟踪,包括基于标记的跟踪与基于特征的跟踪;
踏得网精选2016年度10大最佳HTML5动画
踏得网精选2016年度最酷最新的HTML5动画集,评选标准为:创意新颖度+实现技术难度+趣味程度。使用一些在线H5生成工具的作品,因其主要使用图片和CSS3套路动画,...
如何使用BabylonJS加载OBJ或STL模型
BabylonJS(也就是babylon.js,这是一个和three.js类似的WebGL开发框架),更多的用在游戏领域。
本文说明和演示如何使用babylon.js来加载一个标准3d模型文...JavaScript语言多编程范式简介
和C++等语言类似,JS支持多范式(paradigms)编程。我们常常混合这些范式来完成一些大型Web项目。JS支持3种编程范式:命令式、面向对象和函数式。命令式(Imperative JavaScript)命令式就是简单的从上而下完成任务,流水账过程式编码风格:function
使用CSS3 box-decoration-break特性实现多行文本样式
当文章中的长文本被自动断行为多行文本时,其样式可能会出乎我们的设计。本文介绍如何使用CSS3中的box-decoration-break特性来处理多行元素样式。
按照规范...HTML5动画背后的数学 - 粒子群仿生算法简介
本站收录了多个算法可视化动画,如模拟鸟群运动:http://wow.techbrood.com/fiddle/30529等等。这里面除...
HTTP1.1协议现状、问题和解决方案
HTTP的现状最早的HTTP协议非常简单,只能用来传送文本,方法也只有GET,后来逐步发展到1.1,能够支持多种MIME格式数据(如文本、文件),支持GET,POST,HEAD,OPTI...
Three.js入门教程5 - 10个必须知道的编程技巧
作者为Google的Paul,关于如何写出好的WebGL代码的文章。和很多开发者一样,我通过实践学习,但同时我也向其他更有经验的开发者们学习。在过去的几个月中,我在c...
WebGL入门教程6 - 光照效果和Phong光照模型
正是因为有了光,世界才能被我们看见,在3D的世界里,光照给物体带来真实的视觉感受。当光照射在某一表面上时,它可能被吸收、反射或投射。其中入射到表面上的一...
如何实现SVG clipPath自适应被裁剪对象
CSS3中引入的clip-path(裁剪路径)属性是一个很强大的特性。
clip-path的含义如下图所示,好比剪纸一样,你用剪刀沿着某条路径把目标对象(图像或元素)裁...使用top/left/margin和CSS3 translate两种方法实现标题居中的性能差异详解
要实现标题全屏居中(同时在垂直和水平方向居中),有若干种方法,包括使用弹性布局、表格单元、绝对定位、自动外边距和CSS3平移变换等。你可能已经使用了这些方...
使用requestAnimationFrame和Canvas给按钮添加绕边动画
要给按钮添加酷炫的绕边动画,可以使用Canvas来实现。基本的思路是创建一个和按钮大小相同的Canvas元素,内置在按钮元素中。然后在Canvas上实现边线环绕的动画。...
更多...