Exporting an animated scene with GLTFExporter in ThreeJS? - three.js

I'm trying to export an animation scene in ThreeJS with GLTFExporter, but the animation is not being exported. Everything is correctly exported, the shapes, the color... This project is using the example to export: https://threejs.org/examples/#misc_exporter_gltf, and the example to animate: https://threejs.org/examples/#misc_animation_keys, but they don't work together. Any idea?
If I open the file with https://gltf-viewer.donmccurdy.com/, I see an error:
But if I log the export options when exporting, I can see the animations are there:
Here's the code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - exporter - gltf</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<div id="info">
<button id="export_scene">Export Scene</button>
</div>
<script type="module">
import * as THREE from '../../build/three.module.js';
import { GLTFExporter } from './jsm/exporters/GLTFExporter.js';
function exportGLTF(input, animationClip) {
const gltfExporter = new GLTFExporter();
const options = {
binary: true,
maxTextureSize: 4096,
animations: [animationClip],
includeCustomExtensions: true
};
console.log(options);
gltfExporter.parse(input, function (result) {
if (result instanceof ArrayBuffer) {
saveArrayBuffer(result, 'scene.glb');
} else {
const output = JSON.stringify(result, null, 2);
console.log(output);
saveString(output, 'scene.gltf');
}
}, options);
}
document.getElementById('export_scene').addEventListener('click', function () {
exportGLTF(scene, clip);
});
const link = document.createElement('a');
link.style.display = 'none';
document.body.appendChild(link); // Firefox workaround, see #6594
function save(blob, filename) {
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
}
function saveString(text, filename) {
save(new Blob([text], { type: 'text/plain' }), filename);
}
function saveArrayBuffer(buffer, filename) {
save(new Blob([buffer], { type: 'application/octet-stream' }), filename);
}
let clock;
let camera, geometry, scene, renderer, mixer, clip;
let gridHelper, sphere, smallSphere;
init();
animate();
function init() {
scene = new THREE.Scene();
scene.name = 'scene';
// Perspective Camera
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.set(10, 300, 0);
camera.name = "PerspectiveCamera";
scene.add(camera);
// Ambient light
const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
ambientLight.name = 'AmbientLight';
scene.add(ambientLight);
// DirectLight
const dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.target.position.set(0, 0, - 1);
dirLight.add(dirLight.target);
dirLight.lookAt(- 1, - 1, 0);
dirLight.name = 'DirectionalLight';
scene.add(dirLight);
//Axes
/*
const axes = new THREE.AxesHelper(500);
axes.name = "AxesHelper";
scene.add(axes);*/
// Sphere
const material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true });
sphere = new THREE.Mesh(new THREE.SphereGeometry(70, 10, 10), material);
sphere.position.set(0, 0, 0);
sphere.name = "Sphere";
scene.add(sphere);
// Small sphere
smallSphere = new THREE.Mesh(new THREE.SphereGeometry(20, 10, 10), material);
smallSphere.position.set(80, 0, 0);
smallSphere.name = "SmallSphere";
scene.add(smallSphere);
// POSITION
const positionKF = new THREE.VectorKeyframeTrack('.position', [0, 1, 2], [0, 90, 60, 30, 0, 60, 70, 40, 50]);
// SCALE
const scaleKF = new THREE.VectorKeyframeTrack('.scale', [0, 1, 2], [1, 1, 1, 2, 2, 2, 1, 1, 1]);
// ROTATION
// Rotation should be performed using quaternions, using a THREE.QuaternionKeyframeTrack
// Interpolating Euler angles (.rotation property) can be problematic and is currently not supported
// set up rotation about x axis
const xAxis = new THREE.Vector3(1, 0, 0);
const qInitial = new THREE.Quaternion().setFromAxisAngle(xAxis, 0);
const qFinal = new THREE.Quaternion().setFromAxisAngle(xAxis, Math.PI);
const quaternionKF = new THREE.QuaternionKeyframeTrack('.quaternion', [0, 1, 2], [qInitial.x, qInitial.y, qInitial.z, qInitial.w, qFinal.x, qFinal.y, qFinal.z, qFinal.w, qInitial.x, qInitial.y, qInitial.z, qInitial.w]);
// COLOR
const colorKF = new THREE.ColorKeyframeTrack('.material.color', [0, 1, 2], [1, 0, 0, 0, 1, 0, 0, 0, 1], THREE.InterpolateDiscrete);
// OPACITY
const opacityKF = new THREE.NumberKeyframeTrack('.material.opacity', [0, 1, 2], [1, 0, 1]);
// Clip
clip = new THREE.AnimationClip('Action', 3, [scaleKF, positionKF, quaternionKF, colorKF, opacityKF]);
// Mixer
mixer = new THREE.AnimationMixer(smallSphere);
const clipAction = mixer.clipAction(clip);
clipAction.play();
// Clock
clock = new THREE.Clock();
// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
const timer = Date.now() * 0.0001;
const delta = clock.getDelta();
if (mixer) {
mixer.update(delta);
}
camera.position.x = Math.cos(timer) * 400;
camera.position.z = Math.sin(timer) * 400;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
</script>
</body>
</html>
Any idea?

