使用纹理与Three.js和PLY文件

Using textures with Three.js and PLY file

本文关键字:PLY 文件 js Three 纹理      更新时间:2023-09-26

我现在有ascii ply文件加载很好,但它有一个纹理,我似乎不能让它加载不管我如何配置的东西。

    cameraMain = new THREE.Camera(8, MainWidth / MainHeight, 1, 10000);
sceneMain = new THREE.Scene();
ambientLightMain = new THREE.AmbientLight(0x202020);
directionalLightMainRight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLightMainLeft = new THREE.DirectionalLight(0xffffff, 0.5);
pointLightMain = new THREE.PointLight(0xffffff, 0.3);
directionalLightMainRight.position.x = dlpx;
directionalLightMainRight.position.y = dlpy;
directionalLightMainRight.position.z = dlpz;
directionalLightMainRight.position.normalize();
directionalLightMainLeft.position.x = -dlpx;
directionalLightMainLeft.position.y = dlpy;
directionalLightMainLeft.position.z = dlpz;
directionalLightMainLeft.position.normalize();  
pointLightMain.position.x = plpx;
pointLightMain.position.y = plpy;
pointLightMain.position.z = plpz;
sceneMain.addLight(ambientLightMain);
sceneMain.addLight(directionalLightMainRight);
sceneMain.addLight(directionalLightMainLeft);
sceneMain.addLight(pointLightMain);
rendererMain = new THREE.WebGLRenderer();
texture = THREE.ImageUtils.loadTexture('3D/'+ mainURL +'.jpg', {}, function() {
    rendererMain.render(sceneMain);
});
rendererMain.domElement.style.backgroundColor = backgroundColor;
rendererMain.setSize(MainWidth, MainHeight);
rendererMain.domElement.addEventListener('DOMMouseScroll', onRendererMainScroll, false);
rendererMain.domElement.addEventListener('mousewheel', onRendererMainScroll, false);
rendererMain.domElement.addEventListener('dblclick', onRendererMainDblClick, false);
rendererMain.domElement.addEventListener('mousedown', onRendererMainMouseDown, false);
$("#viewerMain").append(rendererMain.domElement);
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mouseup', onMouseUp, false);

代码块初始化模型。其中一些不需要用于问题目的,它有缩放,旋转等代码。我知道还有另外一行,我把它注释掉了,但由于某种原因它在这里没有显示,所以我将单独显示。

material = new THREE.MeshBasicMaterial({map: texture});

那一行在loadTexture代码之后。

其余部分使用loadPly函数加载

        var geometryMain = new THREE.Geometry();
    for (i in event.data.content[0])
      geometryMain.vertices.push(new THREE.Vertex(new THREE.Vector3(event.data.content[0][i][0], event.data.content[0][i][1], event.data.content[0][i][2])));
    for (i in event.data.content[1])
      geometryMain.faces.push(new THREE.Face3(event.data.content[1][i][0], event.data.content[1][i][1], event.data.content[1][i][2]));
    geometryMain.computeCentroids();
    geometryMain.computeFaceNormals();
    mainModel = new THREE.Mesh(geometryMain, new THREE.MeshLambertMaterial({color:0xffffff, shading:THREE.FlatShading}));
    sceneMain.addObject(mainModel);
    mainModel.overdraw = true;
    mainModel.doubleSided = true;

我试过调整THREE.mesh()部分以包括材料,但它破坏了一切。我试过将map:material添加到MeshLambertMaterial中,也是不去的。有人有什么见解吗?对不起,如果这是过于复杂,但我还远远不知道这是有效的。

如果我加上

map:THREE.ImageUtils.loadTexture('3D/'+ mainURL +'.jpg')

到THREE.Mesh()行,得到

。WebGLRenderingContext: GL ERROR:GL_INVALID_OPERATION: glDrawElements: attempt to access out of range vertex in attribute 2

为了在对象上显示纹理,它需要纹理坐标。你似乎只向几何体添加顶点和面。看看THREE.PLYLoader源代码,它似乎不支持加载纹理坐标。(虽然我不确定您是否使用该加载器,因为它应该已经返回一个准备好的Geometry实例,而不是要求您手动构建数组)

使用THREE.MeshNormalMaterial。当你使用MeshNormalMaterial时,它会显示纹理