Can't animate wireframe rotation in Three.js - javascript

I tried to make the wireframe rotate in the scene.
The animation works when I removed the BoxHelper, but I want to animate the cube wireframe without diagonal line instead of a solid object.
Codepen demo :
Demo
Code :
var w = window.innerWidth, h = window.innerHeight,
scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(75, w/h, 0.1, 1000),
renderer = new THREE.WebGLRenderer(),
geometry = new THREE.BoxGeometry( 1, 1, 1 ),
material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ),
mesh = new THREE.Mesh( geometry, material ),
cube = new THREE.BoxHelper(mesh);
cube.material.color.setRGB(25,25,25);
scene.add(cube);
camera.position.z = 2;
renderer.setSize(w,h);
document.body.appendChild(renderer.domElement);
function render(){
requestAnimationFrame( render );
cube.rotation.x += 1;
renderer.render(scene, camera );
}
render();

The position of your THREE.BoxHelper instance is tied to the position of the THREE.Mesh. For your code to work you will have to add the mesh to the scene and rotate the mesh. Your box helper will follow.
If you don't want to show the mesh you can simply set mesh.visible = false;
This code works:
var w = window.innerWidth, h = window.innerHeight,
scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(75, w/h, 0.1, 1000),
renderer = new THREE.WebGLRenderer(),
geometry = new THREE.BoxGeometry( 1, 1, 1 ),
mesh = new THREE.Mesh( geometry );
camera.position.z = 2;
renderer.setSize(w,h);
document.body.appendChild(renderer.domElement);
mesh.visible = false; //<-- hide mesh
scene.add(mesh); //<-- add mesh to scene
cube = new THREE.BoxHelper(mesh);
cube.material.color.setRGB(25,25,25);
scene.add(cube);
function render(){
mesh.rotation.y += 0.01; //<-- rotate the mesh
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();

Related

spotLight not attached to camera properly

I'm still struggling with getting spotLight to stick to the camera. I can see the light but looks like it stays at one place (?).
See the video for reference
//Camera
camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 1, 0 );
//spotLight attached to camera
spotlight = new THREE.SpotLight( 0xffffff, 55 );
spotlight.angle = 0.20*(Math.PI / 3);
spotlight.penumbra = 0.1;
spotlight.decay = 2;
spotlight.distance = 200;
camera.add( spotlight);
camera.add( spotlight.target );
spotlight.target.position.set( 0, 0, 1 );
spotlight.target=camera;
spotlight.position.copy( camera.position );
controls = new PointerLockControls( camera, document.body );
//adding first person camera from PointerLockControls
scene.add( controls.getObject() );
I also tried grouping camera and spotlight:
const group = new THREE.Group();
group.add(camera);
group.add(spotlight);
spotlight.target=camera;
spotlight.position.copy( camera.position );
controls = new PointerLockControls( group, document.body );
but that did not work either. What should I change? What's missing here?
//edit this is what my current code looks like
import * as THREE from "../node_modules/three/build/three.module.js";
import { GUI } from './jsm/libs/dat.gui.module.js';
let renderer, scene, camera, gui;
let spotlight, lightHelper;
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set(0,0,1);
const boxgeometry = new THREE.BoxGeometry( 25, 25, 25 );
const boxmaterial = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cube = new THREE.Mesh( boxgeometry, boxmaterial );
scene.add( cube );
cube.position.set(-20,0,1);
const ambient = new THREE.AmbientLight( 0xffffff, 0.2 );
scene.add(ambient);
**scene.add(camera);
spotlight = new THREE.SpotLight(0xffffff, 55, 80, 0.8*Math.PI);
camera.add(spotlight);
camera.add(spotlight.target);**
let material = new THREE.MeshPhongMaterial( { color: 0x808080, dithering: true } );
let geometry = new THREE.PlaneGeometry( 2000, 2000 );
let floor= new THREE.Mesh( geometry, material );
floor.position.set( 0, - 1, 0 );
floor.rotation.x = - Math.PI * 0.5;
floor.receiveShadow = true;
scene.add(floor);
render();
window.addEventListener( 'resize', onWindowResize );
}
function animate()
{
requestAnimationFrame( animate );
camera.rotation.y+=0.01;
renderer.render( scene, camera );
}
animate();
The setup should look like so:
let camera, scene, renderer;
init();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 1;
scene = new THREE.Scene();
scene.add(camera);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);
const spotLight = new THREE.SpotLight(0xffffff, 0.6, 0, Math.PI * 0.05);
camera.add(spotLight);
const geometry = new THREE.PlaneGeometry();
const material = new THREE.MeshPhongMaterial();
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animation);
document.body.appendChild(renderer.domElement);
}
function animation(time) {
const t = time * 0.001;
camera.position.x = Math.sin(t) * 0.25;
camera.position.y = Math.cos(t) * 0.25;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.134.0/build/three.min.js"></script>
It's important to add the spot light as a child to the camera and the camera itself to the scene.

Can't see simple geometry in the scene

Apologies - as this may be quite an easy solve. I have the following code, however can't seem to see the BoxGeometry in the scene. The red scene shows up fine
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(0, window.innerWidth / window.innerHeight, 0.1, 1000);
var color = new THREE.Color(0xff0000);
scene.background = color;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial(
{
color: 0x00ff00
}
)
var cube = new THREE.Mesh( geometry, material);
scene.add( cube );
camera.position.z = 5;
function animate(){
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
The only errors in my console are "THREE.WebGLRenderer 79" and "DevTools failed to parse SourceMap"
So turns out the PerspectiveCamera first variable needs to be e.g. 75 and not 0.

THREE.js LineSegments with multimaterial support

In my project I am creating LineSegments (LineMesh) with modified geometry (changing the vertex positions) from another mesh and with MeshBasicMaterialwith black color.Adding the LineMesh to the already existing Mesh.
Everything works fine.
But now I want to hide particular part of the mesh by setting visible property to false by taking the materialIndex from the faces of geometry.But in this, the previously created mesh is hiding but LineMesh added to it is not hiding.
Is it possible to hide particular part of LineMesh and also wanted to know whether LineMesh will support MultiMaterial.So that it will be easy for me to apply visibility, transparent property to particular part of Mesh.
var mesh, renderer, scene, camera, materials;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 300;
camera.lookAt( scene.position );
// directional
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );
// ambient
var ambient = new THREE.AmbientLight( 0x222222 );
scene.add( ambient );
// geometry
var geometry = new THREE.BoxGeometry( 100, 100, 100, 4, 4, 4 );
// materials
materials = [
new THREE.MeshLambertMaterial( { color: 0xffff00, side: THREE.DoubleSide } ),
new THREE.MeshBasicMaterial( { color: 0x00ffff, side: THREE.DoubleSide } )
];
// assign material to each face
for( var i = 0; i < geometry.faces.length; i++ ) {
geometry.faces[ i ].materialIndex = THREE.Math.randInt( 0, 1 );
}
geometry.sortFacesByMaterialIndex(); // optional, to reduce draw calls
// mesh
mesh = new THREE.Mesh( geometry, materials );
scene.add( mesh );
mat = new THREE.LineBasicMaterial({color: 0x000000});
mesh2= new THREE.LineSegments(geometry, mat);
mesh.add(mesh2);
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
mesh.rotation.z += 0.03;
renderer.render( scene, camera );
}
This below code is not to be working for LineSegments
mesh2= new THREE.LineSegments(geometry, new THREE.MultiMaterial(materials));

