Stereoeffect.js is not working. It shows black screen - three.js

I want to switch steroeffect view on click of button. But when i click and enable stereo effect. Scene is blank and shows black screen.
I tried adding this to renderer still no luck.
const size = this.renderer.getSize();
this.renderer.setScissor( 0, 0, size.width, size.height );
this.renderer.setViewport( 0, 0, size.width, size.height );
this.effect.setSize( window.innerWidth, window.innerHeight );
resizeHandler(event) {
this.renderer.setSize( window.innerWidth, window.innerHeight);
this.effect.setSize( window.innerWidth, window.innerHeight );
}
enableVrMode() {
this.stereoEffect = !this.stereoEffect;
this.resizeHandler(true);
this.render();
}
render() {
if (this.renderer) {
if (this.stereoEffect) {
this.effect.render(this.scene, this.camera);
} else {
this.renderer.render(this.scene, this.camera);
}
}
}
Whole scene shows black screen. Kindly guide me to fix this issue.
Thank you

Related

How to access the any property of imported point-cloud object

I’m trying to access any property of my imported point-cloud model.
When I console.log the model within the function loader.load it works. The first problem is that I don’t know how to get the same result outside the function. I did it only with the last three lines of code but initializing the object with different name.
I used the code for point-cloud models from three.js docs and everything works fine except when I want to change the size of the points. I guess it is due to the different structure of my model (photo attached).
Here’s the code that I use.
import './style.css'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { PCDLoader } from 'three/examples/jsm/loaders/PCDLoader'
import { BufferAttribute, BufferGeometry } from 'three';
let camera, scene, renderer;
init();
render();
function init() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 0.01, 40 );
camera.position.set( 0, 0, 7 );
scene.add( camera );
const controls = new OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render ); // use if there is no animation loop
controls.minDistance = 0.5;
controls.maxDistance = 10;
//scene.add( new THREE.AxesHelper( 1 ) );
const loader = new PCDLoader();
loader.load( 'pointcloud.pcd', function ( points ) {
points.geometry.center();
points.geometry.rotateY( Math.PI );
points.geometry.rotateX( Math.PI );
points.geometry.rotateZ( Math.PI );
scene.add( points );
console.log(points)
render();
} );
window.addEventListener( 'resize', onWindowResize );
window.addEventListener( 'keypress', keyboard );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function keyboard( ev ) {
const points = scene.getObjectByProperty( 'pointcloud.pcd' );
switch ( ev.key || String.fromCharCode( ev.keyCode || ev.charCode ) ) {
case '+':
points.material.size *= 1.2;
break;
case '-':
points.material.size /= 1.2;
break;
}
render();
}
function render() {
renderer.render( scene, camera );
}
// I used this to acces the object
const points2 = scene.getObjectByProperty( 'points' );
console.log(points2)
enter image description here
change let camera, scene, renderer; to let camera, scene, renderer, points
to make 'points' global.
because the 'points' object only live inside the function, try create a variable outside the loader.load function, then assign the 'points' object to the new variable before render(); now you can access the 'points' from outside this function

How to animate camera.lookAt using gsap?

