WebGL - 使用多个纹理时的条纹 [英] WebGL - stripes when using multiple textures

查看:30
本文介绍了WebGL - 使用多个纹理时的条纹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的 WebGL 程序中使用了三种纹理,并且得到了条纹/重叠效果.

I'm using three textures in my WebGL program, and I get a striped/overlapping effect.

我绑定的第一个纹理没问题,但顺序纹理得到效果.

The first texture I bind is OK, but sequential textures get the effect.

这是我的顶点数据格式 (x,y,z,s,t,textureIndex,textureName)

Here's my vertex data format (x,y,z,s,t,textureIndex,textureName)

-5.0  0.0 -5.0 0.0 0.0 1 WL01
-5.0  0.0  5.0 0.0 1.0 1 WL01
 5.0  0.0  5.0 1.0 1.0 1 WL01
-5.0  0.0 -5.0 0.0 0.0 1 WL01
 5.0  0.0 -5.0 1.0 0.0 1 WL01
 5.0  0.0  5.0 1.0 1.0 1 WL01

-1.0  1.0 -4.0 0.0 1.0 2 WL02
-1.0  0.0 -4.0 0.0 0.0 2 WL02
-0.0  0.0 -4.0 1.0 0.0 2 WL02
-1.0  1.0 -4.0 0.0 1.0 2 WL02
-0.0  1.0 -4.0 1.0 1.0 2 WL02
-0.0  0.0 -4.0 1.0 0.0 2 WL02

 2.0  1.0 -4.0 1.0 1.0 0 WL00
 2.0  0.0 -4.0 1.0 0.0 0 WL00
 0.5  0.0 -4.0 0.0 0.0 0 WL00
 2.0  1.0 -4.0 1.0 1.0 0 WL00
 0.5  1.0 -4.0 0.0 1.0 0 WL00
 0.5  0.0 -4.0 0.0 0.0 0 WL00

这是我单独初始化每个纹理的方法:

Here's how I initialize each texture individually:

gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, null);

缓冲区初始化:

levelVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, levelVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
levelVertexBuffer.vertexCount = 18;
textureIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, textureIndexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(texIndexBuffData), gl.STATIC_DRAW);

在主循环中我正在做:

...
for( var i = 0; i < level.textures.length; i++ ) {
    gl.activeTexture(gl.TEXTURE0 + i);
    gl.bindTexture(gl.TEXTURE_2D, level.textures[i]);
}
...
gl.uniform1i(shaderProgram.texturesUniform0, 0);
gl.uniform1i(shaderProgram.texturesUniform1, 1);
gl.uniform1i(shaderProgram.texturesUniform2, 2);

顶点着色器:

 <script id="shader-vs" type="x-shader/x-vertex">
    attribute vec3 aVertexPosition;
    attribute vec2 aTextureCoord;
    attribute float aTextureIndex;
    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;
    varying vec2 vTextureCoord;
    varying float vTextureIndex;
    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;
        vTextureIndex = aTextureIndex;
    }
</script>

片段着色器:

<script id="shader-fs" type="x-shader/x-fragment">
    precision mediump float;
    varying float vTextureIndex;
    varying vec2 vTextureCoord;
    uniform sampler2D u_texture0;
    uniform sampler2D u_texture1;
    uniform sampler2D u_texture2;

    vec4 getSampleFromArray(int index, vec2 uv) {
        vec4 color;
        if (index == 0) {
            color = texture2D(u_texture0, uv);
        } else if ( index == 1 ) {
            color = texture2D(u_texture1, uv);
        } else if ( index == 2 ) {
            color = texture2D(u_texture2, uv);
        }
        return color;
    }
    void main() {
        gl_FragColor = getSampleFromArray(int(vTextureIndex), vec2(vTextureCoord.s, vTextureCoord.t));
    }
</script>

实例

推荐答案

我看到的可能性是对不同的 vTextureIndex 的插值很差.尝试将其四舍五入到最接近而不是向下:int(vTextureIndex + 0.5).

The possibility I see is poor interpolation of your varying vTextureIndex. Try rounding it to nearest rather than down: int(vTextureIndex + 0.5).

是的,您会认为这不是必需的,但是 GPU 在允许的地方使用粗略的足够好的近似值.

Yes, you would think this wouldn't be necessary, but GPUs use rough good-enough approximations all over the place where they're allowed to.

这篇关于WebGL - 使用多个纹理时的条纹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