Add color to .obj in ThreeJS - three.js

I am new to ThreeJS and have a simple question. I have the following code that will work properly, but I cannot add color to my .obj. The short and narrow of it is that I designed a game controller in Solidworks 2012, then I exported the CAD file as a .stl. I then used MeshLab to export the .stl as a .obj. Now I use the .obj in ThreeJS and it works, but I cannot for the life of me get color added to the .obj. Here is the code
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - loaders - vtk loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
</style>
</head>
<body>
<div id="info">
three.js -
vtk format loader test -
model from The GeorgiaTech Lagre Geometric Model Archive,
</div>
<script src="three.min.js"></script>
<script src="TrackballControls.js"></script>
<script src="OBJLoader.js"></script>
<script src="BinaryLoader.js"></script>
<script src="Detector.js"></script>
<script src="stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer;
var cross;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.01, 1e10 );
camera.position.z = 200;
camera.position.y = 200;
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 5.0;
controls.zoomSpeed = 5;
controls.panSpeed = 2;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
scene = new THREE.Scene();
scene.add( camera );
// light
var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 20, 20, 100 ).normalize();
camera.add( dirLight );
camera.add( dirLight.target );
// texture
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
var texture = new THREE.Texture();
var loader = new THREE.ImageLoader( manager );
loader.load( 'bigthumbnail.jpg', function ( image ) {
texture.image = image;
texture.needsUpdate = true;
} );
var loader = new THREE.OBJLoader()
loader.load( 'Gamepad.obj', function ( object ) {
object.position.y = 0;
scene.add( object );
} );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>
I have poured through the threejs.org website and looked at most of the examples. All of the examples that use complex colors use .bin files or .js files. So I downloaded Python 2.7.6, installed it and ran convert_obj_three.py. This generated a .js file, but I'm not sure it is correctly formatted. Unfortunately, The output that convert_obj_three.py gave me is too large to post. My Second question is which file format is best for complex coloring, like chrome blue? .bin, .js or can I use .obj? If using a .js is the best way to go then how can I reliably convert the .obj file to .js? By the way, I tried using the .js that was created by convert_obj_three.py, but the webpage is blank all the time. Seems I cannot load the .js using THREE.JSONLoader().
Thanks in advance.

after loader.load function is executed you get a threejs Object3D object. which contains the meshes of your object .
so you need to traverse over them to change the color of the material. The code will be something like this.
var loader = new THREE.OBJLoader()
loader.load( 'Gamepad.obj', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.ambient.setHex(0xFF0000);
child.material.color.setHex(0x00FF00);
}
} );
object.position.y = 0;
scene.add( object );
} );
Now the object's material has two properties which decides its color as you may see in the code ambient and color .
So this is to say that if in the scene you have white AmbientLight the object will appear Red(because the ambient property is set to #FF0000)
If the object is luminated by some other type of light like pointlight or directionalLight (as in your above case) the objects will appear Green(as color is set to #00FF00).
Now the last case if you have say that you have one white AmbientLight and one DirectionalLight in the Scene, then the object will appear as yellow as both material.ambient and material.color both will come into play and Red+Green will render as Yellow.
Hoping this helps.

Related

Why is my camera so far from rendered model?

I am trying to create my first glTF model in Three.js rendered from Blender and I can not get the camera to display close to the rendered model.
No matter what I do to the Blender camera nothing fixes the problem so it must be the code that has been written in Three.js. Please help! Thx
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webglTF - loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no,
minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a {
color: #046;
font-weight: bold;
}
</style>
</head>
<body>
<script src="../build/three.js"></script>
<script src="js/libs/inflate.min.js"></script>
<script src="js/loaders/GLTFLoader.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/WebGL.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
if ( WEBGL.isWebGLAvailable() === false ) {
document.body.appendChild( WEBGL.getWebGLErrorMessage() );
}
var container, stats, controls;
var camera, scene, renderer, light;
var clock = new THREE.Clock();
var mixers = [];
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth /
window.innerHeight, 1, 2000 );
camera.position.set( -400, 0, 200 );
controls = new THREE.OrbitControls( camera );
controls.target.set( 0, 0, 0 );
controls.update();
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xa0a0a0 );
scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
light.position.set( 0, 200, 0 );
scene.add( light );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 200, 100 );
light.castShadow = true;
light.shadow.camera.top = 180;
light.shadow.camera.bottom = -100;
light.shadow.camera.left = -120;
light.shadow.camera.right = 120;
scene.add( light );
// scene.add( new THREE.CameraHelper( light.shadow.camera )
);
// ground
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry(
2000, 2000 ), new THREE.MeshPhongMaterial( { material:
0x999999, depthWrite: false } ) );
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000
);
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
// model
var loader = new THREE.GLTFLoader();
loader.load( '../The-Raisin/TREE_GLTF.gltf', function ( gltf)
{
scene.add( gltf.scene );
}, undefined, function ( error ) {
console.error( error );
} );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
// stats
stats = new Stats();
container.appendChild( stats.dom );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
if ( mixers.length > 0 ) {
for ( var i = 0; i < mixers.length; i ++ ) {
mixers[ i ].update( clock.getDelta() );
}
}
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>
Camera is displayed outside of scene.
No matter what I do to the Blender camera nothing fixes the problem
Changing the camera properties in Blender has not effect if you define an own camera object in your application. You have two options:
Access gltf.cameras in your onLoad() callback which represents an array of cameras defined in the glTF asset. If the camera from Blender is exported, you should find it right there.
Improve the parameters of the camera defined in your application with an approach similar to 3D viewers. You usually center your object first and then derive optimal camera parameters from the object's AABB. Try to use the following code from this three.js based glTF viewer:
https://github.com/donmccurdy/three-gltf-viewer/blob/18f43073bbfdbd3c220e2059e548e74c507522d2/src/viewer.js#L218-L246
three.js R104

