gpt4 book ai didi

THREE.js:寻找 MeshFaceMaterial 的替代品

转载 作者:行者123 更新时间:2023-12-03 20:50:00 25 4
gpt4 key购买 nike

根据three.js github上的各种帖子,MeshFaceMaterial最终会被弃用。

我目前将它用于我的地形。当然,这不是最好的方法。其实它很蹩脚。对于一个我不能使用 BufferGeometry考虑到我通常有 2 层 128x128(分段)平面用于地形,这并不好。内存占用非常高。

我已经修改了所有代码以允许地形为 BufferGeometry除了两件事不起作用。 MeshFaceMaterialBufferGeometry.merge() .合并不适用于索引几何体,考虑到三个创建此几何体,这对我来说很奇怪,但它可以合并来自 blender 的非索引几何体。它不能合并它自己创建的几何体,但可以合并来自外部来源的几何体...哦,那是另一个帖子,回到 MeshFaceMaterial .

我目前使用 128x128 的“MaterialMap”。每个像素代表一个 materialIndex对于平面的每个面。这有两个严重的缺点。将地形部分(无曲线)和纹理边界上的明显区别进行平方。

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

最终我的目标是使用 BufferGeometry并摆脱 MeshFaceMaterial .

Material 贴图示例:enter image description here

地形示例(非常抱歉{work pc}):enter image description here

最佳答案

不久前,您通过电子邮件帮助了我,并提供了有关剔除网格的建议,因此我想返回您的帮助(以我谦虚的策略):)
如果您想使用 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-fight。因此,首先将stoneFloor 添加到场景中,然后是草地,然后是人行道。
由于 depthTest 仍然处于事件状态,您移动的游戏角色将在所有这些不同的纹理之上进行渲染。最初,它看起来也只是禁用“depthTest”,但纹理最终渲染在(“上方”)不正确的字符/模型上。
最终,当 THREE.js 将 ShapeGeometry 移至 BufferGeometry 时,最好定义一个任意多边形(如八边形或其他形状),然后以类似的方式将其贴图并在游戏关卡中将形状放在彼此的顶部,从而避免了您提到的“平方”问题。
至于这个当前的解决方案,在现代 CPU/GPU 上,我认为在创建 3 个 PlaneBufferGeometries 而不是 1 个具有多个面/索引的大平面时,您不会看到太多的性能成本。通过这种方式,您可以获得使用 THREE 的 BufferGeometry 的优势,同时仍然让所有“看起来”都像纹理映射到一个大平面一样。
希望这可以帮助!
-Erich(GitHub 上的 erichlof)

关于THREE.js:寻找 MeshFaceMaterial 的替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29133137/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com