Plane always black

I want to add a texture to my plane that repeats horizontal and vertical. The thing is, when I try to apply the texture, it is always black. I don't get any errors, and i already tried to add some lights, but the problem is still there; I don't know how to solve it... Here is what I did:
window.onload = function init()
{
scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
var spotlight = new THREE.SpotLight( 0xffffff);
spotlight.position.set( -50, 40, 0 );
scene.add( spotlight );
var axes = new THREE.AxisHelper( 20 ); scene.add(axes);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xEEEEEE);
renderer.setSize(window.innerWidth, window.innerHeight);
desenhaMapa();
document.body.appendChild( renderer.domElement );
renderer.render(scene, camera);
}
function desenhaMapa()
{
labirinto = new THREE.Object3D();
var texturaPlano = new THREE.TextureLoader().load("texturaPac.jpg");
geometryPlano = new THREE.PlaneGeometry(50,50);
materialPlano = new THREE.MeshPhongMaterial( {map: texturaPlano} );
var planoPacMan = new THREE.Mesh(geometryPlano,materialPlano);
planoPacMan.rotation.x = -0.5 * Math.PI;
scene.add(planoPacMan);
}
Any suggestions?
TextureLoader.load() is an asynchronous method. That is why it has an onload argument.
You are calling render() before the texture loads. One solution is to call render() in the loader callback.
var loader = new THREE.TextureLoader();
var texture = loader.load( 'myTexture.jpg', function ( texture ) {
renderer.render( scene, camera );
} );
Another solution is to have an animation loop. But that is not required for static scenes.
three.js r.78

Three.js not rendering texture on external model properly

I am trying to create a very realistic scene using Three.js. So far I have implemented mouse controls, loading model from Maya and I came to applying textures. The code works however, as it can be seen on the images below the textures don't fill the box as one would expect. I assume the problem is because each face of the model is filled separately, which occurred to me when I displayed my model as in wireframe mode.
My UV values look like this :
[[0.375,0,0.625,0,0.375,0.25,0.625,0.25,0.375,0.5,0.625,0.5,0.375,0.75,0.625,0.75,0.375,1,0.625,1,0.875,0,0.875,0.25,0.125,0,0.125,0.25]]
function init() {
// renderer
renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.getElementById('container');
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10000 );
camera.position.z = 5;
cameraControls = new THREE.TrackballControls(camera, renderer.domElement);
cameraControls.target.set(0, 0, 0);
scene = new THREE.Scene();
light = new THREE.AmbientLight( 0xffffff );
scene.add( light );
material = new THREE.MeshPhongMaterial( {
map: THREE.ImageUtils.loadTexture('images/box_texture.jpg')
} );
group = new THREE.Object3D();
var loader = new THREE.JSONLoader();
loader.load('models/cube_1.js', modelLoadedCallback);
window.addEventListener( 'resize', onWindowResize, false );
}
function modelLoadedCallback(geometry) {
mesh = new THREE.Mesh( geometry, material );
group.add(mesh);
// scene.add (new THREE.Mesh (geometry,
// new THREE.MeshBasicMaterial ({ color: 0x000000, wireframe: true })));
scene.add (new THREE.Mesh (geometry, material));
scene.add( group );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
function animate() {
var delta = clock.getDelta();
requestAnimationFrame(animate);
cameraControls.update(delta);
renderer.render(scene, camera);
}
It can be helpful
var texture = THREE.ImageUtils.loadTexture('images/box_texture.jpg') ;
and add:
texture.flipY = false;

Categories

Resources