As Don McCurdy explained in the comments, there were two problems:
It's not possible to export animations for the material properties (opacity and color).
I had to specify the object name before each pointer: <object-name>.position.
Thank you Don McCurdy.

You need to set a name to your Object3D:
const mesh = new THREE.Mesh(geometry, material);
mesh.name = 'myMesh'; // <- set a name
scene.add(mesh);
When you create your KeyframeTrack use that object's name:
const positionKF = new THREE.VectorKeyframeTrack('myMesh.position', times, values); // <-- use that object's name

Related

How to change variable after checking controller.userData

I'm working with Three.js on a project. I just started working with it and mostly tried my luck with picking different things from the examples.
In short: I'm loading a volume and want to show another layer of it after the event listener for one of the controllers fired.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js vr - dragging</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<div id="info">
three.js nrrd
</div>
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims#1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "../build/three.module.js",
"three/addons/": "./jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { VRButton } from 'three/addons/webxr/VRButton.js';
import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js';
import { NRRDLoader } from 'three/addons/loaders/NRRDLoader.js';
let camera, scene, renderer;
let controller1, controller2;
let raycaster;
let xlayer ;
const intersected = [];
const tempMatrix = new THREE.Matrix4();
let controls, group, array;
init();
animate();
function init() {
const container = document.createElement('div');
document.body.appendChild(container);
scene = new THREE.Scene();
scene.background = new THREE.Color(0x808080);
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 40);
camera.position.set(0, 1.6, 3);
controls = new OrbitControls(camera, container);
controls.target.set(0, 1.6, 0);
controls.update();
scene.add(new THREE.HemisphereLight(0x808080, 0x606060));
group = new THREE.Group();
array = [];
scene.add(group);
var holder = new THREE.Group();
const loader = new NRRDLoader();
loader.load('models/nrrd/retina.nrrd', function (volume) {
const a = volume.xLength;
const b = volume.yLength;
const c = volume.zLength;
//box helper to see the extend of the volume
const geometry = new THREE.BoxGeometry(volume.xLength, volume.yLength, volume.zLength);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.visible = false;
const box = new THREE.BoxHelper(cube);
holder.add(box);
box.applyMatrix4(volume.matrix);
holder.add(cube);
//z plane
const sliceZ = volume.extractSlice('z', xlayer);
holder.add(sliceZ.mesh);
holder.scale.set((1 / a) * 10, (1 / b) * 6, (1 / c) * 5);
holder.position.set(0, 0, -15);
scene.add(holder);
});
//l-left, r-right, t-top, b-bottom
const planegeometrylr = new THREE.PlaneGeometry(5, 6);
const planegeometrytb = new THREE.PlaneGeometry(10, 5);
const planematerial = new THREE.MeshBasicMaterial({ color: 'blue', side: THREE.DoubleSide });
const planel = new THREE.Mesh(planegeometrylr, planematerial);
const planer = new THREE.Mesh(planegeometrylr, planematerial);
const planet = new THREE.Mesh(planegeometrytb, planematerial);
const planeb = new THREE.Mesh(planegeometrytb, planematerial);
planel.rotateY(Math.PI / 2);
planel.position.set(-(10 / 2), 0, -15);
array.push(planel);
group.add(planel);
planer.rotateY(Math.PI / 2);
planer.position.set((10 / 2), 0, -15);
array.push(planer);
group.add(planer);
planet.rotateX(Math.PI / 2);
planet.position.set(0, (6 / 2), -15);
array.push(planet);
group.add(planet);
planeb.rotateX(Math.PI / 2);
planeb.position.set(0, -(6 / 2), -15);
array.push(planeb);
group.add(planeb);
//
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.shadowMap.enabled = true;
renderer.xr.enabled = true;
container.appendChild(renderer.domElement);
document.body.appendChild(VRButton.createButton(renderer));
// controllers
controller1 = renderer.xr.getController(0);
controller1.addEventListener('selectstart', onSelectStart);
controller1.addEventListener('selectend', onSelectEnd);
controller1.userData.selected = false;
scene.add(controller1);
controller2 = renderer.xr.getController(1);
controller2.addEventListener('selectstart', onSelectStart);
controller2.addEventListener('selectend', onSelectEnd);
controller2.userData.selected = false;
scene.add(controller2);
const controllerModelFactory = new XRControllerModelFactory();
//
const geometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, - 1)]);
const line = new THREE.Line(geometry);
line.name = 'line';
line.scale.z = 5;
controller1.add(line.clone());
controller2.add(line.clone());
raycaster = new THREE.Raycaster();
//
window.addEventListener('resize', onWindowResize);
function onSelectStart() {
this.userData.selected = true;
}
function onSelectEnd(event) {
const controller = event.target;
controller.userData.selected = false;
}
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function handle(controller) {
if (controller.userData.selected){
scene.background = new THREE.Color( 'green' );
xlayer=60;
}
}
function animate() {
renderer.setAnimationLoop(render);
}
function render() {
handle(controller1);
handle(controller2);
renderer.render(scene, camera);
}
</script>
</body>
</html>
xlayer=60 works in handle()(shows layer 60 other than defined in init()):
when its before the if clause of the controller.UserData
when its in it and I set it true right above the if clause
it doesn't work
whenever its in the if clause, even if something else in the if clause worked (like setting the background green)
I wonder if I did something wrong or if it just doesn't work like that.

