Three.js Stereo Effect not lining up - three.js

I'm using Stero Effect in Three.js for a simple VR player, and the views don't line up - i.e. the right view is pointing a little more to the left than the left view and vice versa.
I've looked through all the examples and I'm not sure what I'm doing wrong. No one else seems to have this problem
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1024);
scene = new THREE.Scene();
target = new THREE.Vector3();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;
renderer.autoClear = false;
effect = new THREE.StereoEffect(renderer);
effect.setSize(window.innerWidth, window.innerHeight);
//in the renderer
if(vrMode)
effect.render(scene, camera);
else
renderer.render(scene, camera);
Has anyone seen this before or know what else might cause it?

I think it's due to the eye separation parameter. Try to set it to 0 it worked for me.
The parameter is on the StereoEffect.js file: this.separation

Related

Manually specifying camera matrices in ThreeJS

I'm working on a project where I will draw 3D graphics on a video that is filmed with a real camera. I get provided a static projection and view matrix and my task is to draw the actual graphics on top. I've got it working in pure WebGL and know I'm trying to do it in ThreeJS. The problem is that I can't find a way to manually set the projection and view matrix for the camera in ThreeJS.
I've tried to set camera.matrixAutoUpdate = false and calling camera.projectionMatrix.set(matrix) and camera.matrixWorldInverse.set(matrix), but it doesn't seam to work. It is like the actual variable isn't passed to the shader.
Does anyone know how this can be done?
This is what I've got so far:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.matrixAutoUpdate = false;
camera.projectionMatrix.set(...)
camera.matrixWorldInverse.set(...)
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var animate = function() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
animate();

Adding three.js compound object into A-Frame causing unexpected flickering of child objects

I am adding augmented reality experience to my web app which originally created using threejs
I have a compound object(which is an Object3D instance with multiple meshes). but placing it into A-Frame giving unexpected flickering s shown in below
Pic of the original web app with threejs is given below
I have the three.js code like below
scene = new THREE.Scene();
mainObj = new THREE.Object3D();
scene.add(mainObj);
renderer = new THREE.WebGLRenderer({alpha: true, antialias: true});
renderer.sortObjects = false
container = document.getElementById("canvas-container");
width = $(container).innerWidth();
height = $(container).innerHeight();
renderer.setSize(width, height);
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(75, width / height, 10, 2000);
camera.position.set(0, 67, 100);
controls = new THREE.OrbitControls( camera , container);
controls.dampingFactor = 0.2;
controls.enableDamping = true;
controls.target.set( 0, 10, -20 );
controls.maxPolarAngle = (Math.PI/2) - 0.05;
controls.maxDistance = 800;
controls.minDistance = 2;
controls.target.set(0, buildingConfig.h/2, buildingConfig.l/-2)
controls.enableKeys = false;
controls.update();
scene.add(camera);
light = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.7);
light.position.set(1, 10000, 1);
light.castShadow = true
scene.add( light );
renderer.render(scene, camera);
// logic to add child meshes to mainObj
Which I changed to include in A-Frame.
<script type="text/javascript">
initmodels();
AFRAME.registerComponent('e1', {
init:function(){
this.el.setObject3D('building', mainObj);
}
});
</script>
<a-scene e1>
</a-scene>
I guess this issue is related to the scene or renderer. Can anyone help me with a proper scene or renderer setup in A-Frame
This looks like z-fighting. Is the three.js version running on a different system than your aframe version?
Different platforms have different z-buffer precision. It may require you to make changes to the geometry to compensate for the limited resolution.
Also, I don't know about AR.s, but the THREE renderer has a "logarithmicDepthBuffer" option that can increase the resolution of your z-buffer at near scales, but may have some side effects.
I had exactly the same issue. After a few trial and errors, I was able to fix it
Added recent version of aframe
Add <a-scene embedded artoolkit='sourceType: webcam;' renderer='logarithmicDepthBuffer: true;'>
Add <a-marker-camera camera="far:100000; near:0.01" >
Main reason was the light, Remove all lights and add only the hemisphere light into the scene and improvise upon other lights later on.
Hope this would resolve your issue too.

Putting three.js inside of div 2

