how to make a faced sphere in BuffererGeometry with three.js version after 125 - three.js

The purpose of the code is to make a faced sphere in three.js in the old version before version 125
// 1. the first step is Make a faceted cube
let geometry = new THREE.BoxGeometry(1, 1, 1, 64, 64, 64);
// 2. the second step is Normalize all vertices
for (var i in this.geometry.vertices) {
geometry.vertices[i].normalize().multiplyScalar(this.radius);
}
// geometry.makeGroups();
geometry.computeVertexNormals();
geometry.computeFaceNormals();
geometry.computeMorphNormals();
geometry.computeBoundingSphere();
geometry.computeBoundingBox();
// geometry.computeLineDistances();
geometry.verticesNeedUpdate = true;
geometry.elementsNeedUpdate = true;
geometry.uvsNeedUpdate = true;
geometry.normalsNeedUpdate = true;
// geometry.tangentsNeedUpdate = true;
geometry.colorsNeedUpdate = true;
geometry.lineDistancesNeedUpdate = true;
// geometry.buffersNeedUpdate = true;
geometry.groupsNeedUpdate = true;
After version 125, the geometry class is removed and have BuffererGeometry in place, how would I modify the code to make a sphere again?

You can transform a box into a sphere this way:
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.133.1";
import {OrbitControls} from "https://cdn.skypack.dev/three#0.133.1/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 0, 5);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera, renderer.domElement);
let g = new THREE.BoxGeometry(1, 1, 1, 64, 64, 64);
let pos = g.attributes.position;
let v3 = new THREE.Vector3();
let radius = 2;
for (let i = 0; i < pos.count; i++){
v3.fromBufferAttribute(pos, i).normalize().multiplyScalar(radius);
pos.setXYZ(i, v3.x, v3.y, v3.z);
}
g.computeVertexNormals();
let m = new THREE.MeshNormalMaterial({wireframe: true});
let o = new THREE.Mesh(g, m);
scene.add(o);
window.addEventListener("resize", () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeihgt);
});
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
</script>

Related

Make the plane draggable in ThreeJS

