Three.js "Mixed Mode", DOM CSS3D + WebGL in the same scene

Mixing HTML Elements and WebGL together using CSS3DRenderer and WebGLRenderer.

by murgiaMarco

HTML

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/renderers/CSS3DRenderer.js"></script>

<canvas id="canvasExample" height="200px" width="200px"></canvas>

CSS

body {
    background-color: #ffffff;
    margin: 0;
    overflow: hidden;
}

#css, #webgl {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0; left: 0;
}

#css {
  background: black;
}

#webgl {
  pointer-events: none;
}

JavaScript

var camera, scene, renderer;

var scene2, renderer2;

var mouseX = 0, mouseY = 0;

var controls;

var sphere;

var lights = [];

var lookAt = new THREE.Vector3(0, 0, 0);

var lightMovementAmplitude = 200

init();
animate(performance.now());

function init() {

    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;

    camera = new THREE.PerspectiveCamera(
        45, window.innerWidth / window.innerHeight, 1, 2000
    );
    camera.position.set( 0, 0, 500 );

    scene = new THREE.Scene();
    //scene2 = new THREE.Scene();

    for ( var i = 0; i < 50; i ++ ) {

        var element = document.createElement( 'div' );
        element.style.width = '100px';
        element.style.height = '100px';
        element.style.opacity = 0.999;
        element.style.background = new THREE.Color(
          Math.random() * 0.21568627451 + 0.462745098039,
          Math.random() * 0.21568627451 + 0.462745098039,
          Math.random() * 0.21568627451 + 0.462745098039,
        ).getStyle();
        element.textContent = "I am editable text!"
        element.setAttribute('contenteditable', '')

        var domObject = new THREE.CSS3DObject( element );
        domObject.position.x = Math.random() * 600 - 300;
        domObject.position.y = Math.random() * 600 - 300;
        domObject.position.z = Math.random() * 800 - 600;
        domObject.rotation.x = Math.random();
        domObject.rotation.y = Math.random();
        domObject.rotation.z = Math.random();
        //domObject.scale.x = Math.random() + 0.5;
        //domObject.scale.y = Math.random() + 0.5;
        //scene2.add( domObject );

        // make an invisible plane for the DOM element to chop
        // clip a WebGL geometry with it.
        ~function() {
            var material = new THREE.MeshPhongMaterial({
                opacity	: 0.2,
                color	: new THREE.Color('black'),
                blending: THREE.NoBlending,
                side	: THREE.DoubleSide,
           ...