How to project a texture to curved surface?

Screen capture
I tried to make a 3/4 cylinder surface, and I made it from extruting by a ellipe path,
but when I tried to load a texture to the surface, It does not as I exprected: uniformly painted to the surface, it's stretched
I know it's about texture projection, But I dont know how to set options.
class EllipseCurve3 extends THREE.Curve {
ellipse = null
constructor (ellipse) {
super()
this.ellipse = ellipse
}
getPoint(t, optionalTarget = new THREE.Vector3()) {
const point = this.ellipse.getPoint(t, optionalTarget)
return new THREE.Vector3(
point.x,
point.y,
0
)
}
}
// Scene
const scene = new THREE.Scene();
var shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.moveTo(0, 1);
shape.lineTo(50, 1);
shape.moveTo(50, 0);
shape.lineTo(0, 0);
// var curve = new THREE.CatmullRomCurve3([
// new THREE.Vector3(0, 0, 50),
// new THREE.Vector3(-50, 0, 0),
// new THREE.Vector3(0, 0, -50)
// ]);
const arc = new THREE.EllipseCurve(
0,
0, // ax, aY
100,
100, // xRadius, yRadius
0,
1.5 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
),
path = new EllipseCurve3(arc)
geometry = new THREE.ExtrudeGeometry(shape, {
bevelEnabled: false,
extrudePath: path,
steps: 50,
depth: 5,
amount: 20,
material: 0,
extrudeMaterial: 1
});
// Set up lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(100, 200, 100); // x, y, z
scene.add(directionalLight);
// Camera
const width = 200;
const height = width * (window.innerHeight / window.innerWidth);
const camera = new THREE.OrthographicCamera(
width / -2, // left
width / 2, // right
height / 2, // top
height / -2, // bottom
0.1, // near
1000 // far
);
camera.position.set(400, 400, 400);
camera.lookAt(0, 0, 0);
// Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
renderer.render(scene, camera);
// Add it to HTML
document.body.appendChild(renderer.domElement);
var textureLoader = new THREE.TextureLoader();
textureLoader.crossOrigin = true;
const picture = 'https://threejs.org/examples/textures/uv_grid_opengl.jpg'
textureLoader.load(picture, function(texture) {
// repeat pattern
texture.wrapS = texture.wrapT = THREE.MirroredRepeatWrapping;
// zoom in on pattern
texture.repeat.set(.01, .01);
// assign texture via MeshBasicMaterial
var material = new THREE.MeshBasicMaterial({
map: texture,
needsUpdate: true,
// transparent: true,
// premultipliedAlpha: true,
// side: THREE.DoubleSide,
// blending: THREE.AdditiveBlending
});
// var material = new THREE.MeshPhongMaterial({ color: 0x0048ff });
var mesh = new THREE.Mesh(geometry, material)
mesh.rotation.x = Math.PI / 2
// mesh.rotation.z = Math.PI / 2
scene.add(mesh)
scene.add(cube)
})
function render() {
renderer.render(scene, camera);
// Rotate out group
// svgGroup.rotation.y -= 0.005
controls.update();
requestAnimationFrame(render);
}
render();
Code here
https://codepen.io/mike-xu/pen/RwQeEXJ
"I know it's about texture projection" - It's about computing UV, based on vertices coordinates.
CylinderGeometry also may help to achieve the result you described. With less code, and more convenient and predictable way.
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three#0.136.0/examples/jsm/controls/OrbitControls.js";
console.clear();
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 10, 10);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
let controls = new OrbitControls(camera, renderer.domElement);
scene.add(new THREE.AxesHelper(10));
let g = new THREE.CylinderGeometry(5, 5, 5, 100, 20, true, 0, Math.PI * 1.5);
let m = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: new THREE.TextureLoader().load(
"https://threejs.org/examples/textures/uv_grid_opengl.jpg",
tex => {
tex.wrapS = tex.wrapT = THREE.MirroredRepeatWrapping;
tex.repeat.set(3, 1);
}
)
});
let c = new THREE.Mesh(g, m);
scene.add(c);
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
</script>