camera.lookAt(myObject) will instantly rotate the three.js camera towards the given object.
I would like to animate this rotation using gsap. I have no problem using gsap to animate a change in camera position, but the camera rotation code below does nothing.
const targetOrientation = myObject.quaternion.normalize();
gsap.to({}, {
duration: 2,
onUpdate: function() {
controls.update();
camera.quaternion.slerp(targetOrientation, this.progress());
}
});
How can I animate a camera rotation in this way?
OK this is now fixed. The main problem was a controls.update() line in my render() function. Orbit controls do not work well with camera rotation so you need to make sure that they are completely disabled during the animation.
My revised code that includes rotation and position animations:
const camrot = {'x':camera.rotation.x,'y':camera.rotation.y,'z':camera.rotation.z}
camera.lookAt(mesh.position);
const targetOrientation = camera.quaternion.clone().normalize();
camera.rotation.x = camrot.x;
camera.rotation.y = camrot.y;
camera.rotation.z = camrot.z;
const aabb = new THREE.Box3().setFromObject( mesh );
const center = aabb.getCenter( new THREE.Vector3() );
const size = aabb.getSize( new THREE.Vector3() );
controls.enabled = false;
const startOrientation = camera.quaternion.clone();
gsap.to({}, {
duration: 2,
onUpdate: function() {
camera.quaternion.copy(startOrientation).slerp(targetOrientation, this.progress());
},
onComplete: function() {
gsap.to( camera.position, {
duration: 8,
x: center.x,
y: center.y,
z: center.z+4*size.z,
onUpdate: function() {
camera.lookAt( center );
},
onComplete: function() {
controls.enabled = true;
controls.target.set( center.x, center.y, center.z);
}
} );
}
});
Try it like so:
let mesh, renderer, scene, camera, controls;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 20, 10, 20 );
camera.lookAt( 0, 0, 0 );
// ambient
scene.add( new THREE.AmbientLight( 0x222222 ) );
// light
const light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 20,20, 0 );
scene.add( light );
// axes
scene.add( new THREE.AxesHelper( 20 ) );
// geometry
const geometry = new THREE.SphereBufferGeometry( 5, 12, 8 );
// material
const material = new THREE.MeshPhongMaterial( {
color: 0x00ffff,
flatShading: true,
transparent: true,
opacity: 0.7,
} );
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
const startOrientation = camera.quaternion.clone();
const targetOrientation = mesh.quaternion.clone().normalize();
gsap.to( {}, {
duration: 2,
onUpdate: function() {
camera.quaternion.copy(startOrientation).slerp(targetOrientation, this.progress());
}
} );
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.123/build/three.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.0/gsap.min.js"></script>
You have to ensure to call Quaternion.slerp() always with the start orientation and not with camera.quaternion. Otherwise the interpolation will be incorrect.

ThreeJS black screen - no console errors

Trying to learn three.js and I can only manage to see a black screen while trying to replicate a three.js example. I tried adding hemisphere lights and it did not change anything. If anyone can point me in the right direction I'd be so happy
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.toneMappingExposure = 0.8;
renderer.outputEncoding = THREE.sRGBEncoding
container.appendChild( renderer.domElement );
//var pmremGenerator = new THREE.PMREMGenerator( renderer );
//pmremGenerator.compileEquirectangularShader();
controls = new OrbitControls(camera, renderer.domElement );
controls.addEventListener( 'change', render ); //use if no anim loop
controls.minDistance = 2;
controls.maxDistance = 10
controls.target.set( 0, 0, - 0.2 );
controls.update();
window.addEventListener( 'resize', onWindowResize, false );
}
function.onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
I Really don't know what to do as I'm just starting out. I'm running locally on my home comp so it should not be an issue regarding that. Thanks in advance.

Loading External Shaders Using THREE.JS

