1

我开始学习 WebGL,但我对图形完全没有经验。

我需要将一个完整的网格加载到 WebGL(Dabrovic Sponza 来自:http ://graphics.cs.williams.edu/data/meshes.xml )。从今天开始,我加载的唯一类型的模型是简单的 JSON,通过:

function loadModel(){
    var request=new XMLHttpRequest();
    request.open("GET", "sponza.json");
    request.onreadystatechange=function (){
        if(request.readyState==4)
            handleLoadedModel(JSON.parse(request.responseText));
    }
    request.send();   
}

现在我有这些文件:

在此处输入图像描述

到目前为止我所做的是:

我使用在线找到的此脚本将 obj 转换为 JSON

    function loadObj(url)
    {
        var req = new XMLHttpRequest();
        req.onreadystatechange = function () { processLoadObj(req) };
        req.open("GET", url, true);
        req.send(null);
    }

    function processLoadObj(req)
    {
        if (req.readyState == 4) {
            doLoadObj(req.responseText);
        }
    }

    function doLoadObj(text)
    {
        vertexArray = [ ];
        normalArray = [ ];
        textureArray = [ ];
        indexArray = [ ];

        var vertex = [ ];
        var normal = [ ];
        var texture = [ ];
        var facemap = { };
        var index = 0;

        var lines = text.split("\n");
        for (var lineIndex in lines) {
            var line = lines[lineIndex].replace(/[ \t]+/g, " ").replace(/\s\s*$/, "");

            // ignore comments
            if (line[0] == "#")
                continue;

            var array = line.split(" ");
            if (array[0] == "v") {
                // vertex
                vertex.push(parseFloat(array[1]));
                vertex.push(parseFloat(array[2]));
                vertex.push(parseFloat(array[3]));
            }
            else if (array[0] == "vt") {
                // normal
                texture.push(parseFloat(array[1]));
                texture.push(parseFloat(array[2]));
            }
            else if (array[0] == "vn") {
                // normal
                normal.push(parseFloat(array[1]));
                normal.push(parseFloat(array[2]));
                normal.push(parseFloat(array[3]));
            }
            else if (array[0] == "f") {
                // face
                if (array.length != 4) {
                    //obj.ctx.console.log("*** Error: face '"+line+"' not handled");
                    continue;
                }

                for (var i = 1; i < 4; ++i) {
                    if (!(array[i] in facemap)) {
                        // add a new entry to the map and arrays
                        var f = array[i].split("/");
                        var vtx, nor, tex;

                        if (f.length == 1) {
                            vtx = parseInt(f[0]) - 1;
                            nor = vtx;
                            tex = vtx;
                        }
                        else if (f.length = 3) {
                            vtx = parseInt(f[0]) - 1;
                            tex = parseInt(f[1]) - 1;
                            nor = parseInt(f[2]) - 1;
                        }
                        else {
                            //obj.ctx.console.log("*** Error: did not understand face '"+array[i]+"'");
                            return null;
                        }

                        // do the vertices
                        var x = 0;
                        var y = 0;
                        var z = 0;
                        if (vtx * 3 + 2 < vertex.length) {
                            x = vertex[vtx*3];
                            y = vertex[vtx*3+1];
                            z = vertex[vtx*3+2];
                        }
                        vertexArray.push(x);
                        vertexArray.push(y);
                        vertexArray.push(z);

                        // do the textures
                        x = 0;
                        y = 0;
                        if (tex * 2 + 1 < texture.length) {
                            x = texture[tex*2];
                            y = texture[tex*2+1];
                        }
                        textureArray.push(x);
                        textureArray.push(y);

                        // do the normals
                        x = 0;
                        y = 0;
                        z = 1;
                        if (nor * 3 + 2 < normal.length) {
                            x = normal[nor*3];
                            y = normal[nor*3+1];
                            z = normal[nor*3+2];
                        }
                        normalArray.push(x);
                        normalArray.push(y);
                        normalArray.push(z);

                        facemap[array[i]] = index++;
                    }

                    indexArray.push(facemap[array[i]]);
                }
            }
        }

        result = {};
        result["vertexPositions"] = vertexArray;
        result["vertexNormals"] = normalArray;
        result["vertexTextureCoords"] = textureArray;
        result["indices"] = indexArray;;


        document.write(JSON.stringify(result));

    }
    </script>
    </head>


    <body onload="loadObj('model.obj');">
    </body>

然后将所有信息放入缓冲区(1个用于文本坐标,1个用于顶点,1个用于法线,1个用于索引)

最后对所有东西都使用了单一的纹理。

结果远远超出了 dabrovic sponza(谷歌图片上的随机图片显示了我想要的),我该如何使用那些 jpg 文件和 .mtl ?

我什至不确切知道 mtl 文件是什么,而且我对这些东西完全没有经验,这是我的第一次尝试,所以请耐心等待!

另外,如果我的英语不好,对不起!

编辑:另外,使用随机模型加载器加载网格时,我发现并非所有顶点都正确转换(例如,我没有地板)。此外,如果我对所有部分(柱状柱)都使用纹理,则将其渲染为完全透明……也许我的转换器不好。我有机会写一个像样的转换器吗?我在哪里可以找到这样做的文档?再次感谢

4

1 回答 1

0

显然,您的 OBJ 转换器忽略了 MTL 文件中包含的材料定义。你嫁给这种格式了吗?也许在搅拌机中加载并作为 collada 重新出口?

于 2013-02-16T06:08:49.357 回答