hey guys i am new to threejs and im trying to load a texture on top of my own gltf model and im trying to load it with gltf loader, imported using cdn scripts, however, i got this error saying gltf is not a constructor, any ideas how to fix it? thanks in advance. have a nice day. below attached is the code and errors involving this issue.
Uncaught TypeError: THREE.GLTFLoader is not a constructor
at init (index.html:90)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>3d model</title>
<style>
body {
margin: 0;
}
canvas {
position: fixed; top: 0; left: 0;
}
div#test2 {
height: 5000px;
}
</style>
</head>
<body>
<script type="module">
import * as THREE from 'https://cdn.jsdelivr.net/npm/three#0.114/build/three.module.js';
import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three#0.114/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three#0.114/examples/jsm/loaders/GLTFLoader.js';
import { RGBELoader } from 'https://cdn.jsdelivr.net/npm/three#0.114/examples/jsm/loaders/RGBELoader.js';
var container, controls;
var camera, scene, renderer, mixer, clock;
var obj , material , texture
init();
animate();
function init() {
container = document.getElementById( 'test' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.01, 1000 );
// camera.position.set(0, 5, 30);
camera.position.x = 0
camera.position.y = 5
camera.position.z = 10
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
var light = new THREE.HemisphereLight(0xffffff,0x000000,10);
scene.add(light);
clock = new THREE.Clock();
// model
// var loader = new GLTFLoader();
// loader.load( 'scene.gltf', function ( gltf ) {
// // var matcapTexture = new THREE.TextureLoader().load('purple.jpg')
// // var texture = new THREE.MeshMatcapMaterial( {matcap: matcapTexture})
// obj = scene.add( gltf.scene );
// // obj.material.map = texture
// // obj.material.needsUpdate = tru
// mixer = new THREE.AnimationMixer( gltf.scene );
// gltf.animations.forEach( ( clip ) => {
// mixer.clipAction( clip ).play();
// } );
// } );
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('purple.jpg');
texture.flipY = false;
var loader = new THREE.GLTFLoader();
loader.load('scene.gltf', function(gltf) {
model = gltf.scene;
scene.add(model);
});
model.material.map = texture;
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 0.8;
renderer.outputEncoding = THREE.sRGBEncoding;
container.appendChild( renderer.domElement );
function rotateFunction() {
obj.rotation.y += 0.02;
console.log(obj.rotation.y)
}
document.addEventListener('scroll', function(e) { rotateFunction() });
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
var delta = clock.getDelta();
if ( mixer ) mixer.update( delta );
renderer.render( scene, camera );
}
function adjustCamera() {
var t = scrollY / (5000 - innerHeight);
console.log(t)
// t is 0 to 1
camera.position.z = 10 + 5 * t;
}
document.addEventListener('scroll', function(e) { adjustCamera() });
function changeColor() {
obj.material = texture
console.log(obj)
}
document.addEventListener('scroll', function(e) { changeColor() });
</script>
</body>
<div id="test">
</div>
<div id="test2">
testing121
</div>
</html>
When you import GLTFLoader via ES6 imports, there is no need to use the THREE namespace. Just do this:
const loader = new GLTFLoader();
Related
I'm trying to load a 3D globe into my HTML site using a ThreeJS script (found below) But it's stitched together with code from other sources, meaning the camera is mapped to MouseX and MouseY positions. I want the object to sit in the center of the page with a simple slow spin, but every time I try and achieve this the object vanishes.
The Javascript:
<script>
var container;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 5, window.innerWidth / window.innerHeight, 1, 5000 );
camera.position.z = 250;
scene = new THREE.Scene();
var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.8 );
scene.add( ambientLight );
var pointLight = new THREE.PointLight( 0xFFF1CF, 0.6 , 0 );
camera.add( pointLight );
scene.add( camera );
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete, 2) + '% downloaded' );
}
};
var onError = function ( xhr ) {;
};
var mtlLoader = new THREE.MTLLoader();
mtlLoader.load('planet.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.load('planet.obj', function(object) {
object.position.y = 0;
scene.add(object);
}, onProgress, onError);
});
//
renderer = new THREE.WebGLRenderer( {alpha: true});
renderer.setClearColor( 0x000000, 0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseclick', onmousedown, false);
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX );
mouseY = ( event.clientY );
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY - camera.position.y ) * .05;
camera.lookAt( scene.position );
renderer.render( scene, camera );
}
</script>
You need to change your code a little bit,
In the 'init' function, change the object loading logic as follows
var mtlLoader = new THREE.MTLLoader();
var objLoader = new THREE.OBJLoader();
mtlLoader.load( 'planet.mtl', function(materials) {
materials.preload();
objLoader.setMaterials(materials);
objLoader.load( 'planet.obj', function( object ){
object.position.set( 0, 0, 0 ); // set the position as (0,0,0)
globe = object; // globe is the object to be added to the scene
scene.add(globe);
animate(); //call the animate function only after the object is loaded
}, onProgress, onError);
} );
And change the render method,
function render() {
globe.rotation.y += 0.01; // this will rotate the object
camera.lookAt( scene.position );
renderer.render( scene, camera );
}
I wish to move a cube based on the movement of another cube to which TransformControls is attached by means of Matrix4() method only.
The attempts so far have failed to shift the follower cube.
I'm not sure why the follower doesn't seem to take the world co-ordinates of the directing cube.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - transform controls</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
margin: 0px;
background-color: #000000;
color: #fff;
font-family:Monospace;
text-align: center;
font-size: 15px;
line-height: 30px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
padding: 15px;
z-index:100;
}
</style>
</head>
<body>
<div id="info">
"W" translate | "E" rotate | "R" scale | "+" increase size | "-" decrease size<br />
Press "Q" to toggle world/local space, keep "Ctrl" down to snap to grid
</div>
<script src="build/three.js"></script>
<script src="js/controls/TransformControls.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script>
var camera, scene, renderer, control, mesh, mesh1;
init();
animate();
//render();
//update();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
document.body.appendChild( renderer.domElement );
//
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 3000 );
camera.position.set( 1000, 500, 1000 );
camera.lookAt( new THREE.Vector3( 0, 200, 0 ) );
scene = new THREE.Scene();
scene.add( new THREE.GridHelper( 1000, 10 ) );
var light = new THREE.DirectionalLight( 0xffffff, 2 );
light.position.set( 1, 1, 1 );
scene.add( light );
//var texture = new THREE.TextureLoader().load( 'textures/crate.gif', render );
//texture.mapping = THREE.UVMapping;
//texture.anisotropy = renderer.getMaxAnisotropy();
var geometry = new THREE.BoxGeometry( 200, 200, 200 );
var material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
control = new THREE.TransformControls( camera, renderer.domElement );
control.addEventListener( 'change', render );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
control.attach( mesh );
scene.add( control );
var followerCube = new THREE.BoxGeometry( 200, 200, 200 );
var material1 = new THREE.MeshBasicMaterial( { color: 0xff9909 } );
mesh1 = new THREE.Mesh( followerCube, mesh1 );
scene.updateMatrixWorld();
mesh1.matrixAutoUpdate = false;
var relativeMeshOffset = new THREE.Vector3( 100, 100, 200 );
var offsetPosition = relativeMeshOffset.applyMatrix4( mesh.matrixWorld );
mesh1.position.x = offsetPosition.x;
mesh1.position.y = offsetPosition.y;
mesh1.position.z = offsetPosition.z;
scene.add( mesh1 );
console.log(mesh1.position);
var orbitControl = new THREE.OrbitControls( camera, renderer.domElement );
orbitControl.addEventListener( 'change', render );
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener( 'keydown', function ( event ) {
switch ( event.keyCode ) {
case 81: // Q
control.setSpace( control.space === "local" ? "world" : "local" );
break;
case 17: // Ctrl
control.setTranslationSnap( 100 );
control.setRotationSnap( THREE.Math.degToRad( 15 ) );
break;
case 87: // W
control.setMode( "translate" );
break;
case 69: // E
control.setMode( "rotate" );
break;
case 82: // R
control.setMode( "scale" );
break;
case 187:
case 107: // +, =, num+
control.setSize( control.size + 0.1 );
break;
case 189:
case 109: // -, _, num-
control.setSize( Math.max( control.size - 0.1, 0.1 ) );
break;
}
});
window.addEventListener( 'keyup', function ( event ) {
switch ( event.keyCode ) {
case 17: // Ctrl
control.setTranslationSnap( null );
control.setRotationSnap( null );
break;
}
});
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
function animate() {
requestAnimationFrame( animate );
render();
update();
}
function update() {
var relativeMeshOffset = new THREE.Vector3( 100, 100, 200 );
var offsetPosition = relativeMeshOffset.applyMatrix4( mesh.matrixWorld );
mesh1.position.x = offsetPosition.x;
mesh1.position.y = offsetPosition.y;
mesh1.position.z = offsetPosition.z;
}
function render() {
control.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>
Cause you set mesh1.matrixAutoUpdate = false; in line 75. If you do that, the mesh1 wouldn't change its position.
I want to preload all models and textures with a loadingbar in my project. For that i use the LoadingManger from three.js but i have problems with preloading the json Models. They load but i am unable to display them. Here is an example.
You can see in the console that 200 Meshs are created. 100 For the Asteroids and 100 for the Ships.
Withoud the LoadingManger i can display the models (asteroids) so there should be no problem with the model. You can see in the example Asteroids that are loaded without the loading manager.
Here my simplified code for the problem
$(function(){
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var debugScene = true;
var controler, camera, controls, scene, renderer;
var objectControls;
var ship1geometry,ship1material;
////////////////////////////////////////////////////////
//LOADMANGER
////////////////////////////////////////////////////////
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
$('#loader').css({width:(Math.round(loaded / total *100))+"%"});
console.log( item, loaded, total );
};
manager.onLoad = function () {
$('#loaderholder').fadeOut(function(){
init();
animate();
});
console.log('all items loaded');
};
manager.onError = function () {
console.log('there has been an error');
};
var loader = new THREE.JSONLoader(manager); // init the loader util
loader.load('models/shiptest.json', function (ship1geometry) {
var ship1material = new THREE.MeshFaceMaterial();
}, "models");
function init() {
var width = window.innerWidth;
var height = window.innerHeight;
camera = new THREE.PerspectiveCamera( 45, width / height, 1, 10000000 );
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 1500;
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setClearColor("black");
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.autoClear = false;
var container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;
controls.minDistance = 50;
controls.maxDistance = 300000;
controls.autoRotate = false;
controls.autoRotateSpeed = 0.05;
controls.target.x = 0;
controls.target.y = 0;
controls.target.z = 0;
light = new THREE.AmbientLight( 0x666666 );
scene.add( light );
light = new THREE.PointLight( 0xffffff, 1, 10000 );
light.position.set( 0, 0, 0 );
var params = { recursive: true };
objectControls = new ObjectControls( camera, params );
shipCount = 100;
for (var p = 0; p < shipCount; p++) {
var pX = Math.random() * 5000 - 2500;
var pZ = Math.random() * 5000 - 2500;
var ship = createShipMesh(pX,0,pZ,0,0,0,ship1geometry,ship1material);
scene.add(ship);
}
var loader = new THREE.JSONLoader();
loader.load('models/asteroid.json', function (geometry, mat) {
var material = new THREE.MeshFaceMaterial( mat );
asteroidCount = 100;
for (var p = 0; p < asteroidCount; p++) {
var pX = Math.random() * 5000 - 2500;
var pZ = Math.random() * 5000 - 2500;
var mesh = new THREE.Mesh(geometry,material);
mesh.rotation.y = -Math.PI/Math.random();
mesh.position.set( pX, 0, pZ );
scene.add(mesh);
}
}, "textures");
window.addEventListener( 'resize', onWindowResize, false );
if(debugScene){
var gridHelper = new THREE.GridHelper( 900000, 10000 );
gridHelper.setColors( 0x0000ff, 0x808080 );
scene.add( gridHelper );
var axisHelper = new THREE.AxisHelper( 500 );
scene.add( axisHelper );
console.log(scene);
}
}
function onWindowResize() {
var width = window.innerWidth;
var height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
var lastTimeMsec= null;
var nowMsec= null;
function animate() {
requestAnimationFrame( animate );
render();
update();
}
function update(){
controls.update();
objectControls.update();
}
function render() {
renderer.render( scene, camera );
}
function createShipMesh(positionX,positionY,positionZ,centerX,centerY,centerZ,geometry,material){
positionX = centerX + positionX;
positionY = centerY + positionY;
positionZ = centerZ + positionZ;
var mesh = new THREE.Mesh(geometry,material);
mesh.rotation.y = -Math.PI/Math.random();
mesh.position.set( positionX, positionY, positionZ );
objectControls.add( mesh );
mesh.select = function(){
controls.target.x = position.x;
controls.target.y = position.y;
controls.target.z = position.z;
controls.dollyIn(2);
controls.minDistance = 20;
}
return mesh;
}
});
Okay i found the problem on my own. the Loading Manager works with json but my mistake was to set the variable ship1geometry global and was thinking that the loader would overwrite this variable so that i can use it later in the scene. That was wrong. I just needed to assign the response from the loader in my globaly set variable. So here is the right code
var ship1geometry,ship1material
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
$('#loader').css({width:(Math.round(loaded / total *100))+"%"});
console.log( item, loaded, total );
};
manager.onLoad = function () {
$('#loaderholder').fadeOut(function(){
init();
animate();
});
console.log('all items loaded');
};
manager.onError = function () {
console.log('there has been an error');
};
var loader = new THREE.JSONLoader(manager); // init the loader util
loader.load('models/shiptest.json', function (geometry,mat) {
ship1geometry = geometry;
ship1material = new THREE.MeshLambertMaterial({map:mat });
}, "textures");
function init(){
...
}
I made a simple three.js test, add mouseover event to the canvas, but when I tried to remove this event listener, it doesn't work. Here is my code, when I clicked the above the button, should enable the mouseover enent that console outputs the mouse position, while I clicked the button again, the mouse event should be disabled. but still the console outputs the mouse position.
<!DOCTYPE HTML>
<html ng-app="Mainapp">
<head>
</head>
<body ng-controller="Main">
<button class="btn btn-danger" ng-click="cropImage()">
CropImage
</button>
<div id="container"></div>
<script src="http://www.html5canvastutorials.com/libraries/three.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script defer="defer">
var angularT3 = angular.module('Mainapp', []);
angularT3.run(['$rootScope', '$location','$http', '$window', function ($rootScope, $location, $http, $window) {
//$http.defaults.headers.post['x-csrf-token'] = $cookies['XSRF_TOKEN'];
var canv = document.createElement('canvas');
canv.id = 'snapshot';
canv.width = window.innerWidth;
canv.height = window.innerHeight;
document.body.appendChild(canv);
}]);
angularT3.controller('Main', function ($scope,$http) {
$scope.enabled = false;
$scope.cropImage = function (){
var world = document.getElementById('world');
$scope.enabled = !$scope.enabled;
if($scope.enabled){
console.log('crop image enabled');
world.addEventListener('mousemove', getMousePos , false);
}else{
console.log('not enabled ');
world.removeEventListener('mousemove', getMousePos,false);
}
function getMousePos( evt) {
var rect = world.getBoundingClientRect();
var pos = {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
console.log( 'Mouse position: ' + pos.x + ',' + pos.y );
return pos;
}
}
});
init = function(){
// revolutions per second
var angularSpeed = 0.2;
var lastTime = 0;
// this function is executed on each animation frame
function animate(){
// update
var time = (new Date()).getTime();
var timeDiff = time - lastTime;
var angleChange = angularSpeed * timeDiff * 2 * Math.PI / 1000;
cube.rotation.y += angleChange;
lastTime = time;
// render
renderer.render(scene, camera);
// request new frame
requestAnimationFrame(function(){
animate();
});
}
// renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.domElement.id = 'world';
document.body.appendChild(renderer.domElement);
// camera
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 500;
// scene
var scene = new THREE.Scene();
// cube
var cube = new THREE.Mesh(new THREE.CubeGeometry(200, 200, 200), new THREE.MeshNormalMaterial());
cube.overdraw = true;
scene.add(cube);
animate();
}
init();
</script>
</body>
</html>
I am trying to combine webgl and css3d scenes so that the objects in the two scenes properly blend together. I am following the pattern described here:
and have created a simple example by modifying the three.js example css3d_sandbox.html.
In my version I have added a cube to the webGl scene and expect it to properly blend with the existing planes whether the cube is in front of or behind those objects.
I notice two anomalies. The first is that once the cube is added the planes disappear in unexpected positions as you pan around as if the far and near plane values are not being honored correctly or the objects are being incorrectly determined to be behind something else.
The second issue is that the css3d objects do not render at all when running against three.js r67, but they do render when running against r61. I tried replacing the r67 version of CSS3DRenderer.js with r61, but still do not see any css3d objects.
In r67 when the line to add the webGl dom as a child of the css3d dom is commented out, the css3d objects do appear.
I would appreciate any suggestions on how to resolve these issues. Sample code is below and may be run by dropping into any version of the three.js examples folder (e.g. r61 or r67).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
}
#info {
position: absolute;
top: 0px;
width: 100%;
color: #000000;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
z-index: 1;
}
a {
color: #000000;
}
</style>
</head>
<body>
<div id="info">three.js - css3d sandbox</div>
<script src="../build/three.min.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<!--<script src="js/renderers/CSS3DRenderer-r61.js"></script>-->
<script src="js/renderers/CSS3DRenderer.js"></script>
<script>
var camera, sceneGl, rendererGl;
var sceneCss, rendererCss;
var controls;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 200, 200, 200 );
controls = new THREE.TrackballControls( camera );
sceneGl = new THREE.Scene();
sceneCss = new THREE.Scene();
var material = new THREE.MeshBasicMaterial( { color: 0x000000, opacity : 0.0 } );
material.blending = THREE.NoBlending;
//
var xpos = [50, -10, 30, 70, 110];
var ypos = [60, -40, 0, 40, 80];
var zpos = [-30, -50, 0, 50, 100];
for ( var i = 0; i < 5; i ++ ) {
var element = document.createElement( 'div' );
element.style.width = '100px';
element.style.height = '100px';
element.style.opacity = 1.0;
element.style.background = new THREE.Color( Math.random() * 0xffffff ).getStyle();
var object = new THREE.CSS3DObject( element );
object.position.x = xpos[i];
object.position.y = ypos[i];
object.position.z = zpos[i];
object.rotation.x = Math.PI/(i + 5);
object.rotation.y = Math.PI/(21 - 2 * i);
object.rotation.z = Math.PI/(3 * i + 25);
object.scale.x = i/12 + 0.5;
object.scale.y = 1/ (12 - i) + 0.5;
sceneCss.add( object );
var geometry = new THREE.PlaneGeometry( 100, 100 );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.copy( object.position );
mesh.rotation.copy( object.rotation );
mesh.scale.copy( object.scale );
sceneGl.add( mesh );
}
//
var boxGeom = new THREE.CubeGeometry( 60, 60, 60 );
var cubeMaterial = new THREE.MeshBasicMaterial(
{ color: 0x05009A, shading : THREE.FlatShading, side: THREE.FrontSide } );
var cube = new THREE.Mesh( boxGeom, cubeMaterial );
cube.position.copy( new THREE.Vector3(100, 75, 50) );
cube.rotation.copy( Math.PI/ 6 );
sceneGl.add( cube );
rendererCss = new THREE.CSS3DRenderer();
rendererCss.setSize( window.innerWidth, window.innerHeight );
rendererCss.domElement.style.position = 'absolute';
rendererCss.domElement.style.top = 0;
rendererGl = new THREE.WebGLRenderer();
rendererGl.setClearColor( 0xf0f0f0 );
rendererGl.setSize( window.innerWidth, window.innerHeight );
rendererGl.domElement.style.position = 'absolute';
rendererGl.domElement.style.zIndex = 1;
rendererGl.domElement.style.top = 0;
rendererCss.domElement.appendChild( rendererGl.domElement );
document.body.appendChild( rendererCss.domElement );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
rendererGl.render( sceneGl, camera );
rendererCss.render( sceneCss, camera );
}
</script>
</body>
</html>
Here is a fiddle with the code.
The link in the comment was helpful. As that solution mentions, setting alpha to true solves the issue of getting the css3d objects to render using r67. Making the webGl background transparent solves the problem of the css3d objects disappearing when panning around.
The solution mentioned in the link however adds both the webgl and css3d dom as child elements of the document. This approach did not work in my case. I find it necessary to still have the webgl dom as a child of the css3d dom for the cube to blend correctly with the planes when it is both in front of and behind those objects.
Working code below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script src="js/renderers/CSS3DRenderer.js"></script>
<script>
var camera, sceneGl, rendererGl;
var sceneCss, rendererCss;
var controls;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(200, 200, 200);
controls = new THREE.TrackballControls(camera);
sceneGl = new THREE.Scene();
sceneCss = new THREE.Scene();
var material = new THREE.MeshBasicMaterial({
color: 0x000000,
opacity: 0.0,
side: THREE.DoubleSide
});
var xpos = [50, -10, 30, 70, 110];
var ypos = [60, -40, 0, 40, 80];
var zpos = [-30, -50, 0, 50, 100];
for (var i = 0; i < 5; i++) {
var element = document.createElement('div');
element.style.width = '100px';
element.style.height = '100px';
element.style.opacity = 1.0;
element.style.background = new THREE.Color(Math.random() * 0xff0000).getStyle();
var object = new THREE.CSS3DObject(element);
object.position.x = xpos[i];
object.position.y = ypos[i];
object.position.z = zpos[i];
object.rotation.x = Math.PI / (i + 5);
object.rotation.y = Math.PI / (21 - 2 * i);
object.rotation.z = Math.PI / (3 * i + 25);
object.scale.x = i / 12 + 0.5;
object.scale.y = 1 / (12 - i) + 0.5;
sceneCss.add(object);
var geometry = new THREE.PlaneGeometry(100, 100);
var mesh = new THREE.Mesh(geometry, material);
mesh.position.copy(object.position);
mesh.rotation.copy(object.rotation);
mesh.scale.copy(object.scale);
sceneGl.add(mesh);
}
var boxGeom = new THREE.CubeGeometry(60, 60, 60);
var cubeMaterial = new THREE.MeshBasicMaterial({
color: 0x05009A,
shading: THREE.FlatShading,
side: THREE.DoubleSide
});
var cube = new THREE.Mesh(boxGeom, cubeMaterial);
cube.position.copy(new THREE.Vector3(100, 75, 50));
cube.rotation.copy(Math.PI / 6);
sceneGl.add(cube);
rendererCss = new THREE.CSS3DRenderer();
rendererCss.setSize(window.innerWidth, window.innerHeight);
rendererCss.domElement.style.position = 'absolute';
rendererCss.domElement.style.top = 0;
rendererGl = new THREE.WebGLRenderer({alpha:true});
rendererGl.setClearColor(0x00ff00, 0.0);
rendererGl.setSize(window.innerWidth, window.innerHeight);
rendererGl.domElement.style.position = 'absolute';
rendererGl.domElement.style.zIndex = 1;
rendererGl.domElement.style.top = 0;
rendererCss.domElement.appendChild(rendererGl.domElement);
document.body.appendChild(rendererCss.domElement);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
rendererGl.render(sceneGl, camera);
rendererCss.render(sceneCss, camera);
}
</script>
</body>
</html>