[WebGL入门]二十七,多纹理

翻译 2014年10月19日 01:06:02

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正。



本次的demo的运行结果


使用多个纹理

上次介绍了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变量一共有两个,所做的处理和之前类似或者说一样。
使用GLSL的内置函数texture2D来获取纹理的情报,使用顶点颜色和两个纹理颜色计算出最终的输出的颜色。

这次只需要修改片段着色器,顶点着色器没有做任何改动。


javascript的修改

接着是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。
接着,准备纹理对象,这个还是使用自制的create_texture函数。

>纹理对象的生成部分

// テクスチャ用変数の宣言と生成
var texture0 = null, texture1 = null;
create_texture('texture0.png', 0);
create_texture('texture1.png', 1);
为了使用多个纹理,需要修改一下create_texture函数,来接收纹理单位的编号。
>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函数的第二个参数中指定的整数值必须是一致的。

其他的没有变化,使用合适的坐标变换矩阵的话,就能够在多边形中绘制合成状态的纹理了,是不是出奇的简单啊?


总结

多纹理进行渲染的时候应该注意的是,指定正确的纹理单位进行数据的处理,这就足够了。

其他的细节,主要是activeTexture函数和uniform1i函数的使用方法,这几个不出错的话,之后就可以在着色器一侧使用自己喜欢的图片了。

这次只是单纯的在着色器中将两个纹理数据进行相乘运算,然后各个纹理数据分别进行处理,就可以进行完全不一样的渲染,没有使用固定渲染管道,而是使用GLSL中的程序员自定义着色器,这一点很刺激吧。

可运行demo的连接在最下面。

下次,详细介绍一下关于纹理的参数。


使用多纹理绘图的demo

http://wgld.org/s/sample_015/


转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend

相关文章推荐

22 WebGL使用多幅纹理

Title body { margin: 0; text-align: center; } ...

八、WebGL入门,纹理贴图

本节我们来讲WebGL里面很重要的纹理 纹理贴图在游戏开发中十分常见,但是纹理不单单只是一张贴图那么简单。 在WebGL中,纹理有多种,一维纹理:就是一条线;二维纹理:一张二维图片;二维纹理数组:由多...

[WebGL入门]二十六,纹理绘图

在片段着色器中对光进行计算,阴影,亮点等效果都非常的漂亮,3D场景的真实度大幅度提升。并且能和顶点颜色一起使用,理解了前面讲解的内容之后,就应该能进行比较高质量的3D渲染了。 这一次,来看高级一点的纹...

WebGL加载跨域纹理的解决方法

本人一直对WebGL很有兴趣,也试着尝试用osgjs写了个DEMO,很成功的出现了效果。可是当自己用ASP.net写了个服务端,想用自己写的服务器提供的数据来用做纹理,可是怎么也不出来,还报错。跟了下...

HTML5+webGL 多纹理的拼贴

仍然是探究如何用html5+webGL实现三维街景。本文的主题是如何给一个三维模型贴多张纹理,为何会有多张:因为是网络应用,就必须得考虑网络带宽的问题,如果一张纹理图片不经处理直接从服务器传输到客户端...

WebGL自学教程——WebGL示例:14. 渲染到纹理和多程序对象

14. 渲染到纹理和多程序对象       有的时候(比如实现镜像效果),需要将一些场景作为纹理。我们可以使用离屏渲染,使用帧缓冲来达到目的。具体点,是利用帧缓冲对象的附件。在帧缓冲对象中:  ...
  • tiewen
  • tiewen
  • 2011年11月01日 17:30
  • 3674

《webgl入门指南》学习笔记三之three.js创建多重纹理

之前的demo看起来已经很真了,当然是在大家,一步一步step by step的情况下,被各种初始化的代码虐的体无完肤后的,才会有这么个感受。但是从一个对计算机图形无感的人来看,这当然是很粗糙的,比如...

webGL第五课——屏幕坐标转到webGL坐标

看到第四课,发现好多知识需要了解,所以应该进行系统性顺序性的学习了.参考《webGL编程指南》 webGL入门知识 浏览器支持html5之后,可以创建canvas,并调用js进行二维图形的绘制。 要使...
  • lzwdlut
  • lzwdlut
  • 2016年08月18日 17:21
  • 2062

[WebGL入门]二十六,纹理绘图

在片段着色器中对光进行计算,阴影,亮点等效果都非常的漂亮,3D场景的真实度大幅度提升。并且能和顶点颜色一起使用,理解了前面讲解的内容之后,就应该能进行比较高质量的3D渲染了。 这一次,来看高级一点的纹...

[软件渲染器入门]六-应用纹理、背面剔除以及一些WebGL相关

下面是本系列的最后一个章节了。我们将看到如何从Blender中导出贴图和纹理坐标来使我们的网格应用纹理。如果你已经成功的了解了之前的教程,应用一些纹理对你来说应该是小菜一碟。主要概念依旧是在每个顶点间...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[WebGL入门]二十七,多纹理
举报原因:
原因补充:

(最多只允许输入30个字)