我的问题是,我试图通过从文本文件中检索垂直来将某个纹理设置到三角形上。基本上,我希望能够遍历每个矩阵,并为我希望它设置的纹理设置一个值。现在,我把它设置为只有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个或更多的纹理(提示:除了特殊情况,大多数程序都不这样做),那么你就
-
使你的纹理
// for each texture var tex1 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex1); gl.texImage2D(....);
-
在着色器中引用多个纹理
uniform sampler2D u_tex1; uniform sampler2D u_tex2;
-
决定如何在着色器中选择1或其他纹理。
vec4 color1 = texture2D(u_tex1, v_coordsForTex1); vec4 color2 = texture2D(u_tex2, v_coordsForTex2); vec4 color = mix(color1, color2, mixAmount);
如何设置
mixAmount
由您决定。它可以是一个uniform
,一个公式,它可以来自一个来自属性的varying
,这样每个顶点都可以选择纹理等 -
在渲染时
-
将纹理绑定到纹理单位
gl.activeTexture(gl.TEXTURE0 + unitForTexture1); gl.bindTexture(gl.TEXTURE_2D, tex1); gl.activeTexture(gl.TEXTURE0 + unitForTexture2); gl.bindTexture(gl.TEXTURE_2D, tex2);
-
告诉着色器将纹理放在上的单位
gl.uniform1f(locationOfUTex1, unitForTexture1); gl.uniform1f(locationOfUTex2, unitForTexture2);
-
注意:为了澄清,许多程序在绘制时使用多个纹理,但通常这些纹理是颜色贴图、法线贴图、辉光贴图、环境贴图、环境遮挡纹理等。但很少有程序在一次绘制中使用多个颜色贴图。相反,他们使用纹理图谱。
我知道的一个常见的例外是地形渲染,有时它们会有泥土、草地和雪的纹理,并在它们之间混合。不过,它通常比使用纹理图谱的手绘过渡更丑陋。它主要用于21世纪初,当时4meg的vram很常见。现在大多数GPU的最小值是32倍。