I am trying to add 2 different point lights in my project but it is giving me an error as above at the second declaration with a different name.
`// Lights
const pointLight = new THREE.PointLight(0xffffff, 0.1);
pointLight.position.x = 2;
pointLight.position.y = 3;
pointLight.position.z = 4;
scene.add(pointLight);
const newpointLight = new THREE.PointLight(0xff0000, 2)
//error in the above line "Identifier 'pointLight' has already been declared (42:6)"
newpointLight.intensity=1;
scene.add(newpointLight)`
Related
I'm trying to set the position of my directional light shadow camera to be the same as my main perspective camera in the render loop:
sunlight = new THREE.DirectionalLight(0xffffff, 1);
sunlight.position.x = camera.position.x ;
sunlight.position.y = 300;
sunlight.position.z = camera.position.z ;from top
sunlight.castShadow = true;
sunlight.shadow.mapSize.width = 2048 ;
sunlight.shadow.mapSize.height = 2048 ;
sunlight.shadow.bias = -0.0027;
sunlight.shadow.camera.left = -75;
sunlight.shadow.camera.right = 75;
sunlight.shadow.camera.top = 75;
sunlight.shadow.camera.bottom = -75;
sunlight.shadow.camera.position = camera.position;
sunlight.shadow.camera.far = sunlight.position.distanceTo(scene.position) + 20;
sunlight.shadow.camera.near = sunlight.position.distanceTo(scene.position) - (camera.position.y * 2);
sunlight.shadow.camera.updateProjectionMatrix();
function render() {
renderer.render(scene, camera);
sunlight.shadow.camera.position = camera.position;
sunlight.shadow.camera.updateProjectionMatrix();
}
However the shadow camera does not move at all. Is it possible to update the position of a shadow camera during run-time?
The shadow.camera is more of an internal component to the sunlight.
The way to move the sunlight so that it follows the camera is more something like this:
sunlight.position.copy( camera.position );
sunlight.target.copy( camera.position );
sunlight.position.y += 20;
this ^ should make the sunlight stay above the camera, pointing down, at a distance of 20 units.
Also your shadow.camera.near / far setup looks a little weird.
I would just set those to something like
light.shadow.camera.near = 0.5;
light.shadow.camera.far = 50.0;
..or something like that.
I have made a scene with three.js in which I make use of a PointLight.
var distance = 10000;
var intensity = 10;
var decay = 0;
var hex = 0xFFFFFF;
var light1 = new THREE.PointLight(hex, intensity, distance, decay);
I want to use shadows, so I added
light1.shadow.camera.near = 200;
light1.shadow.camera.far = 10000;
light1.shadow.camera.fov = 90;
light1.shadow.bias = -0.00022;
light1.shadow.mapSize.width = 1024;
light1.shadow.mapSize.height = 1024;
Until here everything worked perfect. However, as soon as I include in the next line:
light1.castShadow = true;
Then the distance visibly changes from 10000 to 1000.
If I call the distance from light1 to the console, it is still 10000. Even though it is not like that in the canvas.
(I have changed it to a ~50-digit number with no change in distance)
Any suggestions on how to solve this?
You can try to create a shadow via THREE.Texture(), in this way the shadow will be an independent element and shouldn't influence the position of the PointLight.
var shadowTexture = new THREE.Texture(canvas);
shadowTexture.needsUpdate = true;
var shadowMaterial = new THREE.MeshBasicMaterial({map: shadowTexture, opacity: 0.5});
var shadowGeo = new THREE.PlaneBufferGeometry(100, 100, 100, 1);
// Locate the position of the shadows
mesh = new THREE.Mesh(shadowGeo, shadowMaterial);
mesh.position.y = 0;
mesh.rotation.x = - Math.PI / 2;
scene.add( mesh );
I am applying the shadow to a PlaneGeometry since I assume that the shadow is casted on the scene. In any case, give also a look at this example concerning shadows in a scene.
I am trying to tile the texture from multiple images onto a plane geometry using MeshFaceMaterial. Every thing works fine, except for a blurry edge forming in between tiles.
.
var textureArray = [];
var tileColumns = 2;
var tileRows = 1;
textureArray[0] = THREE.ImageUtils.loadTexture('./test3.jpg');
textureArray[1] = THREE.ImageUtils.loadTexture('./test4.jpg');
var faceCountPerTileX = 2 * widthSegments/tileColumns;
var faceCountPerTileY = heightSegments/tileRows;
var faceCountX = 2 * widthSegments;
var faceCountY = heightSegments;
for(var tileIndexY = 0; tileIndexY < tileRows; tileIndexY++){
for(var tileIndexX = 0; tileIndexX < tileColumns; tileIndexX++){
var index = tileIndexY * tileColumns + tileIndexX;
textureArray[index].wrapS = THREE.RepeatWrapping;
textureArray[index].wrapT = THREE.RepeatWrapping;
textureArray[index].repeat.set(tileColumns,tileRows);
materialContainer[tileIndexY * tileColumns + tileIndexX] = new THREE.MeshBasicMaterial({
map: textureArray[tileIndexY * tileColumns + tileIndexX],
overdraw: true,
ambient: 0xffffff
});
for(var faceIndexY = tileIndexY * faceCountPerTileY; faceIndexY < (tileIndexY+1) * faceCountPerTileY; faceIndexY++){
for(var faceIndexX = tileIndexX * faceCountPerTileX; faceIndexX < (tileIndexX+1) * faceCountPerTileX; faceIndexX++){
g.faces[faceIndexY * faceCountX + faceIndexX].materialIndex = tileIndexY * tileColumns + tileIndexX;
}
}
}
}
var mat = new THREE.MeshFaceMaterial(materialContainer);
var obj = new THREE.Mesh(g, mat);
I have tried all known solutions, i have even tried writing a custom shader and using ShaderMaterial. But no luck, can some help me out to fix the issue?
By the looks of it, you set the texture mode of the invidual textures in your set to repeat.
This seems wrong, the individual textures do not repeat, they are displayed only once. Setting a texture to repeat causes the right side of the texture to "blend through" on the left (and vice versa), causing visible seams like the one on your screenshot.
I'm attempting to create a randomly distributed particle field that exhibits Brownian (random) motion.
Scroll to the bottom of the code to see where the error happens. I'm trying to set the position of a single vertex with position.x.
I'll omit the rest of the code not directly related to rendering the particles in effort to save your time.
//Using WebGL renderer...
var particle, particles = [], particle_system, material, p_x, p_y, p_z;
particles = new THREE.Geometry();
material = new THREE.ParticleBasicMaterial({color: 0xffffff, size: 1});
for(var count = 0; count < 1000; count++){
p_x = Math.random() * 1000 - 500;
p_y = Math.random() * 1000 - 500;
p_z = Math.random() * 1000 - 500;
particle = new THREE.Vector3(p_x, p_y, p_z);
particles.vertices.push(particle);
}
particle_system = new THREE.ParticleSystem(particles, material);
scene.add(particle_system);
particle_system.geometry.dynamic = true;
//All of the code bellow will go into the render loop.
var index = 0;
while(index < 1000){
index++;
particle_system.geometry.verticiesNeedUpdate = true;
//THESE 3 LINES BELLOW CAUSE THE ERROR
particles.vertices[index].position.x += Math.random() * 1000 - 500;
particles.vertices[index].position.y += Math.random() * 1000 - 500;
particles.vertices[index].position.z += Math.random() * 1000 - 500;
}
verticiesNeedUpdate should be spelled verticesNeedUpdate
your while loop is wrongly incrementing the index variable before it is used. So in the last iteration (when index == 999) you try to access particles.vertices[1000] which is not defined
I think this picture best explains my issue:
First I translate the box along the red line. Next, I want the effect of rotation to be the blue line in a, but what's actually happening is more like the blue line in b. It feels like changing the rotation is always relative to the original object space, but the translation (despite happening first) is always relative to the parent, and doesn't really affect the geometry points in relation to the object space. I apologize if that's confusing; clearly I'm new at this.
The important part of the code which produces this effect is below. Please keep in mind that the orientation of the image is different than this code produces; the image is merely an example to show the effect clearly.
var objectContainer = new THREE.Object3D();
var tubeRadius = 100;
var tubeGeometry = new THREE.CylinderGeometry(tubeRadius, tubeRadius, tubeRadius * 3, 36, 1, false);
var tube = new THREE.Mesh(tubeGeomtry, material);
scene.add( tube );
var boxes = new THREE.Object3D();
var boxEdge = 50;
var boxGeometry = new THREE.CubeGeometry(boxEdge, boxEdge, boxEdge);
var box1 = new THREE.Mesh( boxGeometry, material );
box1.translateX(tubeRadius + boxEdge / 2 + 5);
box1.translateY(boxEdge / 2);
box1.rotation = new THREE.Vector3(0, 2*Math.PI/3*0, 0);
boxes.add(box1);
var box2 = box1.clone();
box2.rotation = new THREE.Vector3(0, 2*Math.PI/3*1, 0);
boxes.add(box2);
var box3 = box1.clone();
box3.rotation = new THREE.Vector3(0, 2*Math.PI/3*2, 0);
boxes.add(box3);
scene.add( boxes );
The only solution I can think of is to wrap each box in another object space and rotate about that, but it seems like excessive work. What is the preferred method to achieve the result I'm looking for?
There are several ways of doing what you want, but I think the easiest is like so:
// parent
parent = new THREE.Group();
scene.add( parent );
// pivots
var pivot1 = new THREE.Object3D();
var pivot2 = new THREE.Object3D();
var pivot3 = new THREE.Object3D();
pivot1.rotation.z = 0;
pivot2.rotation.z = 2 * Math.PI / 3;
pivot3.rotation.z = 4 * Math.PI / 3;
parent.add( pivot1 );
parent.add( pivot2 );
parent.add( pivot3 );
// mesh
var mesh1 = new THREE.Mesh( geometry, material );
var mesh2 = new THREE.Mesh( geometry, material );
var mesh3 = new THREE.Mesh( geometry, material );
mesh1.position.y = 5;
mesh2.position.y = 5;
mesh3.position.y = 5;
pivot1.add( mesh1 );
pivot2.add( mesh2 );
pivot3.add( mesh3 );
Then in your render loop:
parent.rotation.z += 0.01;
three.js r.147
Creating a compound object whose centre will be the point about which the inner objects rotate is one obvious answer, and would be very quick to write. Just create an Object3D and add your box to it.
A similar approach is covered by this question. It shifts the point of the vertices for an object, so it effectively has a new centre.
Alternatively, you can mess around with the matrices by hand. Try this:
var boxGeometry = new THREE.CubeGeometry(boxEdge, boxEdge, boxEdge);
var mr = new THREE.Matrix4();
var mt = new THREE.Matrix4();
mt.setPosition(new THREE.Vector3(0,tubeRadius,0));
var box1 = new THREE.Mesh( boxGeometry, material );
box1.applyMatrix(mt);
var box2 = box1.clone();
mr.makeRotationZ(2 * Math.PI /3);
box2.applyMatrix(mr);
boxes.add(box2);
var box3 = box1.clone();
mr.makeRotationZ(4 * Math.PI /3);
box3.applyMatrix(mr);
boxes.add(box3);
boxes.add(box1);
scene.add( boxes );