标签:webgl
注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正。
那么,这次来说说使用多个纹理来合成图像的方法,学习了这个方法之后可以再一个多边形中使用多个纹理。
为了同时使用多个纹理,先来想想一下需要做些什么呢?
上次已经简单的基础了,WebGL中管理纹理的方法是纹理单位,灵活使用这个纹理单位的话,就能实现多纹理的渲染了。
这次的demo使用下面两个图片。
>第一张
>第二张
下面就使用这两张图片来实现多纹理渲染。
为了渲染多纹理,着色器一侧需要准备多个uniform变量,用来接收多个纹理单位,但是,这次多边形的纹理坐标只需要一个,无论第一个纹理还是第二个纹理都一样,需要变更的代码如下。
>片段着色器的代码修改
precision mediump float; uniform sampler2D texture0; uniform sampler2D texture1; varying vec4 vColor; varying vec2 vTextureCoord; void main(void){ vec4 smpColor0 = texture2D(texture0, vTextureCoord); vec4 smpColor1 = texture2D(texture1, vTextureCoord); gl_FragColor = vColor * smpColor0 * smpColor1; }如上,接收纹理情报的sampler2D型uniform变量一共有两个,所做的处理和之前类似或者说一样。
这次只需要修改片段着色器,顶点着色器没有做任何改动。
接着是javascript的代码修改,在这里需要向新追加的uniform变量中传入正确的纹理数据。
首先,固定的,uniformLocation的获取。
>uniformLocation的获取部分
// uniformLocationを配列に取得 var uniLocation = new Array(); uniLocation[0] = gl.getUniformLocation(prg, ‘mvpMatrix‘); uniLocation[1] = gl.getUniformLocation(prg, ‘texture0‘); uniLocation[2] = gl.getUniformLocation(prg, ‘texture1‘);这里很简单,纯粹的从着色器中获取uniformLocation。
>纹理对象的生成部分
// テクスチャ用変数の宣言と生成 var texture0 = null, texture1 = null; create_texture(‘texture0.png‘, 0); create_texture(‘texture1.png‘, 1);为了使用多个纹理,需要修改一下create_texture函数,来接收纹理单位的编号。
function create_texture(source, number){ // イメージオブジェクトの生成 var img = new Image(); // データのオンロードをトリガーにする img.onload = function(){ // テクスチャオブジェクトの生成 var tex = gl.createTexture(); // テクスチャをバインドする gl.bindTexture(gl.TEXTURE_2D, tex); // テクスチャへイメージを適用 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); // ミップマップを生成 gl.generateMipmap(gl.TEXTURE_2D); // テクスチャのバインドを無効化 gl.bindTexture(gl.TEXTURE_2D, null); // 生成したテクスチャを変数に代入 switch(number){ case 0: texture0 = tex; break; case 1: texture1 = tex; break; default: break; }; } // イメージオブジェクトのソースを指定 img.src = source;第二个参数用来接收纹理单位的编号,来确定生成的纹理对象要赋值给谁。其他地方和之前一样,没有变化。
>持续循环中的处理
// テクスチャユニットを指定してバインドし登録する gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture0); gl.uniform1i(uniLocation[1], 0); // テクスチャユニットを指定してバインドし登録する gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texture1); gl.uniform1i(uniLocation[2], 1);这里的重点是,纹理单位的有效化,纹理对象的绑定,以及向着色器中设定单位编号是一个组合。
多纹理进行渲染的时候应该注意的是,指定正确的纹理单位进行数据的处理,这就足够了。
其他的细节,主要是activeTexture函数和uniform1i函数的使用方法,这几个不出错的话,之后就可以在着色器一侧使用自己喜欢的图片了。
这次只是单纯的在着色器中将两个纹理数据进行相乘运算,然后各个纹理数据分别进行处理,就可以进行完全不一样的渲染,没有使用固定渲染管道,而是使用GLSL中的程序员自定义着色器,这一点很刺激吧。
可运行demo的连接在最下面。
下次,详细介绍一下关于纹理的参数。使用多纹理绘图的demo
转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend
标签:webgl
原文地址:http://blog.csdn.net/lufy_legend/article/details/40250697