【问题标题】:THREE.js loading .OBJ files - why do some render flat?三.js 加载 .OBJ 文件 - 为什么有些渲染平面?
【发布时间】:2015-12-20 00:36:16
【问题描述】:

我正在使用相同的通用代码从 OBJ 文件(从网络上的网站免费获得)加载基本网格对象(无纹理)。

有些物体的渲染效果很好,因为不同的面会向相机反射不同强度的光。但其他物体只是呈现均匀的哑光颜色,因此无法看到它们的形状。

我查看了文件内部并注意到了各种不同之处。例如,一个成功的文件包含具有以下初始字符 v、vt、vn、f、s(顶点、顶点纹理、顶点法线、面、平滑)的记录。不成功文件的示例具有以下初始字符:v、vt、f。

这是我正在使用的代码。

function F_Load_OBJ_Model ( givenFilespec, givenName, givenScene, givenHexColorStr, posX, posY, posZ,  rotX, rotY, rotZ, scaleX, scaleY, scaleZ )
{

var OBJLoader = new THREE.OBJLoader();

OBJLoader.load( givenFilespec, F_make_LoadedOBJ_Handler ( givenName, givenScene, givenHexColorStr, posX, posY, posZ,  rotX, rotY, rotZ, scaleX, scaleY, scaleZ ) );

}


function F_make_LoadedOBJ_Handler( givenName, givenScene,     givenHexColorStr, posX, posY, posZ, rotX, rotY, rotZ, scaleX, scaleY, scaleZ )
{
    //... See Tapio's answer (callback factory for use in loops) 
    //... at http://stackoverflow.com/questions/10920372/associate-loaded-json-files-with-a-name-for-later-access
    //... This is useful in case have a loop loading multiple objects asynchronously.

return function ( object )
{
    //... Note that <object> is a THREE Object3D which can have 1 or more child meshes.
    //... But I will assume that there is only one child mesh.

    //var material = new THREE.MeshBasicMaterial();
    //eval( givenName + " = new THREE.Mesh( geometry, material );" );
    //eval ( " var thisMeshOb =" + givenName );
    //eval( givenName + " = object.children[0];" ); //....OK alias

    eval( givenName + " = object.children[0].clone();" );//... also OK

    //object.delete(); //... not possible or neccy, javascript will delete any object which cannot be referred to again.

    eval ( " var thisMeshOb =" + givenName );//... alias used for following common local commands

    thisMeshOb.position.set( posX, posY, posZ );
    thisMeshOb.rotation.set( rotX, rotY, rotZ );
    thisMeshOb.name = givenName; 
    thisMeshOb.scale.set( scaleX, scaleY, scaleZ );
    givenScene.add( thisMeshOb );
    //xxx thisMeshOb.material.type = THREE.MeshLambertMaterial();

    thisMeshOb.material.color.setHex( givenHexColorStr ) ;//...("0xff0000");

    thisMeshOb.geometry.computeFaceNormals(); //...no effect
    thisMeshOb.geometry.normalsNeedUpdate = true; //... no effect

    //... for PHONG ... floorGeometry.computeVertexNormals();   

    thisMeshOb.updateMatrix(); //... without this the next is not effective!?
    xxx = SOW_F_grob_Add_to_Target_Set( thisMeshOb );
};

}//... EOF F_make_LoadedOBJ_Handler. 

我猜这可能与缺少顶点法线有关。但是添加代码来更新它们对最终结果没有影响。

那么文件有问题还是我可以在 THREE.js 中做一些事情来使它们正确呈现?

【问题讨论】:

    标签: three.js .obj


    【解决方案1】:

    您已经正确地发现,平面文件没有“vn”信息。

    “vn”表示“顶点法线”——即(平滑的)法线所面对的方向。

    您可以尝试调用thisMeshOb.geometry.computeFaceNormals(); 之类的名称,并可能在其后加上thisMeshOb.geometry.computeVertexNormals();——然后设置thisMeshOb.geometry.normalsNeedUpdate = true;——这将直接在THREE 中计算一组新的法线。

    您只需要在每个会话中调用一次,在读入时,顺便说一句——无需重新计算每一帧。

    【讨论】:

    • 啊,是的,我已经尝试过 .computeFaceNormals 和 .normalsNeedUpdate 但我忽略了 .computeVertexNormals() 认为它仅适用于 Phong 材质(假设 THREE.OBJLoader 默认分配 Lambert 材质)。非常感谢:)。
    • 更新:在此处查看 SPACORUM 的答案:stackoverflow.com/questions/35136282/…(也适用于 OBJ 来源)。另请参阅 Zydnar 的答案。有时(确切地说是什么时候我不清楚)从 OBJ 加载后,您需要从(加载的)BufferGeometry 转换为 Geometry 以运行 .mergeVertices(),然后(如果需要性能)转换回 BufferGeometry,然后制作最终网格.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    相关资源
    最近更新 更多