How to resize threejs mesh via controls

The only way I know how to resize an extruded path is but reconstructing it. I want to know whether there is a way I can control the length/width/height in the threejs controls.
Here is my code:
'use strict';
/* global THREE, dat */
function main() {
const canvas = document.querySelector('#canvas');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 10, 20);
const controls = new THREE.OrbitControls(camera, canvas);
controls.target.set(0, 5, 0);
controls.update();
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
{
const planeSize = 40;
const loader = new THREE.TextureLoader();
const texture = loader.load('https://r105.threejsfundamentals.org/threejs/resources/images/checker.png');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.magFilter = THREE.NearestFilter;
const repeats = planeSize / 2;
texture.repeat.set(repeats, repeats);
const planeGeo = new THREE.PlaneBufferGeometry(planeSize, planeSize);
const planeMat = new THREE.MeshPhongMaterial({
map: texture,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(planeGeo, planeMat);
mesh.rotation.x = Math.PI * -.5;
scene.add(mesh);
}
{
// Create a Shape Mesh with basic material
const shape = new THREE.Shape();
const x_len = 12;
const y_len = 8;
const z_len = 1;
shape.moveTo( 0, 0 );
shape.lineTo( 0, y_len );
shape.lineTo( x_len, y_len );
shape.lineTo( x_len, 0 );
shape.lineTo( 0, 0 );
const thickness = 0.5;
shape.lineTo( thickness, thickness );
shape.lineTo( x_len-thickness, thickness );
shape.lineTo( x_len-thickness, y_len-thickness );
shape.lineTo( thickness, y_len-thickness );
shape.lineTo( thickness, thickness );
const extrudeSettings = {
steps: 2,
depth: z_len,
bevelEnabled: false,
bevelThickness: 1,
bevelSize: 1,
bevelOffset: 0,
bevelSegments: 1
};
const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
const material = new THREE.MeshPhongMaterial({color: '#CA8'});
const mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );
}
class ColorGUIHelper {
constructor(object, prop) {
this.object = object;
this.prop = prop;
}
get value() {
return `#${this.object[this.prop].getHexString()}`;
}
set value(hexString) {
this.object[this.prop].set(hexString);
}
}
function makeXYZGUI(gui, vector3, name, onChangeFn) {
const folder = gui.addFolder(name);
folder.add(vector3, 'x', -10, 10).onChange(onChangeFn);
folder.add(vector3, 'y', 0, 10).onChange(onChangeFn);
folder.add(vector3, 'z', -10, 10).onChange(onChangeFn);
folder.open();
}
{
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.PointLight(color, intensity);
light.position.set(0, 10, 4);
scene.add(light);
const helper = new THREE.PointLightHelper(light);
scene.add(helper);
function updateLight() {
helper.update();
}
const gui = new dat.GUI();
gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('color');
gui.add(light, 'intensity', 0, 2, 0.01);
gui.add(light, 'distance', 0, 40).onChange(updateLight);
makeXYZGUI(gui, light.position, 'position');
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- Simple reset to delete the margins -->
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<!-- Our code -->
<canvas id="canvas"></canvas>
<script src="https://r105.threejsfundamentals.org/threejs/resources/threejs/r105/three.min.js"></script>
<script src="https://r105.threejsfundamentals.org/threejs/resources/threejs/r105/js/controls/OrbitControls.js"></script>
<script src="https://r105.threejsfundamentals.org/threejs/../3rdparty/dat.gui.min.js"></script>
</html>
In this code, I want to change x_len, y_len, z_len
I'm using a library called dat.gui.
The problem is that each of these values map to multiple properties. For example, x_len maps to
shape.curves[2].x
shape.curves[3].x
shape.curves[6].x
shape.curves[7].x
so I probably need something like:
gui.add(some object to point to all relevant curves, 'x', 0, 40).onChange(someCallback);
any help will be appreciated.

Increase thickness of cylinder in three js

I am trying to increase thickness of cylinder using ThreeBSP. Using this http://jsfiddle.net/gerdonabbink/tephoLr1/133/ fiddle but it gives me an constructor error.
Type Error: ThreeBSP is not a constructor
currently i am using <script type="module"> to load all JS file using 'import' keyword. so is there need to alter library? because i haven't seen any export statement in library so, or is there any other way is available to increase thickness of cylinder?
My Code Sample 'Instead of 'THREE' i used 'Mine' as module'
You can form such cylinder, using the approach with THREE.Shape and THREE.ExtrudeBufferGeometry():
body {
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from 'https://threejs.org/build/three.module.js';
import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(3, 5, 8);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new OrbitControls(camera, renderer.domElement);
scene.add(new THREE.GridHelper(10, 10));
var arcShape = new THREE.Shape();
arcShape.absarc( 0, 0, 2, 0, Math.PI * 2, false );
var holePath = new THREE.Path();
holePath.absarc( 0, 0, 1, 0, Math.PI * 2, true );
arcShape.holes.push( holePath );
var extrudeGeom = new THREE.ExtrudeBufferGeometry(arcShape, {depth: 6, curveSegments: 36, bevelEnabled: false});
extrudeGeom.translate(0, 0, -3);
extrudeGeom.rotateX(-Math.PI * 0.5);
var cylinder = new THREE.Mesh(extrudeGeom, new THREE.MeshNormalMaterial());
scene.add(cylinder);
renderer.setAnimationLoop(() => { renderer.render(scene, camera); });
</script>

TextGeometry in Three.js not rendering/working

Where am I doing wrong? I've checked the color, it wasn't black on black. I copied the font json file to directory, is it possible that the file wasn't loaded?
var light = new THREE.AmbientLight(0xffffff, 0.5);
var light1 = new THREE.PointLight(0xffffff,0.5);
scene.add(light);
scene.add(light1);
var geometry;
var loader = new THREE.FontLoader();
loader.load('js/helvetiker_regular.typeface.json', function (font) {
var geometry = new THREE.TextGeometry('Hello three.js!', {
font: font,
size: 80,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
});
});
var material = new THREE.MeshLambertMaterial({ color: 0xF3FFE2 });
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set = (0, 0, -1000);
scene.add(mesh);
requestAnimationFrame(render);
function render() {
mesh.rotation.x += 0.05;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
window.onload = function(params) {
/*
*
* SET UP THE WORLD
*
*/
//set up the ratio
var gWidth = window.innerWidth;
var gHeight = window.innerHeight;
var ratio = gWidth / gHeight;
var borders = [40, 24] //indicate where the ball needs to move in mirror position
var light = new THREE.AmbientLight(0xffffff, 0.5);
var light1 = new THREE.PointLight(0xffffff, 0.5);
light1.position.set(0, 5, 0);
light1.castShadow = true;
// set the renderer
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera();
camera.position.set(10, 10, 10);
camera.lookAt(new THREE.Vector3(0, 0, 0));
//properties for casting shadow
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(gWidth, gHeight);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
scene.add(light);
scene.add(light1);
var ground = new THREE.Mesh(new THREE.BoxGeometry(10, 0.5, 10),new THREE.MeshLambertMaterial())
ground.receiveShadow = true;
scene.add(ground)
var geometry;
var loader = new THREE.FontLoader();
var mesh;
requestAnimationFrame(render);
function render() {
if (mesh){ mesh.rotation.y += 0.01;mesh.rotation.z += 0.007;}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
loader.load('https://cdn.rawgit.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.json', function(font) {
var geometry = new THREE.TextGeometry('Hello three.js!', {
font: font,
size: 80,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
});
var material = new THREE.MeshLambertMaterial({
color: 0xF3FFE2
});
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 2, 0);
mesh.scale.multiplyScalar(0.01)
mesh.castShadow = true;
scene.add(mesh);
});
}
body {
padding: 0;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<html>
<head>
</head>
<body>
</body>
</html>

Resources