Three.js 材料根据观察方向反转

Three.js Materials are reversed depending on direction of view

我正在使用 Three.js 制作房屋模型。我的想法是,我可以向建筑师展示房屋并进一步讨论。该项目应该适合步行,所以我将所有内容放在这个网站上。如果您访问该站点查看代码,请使用箭头键相对于草地水平移动,使用 W/S 移动 up/down,使用 A/D 偏航视图。

https://bsdillon.github.io/cs200_Spring2020/ThreeJs/solarhouse.html

我能够制作面板(实际上是立方体)并在上面放置纹理。一切看起来都很棒,除了墙壁根据观察方向看起来不同。请参见下图。我添加了一条红线和黄色三角形,以帮助使几何图形更加明显。左图显示了一个面板的外部视图,面板的外部是隔板,左边是一个敞开的门口。右图显示了从结构内部看到的同一面板。可以看到从里面看门还是在左边(应该是在右边)而且棍框内部也好像是反了。

我以前从未注意到这一点,但它似乎是我设置这些面板的方式的标准。显然我做错了什么。问题是如何显示纹理以使视图保持一致。

var materialArray = new Object();//I set up an object I set up to store materials

function makeMaterial2(filename, repeatX, repeatY)//a method for creating materials from an image file
{
  var m = new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( filename ), transparent: true, opacity: 0.9, color: 0xffffff }); 
  return m;
}

//two examples of the material creation I implemented
materialArray["rDoor"] = makeMaterial2("doorRight.png",false,false);
materialArray["crDoor"] = makeMaterial2("doorRightClapboard.png",false,false);

function drawPanel2(x,y,z,x2,y2,z2,str)//this funciton creates a cube with the material in question
{
  var cubegeometry = new THREE.BoxGeometry(Math.abs(x-x2),Math.abs(y-y2),Math.abs(z-z2));
  var cube = new THREE.Mesh(cubegeometry, materialArray[str]);
  cube.position.set((x+x2)/2,(y+y2)/2,(z+z2)/2);
  return cube;
}

//adding the panels to the scene with the materials
scene.add(drawPanel2(-10,level,front,0,level+height,front,"rDoor"));
scene.add(drawPanel2(-10,level,front+margin,0,level+height,front+margin,"crDoor"));

您正在使用具有标准 UV 纹理坐标的简单 BoxGeometry。映射到该几何体上的纹理从各个方面看起来都一样 (see box example)。但是,您希望门的打开 space 处于同一位置。您可以执行以下操作之一来实现:

  1. 将不同的 material 和纹理应用到盒子的不同侧面。 BoxGeometry 的 6 个边已经被索引以供多 material 使用。

    a) 你必须在图像编辑软件中翻转纹理并单独保存。加载这些多个纹理。

    b) 克隆纹理并设置 texture.wrapS = THREE.RepeatWrapping; texture.repeat.x = - 1; 翻转它 ()。

    创建一个 6 material 数组,每个数组都有相应的纹理,并将其传递给网格。

  2. 更改 BoxGeometry 的 UV 纹理坐标,这样一侧将显示翻转的纹理。

  3. 你的箱子是平的。 4面不可见。除了 BoxGeometry,您还可以创建 PlaneGeometry。设置 material.side: THREE.DoubleSide 使平面从两侧都可见。按照这种方法,您将不得不修改 drawPanel2 方法,因为您不能只展平几何体的一侧,还必须根据面板的预期方向旋转平面。