具有更高 renderOrder 的对象被旋转元素裁剪

Object with a higher renderOrder being clipped by rotated element

即使第二个物体的 renderOrder 更高,旋转的物体(在这种情况下为圆柱体)也会切断物体(在这种情况下由线组成的三角形)。效果见this jsfiddle demo

三角形应该完全渲染在圆柱体的顶部,但在圆柱体外部与其相交的地方被切断。使用纹理时更容易理解发生了什么,但是 jsfiddle 不擅长使用外部图像。

var mesh, renderer, scene, camera, controls;

init();
animate();

function init() {
  renderer = new THREE.WebGLRenderer({
    antialias: true, 
    preserveDrawingBuffer: true 
  });
  renderer.setClearColor(0x24132E, 1);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 10000);
  camera.position.set(0, 0, 7);
  camera.lookAt(scene.position)
  scene.add(camera);

  var geometry = new THREE.CylinderGeometry(1, 1, 100, 32, 1, true);

  var material = new THREE.MeshBasicMaterial({
    color: 0x0000ff
  });

  material.side = THREE.DoubleSide; 
  mesh = new THREE.Mesh(geometry, material);
  mesh.rotation.x = Math.PI / 2;
  scene.add(mesh);



  var c = 3, // Side length of the triangle
    a = c / 2,
    b = Math.sqrt(c * c - a * a),
    yOffset = -b / 3; // The vertical offset (if 0, triangle is on x axis)

  // Draw the red triangle
  var geo = new THREE.Geometry();
  geo.vertices.push(
    new THREE.Vector3(0, b + yOffset, 0),
    new THREE.Vector3(-a, 0 + yOffset, 0),
    new THREE.Vector3(a, 0 + yOffset, 0),
    new THREE.Vector3(0, b + yOffset, 0)
  );

  var lineMaterial = new THREE.LineBasicMaterial({
    color: 0xff0000,
    linewidth: 5,
    linejoin: "miter"
  });

  plane = new THREE.Line(geo, lineMaterial);
  // Place it on top of the cylinder
  plane.renderOrder = 2; // This should override any clipping, right?
  scene.add(plane);
}


function animate() {
  requestAnimationFrame(animate);

  render();
}

function render() {
  renderer.render(scene, camera);
}

我是不是做错了什么或者这是一个错误?

对于您想要的效果,使用第二个场景并将其渲染到第一个场景上

function init(){
    .....
    renderer.autoClear = false;
    scene.add(tube);
    overlayScene.add(triangle);
    .....
}

function render() {
    renderer.clear();
    renderer.render(scene, camera);
    renderer.clearDepth();
    renderer.render(overlayScene, camera);
}

renderOrder并不是你想的那个意思,看WebGLRenderer中的实现 对象按顺序排序,如果它意味着您对它的预期,总会有一些固定的渲染顺序并且碰撞对象会相互看到,renderOrder 是 AFAIK 当您对透明/不透明对象的顺序有问题时使用

我为 three.js 编写了一个小插件,用于我的游戏的照明弹。 Three.js 内置的光斑插件很慢,我不想 运行 另一个将帧率减半的渲染通道。这是我如何在实际位于它们前面的物体顶部看到耀斑。

Material 参数:

{
  side: THREE.FrontSide,
  blending: THREE.AdditiveBlending,
  transparent: true,
  map: flareMap,
  depthWrite: false,
  polygonOffset: true,
  polygonOffsetFactor: -200
}

depthWrite - 设置为 false

polygonOffset - 设置为真

polygonOffsetFactor - 给出负数以在其他人面前获得对象。给它一些非常高的价值,使其真正处于一切之上,即 -10000

忽略其他参数,我的照明弹需要它们