How to make the plane draggable in X , Y direction. Here I'm trying to work on box clipping where I draw a plane on X and Y direction. But I have no idea how to make it draggable to the particular direction. Can anyone help me put with the issue.
I want to make the plane to be draggable only in the own direction on mouse event
import * as THREE from '../build/three.module.js';
import Stats from './jsm/libs/stats.module.js';
import { GUI } from './jsm/libs/dat.gui.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { DragControls } from './jsm/controls/DragControls.js';
var camera, scene, renderer, startTime, object, stats;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(36, window.innerWidth / window.innerHeight, 0.0001, 100000);
camera.position.set(0, 1.3, 8);
scene = new THREE.Scene();
// Lights
scene.add(new THREE.AmbientLight(0x505050));
scene.background = new THREE.Color('white')
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.angle = Math.PI / 5;
spotLight.penumbra = 0.2;
spotLight.position.set(2, 3, 3);
spotLight.castShadow = true;
spotLight.shadow.camera.near = 3;
spotLight.shadow.camera.far = 10;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
scene.add(spotLight);
var dirLight = new THREE.DirectionalLight(0x55505a, 1);
dirLight.position.set(0, 3, 0);
dirLight.castShadow = true;
dirLight.shadow.camera.near = 1;
dirLight.shadow.camera.far = 10;
dirLight.shadow.camera.right = 1;
dirLight.shadow.camera.left = - 1;
dirLight.shadow.camera.top = 1;
dirLight.shadow.camera.bottom = - 1;
dirLight.shadow.mapSize.width = 1024;
dirLight.shadow.mapSize.height = 1024;
scene.add(dirLight);
// ***** Clipping planes: *****
var localPlane = new THREE.Plane(new THREE.Vector3(0, - 1, 0), 1.5);
var helper1 = new THREE.PlaneHelper(localPlane, 3, 0xffff00);
scene.add(helper1);
var globalPlane = new THREE.Plane(new THREE.Vector3(- 1, 0, 0), 1);
var helper = new THREE.PlaneHelper(globalPlane, 3, 0xffff00);
scene.add(helper); // Geometry
var material = new THREE.MeshPhongMaterial({
color: 0x80ee10,
shininess: 100,
side: THREE.DoubleSide,
// ***** Clipping setup (material): *****
clippingPlanes: [localPlane],
clipShadows: true
});
var geometry = new THREE.TorusKnotBufferGeometry(0.4, 0.08, 95, 20);
object = new THREE.Mesh(geometry, material);
object.castShadow = true;
scene.add(object);
var ground = new THREE.Mesh(
new THREE.PlaneBufferGeometry(9, 9, 1, 1),
new THREE.MeshPhongMaterial({ color: 0xa0adaf, shininess: 150 })
);
ground.rotation.x = - Math.PI / 2; // rotates X/Y to X/Z
ground.receiveShadow = true;
// scene.add( ground );
// Stats
stats = new Stats();
document.body.appendChild(stats.dom);
// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.shadowMap.enabled = true;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
window.addEventListener('resize', onWindowResize, false);
document.body.appendChild(renderer.domElement);
// ***** Clipping setup (renderer): *****
var globalPlanes = [globalPlane],
Empty = Object.freeze([]);
renderer.clippingPlanes = Empty; // GUI sets it to globalPlanes
renderer.localClippingEnabled = true;
renderer.clippingPlanes = globalPlanes;
// Controls
var controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 1, 0);
controls.update();
// controls1 = new DragControls([...globalPlane], camera, renderer.domElement);
// controls1.addEventListener('drag', render);
// GUI
var gui = new GUI(),
folderLocal = gui.addFolder('Local Clipping'),
propsLocal = {
get 'Enabled'() {
return renderer.localClippingEnabled;
},
set 'Enabled'(v) {
renderer.localClippingEnabled = v;
},
get 'Shadows'() {
return material.clipShadows;
},
set 'Shadows'(v) {
material.clipShadows = v;
},
get 'Plane'() {
return localPlane.constant;
},
set 'Plane'(v) {
localPlane.constant = v;
}
},
folderGlobal = gui.addFolder('Global Clipping'),
propsGlobal = {
get 'Enabled'() {
console.log('hitting 1')
return renderer.clippingPlanes !== Empty;
console.log(renderer.clippingPlanes);
},
set 'Enabled'(v) {
console.log('hitting 2')
renderer.clippingPlanes = v ? globalPlanes : Empty;
console.log(renderer.clippingPlanes);
},
get 'Plane'() {
return globalPlane.constant;
},
set 'Plane'(v) {
globalPlane.constant = v;
}
};
folderLocal.add(propsLocal, 'Enabled');
folderLocal.add(propsLocal, 'Shadows');
folderLocal.add(propsLocal, 'Plane', 0.3, 1.25);
folderGlobal.add(propsGlobal, 'Enabled');
folderGlobal.add(propsGlobal, 'Plane', - 0.4, 3);
// Start
startTime = Date.now();
document.addEventListener('click', onClick, false);
}
function onClick(event) {
event.preventDefault();
if (enableSelection === true) {
var draggableObjects = controls.getObjects();
draggableObjects.length = 0;
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersections = raycaster.intersectObjects(objects, true);
if (intersections.length > 0) {
var object = intersections[0].object;
if (group.children.includes(object) === true) {
object.material.emissive.set(0x000000);
scene.attach(object);
} else {
object.material.emissive.set(0xaaaaaa);
group.attach(object);
}
controls.transformGroup = true;
draggableObjects.push(group);
}
if (group.children.length === 0) {
controls.transformGroup = false;
draggableObjects.push(...objects);
}
}
render();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
// var currentTime = Date.now();
// var time = ( currentTime - startTime ) / 1000;
requestAnimationFrame(animate);
// object.position.y = 0.8;
// object.rotation.x = time * 0.5;
// object.rotation.y = time * 0.2;
// object.scale.setScalar( Math.cos( time ) * 0.125 + 0.875 );
stats.begin();
renderer.render(scene, camera);
stats.end();
}
In order to move things in three.js you use TransformControls. Check out https://threejs.org/docs/#examples/en/controls/TransformControls for its documentation and https://github.com/mrdoob/three.js/blob/master/examples/misc_controls_transform.html for implementation example.
Here you can set the mode to "translate" and scale to "XY" to restrict the movement in X and Y direction only.
controls.axis ="XY";