Change the color of 3D model using colorPicker three.js

I am trying to change the color of 3D object where intersected using color picker.I am trying with dat.gui.I want to change the color of 3d part where it gets clicked and change the selected from the colorPicker.I tried out some possible ways but it doesn't work out.Please,refer to the code I tried out. Help me out with some solution and draw my attention to where I am getting wrong. Thanks.
<!DOCTYPE html>
<html lang="en">
<head>
<title>color</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="three.js"></script>
<script src="OrbitControls.js"></script>
<script src="Detector.js"></script>
<script src="stats.min.js"></script>
<script src="loaders/MTLLoader.js"></script>
<script src="loaders/OBJLoader.js"></script>
<script type='text/javascript' src='DAT.GUI.min.js'></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer,effectController;
var raycaster;
var objects = [];
var selectedObject,selectedPos;
var rotation;
var pos,quat;
var INTERSECTED;
var guiColor;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 15;
controls = new THREE.OrbitControls( camera );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x555000 );
scene.add( camera );
// light
var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 200, 200, 1000 ).normalize();
camera.add( dirLight );
camera.add( dirLight.target );
var mtlLoader = new THREE.MTLLoader(); mtlLoader.setBaseUrl('assets/'); mtlLoader.setPath('assets/'); mtlLoader.load('anno.mtl', function (materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('anno.obj', function (object) {
scene.add( object );
objects.push( object );
});
});
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
/* Controls */
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;
raycaster = new THREE.Raycaster();
gui = new dat.GUI();
parameters =
{
color: "#ff0000",
};
gui.add( parameters, 'reset' ).name("Reset");
guiColor = gui.addColor( parameters, 'color' ).name('Color');
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
window.addEventListener( 'resize', onWindowResize, false );
renderer.domElement.addEventListener("click", onclick, false);
}
var mouse = new THREE.Vector2();
function onclick(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects, true);
if (intersects.length > 0) {
INTERSECTED = intersects[0].object;
if ( INTERSECTED && INTERSECTED.material.emissive != null ){
guiColor.onChange(function(){
INTERSECTED.material.emissive.setHex(parameters.color)
});
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>
I've create a little live demo with your code and a basic working solution. I'd like to highlight three important changes:
You can use the onChange() event handler in order to know when a certain dat.gui property has changed. The demo uses this feature to update the color of a selected object.
I have refactored your raycasting logic into something more simple. I've seen you've copied some code from the official three.js examples but the new code should be sufficient for your case. Besides, it's also better to update Material.color instead of Material.emissive.
If you set OrbitControls.enableDamping to true, you have to update the controls in your animation loop.
https://jsfiddle.net/btuzd23o/2/
three.js R103

adding textures for dynamic 3d model in three js and wanted to understand animation of 3d model?

i tried to import 3d model in .dae format in three js like below i am able to import it properly but i can not see textures for that model even thought i have textures folder and no error related to that. so i added one function using my function (switchtexture()) by passing object of child and matching the name of child i can give assign texture but no success can someone tell me where i am doing wrong ? is this right way or not
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - collada - skinning</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background: #777;
padding: 0;
margin: 0;
font-weight: bold;
overflow: hidden;
}
#info {
position: absolute;
top: 0px;
width: 100%;
color: #ffffff;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
}
a {
color: #ffffff;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
three.js webgl - collada - skinning
</div>
<script src="js/three.js"></script>
<script src="js/ColladaLoader.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/Detector.js"></script>
<script src="js/stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats, clock;
var camera, scene, renderer, mixer;
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 25, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( - 7, 4, 7 );
scene = new THREE.Scene();
clock = new THREE.Clock();
// collada
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load("./wolf/Wolf_dae.dae", function (collada) {
var object = collada.scene;
mixer = new THREE.AnimationMixer( object );
object.traverse( function ( child ) {
switchTexture(child);
if ( child instanceof THREE.SkinnedMesh ) {
var clip = THREE.AnimationClip.parseAnimation( child.geometry.animation, child.geometry.bones );
mixer.clipAction( clip, child ).play();
}
} );
object.scale.set(1,1,1);
object.position.set(0, 0, 0);
object.rotateX(- Math.PI/2);
scene.add( object );
} );
//
var gridHelper = new THREE.GridHelper( 5, 20 );
scene.add( gridHelper );
//
var ambientLight = new THREE.AmbientLight( 0xcccccc );
scene.add( ambientLight );
var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.set( -1, 0.5, -1 ).normalize();
scene.add( directionalLight );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild( renderer.domElement );
//
controls = new THREE.OrbitControls( camera, renderer.domElement );
//
stats = new Stats();
container.appendChild( stats.dom );
//
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 );
render();
stats.update();
}
function switchTexture(obj) {
// for Textures
var imageDir = './wolf/textures/';
var images = {
"Wolf_obj_fur": imageDir + 'Wolf_Fur.jpg'
};
for (var prop in images) {
if (obj.name == prop) {
obj.children[0].material.map = THREE.ImageUtils.loadTexture(images[prop], {}, function () {
// add callback here if you want
});
}
}
}
function render() {
var delta = clock.getDelta();
if ( mixer !== undefined ) {
mixer.update( delta );
}
renderer.render( scene, camera );
}
</script>
</body>
</html>
here is the jiddle to see the code
https://jsfiddle.net/saisoft00/jv7rnos2/
and i downloaded the 3d model from this
https://free3d.com/3d-model/wolf-rigged-and-game-ready-42808.html
Try using THREE.MeshStandardMaterial for the mesh materials.
Your switchTexture will look something like this:
function switchTexture(obj) {
// for Textures
var imageDir = './wolf/textures/';
var images = {
"Wolf_obj_fur": imageDir + 'Wolf_Fur.jpg'
};
for (var prop in images) {
var material = new THREE.MeshStandardMaterial( {
map: new THREE.TextureLoader().load(images[prop])
});
if (obj.name == prop) {
obj.children[0].material = material;
}
}
}
You should also move from ImageUtils to TextureLoader, ImageUtils was deprecated.