I am trying to make a THREE.JS scene with GLSL shaders applied, but am having trouble figuring out how to make it load my shaders. The scene appears to work, but the shaders don't do what they're supposed to. I'm using a shader loader function I found that uses pure THREE.JS instead of AJAX or Jquery.
Here is the main javascript for my scene.
var container,
renderer,
scene,
camera,
light,
mesh,
controls,
start = Date.now(),
fov = 30;
window.addEventListener( 'load', function() {
container = document.getElementById( "container" );
if(!Detector.webgl) {
Detector.addGetWebGLMessage(container);
return;
}
//get the width and height
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
//sphere params
var radius = 20,
segments = 4,
rotation = 6;
scene = new THREE.Scene();
// ASPECT RATIO
camera = new THREE.PerspectiveCamera(fov, WIDTH / HEIGHT, 1, 10000);
camera.position.z = 100;
scene.add(new THREE.AmbientLight(0x333333));
light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(100, 3, 5);
scene.add(light);
;
ShaderLoader('./shaders/vertex.vert', './shaders/fragment.frag')
material = new THREE.ShaderMaterial( {
uniforms: {
tExplosion: {
type: "t",
value: THREE.ImageUtils.loadTexture( 'images/explosion.png' )
},
time: { //float initialized to 0
type: "f",
value: 0.0
}
},
vertexShader: ShaderLoader.vertex_text,
fragmentShader: ShaderLoader.fragment_text
} );
mesh = new THREE.Mesh(
new THREE.IcosahedronGeometry( radius, segments ),
material
);
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( WIDTH, HEIGHT );
renderer.setPixelRatio( window.devicePixelRatio );
//update renderer size, aspect ratio, and projectionmatrix, on resize
window.addEventListener('resize', function() {
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
});
controls = new THREE.TrackballControls( camera );
container.appendChild( renderer.domElement );
render();
} );
function render() {
material.uniforms[ 'time' ].value = .00025 * ( Date.now() - start );
controls.update();
requestAnimationFrame( render );
renderer.render(scene, camera);
}
// This is a basic asyncronous shader loader for THREE.js.
function ShaderLoader(vertex_url, fragment_url, onLoad, onProgress, onError) {
var vertex_loader = new THREE.XHRLoader(THREE.DefaultLoadingManager);
vertex_loader.setResponseType('text');
vertex_loader.load(vertex_url, function (vertex_text) {
var fragment_loader = new THREE.XHRLoader(THREE.DefaultLoadingManager);
fragment_loader.setResponseType('text');
fragment_loader.load(fragment_url, function (fragment_text) {
onLoad(vertex_text, fragment_text);
});
}, onProgress, onError);
}
But when my scene loads, it is just a red sphere with no lighting or applied shaders... What am I doing wrong? I'm new to all of this so it is probably something easily noticeable for someone more experienced, but I have searched and searched and been experimenting and can't figure it out.
Thanks!
Try to add material.needsUpdate = true after you load your shader.
The snippet show error of the WebGL detector.
Are you loading that library?
https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js

three.js Mesh not displaying rectangle depending on orientation

I have created a MWE that creates a single rectangle spinning. However, the rectangle disappears based on its orientation, and the material (which claims to be dotted lines) does not work and instead the rectangle is drawn in solid white.
I suspect the disappearance is due to rectangles only being visible facing the camera. Is there a simple two-sided rectangle parameter?
Why isn't the rectangle being drawn as a dashed outline?
var container, stats;
var camera, scene, renderer;
var group;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
function init( ) {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 150, 500 );
scene = new THREE.Scene();
var lineDash = new THREE.LineDashedMaterial( { color: 0xffaa00, dashSize: 3, gapSize: 1, linewidth: 2 } );
var wall = new THREE.Geometry();
var h = 200;
wall.vertices.push(new THREE.Vector3(0, 0, 0));
wall.vertices.push(new THREE.Vector3(200, 0, 0));
wall.vertices.push(new THREE.Vector3(200, 0, h));
wall.vertices.push(new THREE.Vector3(0, 0, h));
wall.faces.push( new THREE.Face3( 0, 1, 2 ) );
wall.faces.push( new THREE.Face3( 0, 2, 3 ) );
var wallObj = new THREE.Mesh(wall, lineDash );
wallObj.position.x = 0;
wallObj.position.y = 200;
wallObj.rotation.x = Math.PI/2;
group = new THREE.Group();
group.add(wallObj);
scene.add( group );
renderer = new THREE.CanvasRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
group.rotation.y += .05;
renderer.render( scene, camera );
}
init( );
animate();
To make a material double-sided, set
material.side = THREE.DoubleSide.
LineDashedMaterial requires line distances to be computed.
geometry.computeLineDistances().
WebGLRenderer is preferable to CanvasRenderer.
three.js r.75

Resources