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)。
最新评论
- 相关文章
增强现实引擎ARToolKit工作原理简介
ARToolkit是一个基于CV(计算机视觉)和Marker(标识)的开源增强现实引擎。其具备如下功能特性:A. 鲁棒跟踪,包括基于标记的跟踪与基于特征的跟踪;
Monaco Editor 编辑器拷贝粘贴功能调用和获取选中文本
有时候需要在monaco editor外部调用编辑器的内置功能比如希望在页面主工具栏实现一些快捷操作。button
React JSX语法简介
JSX是一种类似XML的标签语法,用来简化代码,我们可以不使用JSX,但了解并使用也没什么坏处:)在React中,JSX是一个使用 React.createElement() API的快捷方式...
HTML5动画背后的数学 - 粒子群仿生算法简介
本站收录了多个算法可视化动画,如模拟鸟群运动:http://wow.techbrood.com/fiddle/30529等等。这里面除...
计算WebGL中的uniforms变量使用数
在使用Three.js为人体模型加载皮肤材料时,启用了skinning:true的参数。有时候会导致GL编译错误,提示“too many uniforms”。下面的文章有助于理解错误原因和检...
Three.js 对象局部坐标转换为世界坐标
在Three.js中进行顶点几何计算时,一个需要注意的地方是,需要统一坐标系。比如你通过Three.js提供的API创建了一个球体网孔对象,那么默认情况下,各网孔顶点的...
Three.js入门教程6 - 创建全景图和纹理
全景图非常酷。使用Three.js做一个属于自己的全景图并不是那么困难。要做一个全景图,你需要一个软件用来做一张全景图片。我使用了iPhone上的Microsoft Photosyn...
Three.js入门教程5 - 10个必须知道的编程技巧
作者为Google的Paul,关于如何写出好的WebGL代码的文章。和很多开发者一样,我通过实践学习,但同时我也向其他更有经验的开发者们学习。在过去的几个月中,我在c...
Three.js 开发基础知识 - 绘制3D对象
Three.js是一个用来简化WebGL开发的JavaScript库,比如绘制一个三维立方体,使用WebGL需要100多行,那Three.js只要10几行就能够完成。本文通过创建一个立方体来...
inline-block元素设置overflow:hidden属性导致相邻行内元素向下偏移
在表单修改界面中常会使用一个标签、一个内容加一个修改按钮来组成单行界面,如图1所示。那么在表单总长度受限的情况下,当中间的邮箱名称过长时,会遮盖到旁边...
如何使用CSS3/SCSS实现逼真的车窗雨滴效果
在天气预报类的Web移动应用中,常常需要实现屏幕的雨滴效果,表示阴雨天气。感觉上比较神奇,其实想通了,这个效果的实现只需要一点物理知识和CSS3的简单变换。实现一个小雨滴首先雨滴是一个个小的椭圆形元素:.raindrop
在PHP网页程序中执行Sass/Compass命令
我们需要在wow云开发平台支持sass/compass等预编译样式语言,为此我们首先尝试了scssphp扩展,但是在支持最新语法上,经常会出现异常。所以我们采用了代理的方式...
更多...