Three.js StereoEffect cannot be applied to CSS3DRenderer - three.js

I'm in the process of developing a chrome VR web app. Now I'm desperately trying to figure out how to render a website into my into my stereoscopic scene which has some meshes in it.
So I have my renderer for the meshes, which works well. The following code is only the relevant snippets:
var renderer = new THREE.WebGLRenderer();
Then i have my stereoeffect renderer which receives the webgl renderer:
var effect = new THREE.StereoEffect(renderer);
Next is that I create the website renderer, and apply it to the stereoeffect:
var rendererCSS = new THREE.CSS3DRenderer();
var effectHUD = new THREE.StereoEffect(rendererCSS);
Then I have scenes which are being rendered:
var scene = new THREE.Scene();
var sceneCSS = new THREE.Scene();
function render(dt) {
effect.render(scene, camera);
effectHUD.render( sceneCSS, camera );
}
No what I receive is this:
A stereoscopic image of my mesh, but a non stereoscopic image of the website. The problem is that the when I try to add the css renderer into the StereoEffect renderer, the setViewport function (among others, probably) are missing.
I've tried adding the website object to the webgl renderer, but it doesn't want to render my website, so adding the website object to the scene with the meshes doesn't work.
Any help is greatly appreciated!

I've been having the same problem.
It appears there was a CSS Stereo renderer but it's been removed along with all examples. This could have been for any number of reasons so use the following with caution, or until they reintroduce compatibility:
After searching I found a remaining copy of their demo from which you can mine the code and copy its CSS3DStereoRenderer.js file.
Hopefully this helps.

Related

How can I add 2d text to three.js (already tried sprites, fontLoader, etc)?

