【问题标题】:WebGL - Texture is not showing correctlyWebGL - 纹理显示不正确
【发布时间】:2014-12-17 11:24:23
【问题描述】:

在创建纹理 (http://www.webglacademy.com/#5) 的 webglacademy 第 5 篇教程之后,重点是将纹理加载到可行的立方体对象上。

看结果——

谁能告诉我为什么纹理看起来像这样,而它应该完全适合立方体的一面?

这里的演示 - http://kgpk.esy.es/WebGL/(按住鼠标按钮并拖动移动立方体;鼠标滚轮放大/缩小)

使用的纹理 - http://kgpk.esy.es/WebGL/texture.png

代码 - http://kgpk.esy.es/WebGL/WEBGL.js(纹理在 f_IniatializeTextures 函数 [第 209 行] 中加载,该函数使用 f_GetTexture 函数 [第 255 行] 加载纹理,纹理在 f_Animate 函数[第 427 行] 处被投入流中

顶点和片段可以在函数 f_InitializeShaders [line 215] 中找到

        base.m_ShaderVertex = [
            "attribute vec3 position;", // The position of the point.
            "uniform mat4 Pmatrix;",    // Projection matrix.
            "uniform mat4 Vmatrix;",    // Movement matrix from object reference to view reference.
            "uniform mat4 Mmatrix;",    // Movement matrix.
            "attribute vec2 uv;",
            "varying vec2 vUV;",

            "void main(void) {",
                "gl_Position = Pmatrix * Vmatrix * Mmatrix * vec4(position, 1.0);",
                "vUV = uv;", // Set color.
            "}"
        ].join("\n");

        base.m_ShaderFragment = [
            "precision mediump float;",
            "uniform sampler2D sampler;",
            "varying vec2 vUV;",

            "void main(void) {",
                "gl_FragColor = texture2D(sampler, vUV);", // Assign the color to pixel with total opaque.
            "}"
        ].join("\n"); 

谢谢。

【问题讨论】:

  • 是否有任何控制台错误?您永远不会缓冲 UV 数据。你有你的位置和索引缓冲区,但 UV 缓冲区不存在。看看:learningwebgl.com/blog/?page_id=1217(第5课)
  • 别介意前面的评论,我被代码弄糊涂了。跟着教程走,他们可能错过了标记一些东西。

标签: javascript textures webgl


【解决方案1】:

您的顶点缓冲区设置不正确。只需按照教程的代码:

var cube_vertex=[
-1,-1,-1,    0,0,
1,-1,-1,     1,0,
1, 1,-1,     1,1,
-1, 1,-1,    0,1,

-1,-1, 1,    0,0,
1,-1, 1,     1,0,
1, 1, 1,     1,1,
-1, 1, 1,    0,1,

-1,-1,-1,    0,0,
-1, 1,-1,    1,0,
-1, 1, 1,    1,1,
-1,-1, 1,    0,1,

1,-1,-1,     0,0,
1, 1,-1,     1,0,
1, 1, 1,     1,1,
1,-1, 1,     0,1,

-1,-1,-1,    0,0,
-1,-1, 1,    1,0,
1,-1, 1,     1,1,
1,-1,-1,     0,1,

-1, 1,-1,    0,0,
-1, 1, 1,    1,0,
1, 1, 1,     1,1,
1, 1,-1,     0,1

];

每行中的前 3/5 个值用于顶点的位置,其他两个值用于其 UV 坐标。你有一些额外的 UV 值,会弄乱其余部分。

这部分代码负责缓冲区内的偏移量(最后一个参数):

GL.vertexAttribPointer(_position, 3, GL.FLOAT, false, 4*(3+2), 0) ;
GL.vertexAttribPointer(_uv,       2, GL.FLOAT, false, 4*(3+2), 3*4) ;

编辑:

来自webGL spec

void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset)

将当前绑定到 ARRAY_BUFFER 目标的 WebGLBuffer 对象分配给传递索引处的顶点属性。大小是每个属性的组件数。步幅和偏移量以字节为单位。传递的步幅和偏移量必须适合传递的类型和大小,否则将生成 INVALID_OPERATION 错误;请参阅缓冲区偏移和步幅要求。如果 offset 为负数,则会产生 INVALID_VALUE 错误。如果没有 WebGLBuffer 绑定到 ARRAY_BUFFER 目标,则会生成 INVALID_OPERATION 错误。在 WebGL 中,支持的最大步幅为 255;请参阅顶点属性数据步幅。

当您将多个属性打包到同一个缓冲区中时,将使用最后两个参数,如您的示例中所示。 步幅(倒数第二个参数)告诉您每个顶点有多少字节数据,即 5 个值乘以每个值 4 个字节 = 20。 偏移量告诉您要绑定到特定 VBO 的每个顶点值中的字节偏移量是多少。 在您的示例中,您可以看到:

[pos] [pos] [pos] [uv] [uv]
[4B ] [4B ] [4B ] [4B] [4B]
[   12B         ] [  8B   ]

因此,您希望位置位于缓冲区中的每 20*i+0 字节上,并且您的 UV 位于缓冲区中的每 20*i + 3*4 字节上。这就是 0 和 3*4 的由来。

【讨论】:

  • 是的,现在可以了。非常感谢。我完全错过了立方体顶点的变化。顺便说一句,你能解释一下为什么有 4*(3+2) - 这是什么意思?
  • 我还添加了步幅/偏移问题的答案,请参阅编辑。但是,这应该是一个不同的 SO 问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 2021-04-06
相关资源
最近更新 更多