【问题标题】:How to move a texture in WebGL in x-axis?如何在 x 轴上移动 WebGL 中的纹理?
【发布时间】:2016-06-06 13:17:23
【问题描述】:

我能够将图像渲染为纹理,该纹理呈现在屏幕的左上角。现在我想将纹理在 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 像素。

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

【问题讨论】:

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


    【解决方案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);
    

    【讨论】:

    • 看了很长时间的书,做了一些例子,我对WebGL有点熟悉了,我写了这个fiddle,它可以放大/缩小鼠标滚轮,但是pan对我来说仍然是一个难题,你能修改小提琴来修复平移吗?
    【解决方案2】:

    这通常通过转换纹理坐标本身来完成。顶点着色器通常会包含一个纹理矩阵:

    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,看看用单个纹理缩放纹理坐标的效果。您需要执行多重纹理以获得所需的效果。

    【讨论】:

    • 指向 torus 的链接是一个很好的演示,但它与我的问题有什么关系。我需要两个纹理一个接一个地渲染为幻灯片。我的问题令人困惑吗?如果是,请告诉我,我会尝试以不同的方式解释
    • 看了很长时间的书,做了一些例子,我对WebGL有点熟悉了,我写了这个fiddle,它可以放大/缩小鼠标滚轮,但是pan对我来说仍然是一个难题,你能修改小提琴来修复平移吗?
    猜你喜欢
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多