阅读 251

WebGL之纹理动画

在前端我们可以使通过改变dom的样式来实现dom的动画效果。在WebGL中我们同样可以实现动画效果。通过改变纹理坐标我们也可以实现纹理贴图的动画效果。 实现代码如下。 我们只需要在纹理贴图demo的基础上修改两个地方就可以实现纹理动画效果了。

  • 修改assignValue函数

这里不再调用gl.bufferData向缓冲区传递数据了。

function assignValue(gl, program) {
    let positions = new Float32Array([
    -0.5, -0.5, 0, 0,
    -0.5, 0.5, 0, 1,
    0.5, 0.5, 1, 1,
    -0.5, -0.5, 0, 0,
    0.5, 0.5, 1, 1,
    0.5, -0.5, 1, 0,
    
    ]);
    // 找到着色器中的全局变量 u_Color;
    var u_Texture = gl.getUniformLocation(program, "u_Texture");
    var a_Position = gl.getAttribLocation(program, "a_Position");
    var a_Uv = gl.getAttribLocation(program, "a_Uv");

    gl.enableVertexAttribArray(a_Position);
    gl.enableVertexAttribArray(a_Uv);
    // 创建缓冲区
    var buffer = gl.createBuffer();
    // 绑定缓冲区为当前缓冲
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    // 设置 a_Position 属性从缓冲区读取数据方式
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 16, 0);
    // 设置 a_Uv 属性从缓冲区读取数据方式
    gl.vertexAttribPointer(a_Uv, 2, gl.FLOAT, false, 16, 8);
    // 向缓冲区传递数据
    // gl.bufferData(
    //     gl.ARRAY_BUFFER,
    //     positions,
    //     gl.STATIC_DRAW
    // );
    loadTexture(gl, '../images/1.jpg', u_Texture, function () {
        render(gl, positions);
    })
}
复制代码
  • WebGL渲染函数

在这里调用gl.bufferData向缓冲区传递数据,因为数据的纹理坐标一直在发生改变,所以写入缓冲区的数据也要不断重新写入。调用requestAnimationFrame动画函数,每一次重新渲染时纹理坐标x轴值不断增加0.005,使得图片呈现一直向左运动的效果。当然也可以通过修改y轴的值实现向下或向上的运行.

let anim = 0.005;
function render(gl, positions) {
    // 向缓冲区传递数据
    gl.bufferData(
        gl.ARRAY_BUFFER,
        new Float32Array(positions),
        l.STATIC_DRAW
    );
    //设置清屏颜色为黑色。
    gl.clearColor(0, 0, 0, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLES, 0, positions.length / 4);
    if (positions.length <= 0) return;
    for (let i = 2; i < positions.length; i += 4) {
        positions[i] += anim;
    }
    requestAnimationFrame(()=>{
        render(gl,positions);
    }); 
}
复制代码

效果如下所示:

纹理动画-向左运动.gif

文章分类
前端
文章标签