I apologize for one more basic question which basically is a copy of another old thread, but I'm new to three.js and learning more or less through trial and error over here...
I found the old thread 'Putting three.js animation inside of div' where they succeeded putting a three.js animation inside of a div with the following lines of code:
container = document.getElementById( 'canvas' );
document.body.appendChild( container );
renderer = new THREE.WebGLRenderer();
renderer.setSize( 200, 200 );
container.appendChild( renderer.domElement );
A JSFiddle of above script (http://jsfiddle.net/fek9ddg5/1/)
I'm trying to do the same and added the lines to my script, but ended up with a completely white screen instead. I managed to basically part the screen in two parts, one completely white and another with the script. However, it failed since the script reacted to the mouse even if it moved in the white part. I made a codepen, I placed the script I added inside of comment-signs.
See it here: http://codepen.io/anon/pen/qRdGWo
Usually to add three.js to a page I would use this:
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
As can be seen in this fiddle
But, to add it to a div that is already on the page with the ID 'canvas-container' I would use..
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
// get the div that will hold the renderer
var container = document.getElementById('canvas-container');
var w = container.offsetWidth;
var h = container.offsetHeight;
renderer.setSize(w, h);
// add the renderer to the div
container.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, w / h, 1, 1000);
camera.position.z = 400;
Which can be seen in this fiddle
Basically where the renderer is added is determined on what dom element you call appendChild(renderer.domElement) on.

Three.VRControls initial rotation

I've been doing through this Unable to change camera position when using VRControls and Three.js - VRControls integration - How to move in the scene? but it's not quite doing what I need.
I have a VR video app and I've just switched to VRControls with the WebVR polyfill from something old and custom. This is working well, however I'm really struggling to set the initial camera angle.
I.e. I want the camera to start pointing at a particular angle, and then rotate with the controls - however the controls always override this angle.
I've tried adding the camera to a Dolly Group or Persepective Camera, and it seems like I can move the camera but not set the initial viewing angle.
Here is how the camera is set up
container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1024);
scene = new THREE.Scene();
target = new THREE.Vector3();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
var vrEffect = new THREE.VREffect(renderer);
vrEffect.setSize(window.innerWidth, window.innerHeight);
var params = {
hideButton: false, // Default: false.
isUndistorted: false // Default: false.
};
manager = new WebVRManager(renderer, vrEffect, params);
dolly = new THREE.PerspectiveCamera();
dolly.add( camera );
//scene.add( dolly );
controls = new THREE.VRControls(camera);// (I've tried using Dolly here)
controls.standing = true;
And I've tried various ways to rotate the camera, dolly or scene
camera.position.y = currentScene.pan * Math.PI/180;
//controls.resetPose();
//dolly.position.x = currentScene.tilt * Math.PI/180;
//camera.updateProjectionMatrix();
I can rotate the mesh, but then all the objects inside the mesh are in the wrong place.. I could try moving them but this seems like the wrong approach to point the camera to the place I want it..
The camera was getting re-added to the scene at a later time, overriding the dolly. It's working now.

How do I load collada object to three.js?

I'm new to three.js and am having trouble loading a collada object to it. I can't get home.dae to render in the browser.
I updated the code under SECOND UPDATE based on the answers.
// INITIAL
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var loader = new THREE.ColladaLoader();
loader.load('home.dae', function(collada){
scene.add(collada);
});
function render() {
renderer.render(scene, camera);
}
render();
// SECOND UPDATE
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(0,1,4);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var loader = new THREE.ColladaLoader();
loader.load('home.dae', function(collada){
scene.add(collada.scene);
});
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
Your render function is called only once. Try with this -
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
Also check if you file path is valid.
Few things that come to mind:
as #Rasheduzzaman already noted, the render-function is called too early (when you call render(), the scene.add(collada); call can not have happened. Use his Answer instead.
the collada-loader works a bit differently: the documentation isn't clear about this, but the returned object is a collection of all the stuff that could've been in the collada-file, see here for a list: https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/ColladaLoader.js#L181-L204 (also: use the debugger from the browser-devtools to inspect the data you find there). You will probably want to do scene.add(collada.scene) or similar.
you are not setting a position for the camera, so it is located at (0,0,0), which might not be a great idea, try camera.position.set(0,1,4) or something like that.
you need to know what to expect: what is the size of the model you are loading? Where is it placed? Make sure to point your camera there (could use camera.lookAt(object.position)) and adjust nearPlane and farPlane accordingly.

Resources