2015-03-18 259 views
2

根据three.js github上的各种帖子,MeshFaceMaterial最终将被弃用。THREE.js:寻找替代MeshFaceMaterial

我目前在我的地形上使用它。当然,这不是最好的办法。其实它非常糟糕。对于一个我不能使用BufferGeometry这是不好的考虑我通常有2层128x128(分段)飞机的地形。非常高的内存使用率。

我已经调整了我的所有代码,以允许地形为BufferGeometry,除了两件事情不起作用。 MeshFaceMaterialBufferGeometry.merge()。合并对索引几何不起作用,对于我来说这很奇怪,因为THREE创建了这个几何,但它可以合并来自搅拌器的非索引几何。它不能合并自己创建的几何体,但可以合并外部来源的几何体......哦,那是另一个帖子,返回MeshFaceMaterial

我目前使用128x128“MaterialMap”。每个像素代表飞机每个面的materialIndex。这有两个严重的缺点。将各部分地形(无曲线)和纹理边界上的粗糙区分开来。

我的问题是:如何在不使用MeshFaceMaterial的情况下生成具有多个纹理的地形。我拥有的最高分辨率纹理是2048x2048,区域大小很容易就是10000x10000,因此需要重复(右?)。我的目标是使用BufferGeometry并摆脱MeshFaceMaterial

MATERIALMAP例如:enter image description here

地形实例(非常冒出对不起{工作PC}):enter image description here

回答

4

你可以通过与剔除意见回复电子邮件帮了我,同时啮合,我想返回如果你想使用THREE.PlaneBufferGeometry(正如你知道的那样,THREE.js中的所有几何图形很快会出现在这里),那么我的建议是将不同的PlaneBufferGeometries在彼此之上。比如在上面的例子中的图片,你可以有

` 
var stoneFloorGeometry = new THREE.PlaneBufferGeometry(arenaWidth, arenaHeight, 1, 1); 
var stoneFloorMaterial = new THREE.MeshBasicMaterial({ 
    depthWrite: false, // This is always underneath every other object 
    map: stoneFloorTexture 
}); 
var stoneFloor = new THREE.Mesh(stoneFloorGeometry, stoneFloorMaterial); 
stoneFloor.rotation.x = Math.PI/-2; // rotate to be flat in the X-Z plane 
stoneFloor.position.set(0, 0, 0); 
scene.add(stoneFloor); 

// now add the grass plane right on top of that with its own texture and shape 

var grassGeometry = new THREE.PlaneBufferGeometry(lawnWidth, lawnHeight, 1, 1); 
var grassMaterial = new THREE.MeshBasicMaterial({ 
    depthWrite: false, // this is rendered right on top of the stone floor 
    map: grassTexture 
}); 
var grass = new THREE.Mesh(grassGeometry, grassMaterial); 
grass.rotation.x = Math.PI/-2; 
grass.position.set(0, 0, 0); 
scene.add(grass); 

// finally add the stone path walkway on top of the grass, leading to the castle 

var walkwayGeometry = new THREE.PlaneBufferGeometry(walkwayWidth, walkwayHeight, 1, 1); 
var walkwayMaterial = new THREE.MeshBasicMaterial({ 
    depthWrite: false, // this is rendered right on top of the grass 
    map: stoneFloorTexture // uses same texture as large stoneFloor before 
}); 
var walkway = new THREE.Mesh(walkwayGeometry, walkwayMaterial); 
walkway.rotation.x = Math.PI/-2; 
walkway.position.set(0, 0, 0); 
scene.add(walkway); 

` 

只要您层与底部水平,顶部和禁用depthWrite长,所有不同的纹理会正确地显示在对方之上,没有人会Z-斗争。所以,StoneFloor首先被添加到场景中,然后是草地,然后是走道。
由于depthTest仍然处于活动状态,所以您的移动游戏角色将在所有这些不同纹理之上进行渲染。最初,它看起来好像只是禁用了'depthTest',但纹理结束了渲染('高于')字符/模型,这是不正确的。

最后,当THREE.js将ShapeGeometry移动到BufferGeometry时,最好定义一个任意的多边形形状(如八角形或其他东西),然后纹理贴图并放下游戏关卡的顶部形状以类似的方式,从而避免你提到的'正方形'问题。

至于这个当前的解决方案,在现代CPU/GPU上,我认为在创建3个PlaneBufferGeometries而不是1个带有多个面/索引的大型平台中,您不会看到太多的性能成本。通过这种方式,您可以使用THREE的BufferGeometry,同时仍然可以看到所有内容都被纹理映射到一个大平面上。

希望这会有所帮助! -Erich(在GitHub上的erichlof)

+0

酷酷的人,这是我将与此一起去的方向。现在让高度图在这个设置中工作。肯定会有一些工作=] – Hobbes 2015-04-08 02:29:26