Rendered object looks flat even with shadows

I'm a three.js newb. I've been playing around with it for a couple of days and haven't been able to figure out how to make my objects look more realistic. I suspect there's no simple answer for this question, but is there anything I can do to improve my rendering quality without going into the depth of "rendering science"? Maybe I'm missing some configs. Thank you for any advice!
Here's the relevant code used in rendering a kitchen cabinet frame.
this.renderer = new THREE.WebGLRenderer({ antialias: true })
this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight)
this.renderer.sortObjects = false
this.renderer.setClearColor(0xf0f0f0)
this.renderer.gammaFactor = 2.2
this.renderer.gammaOutput = true
this.renderer.setPixelRatio(window.devicePixelRatio)
this.renderer.shadowMap.enabled = true
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
const light = new THREE.AmbientLight(0xffffff, 0.8)
const light2 = new THREE.PointLight(0xffffff, 0.3)
light2.position.set(400, 400, 400)
light2.shadow.camera.near = 10
light2.shadow.camera.far = 10000
light2.shadow.mapSize.width = 2048
light2.shadow.mapSize.height = 2048
light2.castShadow = true
this.scene.add(light2)
this.scene.add(light)
const material = new THREE.MeshStandardMaterial({ color: 0xffffff, metalness: 0, roughness: 0 })
let scene, camera, controls, ambient, point, loader, renderer, container, stats;
const targetRotation = 0;
const targetRotationOnMouseDown = 0;
const mouseX = 0;
const mouseXOnMouseDown = 0;
const windowHalfX = window.innerWidth / 2;
const windowHalfY = window.innerHeight / 2;
init();
animate();
var box, b1, b2, b3;
function init() {
// Create a scene which will hold all our meshes to be rendered
scene = new THREE.Scene();
// Create and position a camera
camera = new THREE.PerspectiveCamera(
60, // Field of view
window.innerWidth / window.innerHeight, // Aspect ratio
/*window.innerWidth / -8,
window.innerWidth / 8,
window.innerHeight / 8,
window.innerHeight / -8,
*/
0.1, // Near clipping pane
1000 // Far clipping pane
);
scene.add(camera)
// Reposition the camera
camera.position.set(0, 5, 10);
// Point the camera at a given coordinate
camera.lookAt(new THREE.Vector3(0, 0, 0));
// Add orbit control
controls = new THREE.OrbitControls(camera);
controls.target.set(0, -0.5, 0);
controls.update();
// Add an ambient lights
ambient = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambient);
// Add a point light that will cast shadows
point = new THREE.PointLight(0xffffff, 1);
point.position.set(25, 50, 25);
point.castShadow = true;
point.shadow.mapSize.width = 1024;
point.shadow.mapSize.height = 1024;
scene.add(point);
group = new THREE.Group();
group.position.y = 0;
scene.add(group);
rotationAnchor = new THREE.Object3D()
group.add(rotationAnchor);
box = new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshStandardMaterial({
color: 'grey'
}))
b1 = box.clone();
b2 = box.clone();
b3 = box.clone();
b3.material = b3.material.clone()
b3.material.color.set('red')
group.add(box);
group.add(b1);
b1.position.y += 1
group.add(b2);
b2.position.z += 1
rotationAnchor.add(b3);
rotationAnchor.position.set(0.5, 0.5, 1.5)
b3.position.set(-.5, -.5, -.5)
// Create a renderer
renderer = new THREE.WebGLRenderer({
antialias: true
});
// Set size
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// Set color
renderer.setClearColor(0xf8a5c2);
renderer.gammaOutput = true;
// Enable shadow mapping
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// Append to the document
container = document.createElement("div");
document.body.appendChild(container);
document.body.appendChild(renderer.domElement);
// Add resize listener
window.addEventListener("resize", onWindowResize, false);
// Enable FPS stats
stats = new Stats();
container.appendChild(stats.dom);
var gui = new dat.GUI({
height: 5 * 32 - 1
});
let params = {
'test': 4,
'bevelThickness': 1,
'bevelSize': 1.5,
'bevelSegments': 3
}
gui.add(params, 'test', 0, 10).onChange(val => {
test = val
})
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
rotationAnchor.rotation.z = (Math.cos(performance.now() * 0.001) * Math.PI * 0.25) + (Math.PI * 1.25)
requestAnimationFrame(animate);
// Re-render scene
renderer.render(scene, camera);
// Update stats
stats.update();
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.2/dat.gui.min.js"></script>

