Warm tip: This article is reproduced from serverfault.com, please click

Three.js: How to add 3D primitives to CSS3DRenderer scene in specific case?

发布于 2020-11-29 23:00:38

This is the code:

"use strict";
var OrbitControls = THREE.OrbitControls,
  CSS3DRenderer = THREE.CSS3DRenderer,
  CSS3DObject = THREE.CSS3DObject,
  Scene = THREE.Scene,
  PerspectiveCamera = THREE.PerspectiveCamera,
  Mesh = THREE.Mesh,
  PlaneGeometry = THREE.PlaneGeometry,
  MeshPhongMaterial = THREE.MeshPhongMaterial,
  Color = THREE.Color,
  DoubleSide = THREE.DoubleSide,
  NoBlending = THREE.NoBlending,
  WebGLRenderer = THREE.WebGLRenderer,
  MeshBasicMaterial = THREE.MeshBasicMaterial;
var CSS3DDemo = /** @class */ (function() {
  function CSS3DDemo() {
    this.scene = new Scene();
    this.camera = new PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 500);
    this.webGLRenderer = new WebGLRenderer();
    this.css3DRenderer = new CSS3DRenderer();
    this.controls = new OrbitControls(this.camera, this.css3DRenderer.domElement);
    this.controls.autoRotate = true;
    this.camera.position.set(0, 0, 20);
    this.webGLRenderer.setSize(window.innerWidth, window.innerHeight);
    this.webGLRenderer.setClearColor(0xFFFFFF);
    this.css3DRenderer.setSize(window.innerWidth, window.innerHeight);
    this.css3DRenderer.domElement.style.top = '0px';
    this.css3DRenderer.domElement.style.left = '0px';
    this.css3DRenderer.domElement.style.position = 'absolute';
    var div = window.document.createElement('img');
    div.style.width = '160px';
    div.style.height = 'auto';
    div.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/1-month-old_kitten_42.jpg/2880px-1-month-old_kitten_42.jpg';
    var object = new CSS3DObject(div);
    object.position.set(0, 0, 0);
    object.scale.set(1 / 16, 1 / 16, 1 / 16);
    this.scene.add(object);
    var planeGeometry = new PlaneGeometry(10, 10);
    this.scene.add(this.camera);
    document.getElementById("content").appendChild(this.webGLRenderer.domElement);
    document.getElementById("content").appendChild(this.css3DRenderer.domElement);
    this.render();
  }
  CSS3DDemo.prototype.render = function() {
    var _this = this;
    window.requestAnimationFrame(function() {
      return _this.render();
    });
    this.css3DRenderer.render(this.scene, this.camera);
    this.webGLRenderer.render(this.scene, this.camera);
    this.controls.update();
  };
  return CSS3DDemo;
}());
new CSS3DDemo();
html,
body {
  width: 100vw;
  margin: 0;
  height: 100vh;
  padding: 0;
  overflow: hidden;
  border: 0;
}

#content {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
<div id="content"></div>
<script src='https://gitcdn.xyz/repo/mrdoob/three.js/dev/build/three.min.js'></script>
<script src='https://gitcdn.xyz/repo/mrdoob/three.js/dev/examples/js/controls/OrbitControls.js'></script>
<script src='https://gitcdn.xyz/repo/mrdoob/three.js/dev/examples/js/renderers/CSS3DRenderer.js'></script>

Now I would like to add a torus with MeshBasicMaterial.

I tried to add something like that:

const geometry = new THREE.TorusGeometry( 10, 3, 16, 100 );
const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
const torus = new THREE.Mesh( geometry, material );
torus.position.set(0, 0, 0);
scene.add( torus );

Unfortunately, it doesn't work. I also don't know if it could work theoretically.

Could somebody help me? I would be very happy! :)

Questioner
Anna_B
Viewed
0
Mugen87 2020-11-30 17:45:00

If I replace scene with this.scene it seems to work just fine. Notice however that the combination of WebGL rendered 3D objects and HTML elements is problematic in some cases since depth testing does not work across both primitive types.

With the current setup, the image will always be rendered on top of the torus.

"use strict";
var OrbitControls = THREE.OrbitControls,
  CSS3DRenderer = THREE.CSS3DRenderer,
  CSS3DObject = THREE.CSS3DObject,
  Scene = THREE.Scene,
  PerspectiveCamera = THREE.PerspectiveCamera,
  Mesh = THREE.Mesh,
  PlaneGeometry = THREE.PlaneGeometry,
  MeshPhongMaterial = THREE.MeshPhongMaterial,
  Color = THREE.Color,
  DoubleSide = THREE.DoubleSide,
  NoBlending = THREE.NoBlending,
  WebGLRenderer = THREE.WebGLRenderer,
  MeshBasicMaterial = THREE.MeshBasicMaterial;
var CSS3DDemo = /** @class */ (function() {
  function CSS3DDemo() {
    this.scene = new Scene();
    this.camera = new PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 500);
    this.webGLRenderer = new WebGLRenderer();
    this.css3DRenderer = new CSS3DRenderer();
    this.controls = new OrbitControls(this.camera, this.css3DRenderer.domElement);
    this.controls.autoRotate = true;
    this.camera.position.set(0, 0, 20);
    this.webGLRenderer.setSize(window.innerWidth, window.innerHeight);
    this.webGLRenderer.setClearColor(0xFFFFFF);
    this.css3DRenderer.setSize(window.innerWidth, window.innerHeight);
    this.css3DRenderer.domElement.style.top = '0px';
    this.css3DRenderer.domElement.style.left = '0px';
    this.css3DRenderer.domElement.style.position = 'absolute';
    var div = window.document.createElement('img');
    div.style.width = '160px';
    div.style.height = 'auto';
    div.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/1-month-old_kitten_42.jpg/2880px-1-month-old_kitten_42.jpg';
    var object = new CSS3DObject(div);
    object.position.set(0, 0, 0);
    object.scale.set(1 / 16, 1 / 16, 1 / 16);
    this.scene.add(object);

    const geometry = new THREE.TorusGeometry( 10, 3, 16, 100 );
    const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
    const torus = new THREE.Mesh( geometry, material );
    this.scene.add( torus );
    document.getElementById("content").appendChild(this.webGLRenderer.domElement);
    document.getElementById("content").appendChild(this.css3DRenderer.domElement);
    this.render();
  }
  CSS3DDemo.prototype.render = function() {
    var _this = this;
    window.requestAnimationFrame(function() {
      return _this.render();
    });
    this.css3DRenderer.render(this.scene, this.camera);
    this.webGLRenderer.render(this.scene, this.camera);
    this.controls.update();
  };
  return CSS3DDemo;
}());
new CSS3DDemo();
html,
body {
  width: 100vw;
  margin: 0;
  height: 100vh;
  padding: 0;
  overflow: hidden;
  border: 0;
}

#content {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
<div id="content"></div>
<script src='https://gitcdn.xyz/repo/mrdoob/three.js/dev/build/three.min.js'></script>
<script src='https://gitcdn.xyz/repo/mrdoob/three.js/dev/examples/js/controls/OrbitControls.js'></script>
<script src='https://gitcdn.xyz/repo/mrdoob/three.js/dev/examples/js/renderers/CSS3DRenderer.js'></script>