标签: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