【问题标题】:Display Mesh On Top Of Another | Remove Overalapping | Render Order | Three.js在另一个之上显示网格 |删除重叠 |渲染订单 |三.js
【发布时间】:2023-03-28 14:45:01
【问题描述】:

我有 2 个 obj 网格。 他们都有一些共同的领域,但并不完全。

我通过将它们添加到屏幕来显示它们...... 就像一个网格在另一个之上。 但下部网格与顶部网格重叠 但我想要实现的是下部网格应始终保持在下方,而不会重叠并为整个顶部网格留出空间。

我经历了这个小提琴..Fiddle with renderorder

我尝试了类似的东西..

var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
           root.renderOrder = 0;
           scene.add(root);
       });
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
           root.renderOrder = 1;
           scene.add(root);
      });

但我不知道为什么重叠仍然存在..

我试过了……

var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
           objLoader1.renderOrder = 0;
           scene.add(root);
       });
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
           objLoader2.renderOrder = 1;
           scene.add(root);
      });

然后我尝试通过这个 Fiddle .. Another Fiddle 但是当我跑进去时,我只得到下层或上层网格。 但我想看到两者没有任何重叠..

 var layer1 = new Layer(camera);
 composer.addPass(layer1.renderPass);
 layer1.scene.add(new THREE.AmbientLight(0xFFFFFF));
 var objLoader1 = new OBJLoader2();
 objLoader1.load('assets/object1.obj', (root) => {
        layer1.scene.add(root);
  });
  var layer2 = new Layer(camera);
  composer.addPass(layer2.renderPass);
  layer2.scene.add(new THREE.AmbientLight(0xFFFFFF));
  var objLoader2 = new OBJLoader2();
  objLoader2.load('assets/object2.obj', (root) => {
        layer2.scene.add(root);
  });

我将材质 depthTest 设置为 False 但没有任何帮助..

谁能帮我实现我想要的.. 如果有人不明白我所说的重叠是什么意思,请看下图..

感谢所有花时间和精力帮助我的人...

【问题讨论】:

    标签: three.js render overlapping 3d-rendering


    【解决方案1】:

    您可以使用polygonOffset 来实现您的目标,它会在写入片段之前修改深度值,以帮助将多边形彼此分开,而不会在视觉上改变位置:

    material.polygonOffset = true;
    material.polygonOffsetUnit = 1;
    material.polygonOffsetFactor = 1;
    

    这是一个演示解决方案的小提琴:

    https://jsfiddle.net/5s8ey0ad/1/

    以下是OpenGL Docs 对多边形偏移的看法:

    当启用 GL_POLYGON_OFFSET_FILL、GL_POLYGON_OFFSET_LINE 或 GL_POLYGON_OFFSET_POINT 时,每个片段的深度值将在从相应顶点的深度值插值后偏移。 offset 的值是 factor×DZ+r×units,其中 DZ 是相对于多边形屏幕区域的深度变化的测量值,r 是保证为给定的给定偏移量产生可解析偏移量的最小值执行。偏移量是在深度测试执行之前和将值写入深度缓冲区之前添加的。

    【讨论】:

      【解决方案2】:

      您遇到z-fighting,即两个或多个平面在 depthBuffer 中占据相同空间,因此渲染器不知道要在另一个之上渲染哪个平面。单独的渲染顺序并不能解决这个问题,因为它们仍然在同一个平面上,无论哪个先绘制。您有几个选项可以解决此问题:

      1. 在 y 轴上稍微向上移动一个光束。一小部分会使一个优先级高于另一个,这个距离可能不会被眼睛注意到。
      2. 我看到了你的小提琴,你忘了在你的材料中添加depthTest: false。但是,这会在对形状的其余部分进行深度测试时引起问题,因为一些白色位于红色之上,但也有一些红色位于白色之上。小提琴中的方法仅适用于简单平面,而不是更复杂的几何形状。
      3. 您可以使用布尔运算从另一个形状中删除一个形状,例如 CSG

      我认为使用方法 1 可以省去很多麻烦。

      【讨论】:

      • 感谢您的回复..但是 1.梁示例只是一个案例,但我必须面对球体和立方体等不同几何形状以及更多 .obj 几何形状的相同问题,所以我认为移动不是一个好的选择,因为我希望两者保持靠近而不重叠以实现所需的几何形状。2.我确实尝试过做....var material = new THREE.MeshPhongMaterial({side: THREE.DoubleSide, depthTest :false});.... 但是仍然只显示了一个几何图形...而且我认为它可以完全用三个来完成。单独加载或调用它有什么问题..
      • Z-fighting 不能在没有解决方法的情况下解决。如果您认为可以完成,您应该展示或构建一个工作小提琴来准确演示您想要的东西,而不是仅使用平面的简单演示。这不是装载机的错。
      猜你喜欢
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 2018-11-02
      • 2019-11-12
      • 1970-01-01
      • 2012-08-10
      • 2022-11-14
      相关资源
      最近更新 更多