I'm to add 2d text as labels next to an object, as shown in the image. I've tried sprites (which, as far as I understand, don't work in newer versions of three.js), fontLoader, and a couple of rendering mechanisms--but I have not had any success, unfortunately.
I see that I can use CSS3D, but I'm not sure what to grab from the sample codes. If someone could point me in the right direction, I would appreciate it.
Image showing what I'm trying to achieve
If anyone has any advice, I would greatly appreciate it.
The following are some key parts of my code:
<script src="https://unpkg.com/three#0.132.2/build/three.min.js"></script>
<script src="https://unpkg.com/three#0.132.2/examples/js/loaders/GLTFLoader.js"></script>
<script src="https://unpkg.com/three#0.132.2/examples/js/loaders/DRACOLoader.js"></script>
<script src="https://unpkg.com/three#0.132.2/examples/js/controls/OrbitControls.js"></script>
<canvas id="c"></canvas>
window.addEventListener('load', init);
function init() {
const width = window.innerWidth;
const height = window.innerHeight;
const canvasElement = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({
canvas: canvasElement,
});
renderer.setSize(width, height);
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0xf5e8c6 );
loader.load('js/PricklyPearObject/scene.gltf', (gltf) => {
const model = gltf.scene;
model.scale.set( 0.1,0.1,0.1);
model.position.set(-2, 0, 0);
scene.add(model);
});
I tried using sprites, fontloader, and an approach using render but could not get them to work.
I'll show you a quick and easy way to achieve this when no experience with coding. You can use "Model Viewer". Go to: https://modelviewer.dev/
Click their Editor shown in the pic ->>
Then, drag your glTF or GLB model to the scene.
Then click "Edit" button, then "Add Hotspot" button. Add the text as a label. See the pic below:
Then you can setup the camera (initial position etc.), improve the lights and shadow, or add styles and customize the material.
When you are happy with your model, copy the "snippet code" to add it to your HTML (without forgetting to add the scripts), or "download the scene" as a Three.js project and check the code and run it with simply "Go Live" button in VS Code.
Hope it helps.

Three.js Mesh With Multiple Materials Disappears?

I'm trying to load a pretty simple model with two materials (applied per-face) in Three.js exported from Blender. The issue I'm running into is that with multiple materials applied via the code below the mesh disappears entirely, but I can easily use materials[0] or materials[1] in place of materials and see a solid object. My export settings from blender along with what it should look like are below and the json of the model is visible online here.
I tried your JSON file and it displayed just like your image. Here's the code I used (three.js r83):
var mesh = new THREE.Object3D();
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load('/js/models/cube.json',
function (geometry, materials) {
mesh = new THREE.Mesh(geometry,
new THREE.MultiMaterial(materials));
scene.add(mesh);
}
);
http://www.threejsworld.com/tutorials/working-with-materials-in-threejs

Clean up Threejs WebGl contexts

I have a problem while cleaning up my WebGl-Scenes. I'm using Three.js with a WebGlRenderer. In my application I have to change the views quite often and therefore need to render new scenes all the time. Uptil now I destroy and reinitialize the entire Threejs scene. After switching the scenes about 15 - 20 times I get following warning:
WARNING: Too many active WebGL contexts. Oldest context will be lost.
After switching a couple of times more the context is lost completly and the application crashes.
Is there a way to destroy the current WebGl context, when cleaning up? Or does the WebGlRenderer always create a new WebGl context when being instantiated?
I'm using Three.js R64.
I've got same problem, but i couldn't solve it using SPA, because of requirements.
There is .forceContextLoss() method in WebGLRenderer (rev 71, maybe was early) for this situations.
So, my code in 'deallocate' method is somemethig like
_self.renderer.forceContextLoss();
_self.renderer.context = null;
_self.renderer.domElement = null;
_self.renderer = null;
You can keep the same renderer for different scenes. The renderer does not care what scene it will render. You can supply a different Scene everytime you call render() if you like.
// instantiate only once and keep it
var renderer = new THREE.WebGLRenderer();
// current scene and camera. Switch whenever you like
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(...);
fillScene(scene);
// rendering always uses current scene
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
/* ...
* somewhere in your application
* ...
*/
if(condition) {
// switch scene
scene = new THREE.Scene();
fillOtherScene(scene);
}
You should create and use only one WebGlRenderer. In my SPA (single page application) I had weird problem with camera/scene in THREE.js after few redirects. It was because WebGlRenderer was created every time when one particular page was rendered. There was no error in console log (only the warning you wrote).
Bug appeared as change in camera position and problems with rendering.

ColladaLoader: Could not find the skeleton for the skin

I was trying to render a primitive character I made in 3dsmax, but seems like there's something wrong with my exported DAE file or just ColladaLoader is unable to process it correctly.
Scene consists of an animated biped skeleton, simple rigged character using Physique modifier, one static box and an animated one.
Here's my code:
<script src="three.js" type="text/javascript"></script>
<script src="ColladaLoader.js" type="text/javascript"></script>
<script type="text/javascript">
var size_width = window.innerWidth;
var size_height = window.innerHeight;
var player;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, size_width/size_height, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(size_width, size_height);
document.body.appendChild(renderer.domElement);
camera.position.x = 100;
camera.position.y = -50;
camera.position.z = 7;
camera.rotation.x = 1.4;
var player_loader = new THREE.ColladaLoader();
player_loader.load( "running_babe.dae", function(collada) {
player = collada.scene;
init();
});
function init() {
scene.add(player);
render();
}
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
</script>
But all I get are those two boxes and a error:
ColladaLoader: Could not find the skeleton for the skin.
Here's exported DAE file I use - http://touhou.ru/upload/ff72eb0b40adf5c97286a1bcb164e1f0.DAE
Any suggestions?
Update: After rigging character with skin modifier I came up with the same result - could not find the skeleton for the skin.
Here's the link to exported dae with skin modifier - http://touhou.ru/upload/af6ba52b7bff5fa2b0f6ba3f704a3b77.dae
I had the same problem and spent days playing with exporter settings before i started reading the threejs colladaloader source and figured it out. so in case you haven't solved it yet, here's what you have to do:
First: when you export your model from max, make sure none of the elements in your scene have the same name as your filename (or your geometry wont show up this has something to do with generated ids in the DAE file)
Now, 3DSMax somehow neglects to export a node, so you have to add that manually:
open the running_babe.dae file in a text editor
look for an <instance_controller url="...."/> node and rewrite it to:
<instance_controller url="....">
<skeleton>#xxxxx</skeleton>
</instance_controller>
wherein 'xxxxx' is the id(=element/bone name in 3dsmax) that is the root element of your skeleton hierarchy. and don't forget the 'hash' at the beginning! :)
hope that solves it for you. i haven't tried animation yet, but i will now, and let you know if there's anything missing from this solution.
edit: nevermind, apparently i just scratched the surface of the tip
of a huge frigging iceberg.. seems like getting collada(from 3dsmax
2013) + skinned animation working is a pain.. i'll look at writing a new json exporter.
the format seems straight forward and well documented, plus, there's the old .ms file
from github to start from. good luck to you! if you find something, be so kind as to post
your method here, would you? :)
The default plugin that comes with 3ds max does not work. You need to use the OpenCollada plugin. Then you can follow the collada loader example. You get bones, animations and all!

Can't seem to make a functional THREE.js collada loader

I'm having issues getting a custom made collada object with no built in camera or lighting to render. I more or less copied what I had seen in a few collada examples to create my own loader, which looks like this:
var loader = new THREE.ColladaLoader();
var room, scene, stats;
loader.load('../Models/Rooms/boot.dae', function colladaReady( collada ){
collada.scene.getChildByName('Cube',true).doubleSided = true;
room = collada.scene;
room.scale.x = room.scale.y = room.scale.z = 1;
room.updateMatrix();
init();
});
The init function is fairly basic and looks like this
scene = new THREE.Scene();
scene.add( room );
scene.add( camera );
renderer.render(scene, camera);
Here is the actual object I'm trying to render. I have also tried it out with the monster.dae file that is in the examples folder without success. The Chrome javascript console isn't showing any errors, so I'm not quite sure where to look in my code. It all resembles functional examples, so I'm not sure why it's not functional. Is there something I'm unaware of that is relevant to collada loading?
RESOLVED: The item was rendering, but had no skin or texture associated with it. So it was rendering at the same colour as the background, which understandably appears to not be rendering at all. Discovered by adding a grid to the ground just to check.

Resources