three.js not rendering custom shape - three.js

I have been trying to incorporate FirstPersonControls following this example which is a bit more complicated to what I need. I haven't implemented the controls yet but I still am not able to see the content of what I am loading. This is my code so far:
<html>
<head>
<title> Prototype 2 </title>
<meta charset="utf-8">
<!--Include this one if the code doesn't work <script src="js/keyboard.js"></script>-->
<style>
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
font-family: arial;
}
#container {
position: absolute;
/*left: 0;
right: 0;
top: 0;
bottom: 0;*/
width: 100%;
height: 100%;
/*background-color: rgba(0,0,0,0.5);*/
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="js/three.min.js" type="text/javascript" ></script>
<script src="js/FirstPersonControls.js"></script>
</head>
<body>
<div id="container" >
</div >
<script src="js/main2.js"> </script>
</body>
</html>
This is main2.js
var container, scene, camera, renderer, controls, mesh;
function init() {
container = $('#container');
var WIDTH = container.width(),
HEIGHT = container.height();
//Scene
scene = new THREE.Scene();
//Render
renderer = new THREE.WebGLRenderer( {antialias: true} );
renderer.setClearColor( 0x000000 );
renderer.setSize( WIDTH, HEIGHT);
container.append( renderer.domelement);
//Camera
camera = new THREE.PerspectiveCamera( 45, WIDTH / HEIGHT, 0.1, 20000 );
//Might need this stuff later
camera.position.z = 10;
camera.position.y = 10;
camera.position.x = 20;
scene.add(camera);
//Create a light
var light = new THREE.PointLight(0xffffff);
light.position.set(-100,200,100);
scene.add(light);
//Here we load our custom shape
var loader = new THREE.JSONLoader();
loader.load("threejs_objects/lightwave.js", function( geometry){
// var material = new THREE.MeshLambertMaterial({color: 0xff0000});
var material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true} );
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
objects.push( mesh );
});
//If Window resizing...
window.addEventListener('resize', function(){
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
renderer.setSize( WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
});
}
function render(){
renderer.render( scene, camera);
}
function animate() {
requestAnimationFrame( animate );
render();
}
init();
animate();
Thanks!

Your code is running before the browser has parsed the HTML document and built the DOM.
Put your code inside onload.
window.onload = function() {
// your js code ( all the code inside the main2.js )
};

Related

Three JS Geometry not rendering in scene?

I'm a complete beginner with three.js and am just trying to get to grips with creating a basic scene. I have copied and pasted code from a tutorial into VSCode and executed it through the live server extension.
This is the code below:
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8" />
<title>Three.js Basic Scene</title>
<style>
body {
margin: 0;
padding: 0;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
renderer.setClearColor(0xDDDDDD, 1);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT);
camera.position.z = 50;
scene.add(camera);
var boxGeometry = new THREE.BoxGeometry(10, 10, 10);
var basicMaterial = new THREE.MeshBasicMaterial({ color: 0x0095DD });
var cube = new THREE.Mesh(boxGeometry, basicMaterial);
scene.add(cube);
cube.rotation.set(0.4, 0.2, 0);
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>
The intended output is a blue cube on the screen with a white background, however all i am getting is a completely white screen. Any ideas why this is happening when the code is completely copied and pasted?

Orbit Controls cannot initialize properly

