我在我的项目开发中遇到了砖墙。我试图在独特的尺寸和形状的物体上使用各种类型的 phong Material 来达到一个水平。默认情况下,Three.JS 处理纹理的方式会使其拉伸(stretch)并在呈现在不完全是 1:1:1 比例大小的网格上时变得难以忍受,这意味着一切都必须是立方体或完美大小的球体才能看起来正常.为了避免这个问题,您可以使用重复选项加载纹理。这种方法的问题在于,对于 100 多个不同大小的对象,对于每种 Material 、每个对象,这些重复选项必须不同。这意味着加载数百个纹理或用克隆填充内存。后者并没有太打扰我。我需要帮助试图弄清楚如何处理大量具有独特几何形状和独特颜色图、自发光贴图、高光贴图、AOMAP、凹凸贴图和法线贴图的独特对象。我怎样才能让 1 个纹理具有基于 Material 的独特重复设置?即使我解决了这个问题,我也必须为每个 Material 重复 5 个以上的纹理。 5*~100 = ~500 纹理/纹理变化。这是个问题。最少100个,最多800个。

我对此非常绝望,如果无法批量处理对象,我正在考虑切换到 Unity 或 UE4。

我愿意从第 1 方格中完全重写我的代码。这没什么特别的,而且非常粗糙。但我想展示我在 THREE.js 中处理对象的方式。这不是我的完整程序(显然),它只是我如何做事的一个例子。

var energyRockMaterial =
  new THREE.MeshPhongMaterial(
    {
        envMap: scene.background,
        map: new THREE.TextureLoader().load("energyrock.jpg"),
        normalMap: new THREE.TextureLoader().load("energyrocknormal.jpg"),
        //bumpMap: new THREE.TextureLoader().load("energyrockbump.jpg"),
        aoMap: new THREE.TextureLoader().load("energyrockao.jpg"),
        specularMap: new
        THREE.TextureLoader().load("energyrockspecular.jpg"),
        emissiveMap: new
        THREE.TextureLoader().load("energyrockemissive.jpg"),
        color:"#ffffff",
        emissive:"#bb00bb",
        specular:"#000000",
        reflectivity:1,
    });
var energyRockGeometry = new THREE.BoxBufferGeometry(1,1,1);
var energyRockMesh = new
THREE.Mesh(energyRockGeometry,energyRockMaterial);
scene.add(energyRockMesh)

对有问题的缩进表示歉意,HTML 表单不喜欢我的标签,我不得不把它弄出来。

感谢您的回复。

最佳答案

首先,阅读 UV mapping 。简而言之,UV 是分配给顶点的纹理坐标。它们告诉渲染器纹理上的哪个点映射到网格上的哪个顶点,渲染器处理其余部分,将纹理映射到三 Angular 形上。

THREE.js 通过 GeometryBufferGeometry 支持 UV。 (在我看来,后者更容易用于此目的。)

这适用于您的情况的好处是您可以将单一 Material 用于多种形状。具有独特 UV 的形状将独特地映射纹理。换句话说,具有一组 UV 的立方体可以与具有不同 UV 的另一个立方体具有相同的 Material ,并且它们每个都将根据自己的 UV 映射纹理。

其次,可能与您的情况不太相关,您可以考虑使用 texture atlas 。这是一个包含多个纹理的大图像文件。即使所有形状都有不同的纹理,您也可以(可能)加载单个图像文件,将其放入单个 Material 中供网格共享,并且它们将使用其独特的 UV 映射到与它们相关的纹理部分。

关于javascript - 在 Three.JS 中处理大量独特的对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52489634/

10-11 03:53