基于垂直方向绑定多个纹理



我的问题是,我试图通过从文本文件中检索垂直来将某个纹理设置到三角形上。基本上,我希望能够遍历每个矩阵,并为我希望它设置的纹理设置一个值。现在,我把它设置为只有1个纹理,几乎所有的东西。我举了一个例子,但这是直接的webgl,没有库或任何东西,我严格地将其用于去工程和学习目的。一定有一种方法可以做到这一点,因为我正在为x,y,z坐标和纹理坐标做这件事。

    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, rockTexture);
    gl.uniform1i(shaderProgram.samplerUniform, 0);

我查阅了一些文档,但你不能像bindBuffer那样将数组绑定到纹理上,基本上我只是试图从文本文件中获取一个值,以确定我希望它是哪个纹理。一些帮助,甚至朝着正确的方向迈出一步并做出一些解释,都会带来奇迹。

我如何使用坐标进行此操作的示例:

(文本文件示例)

// Floor 1
-25.0  0.0 -25.0 0.0 25.0
-25.0  0.0  25.0 0.0 0.0
 25.0  0.0  25.0 25.0 0.0
-25.0  0.0 -25.0 0.0 25.0
 25.0  0.0 -25.0 25.0 25.0
 25.0  0.0  25.0 25.0 0.0
// Ceiling 1
-25.0  4.0 -25.0 0.0 24.0
-25.0  4.0  25.0 0.0 0.0
 25.0  4.0  25.0 24.0 0.0
-25.0  4.0 -25.0 0.0 24.0
 25.0  4.0 -25.0 24.0 24.0
 25.0  4.0  25.0 24.0 0.0

然后它解析并通过这里连接它:

var lines = data.split("n");
        var vertexCount = 0;
        var vertexPositions = [];
        var vertexTextureCoords = [];
        for (var i in lines) {
            var vals = lines[i].replace(/^s+/, "").split(/s+/);
            if (vals.length == 6 && vals[0] != "//") {
                // It is a line describing a vertex; get X, Y and Z first
                vertexPositions.push(parseFloat(vals[0]));
                vertexPositions.push(parseFloat(vals[1]));
                vertexPositions.push(parseFloat(vals[2]));
                // And then the texture coords
                vertexTextureCoords.push(parseFloat(vals[3]));
                vertexTextureCoords.push(parseFloat(vals[4]));
                vertexCount += 1;
            }
        }
        worldVertexPositionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositions), gl.STATIC_DRAW);
        worldVertexPositionBuffer.itemSize = 3;
        worldVertexPositionBuffer.numItems = vertexCount;
        worldVertexTextureCoordBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexTextureCoords), gl.STATIC_DRAW);
        worldVertexTextureCoordBuffer.itemSize = 2;
        worldVertexTextureCoordBuffer.numItems = vertexCount;

所以基本上,我只是想告诉程序我想使用哪个纹理。

通常,如果您希望在同一模型上有两个或多个纹理,请将它们合并到纹理图谱中。你可以看到一个实际的例子作为最后一个例子在这个页面

否则,如果你真的想使用2个或更多的纹理(提示:除了特殊情况,大多数程序都不这样做),那么你就

  1. 使你的纹理

    // for each texture
    var tex1 = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex1);
    gl.texImage2D(....);
    
  2. 在着色器中引用多个纹理

    uniform sampler2D u_tex1;
    uniform sampler2D u_tex2;
    
  3. 决定如何在着色器中选择1或其他纹理。

    vec4 color1 = texture2D(u_tex1, v_coordsForTex1);
    vec4 color2 = texture2D(u_tex2, v_coordsForTex2);
    vec4 color =  mix(color1, color2, mixAmount);
    

    如何设置mixAmount由您决定。它可以是一个uniform,一个公式,它可以来自一个来自属性的varying,这样每个顶点都可以选择纹理等

  4. 在渲染时

    1. 将纹理绑定到纹理单位

      gl.activeTexture(gl.TEXTURE0 + unitForTexture1);
      gl.bindTexture(gl.TEXTURE_2D, tex1);
      gl.activeTexture(gl.TEXTURE0 + unitForTexture2);
      gl.bindTexture(gl.TEXTURE_2D, tex2);
      
    2. 告诉着色器将纹理放在上的单位

      gl.uniform1f(locationOfUTex1, unitForTexture1);
      gl.uniform1f(locationOfUTex2, unitForTexture2);
      

注意:为了澄清,许多程序在绘制时使用多个纹理,但通常这些纹理是颜色贴图、法线贴图、辉光贴图、环境贴图、环境遮挡纹理等。但很少有程序在一次绘制中使用多个颜色贴图。相反,他们使用纹理图谱。

我知道的一个常见的例外是地形渲染,有时它们会有泥土、草地和雪的纹理,并在它们之间混合。不过,它通常比使用纹理图谱的手绘过渡更丑陋。它主要用于21世纪初,当时4meg的vram很常见。现在大多数GPU的最小值是32倍。

最新更新