Can't run basic example on threejs.org website - javascript

I am trying to learn three.js, and was looking up some examples.
I was trying to run this code https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_cube.html
however, all it displayed was a black screen.
I modified the three.js source to my directory, and I also modified the material to the following, because I don't have the crate texture.
var material = new THREE.MeshStandardMaterial({metalness: 0, roughness: 0.5});
material.color.setHex(0xc23560)

Some code with explanations:
var camera, scene, renderer;
var mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
scene = new THREE.Scene();
light = new THREE.PointLight(0xffffff, 1, 1000); // increase the distance
light.position.set(300,300,300); // [50,50,50] - inside the cube
scene.add(light);
var geometry = new THREE.BoxBufferGeometry(200, 200, 200);
var material = new THREE.MeshStandardMaterial({
color: 0xc23560,
metalness: 0,
roughness: 0.5
});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>

I figured it out, it just turned out that the material of my box is metallic, and I added the light source wrongly.

Related

Three JS not rendering anything at all. It’s all a black screen

I’ve went through similar questions on this site, and I have seen all the things that are recommended. Like, camera positioning (not inside the mesh), calling the render function, setting the (ambient) light. Each and every thing I’ve found so far in the forum I’ve tried, but nothing is working.
Can anyone please look at this fiddle and guide me as to what I am doing wrong?
https://jsfiddle.net/4mxybs5h/1/
// HTML
<main>
<div id="threeContainer">
hi
<canvas #canvas id="canvas"></canvas>
</div>
</main>
// JS
//this.animate(null);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
boxGeometry = new THREE.BoxGeometry(2, 2, 2);
material = new THREE.MeshBasicMaterial({color: 0xff0000});
mesh = new THREE.Mesh( boxGeometry, material );
canva = document.getElementById("canvas");
renderer = new THREE.WebGLRenderer({antialias: true, canvas: canva });
startScene();
animate();
function startScene() {
//let scene = new THREE.Scene();
//let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
let light = new THREE.AmbientLight( 0xffaaff );
scene.add( mesh );
light.position.set(10,10,10)
scene.add( light );
camera.position.set(500, 500, 500);
mesh.castShadow = true;
mesh.receiveShadow = true;
//this.renderer.setClearColor('#E5E5E5')
renderer.setClearColor(0xEEEEEE);
//this.renderer.setSize(window.innerWidth, window.innerHeight)
//this.renderer.render(this.scene, this.camera)
//this.renderer.setAnimationLoop(this.animate.bind(this))
//document.body.appendChild(this.renderer.domElement)
// window.addEventListener('resize', () => {
// this.renderer.setSize(window.innerWidth, window.innerHeight)
// this.camera.aspect = window.innerWidth / innerHeight
// this.camera.updateProjectionMatrix();
// })
}
function animate() {
camera.aspect = window.innerWidth / innerHeight
camera.updateProjectionMatrix();
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
//this.mesh.rotation.y += 1;
//document.body.appendChild(this.renderer.domElement)
renderer.render(scene, camera);
}
I feel like it must be something small or obvious, but I am not able to be figure out. Any help is appreciated.
You're not seeing anything because you're setting the camera way off.
Inside the startScene function, change the following:
// From
camera.position.set(500, 500, 500);
// TO
camera.position.set(0, 0, 5);
Applying the above gives:
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
boxGeometry = new THREE.BoxGeometry(2, 2, 2);
material = new THREE.MeshBasicMaterial({color: 0xff0000});
mesh = new THREE.Mesh( boxGeometry, material );
canva = document.getElementById("canvas");
renderer = new THREE.WebGLRenderer({antialias: true, canvas: canva });
startScene();
animate();
function startScene() {
let light = new THREE.AmbientLight( 0xffaaff );
scene.add( mesh );
light.position.set(10,10,10)
scene.add( light );
camera.position.set(0, 0, 5);
mesh.castShadow = true;
mesh.receiveShadow = true;
renderer.setClearColor(0xEEEEEE);
}
function animate() {
camera.aspect = window.innerWidth / innerHeight
camera.updateProjectionMatrix();
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<main>
<div id="threeContainer">
<canvas #canvas id="canvas"></canvas>
</div>
</main>

Can't implement post.processing with EffectComposer in Three.js

Im trying to implement post-processing effects in Three.js through this example here:
https://threejs.org/docs/#manual/en/introduction/How-to-use-post-processing
With the following code:
import * as THREE from 'three';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js';
var scene, camera, renderer, box, composer;
init();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color("#333333");
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: new THREE.Color('skyblue') });
box = new THREE.Mesh(geometry, material);
scene.add(box);
const light = new THREE.DirectionalLight();
light.position.set(0, 1, 2);
scene.add(light);
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 3;
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);
// add EFFECT
composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
const filmPass = new FilmPass(0.35, 0.025, 648, false,);
filmPass.renderToScreen = true;
composer.addPass(filmPass);
window.addEventListener('resize', onResize, false);
update();
}
function update() {
requestAnimationFrame(update);
box.rotation.y += 0.01;
composer.render(scene, camera);
}
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
composer.setSize(window.innerWidth, window.innerHeight);
}
This gives me error that it cant find /node_modules/three/examples/jsm/postprocessing/
This is indead true. The file does not exist anymore for some reason in my version of three
I found this:
https://www.npmjs.com/package/postprocessing
and did try to install and use that instead but without success:
npm install three postprocessing
And the following code:
import * as THREE from 'three';
import { BloomEffect, EffectComposer, EffectPass, RenderPass } from "postprocessing";
var scene, camera, renderer, box, composer;
init();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color("#333333");
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: new THREE.Color('skyblue') });
box = new THREE.Mesh(geometry, material);
scene.add(box);
const light = new THREE.DirectionalLight();
light.position.set(0, 1, 2);
scene.add(light);
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 3;
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);
// add EFFECT
composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
// const filmPass = new BloomEffect());
// filmPass.renderToScreen = true;
composer.addPass(new BloomEffect());
window.addEventListener('resize', onResize, false);
update();
}
function update() {
requestAnimationFrame(update);
box.rotation.y += 0.01;
composer.render(scene, camera);
}
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
composer.setSize(window.innerWidth, window.innerHeight);
}
This render my scene all black.
What am I doing wrong? How do I implement EffectComposer in Three.js

