美文网首页
webgl 13.多纹理

webgl 13.多纹理

作者: lesliefang | 来源:发表于2017-08-30 13:48 被阅读44次

上节我们知道 webgl 通过 texture unit 来支持多个纹理图片。这节我们用 2 张图片来合成一个叠加的效果。

two textures.png muptiple textures.png
// fragment shader
var FRAGMENT_SHADER_SOURCE =
'precision mediump float;\n' +
'varying vec2 v_TexCoord;\n' +
'uniform sampler2D u_Sampler0;\n' +
'uniform sampler2D u_Sampler1;\n' +

'void main() {\n' +
'   vec4 color0 = texture2D(u_Sampler0, v_TexCoord);\n' +
'   vec4 color1 = texture2D(u_Sampler1, v_TexCoord);\n' +
'   gl_FragColor = color0 * color1;\n' +
'}\n';

合成后颜色是 color0 * color1, 这是 component-wise 的乘法。
假设 color0 = (r1, g1, b1, a1) , color1 = (r2, g2, b2, a2)
则 color0 * color1 = (r1 * r2, g1 * g2, b1 * b2, a1 * a2)

完整代码

// vertex shader
var VERTEX_SHADER_SOURCE =
    'attribute vec4 a_Position;\n' +
    'attribute vec2 a_TexCoord;\n' +
    'varying vec2 v_TexCoord;\n' +

    'void main() {\n' +
    '   gl_Position = a_Position;\n' +
    '   v_TexCoord = a_TexCoord;\n' +
    '}\n';

// fragment shader
var FRAGMENT_SHADER_SOURCE =
    'precision mediump float;\n' +
    'varying vec2 v_TexCoord;\n' +
    'uniform sampler2D u_Sampler0;\n' +
    'uniform sampler2D u_Sampler1;\n' +

    'void main() {\n' +
    '   vec4 color0 = texture2D(u_Sampler0, v_TexCoord);\n' +
    '   vec4 color1 = texture2D(u_Sampler1, v_TexCoord);\n' +
    '   gl_FragColor = color0 * color1;\n' +
    '}\n';

var canvas = document.getElementById("canvas");
var gl = canvas.getContext('webgl');
gl.clearColor(0.0, 0.0, 0.0, 1.0);

if (!initShaders(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)) {
    alert('Failed to init shaders');
}

var vertices = new Float32Array([
    -0.5, 0.5, 0.0, 1.0, // 前 2 位是位置坐标, 后 2 位是纹理坐标
    -0.5, -0.5, 0.0, 0.0,
    0.5, 0.5, 1.0, 1.0,
    0.5, -0.5, 1.0, 0.0
]);

initVertexBuffers(gl, vertices);

var u_Sampler0 = gl.getUniformLocation(gl.program, 'u_Sampler0');
var u_Sampler1 = gl.getUniformLocation(gl.program, 'u_Sampler1');

var image0Loaded = false;
var image1Loaded = false;

var image0 = new Image();
image0.onload = function () {
    image0Loaded = true;
    loadTexture(image0, 0, u_Sampler0);
};
image0.src = 'images/sky.jpg';

var image1 = new Image();
image1.onload = function () {
    image1Loaded = true;
    loadTexture(image1, 1, u_Sampler1);
};
image1.src = 'images/circle.gif';

function initVertexBuffers(gl, vertices) {
    var vertexBuffer = gl.createBuffer();
    if (!vertexBuffer) {
        console.log('Failed to create buffer object');
        return -1;
    }

    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    var FSIZE = vertices.BYTES_PER_ELEMENT;

    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 4 * FSIZE, 0);
    gl.enableVertexAttribArray(a_Position);

    var a_TexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');
    gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, 4 * FSIZE, 2 * FSIZE);
    gl.enableVertexAttribArray(a_TexCoord);
}

function loadTexture(image, textureUnit, u_Sampler) {
    var texture = gl.createTexture();
    // 翻转 Y 轴
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);

    if (textureUnit == 0) {
        gl.activeTexture(gl.TEXTURE0);
    } else if (textureUnit == 1) {
        gl.activeTexture(gl.TEXTURE1);
    }

    gl.bindTexture(gl.TEXTURE_2D, texture);

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);

    gl.uniform1i(u_Sampler, textureUnit);

    if (image1Loaded && image1Loaded) {
        // 两个图片都加载完毕后再绘制
        draw();
    }
}

function draw() {
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}

查看源码

相关文章

  • webgl 13.多纹理

    上节我们知道 webgl 通过 texture unit 来支持多个纹理图片。这节我们用 2 张图片来合成一个叠加...

  • webgl 纹理

    前言前面了解了彩色图形的绘制,虽然这种功能很强大,但是对于一些更加复杂的情况下任然不能胜任.比如绘制一只动画,或者...

  • webgl 纹理

    对于绘制多个点,并且多个点的颜色需要不一样。单个attribute是不能够完成的,这时候需要多个attribute...

  • WebGL和OpenGL的差异 - UNPACK_PREMULT

    WebGL可以使用UNPACK_PREMULTIPLY_ALPHA_WEBGL功能,向GPU传输纹理数据时自动给R...

  • WebGL2系列之不可变纹理

    纹理背景知识 在WebGL1中,纹理包括2D纹理和立方体纹理,在实际的使用中,如果纹理的图片是宽和高是2的幂,可以...

  • WebGL 纹理压缩 crunch

    1、WebGL支持将压缩过的纹理传入到显卡,显卡自带解压功能,这就减少了传输数据量,加快纹理传输到显卡; 2、该功...

  • WebGL 纹理颜色原理

    本文由云+社区发表 作者:ivweb qcyhust 导语 WebGL绘制图像时,往着色器中传入颜色信息就可以给图...

  • 13. Input in WebGL

    在WebGL中的输入 Gamepad and Joystick support 游戏手柄和游戏杆支持 在支持HT...

  • WebGL编程指南笔记三 第五章 颜色和纹理

    参考【《WebGL编程指南》读书笔记-颜色与纹理】[https://blog.csdn.net/floating_...

  • WebGL2系列之采样器对象

    前言 在WebGL1中,纹理的图片和采样信息都是写在纹理对象之中. 采样信息告诉GPU如何去读取贴图上图片的信息。...

网友评论

      本文标题:webgl 13.多纹理

      本文链接:https://www.haomeiwen.com/subject/qeltjxtx.html