如何在x轴中移动WebGL中的纹理?

时间:2016-02-24 10:04:26

标签: javascript canvas opengl-es html5-canvas webgl

我能够将图像渲染到纹理,该纹理在屏幕的左上角渲染。现在我想在X轴上慢慢移动纹理,并在左上角添加另一个纹理,并希望连续进行。

现在,我能够渲染单个纹理,但无法进一步移动。有人可以帮助我进一步前进吗?

我正在处理我迄今为止所做的代码。

代码:

顶点着色器

attribute vec2 a_position;
uniform vec2 u_resolution;
uniform mat3 u_matrix;
varying vec2 v_texCoord;
void main() {
    gl_Position = vec4(u_matrix * vec3(a_position, 1), 1);
    v_texCoord = a_position;
}

片段着色器

precision mediump float;
// our texture
uniform sampler2D u_image;
// the texCoords passed in from the vertex shader.
varying vec2 v_texCoord;
void main() {
    gl_FragColor = texture2D(u_image, v_texCoord);
}

的Javascript

gl.clear(gl.COLOR_BUFFER_BIT || gl.DEPTH_BUFFER_BIT);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.width, image.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, dataTypedArray);
//Draw the rectangle.
gl.drawArrays(gl.TRIANGLES, 0, 6);

其中dataTypedArray是像素的Uint8Array。

接下来,我想移动此渲染纹理并添加更多纹理以前的位置。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我认为实现这一目标的最简单方法是基本上绘制2个四边形,并进行2次单独的绘制调用。在第一次绘制调用中,在所需的x位置绘制第一个四边形,然后切换到第二个纹理,并在所需位置绘制第二个四边形。您无需以任何方式更改着色器。

在伪js中:

// allocate the two textures 

gl.clear(gl.COLOR_BUFFER_BIT || gl.DEPTH_BUFFER_BIT);
gl.bindTexture(gl.TEXTURE_2D, firstTexture);
// use whatever method you want uniform/attribute/watever to upload the quad position
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindTexture(gl.TEXTURE_2D, secondTexture);
// upload the second quad position
gl.drawArrays(gl.TRIANGLES, 0, 6);

答案 1 :(得分:0)

这通常通过翻译纹理坐标本身来完成。顶点着色器通常包含纹理矩阵:

attribute vec2 vertexTexCoord;  // input texture coord (s,t)
uniform mat4 TextureMatrix;     // for transforming (s,t)
varying vec2 texCoord;          // output texture coord
...
 void main() {
      gl_Position = ModelViewProjection*vec4(vertexPosition,1.0);
      texCoord = (TextureMatrix*vec4(vertexTexCoord,0.0,1.0)).st;
      ...
 }

纹理矩阵可以平移,旋转,缩放......纹理。客户端JS代码构造适当的转换并加载着色器的纹理矩阵。如果您希望为翻译设置动画,则可以在以下位置重新计算纹理矩阵:

 ... compute s-traslation ds based on frame time ...
 Texture = new Matrix4x4;
 Texture.translate(ds, 0, 0).scale(4, 2, 1);
 ...
 gl.uniformMatrix4fv(program.TextureMatrix, false, Texture.array);

如果你想涉及多个纹理,那么你将不得不使用多个纹理单元并在片段着色器中根据需要访问它们:

 varying vec2 texCoord;
 uniform sampler2D texUnit0;
 uniform sampler2D texUnit1;
 ...
 void main() {
     ... choose which texture you want to access based on texCoord.st
     gl_FragColor = texture2D(desiredTexUnit, texCoord);
     ...
 }

查看this textured donut以查看使用单个纹理缩放纹理坐标的效果。您需要执行多纹理才能获得所需的效果。