Two objects don't cast a shadow while other one does

I have exactly the same three cube objects except their x position.
I want them to cast a shadow, but somehow two of them don't cast a shadow while the other one does.
Here is the pic of what's happening.
https://ibb.co/z6Vwxmf
I'm sure that castShadow is set to true on all the objects.
And I don't think I missed any shadow setting property either (because the middle object casts a shadow properly.)
These objects are created under //left cube //right cube comments in the below code.
< script >
window.addEventListener('load', init, false);
function init(event) {
createScene();
createLights();
createTile01();
createTile02();
createTile03();
createBase();
loop();
}
var scene, camera, Width, Height, renderer, container;
function createScene() {
Width = window.innerWidth;
Height = window.innerHeight;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 0;
camera.position.y = 10;
camera.position.z = 50;
camera.lookAt(scene.position);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(Width, Height);
renderer.shadowMap.enabled = true;
container = document.getElementById('scene');
container.appendChild(renderer.domElement);
window.addEventListener('resize', handleWindowResize, false);
}
function handleWindowResize() {
Height = window.InnerHeight;
Width = window.InnerWidth;
renderer.setSize(Width, Height);
camera.aspect = Width / Height;
camera.updateProjectionMatrix();
}
var ambiLight, spotLight;
function createLights() {
ambiLight = new THREE.AmbientLight(0xffffff);
scene.add(ambiLight);
spotLight = new THREE.DirectionalLight(0xffffff);
spotLight.position.set(0, 30, -0);
spotLight.intensity = 1;
spotLight.castShadow = true;
scene.add(spotLight);
}
Tile01 = function() {
var geom = new THREE.BoxGeometry(10, 10, 2);
var mat = new THREE.MeshPhongMaterial({
color: 0x53b0df
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.receiveShadow = true;
this.mesh.castShadow = true;
}
var tile01;
function createTile01() {
tile01 = new Tile01();
tile01.mesh.position.set(0, 0, 0);
scene.add(tile01.mesh);
}
//right cube
Tile02 = function() {
var geom = new THREE.BoxGeometry(10, 10, 2);
var mat = new THREE.MeshPhongMaterial({
color: 0x25b0cf
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.receiveShadow = true;
this.mesh.castShadow = true;
}
var tile02;
function createTile02() {
tile02 = new Tile02();
tile02.mesh.position.set(20, 0, 0);
scene.add(tile02.mesh);
}
//left cube
Tile03 = function() {
var geom = new THREE.BoxGeometry(10, 10, 2);
var mat = new THREE.MeshPhongMaterial({
color: 0x00b0df
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.receiveShadow = true;
this.mesh.castShadow = true;
}
var tile03;
function createTile03() {
tile03 = new Tile03();
tile03.mesh.position.set(-20, 0, 0);
scene.add(tile03.mesh);
}
Base = function() {
var geom = new THREE.CylinderGeometry(100, 30, 5, 60);
var mat = new THREE.MeshPhongMaterial({
color: 0xcf34ec
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.castShadow = true;
this.mesh.receiveShadow = true;
}
var base;
function createBase() {
base = new Base();
base.mesh.position.set(0, -10, -20);
scene.add(base.mesh);
}
function loop() {
renderer.render(scene, camera);
requestAnimationFrame(loop);
}
< /script>
Could you help me figure out what's wrong with the setting?
I was able to resolve the issue myself.
Referring to some solutions I found at other Q/As about a shadow issue, I added a shadow.camera.left/right/top/bottom properties to the light and it worked.
The below is the code I corrected.
Now I can see the shadows of all the three objects.
var ambiLight, spotLight;
function createLights() {
ambiLight = new THREE.AmbientLight(0xffffff);
scene.add(ambiLight);
spotLight = new THREE.DirectionalLight(0xffffff);
spotLight.position.set(0, 30, -0);
spotLight.intensity = 1;
spotLight.castShadow = true;
spotLight.shadow.camera.left = -400;
spotLight.shadow.camera.right = 400;
spotLight.shadow.camera.top = 400;
spotLight.shadow.camera.bottom = -400;
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 1000;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
scene.add(spotLight);
}

overlapping semitransparent objects are not rendered as expected

I have two overlapping semitransparent boxes and I'd expect to see both of them independent of the viewing angle. The first image shows a rendering from aside and the small box is visible within the bigger box. The second image shows the same scene but form another viewing angle. As you can see, the smaller box is visible but the part which is with the bigger box is invisible. What am I missing?
var camera, scene, renderer;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50);
camera.position.set(2, 2, 2);
camera.lookAt(new THREE.Vector3(0.0, 0.0, 0.0));
// Create scene.
scene = new THREE.Scene();
// Create material
var material = new THREE.MeshStandardMaterial();
material.transparent = true;
material.opacity = 0.5;
// Create cube and add to scene.
var geometry1 = new THREE.BoxGeometry(1, 1, 1);
var mesh1 = new THREE.Mesh(geometry1, material);
mesh1.position.set(0, 0, 0);
//mesh1.castShadow = true;
scene.add(mesh1);
// Create cube and add to scene.
var geometry2 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var mesh2 = new THREE.Mesh(geometry2, material);
mesh2.position.set(0.0, 0, 0.5);
//mesh2.castShadow = true;
scene.add(mesh2);
var spotLight = new THREE.SpotLight(0xffffff, 0.32);
spotLight.position.set(0, 5, 0);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.near = 0.1;
spotLight.shadow.camera.far = 20;
scene.add(spotLight);
let hemiLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.8);
scene.add(hemiLight);
// Ground plane
var groundGeo = new THREE.PlaneBufferGeometry(50, 50);
var groundMat = new THREE.MeshStandardMaterial({color: 0xffffff});
var ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -0.5;
ground.receiveShadow = true;
scene.add(ground);
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
let controls = new THREE.OrbitControls(camera);
controls.enableZoom = true;
controls.enablePan = false;
controls.maxDistance = 20.0;
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 2;
controls.target.set(0, 0, 0);
controls.update();
}
function animate() {
requestAnimationFrame(animate);
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/98/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Transparent objects in WebGL are sometimes rather problematic. It's all about the rendering order: If the small cube is rendered after the large cube, how should the rendering behave? This question has some information you might find useful.
In your particular case (though not necessarily always), one solution could be to disable renderer object sorting:
renderer.sortObjects = false;
and(!) make sure you add your objects in the correct order, i.e. the small cube first and the large one second. Here is an updated version of your snippet:
var camera, scene, renderer;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.sortObjects = false;
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50);
camera.position.set(2, 2, 2);
camera.lookAt(new THREE.Vector3(0.0, 0.0, 0.0));
// Create scene.
scene = new THREE.Scene();
// Create material
var material = new THREE.MeshStandardMaterial();
material.transparent = true;
material.opacity = 0.5;
// Create cube and add to scene.
var geometry2 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var mesh2 = new THREE.Mesh(geometry2, material);
mesh2.position.set(0.0, 0, 0.5);
//mesh2.castShadow = true;
scene.add(mesh2);
// Create cube and add to scene.
var geometry1 = new THREE.BoxGeometry(1, 1, 1);
var mesh1 = new THREE.Mesh(geometry1, material);
mesh1.position.set(0, 0, 0);
//mesh1.castShadow = true;
scene.add(mesh1);
var spotLight = new THREE.SpotLight(0xffffff, 0.32);
spotLight.position.set(0, 5, 0);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.near = 0.1;
spotLight.shadow.camera.far = 20;
scene.add(spotLight);
let hemiLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.8);
scene.add(hemiLight);
// Ground plane
var groundGeo = new THREE.PlaneBufferGeometry(50, 50);
var groundMat = new THREE.MeshStandardMaterial({color: 0xffffff});
var ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -0.5;
ground.receiveShadow = true;
scene.add(ground);
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
let controls = new THREE.OrbitControls(camera);
controls.enableZoom = true;
controls.enablePan = false;
controls.maxDistance = 20.0;
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 2;
controls.target.set(0, 0, 0);
controls.update();
}
function animate() {
requestAnimationFrame(animate);
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/98/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Three.js, moving a partical along an EllipseCurve

I know questions related to my problem have been asked and answered before but three.js changed a lot in the last couple years and I'm having trouble finding what I need in the currently available examples.
I have an elliptical curve that I'd like to run particles along. My code runs without error but it doesn't actually move the particle anywhere. What am I missing?
var t = 0;
var curve = new THREE.EllipseCurve( .37, .15, .35, .25, 150, 450, false, 0 );
var points = curve.getPoints( 50 );
var curveGeometry = new THREE.BufferGeometry().setFromPoints( points );
var particleGeometry = new THREE.Geometry();
var particleMap = new THREE.TextureLoader().load( "/img/spark.png" );
var vertex = new THREE.Vector3();
vertex.x = points[0].x;
vertex.y = points[0].y;
vertex.z = 0;
particleGeometry.vertices.push(vertex);
particleMaterial = new THREE.PointsMaterial({
size: .05,
map: particleMap,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent : true
});
particles = new THREE.Points( particleGeometry, particleMaterial );
scene.add(particles);
animate();
function animate() {
if (t <= 1) {
particles.position = curveGeometry.getPointAt(t)
t += 0.005
} else {
t = 0;
}
requestAnimationFrame( animate );
render();
}
function render() {
renderer.render( scene, camera );
}
Just a rough concept of how you can do it, using THREE.Geometry():
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 50);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0x404040);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var grid = new THREE.GridHelper(40, 40, "white", "gray");
grid.rotation.x = Math.PI * -0.5;
scene.add(grid);
var curve = new THREE.EllipseCurve(0, 0, 20, 20, 0, Math.PI * 2, false, 0);
// using of .getPoints(division) will give you a set of points of division + 1
// so, let's get the points manually :)
var count = 10;
var inc = 1 / count;
var pointAt = 0;
var points = [];
for (let i = 0; i < count; i++) {
let point = curve.getPoint(pointAt); // get a point of THREE.Vector2()
point.z = 0; // geometry needs points of x, y, z; so add z
point.pointAt = pointAt; // save position along the curve in a custom property
points.push(point);
pointAt += inc; // increment position along the curve for next point
}
var pointsGeom = new THREE.Geometry();
pointsGeom.vertices = points;
console.log(points);
var pointsObj = new THREE.Points(pointsGeom, new THREE.PointsMaterial({
size: 1,
color: "aqua"
}));
scene.add(pointsObj);
var clock = new THREE.Clock();
var time = 0;
render();
function render() {
requestAnimationFrame(render);
time = clock.getDelta();
points.forEach(p => {
p.pointAt = (p.pointAt + time * 0.1) % 1; // it always will be from 0 to 1
curve.getPoint(p.pointAt, p); //re-using of the current point
});
pointsGeom.verticesNeedUpdate = true;
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Resources