How to make visible edges that are intersects other objects' surfaces?(THREE.js)

I am working in a three.js project. In the project I have to show all edges of geometries even those edges are intersecting with other objects' surfaces.
Here is the snippet code that illustrates my problem.
var camera, scene, renderer, material, stats, group, wireframeMaterial;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({antialias: true, alpha:true,clearAlpha:0,clearColor: 0xff0000});
//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;
// Create scene.
scene = new THREE.Scene();
group=new THREE.Group()
// Create material
material = new THREE.MeshBasicMaterial();
wireframeMaterial=new THREE.LineBasicMaterial( { color: 0x000000, side:THREE.FrontSide ,transparent:false,opacity:1,linewidth: 1 })
// Create cube and add to scene.
var geometry = new THREE.BoxGeometry(200, 200, 200);
var mesh1 = new THREE.Mesh(geometry, material);
group.add(mesh1);
var geometry2 = new THREE.BoxGeometry(100,100,100);
var mesh2 = new THREE.Mesh(geometry2, material);
group.add(mesh2);
mesh2.position.fromArray([0,150,0])
var edges = new THREE.EdgesGeometry( geometry );
var line = new THREE.LineSegments( edges, wireframeMaterial );
mesh1.add( line );
var edges2 = new THREE.EdgesGeometry( geometry2 );
var line2 = new THREE.LineSegments( edges2, wireframeMaterial );
mesh2.add( line2 );
scene.add(group)
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
}
function animate() {
requestAnimationFrame(animate);
group.rotation.x += 0.005;
group.rotation.y += 0.01;
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
body {
padding: 0;
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js"></script>
In fiddle code you can see there are two cubes top of each other. I want bottom edges of small cube to become visible. One solution is making mesh basic material transparent. However in that situation edges that are behind cubes it self will be visible too which is not allowed in the project.
So are there any alternative solution for this issue?
Found a good solution, you need to use the polygonOffset parameters of the basic material.
var material = new THREE.MeshBasicMaterial({
polygonOffset: true,
polygonOffsetFactor: 1, // positive value pushes polygon further away
polygonOffsetUnits: 1
});
Found it on this question: three.js EdgesHelper showing certain diagonal lines on Collada model
EdgesGeometry will render the hard edges only.
WireframeGeometry will render all edges.
var camera, scene, renderer, material, stats, group, wireframeMaterial;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({antialias: true, alpha:true,clearAlpha:0,clearColor: 0xff0000});
//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;
// Create scene.
scene = new THREE.Scene();
group=new THREE.Group()
// Create materials
var material = new THREE.MeshBasicMaterial({
polygonOffset: true,
polygonOffsetFactor: 1, // positive value pushes polygon further away
polygonOffsetUnits: 1
});
var wireframeMaterial= new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 2 } );
// Create cube and add to scene.
var geometry = new THREE.BoxGeometry(200, 200, 200);
var edges = new THREE.EdgesGeometry(geometry);
var line = new THREE.LineSegments( edges, wireframeMaterial );
var mesh = new THREE.Mesh(geometry, material);
group.add(mesh, line);
var geometry2 = new THREE.BoxGeometry(100,100,100);
var wire = new THREE.EdgesGeometry(geometry2);
var line2 = new THREE.LineSegments( wire, wireframeMaterial );
var mesh2 = new THREE.Mesh(geometry2, material);
line2.position.fromArray([0,150,0]);
mesh2.position.fromArray([0,150,0]);
group.add(mesh2, line2);
scene.add(group)
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
// Add stats to page.
stats = new Stats();
document.body.appendChild( stats.dom );
}
function animate() {
requestAnimationFrame(animate);
group.rotation.x += 0.005;
group.rotation.y += 0.01;
renderer.render(scene, camera);
stats.update();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
<script type="text/javascript" src="https://rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/mrdoob/stats.js/r17/build/stats.min.js"></script>

How do I position geometry in Threejs to the bottom maintaining its aspect ratio

I am new to Threejs and facing a problem in the positioning of geometry. I want to position geometry at the bottom and it should be half cut i.e like half area should be visible but when try adding position.setY(-300), it moves down but stretches the geometry. I don't know what I am doing wrong or what will be the correct way to position the geometry without losing its aspect ratio. Can some help me to solve this?
I am also attaching the link of fiddle and code: link to fiddle
var camera, scene, renderer;
var geometry, material, muesum;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 600;
scene = new THREE.Scene();
geometry = new THREE.IcosahedronGeometry(350, 2);
material = new THREE.MeshPhongMaterial({
wireframe: true,
});
muesum = new THREE.Mesh(geometry, material);
scene.add(muesum);
muesum.position.setY(-300);
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
muesum.rotation.x += 0.001;
muesum.rotation.y += 0.002;
renderer.clear();
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>
What you call "losing its aspect ratio.", is the perspective projection, of an big object, that is very close to the camera.
If you don't want that, then you have to use the OrthographicCamera, which creates an orthographic projection matrix and projects the scene parallel on the viewport.
See the Example:
var camera, scene, renderer;
var geometry, material, muesum;
init();
animate();
function updateCameraProjection() {
var aspect = window.innerWidth / window.innerHeight;
var wndHeight = 700;
camera.right = aspect*wndHeight/2
camera.left = -camera.right;
camera.top = wndHeight/2;
camera.bottom = -camera.top;
camera.near = 1;
camera.far = 1000;
camera.updateProjectionMatrix();
}
function init() {
camera = new THREE.OrthographicCamera();
updateCameraProjection();
camera.position.z = 500;
scene = new THREE.Scene();
geometry = new THREE.IcosahedronGeometry(350, 2);
material = new THREE.MeshPhongMaterial({
wireframe: true,
});
muesum = new THREE.Mesh(geometry, material);
scene.add(muesum);
muesum.position.setY(camera.bottom);
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
updateCameraProjection();
muesum.position.setY(camera.bottom);
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
muesum.rotation.x += 0.001;
muesum.rotation.y += 0.002;
renderer.clear();
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>

how i rotate cube on button click in three.js?

here is my code...cube is a perfect but i want rotate on button click.
eg..when i click front button then cube will be show front side same as other button
I did a lot of research but i did not find any solution
please anyone can help me..
var scene, camera, renderer, cube;
init();
//drag();
function init() {
// renderer
var container = document.getElementById("container");
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor ('#fff', 1);
container.appendChild(renderer.domElement);
// camera
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.x = 50;
camera.position.y = 50;
camera.position.z = 800;
//cube
var geometry = new THREE.BoxBufferGeometry(250, 350, 100,1,1,1);
var cubeMaterial = new THREE.MeshLambertMaterial({color:"red"});
cube = new THREE.Mesh(geometry, cubeMaterial);
//cube.doubleSided = true;
cube.rotation.x = Math.PI / 1.5;
cube.rotation.y = Math.PI / 1;
// scene
scene = new THREE.Scene();
scene.add(cube);
// add subtle ambient lighting
var ambientLight = new THREE.AmbientLight(0x888888);
scene.add(ambientLight);
// directional lighting
var directionalLight = new THREE.DirectionalLight(0x666666);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
function render() {
renderer.render(scene, camera);
//requestAnimFrame(render);
requestAnimationFrame(render);
}
render();
}
body {
margin: 0px;
}
#container {
width: 100%;
height: 100%;
}
<script src="https://rawgit.com/mrdoob/three.js/r86/build/three.min.js"></script>
<div id="container"></div>
You already have code which does some rotation:
cube.rotation.x = Math.PI / 1.5;
cube.rotation.y = Math.PI / 1;
Make yourself a set of functions which rotate the object to the desired angles and call them on buttons' clicks.

Categories