three.js equirectangular video shaking in vive headset

I render an equirectangular video on the three.js sphere and test the performance of Chromium WebVR on VIVE.
I notice that the video vibrates and shakes when I look around in VIVE. That makes me feel dizzy.
If I replace video to image, the vibration stop. I test different videos, every video vibrate. So maybe the problem happens when three.js tries to render these videos on the sphere.
I also check the fps. It's around 85~90 fps. Looks pretty good.
( Before that, I've test the same script on mobile using WebVR Boilerplate and watch video in Cardboard, it works fine. No shaking and vibration. The fps is around 50. )
While I'm testing, I accidentally figure out if I put an sphere in three.js example webvr_vive_sculp.html, the vibration reduce. Also the fps reduce to 50~60. If I limited the fps in my original script, nothing change.
Did anyone face this problem?
Here's my script:
<!DOCTYPE html>
<html lang="en">
<head>
<title>360 video in vive</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
color: #ffffff;
padding: 5px;
font-family:Monospace;
font-size:13px;
font-weight: bold;
text-align:center;
}
a {
color: #ffffff;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../build/three.js"></script>
<script src="js/controls/VRControls.js"></script>
<script src="js/effects/VREffect.js"></script>
<script src="js/vr/ViveController.js"></script>
<script src="js/vr/WebVR.js"></script>
<script>
if ( WEBVR.isAvailable() === false ) {
document.body.appendChild( WEBVR.getMessage() );
}
var camera, scene, renderer;
var effect, controls;
var video;
init();
animate();
function init() {
var container, mesh;
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1100 );
camera.target = new THREE.Vector3( 0, 0, 0 );
controls = new THREE.VRControls( camera );
controls.standing = true;
scene = new THREE.Scene();
// 360 video
video = document.createElement('video');
video.autoplay = true;
video.src = 'video/8Kevil_3840x1920_hq.webm'; // 'video/Danger in the Room.webm' // 8Kevil_3840x1920_hq
video.crossOrigin = '';
videoTexture = new THREE.Texture(video);
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
videoTexture.format = THREE.RGBFormat;
// 360 video sphere
var cubeGeometry = new THREE.SphereGeometry(500, 60, 40);
var sphereMat = new THREE.MeshBasicMaterial({map: videoTexture});
sphereMat.side = THREE.BackSide;
var cube = new THREE.Mesh(cubeGeometry, sphereMat);
scene.add(cube);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
effect = new THREE.VREffect( renderer );
if ( WEBVR.isAvailable() === true ) {
document.body.appendChild( WEBVR.getButton( effect ) );
}
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
effect.requestAnimationFrame( animate );
update();
}
function update() {
if( video.readyState === video.HAVE_ENOUGH_DATA ){
videoTexture.needsUpdate = true;
}
controls.update();
effect.render( scene, camera );
}
</script>
</body>
WebVr does not handle video textures well right now, if you pause the video the flickering stops right ?
You can try Firefox nightly, it handles video textures a little bit better, and has lower latency in general.
You can test it by opening the vive menu during the experience and shaking your head, in Chrome you'll notice much more latency between Vive's native menu performance and your experience in the dimmed background.
Try to usevideoTexture.minFilter = THREE.NearestFilter; and videoTexture.maxFilter = THREE.NearestFilter;
For the sphere use new THREE.SphereGeometry(500, 720, 4); I know it looks weird, but this way you'll get much smoother stitches on top/bottom of the sphere.