I am trying to code an STL model viewer in three.js
This is the code:
<!-- prerenderer -->
<!doctype html>
<html>
<head>
<title>Enjoy your model</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="../libs/three.js"></script>
<script src="../libs/OrbitControls.js"></script>
<script src="../libs/STLLoader.js"></script >
<style type="text/css">
body { padding-top:10px; word-wrap:break-word; width: 100vw; height: 100vh; margin: 0; overflow: hidden;}
form { text-align: center; }
</style>
</head>
<body>
<div >
<form action="/">
<input type="submit" value="Back to the homepage!" />
</form>
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 50, window.innerWidth/window.innerHeight, 1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById("WebGL-output").appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.center = new THREE.Vector3(
);
var loader = new THREE.STLLoader();
loader.load( 'myModel.stl', function ( geometry ) {
Var mesh = new THREE.Mesh (geometry);
Mesh.scale.set (0.1, 0.1, 0.1);
// mesh.rotation.set (- Math.PI / 2, Math.PI / 2, 0);
// mesh.scale.set (0.3, 0.3, 0.3);
// mesh.receiveShadow = true;
Scene.add (mesh);
} );
camera.position.z = 5;
var animate = function () {
requestAnimationFrame( animate );
renderer.render(scene, camera);
};
animate();
</script>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script >
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="../libs/bootstrap.min.js"></script>
</body>
</html>
What i get is Uncaught SyntaxError: Cannot use import statement outside a module for Orbit Controls and STLLoader.
What's even weirder is that sometimes it works, other times it does not
Then i tried this:
<!DOCTYPE html>
<html>
<head>
<title>Example 01.02 - First Scene</title>
<script type="text/javascript" src="../libs/three.js"></script>
<script src="../libs/OrbitControls.js"></script>
<script src="../libs/STLLoader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
<style>
body {
/* set margin to 0 and overflow to hidden, to go fullscreen */
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>
<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
// Necessary for camera/plane rotation
var degree = Math.PI/180;
// Setup
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
//bind rendered to the dom element
document.getElementById("WebGL-output").appendChild(renderer.domElement);
// Resize after viewport-size-change
window.addEventListener("resize", function () {
var height = window.innerHeight;
var width = window.innerWidth;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
// Adding controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
// Ground (comment out line: "scene.add( plane );" if Ground is not needed...)
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry(500, 500 ),
new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
);
plane.rotation.x = -90 * degree;
plane.position.y = 0;
scene.add( plane );
plane.receiveShadow = true;
// ASCII file - STL Import
var loader = new THREE.STLLoader();
loader.load( '../esp32.stl', function ( geometry ) {
var material = new THREE.MeshLambertMaterial( { color: 0xFFFFFF, specular: 0x111111, shininess: 200 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, 0, 0);
scene.add( mesh );
} );
// Binary files - STL Import
loader.load( '../esp32.stl', function ( geometry ) {
var material = new THREE.MeshLambertMaterial( { color: 0xFFFFFF, specular: 0x111111, shininess: 200 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, 20, 0);
scene.add( mesh );
} );
// Camera positioning
camera.position.z = 100;
camera.position.y = 100;
camera.rotation.x = -45 * degree;
// Ambient light (necessary for Phong/Lambert-materials, not for Basic)
var ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);
// Draw scene
var render = function () {
renderer.render(scene, camera);
};
// Run game loop (render,repeat)
var GameLoop = function () {
requestAnimationFrame(GameLoop);
render();
};
GameLoop();
</script>
</body>
</html>
And i get a black screen and
Uncaught TypeError: THREE.STLLoader is not a constructor
at test2.html:65
and
Uncaught ReferenceError: module is not defined
at STLLoader.js:32
All i want is to load an stl file and have some orbit controls to rotate around it.
EDIT:
Look at all these errors that pop up for god knows why:
Uncaught SyntaxError: Cannot use import statement outside a module
ot OrbitControls
Uncaught ReferenceError: module is not defined
at STLLoader.js:32
test2.html:51 Uncaught TypeError: THREE.OrbitControls is not a constructor
at test2.html:51
How hard can it be to just even load a model?
EDIT 2:
I am doing everything BY THE BOOK, and new errors pop up like :
Uncaught SyntaxError: The requested module '../libs/STLLoader.js' does not provide an export named 'STLLoader'
Sounds similar to Uncaught SyntaxError: Cannot use import statement outside a module
Depending on how you include OrbitControls and STLLoader, via <script> or import, you will need to copy from 'examples/js' or 'examples/jsm' respectively.

How to attach three.js scene snapshot to the image, and restore it on click

Here I'm trying to capture the element Id of each image when the button clicked. Say for every image snapshot I have to capture a id for each image. I can able to print the image on console but I'm stuck in creating id for each image.Thanks in advance. Here's the fiddle https://jsfiddle.net/bg17oja3/1/
<!DOCTYPE html>
<html>
<head>
<title>Snapshot Three JS</title>
</head>
<body>
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
<script type="text/javascript">
var camera, scene, renderer;
var mesh;
var strDownloadMime = "image/octet-stream";
init();
animate();
function init() {
var saveLink = document.createElement('div');
saveLink.style.position = 'absolute';
saveLink.style.top = '10px';
saveLink.style.width = '100%';
saveLink.style.background = '#FFFFFF';
saveLink.style.textAlign = 'center';
saveLink.innerHTML =
'<button href="#" id="clickButton">Save Frame</button>';
document.body.appendChild(saveLink);
// document.getElementById("saveLink").addEventListener('click', saveAsImage);
renderer = new THREE.WebGLRenderer({
preserveDrawingBuffer: true,
captureId
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
scene = new THREE.Scene();
var geometry = new THREE.BoxGeometry(200, 200, 200);
var captureId = document.getElementById('image');
// var renderer = new Three.WebGLRenderer({captureId});
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
console.log(captureId);
window.addEventListener('resize', onWindowResize, false);
document.getElementById('clickButton').addEventListener('click', buttonClick);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
function buttonClick() {
renderer.render(scene, camera);
document.getElementById('image').src = renderer.domElement.toDataURL();
console.log(image);
}
</script>
<style type="text/css">
html,
body {
padding: 0px;
margin: 0px;
}
canvas {
width: 100%;
height: 100%
}
#clickButton {
position: absolute;
top: 10px;
left: 10px;
z-index: 2;
cursor: pointer;
}
#image {
position: absolute;
top: 10px;
right: 10px;
max-width: 150px;
width: 150px;
height: 90px;
z-index: 3;
border: 1px solid #fff;
}
</style>
<img id="image" src="" />
</body>
I have forked your fiddle to demonstrate the solution: https://jsfiddle.net/mmalex/o0k2fu8t/
How to test it:
Take a snapshot,
Click the image to return to serialized scene.
The idea is:
serialize the whole scene when you take screenshot,
set data attribute on image,
deserialize scene from image data attribute whenever you need it.
function buttonClick()
{
renderer.render(scene, camera);
let imageEl = document.getElementById('image');
imageEl.src = renderer.domElement.toDataURL();
// convert scene to json format
let sceneJson = scene.toJSON();
// don't forget to make it text
let sceneJsonText = JSON.stringify(sceneJson);
// set serialized scene to image data-scene attribute
imageEl.setAttribute('data-scene', sceneJsonText);
}
function imageClick()
{
let imageEl = document.getElementById('image');
// access serialized scene on image click
var sceneJsonText = imageEl.getAttribute('data-scene');
// parse it into json object
let sceneJson = JSON.parse(sceneJsonText)
// convert json object into THREE.Scene
var loader = new THREE.ObjectLoader();
scene = loader.parse(sceneJson);
// don't forget to update referenced, as deserialized scene will stop rotation if you don't do that
mesh = scene.children[0];
}

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.

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