Javascript 在WebGL中,如何加载使用多个纹理的3D模型(波前)?
现在,我的代码支持加载.obj(wavefront)文件并将其转换为WebGL对象(GL缓冲区和渲染函数)。但是,我现在只能将一个纹理映射到整个对象 我的文件加载器逐行读取,当前忽略.obj文件的Javascript 在WebGL中,如何加载使用多个纹理的3D模型(波前)?,javascript,graphics,html5-canvas,webgl,Javascript,Graphics,Html5 Canvas,Webgl,现在,我的代码支持加载.obj(wavefront)文件并将其转换为WebGL对象(GL缓冲区和渲染函数)。但是,我现在只能将一个纹理映射到整个对象 我的文件加载器逐行读取,当前忽略.obj文件的usemtl行。我的object render函数看起来像这样(改编自教程)-还不完美,但为了完整起见,我发布了整个工作函数: this.render = function(gl){ // push identity to the matrix stack (to apply changes o
usemtl
行。我的object render函数看起来像这样(改编自教程)-还不完美,但为了完整起见,我发布了整个工作函数:
this.render = function(gl){
// push identity to the matrix stack (to apply changes only to this object)
mvPushMatrix();
// apply translations
mat4.translate(mvMatrix, [this.transX, this.transY, this.transZ]);
// apply scaling
mat4.scale(mvMatrix, [this.scaleX, this.scaleY, this.scaleZ]);
// apply rotations
mat4.rotate(mvMatrix, this.rotX, [1, 0, 0]);
mat4.rotate(mvMatrix, this.rotY, [0, 1, 0]);
mat4.rotate(mvMatrix, this.rotZ, [0, 0, 1]);
// load position buffer
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionVertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
this.positionVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
// load normals buffer
gl.bindBuffer(gl.ARRAY_BUFFER, this.normalVertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
this.normalVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
// load texture buffer
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureVertexBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute,
this.textureVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
// load and apply the texture
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.uniform1i(shaderProgram.samplerUniform, 0);
// if blending is turned on, apply the blending and alpha value
if(this.blending || this.firstRun){
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
gl.enable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
gl.uniform1f(shaderProgram.alphaUniform, this.alpha);
}
// otherwise, disable blending mode and render normally
else{
gl.disable(gl.BLEND);
gl.enable(gl.DEPTH_TEST);
gl.uniform1f(shaderProgram.alphaUniform, 1.0);
}
// render with indices IF indices are enabled
if(this.indicesEnabled){
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexVertexBuffer);
setMatrixUniforms();
gl.drawElements(gl.TRIANGLES,
this.indexVertexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
}
// otherwise, render normally
else {
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES, 0, this.textureVertexBuffer.numItems);
}
// pop the matrix stack
mvPopMatrix();
// unflag first run after first frame rendering
this.firstRun = false;
}
我想做的是读取使用多个纹理的文件。我该怎么做?我最初的假设是从.obj读取一个纹理的所有面,一旦纹理发生变化,就开始读取一个单独的缓冲区,然后将对象分割成多个部分(每个纹理一个部分),并将它们渲染为单独的对象。但是在我更改代码之前,我想看看这是否正确,或者是否有一种特别好的方法来解决这个问题
老实说,我根本不知道该怎么做。有什么建议吗?谢谢。是的,差不多就是这样做的 通常,对于专业游戏,艺术家需要为每个对象使用1个纹理,因为两个100多边形模型的2次调用gl.drawXXX比一个200多边形模型的1次调用gl.drawXXX慢 否则,一些团队会使用工具读取文件并将所有内容转换为一个纹理,将纹理合并为一个超级纹理。其他团队有工具可以将多边形按每个纹理分类为1个模型
对于每个多边形,他们有效地找出它所属的纹理,然后将这些顶点放入该纹理的桶中。最后,他们写出每个桶,每个纹理一个。谢谢!最后,我坚持使用一个纹理缓冲区,但对渲染函数使用偏移索引和缓冲区段的长度,从而使其正常工作。相同的概念,但出于某种原因,它不能用于多个缓冲区,但此解决方案非常有效。