How to make a flat ring in Three.js?

I was able to make a donut with Three.js using THREE.TorusGeometry. But I can't get it to look like a flat ring like the ones in these pictures:
http://www.google.com/imgres?imgurl=http://www.titanjewellery.co.uk/Mens/TI21-Titanium-8mm-Flat-Brushed-Ring.jpg&imgrefurl=http://www.titanjewellery.co.uk/Mens/8mm-Brushed-Titanium-Flat-Ring.html&h=301&w=232&sz=16&tbnid=LCN7eQuo2wyG_M:&tbnh=90&tbnw=69&zoom=1&usg=__3vayMvDy26tsj2hwvCK9SsYwVwY=&docid=ZMdcBBBQOzMSoM&sa=X&ei=pEhsUeL4FKWJiAKCzIHYCQ&ved=0CEAQ9QEwBA&dur=1660
Here's what my donut looks like:
Is there another Three.js geometry that can generate a flat ring (right with flat inner and outer walls)? Or another way of going about this?
Thanks for any pointers you can share! :)
Update:
The code and dependencies were taken from:
http://mrdoob.github.io/three.js/examples/misc_controls_trackball.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - trackball controls</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #000;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color:#000;
position: absolute;
top: 0px; width: 100%;
padding: 5px;
}
a {
color: red;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
three.js - trackball controls example</br>MOVE mouse & press LEFT/A: rotate, MIDDLE/S: zoom, RIGHT/D: pan
</div>
<script src="three.min.js"></script>
<script src="TrackballControls.js"></script>
<script src="Detector.js"></script>
<script src="stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer;
var cross;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 500;
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render );
// world
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );
var radius = 100;
var tubeRadius = 50;
var radialSegments = 8 * 10;
var tubularSegments = 6 * 15;
var arc = Math.PI * 2;
var geometry = new THREE.TorusGeometry( radius, tubeRadius, radialSegments, tubularSegments, arc );
var material = new THREE.MeshLambertMaterial( { color:0xffffff, shading: THREE.FlatShading } );
for ( var i = 0; i < 1; i ++ ) {
var mesh = new THREE.Mesh( geometry, material );
mesh.updateMatrix();
mesh.matrixAutoUpdate = false;
scene.add( mesh );
}
// lights
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );
light = new THREE.DirectionalLight( 0x002288 );
light.position.set( -1, -1, -1 );
scene.add( light );
light = new THREE.AmbientLight( 0x222222 );
scene.add( light );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setClearColor( scene.fog.color, 1 );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
render();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>
http://jsfiddle.net/alininja/b4qGx/1/
There are multiple options:
Use TubeGeometry - this is probably what you need
ExtrudeGeometry to extrude a disk
lathe an offset rectangle with LatheGeometry
Use THREE.Shape -> grab the tube like shape from the webgl_geometry_shapes sample
You can use the RingGeometry function. The following code adds to the scene a full (between 0 and 360 degrees) wireframed red ring of inner radius equals to 10 and outer radio equals to 20. You can play with the other indicated variables to adjust the aspect of the disc you want to generate ()
var geometry = new THREE.RingGeometry(10, 20, thetaSegments, phiSegments, 0, Math.PI * 2);
var ring = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true}));
ring.position.set(25, 30, 0);
scene.add(ring);
Check this code!
var geometry = new THREE.TorusGeometry( 3, 0.5, 20, 2999 );
ring1 = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({color: 0xffffff, wireframe: true}));
scene.add(ring1);

Resources