Plotting 3d network in three.js - javascript

I am trying to generate a 3d graph using three.js
Code:
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/three#0.119.0/build/three.min.js"></script>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script>
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 );
document.body.appendChild( renderer.domElement );
var node1_geometry = new THREE.BoxGeometry( 1, 1, 1 );
var node1_material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var node1 = new THREE.Mesh( node1_geometry, node1_material );
node1.position.set(-2, 4, 1);
var node2_geometry = new THREE.BoxGeometry( 1, 1, 1 );
var node2_material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
var node2 = new THREE.Mesh( node2_geometry, node2_material );
node2.position.set(2, 4, 1);
var edge_geometry = new THREE.Geometry();
edge_geometry.vertices.push( node1.position, node2.position );
var edge_material = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 2 } );
var edge = new THREE.Line( edge_geometry, edge_material );
scene.add( node1 );
scene.add( node2 );
scene.add( edge );
camera.position.z = 5;
var animate = function () {
requestAnimationFrame( animate );
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
But this only gives a black window and the graph is not displayed.
Suggestions on how to fix this will be really helpful.

To get the snippet to run you have a small problem with you line
var edge_material = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 2 } );
You can change this to:
var edge_material = new THREE.LineDashedMaterial({
color: 0xffffff,
dashSize: 2,
gapSize: 2
});
It should now render, but a black background still shows up. The problem now is that your camera is not angled at the content you have created, so add a line with a camera position below.
camera.position.y = 5;
Now you should be able to see your two boxes, and the line.
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
scene.background = new THREE.Color(0x333333);
var node1_geometry = new THREE.BoxGeometry(1, 1, 1);
var node1_material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
var node1 = new THREE.Mesh(node1_geometry, node1_material);
node1.position.set(-2, 4, 1);
var node2_geometry = new THREE.BoxGeometry(1, 1, 1);
var node2_material = new THREE.MeshBasicMaterial({
color: 0xff00ff
});
var node2 = new THREE.Mesh(node2_geometry, node2_material);
node2.position.set(2, 4, 1);
var edge_geometry = new THREE.Geometry();
edge_geometry.vertices.push(node1.position, node2.position);
var edge_material = new THREE.LineDashedMaterial({
color: 0xffffff,
dashSize: 2,
gapSize: 2
});
var edge = new THREE.Line(edge_geometry, edge_material);
scene.add(node1);
scene.add(node2);
scene.add(edge);
camera.position.z = 5;
camera.position.y = 5;
var animate = function() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
animate();
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/three#0.119.0/build/three.min.js"></script>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
</body>
</html>

Related

How create window, holes or subtract geometry in three.js

I'm new with three.js and I need to create a "room" with doors and windows. This is a simple task but I have found only not up to date answers.
Similar questions are here:
- subtracting-geometry-in-three-js
- is-it-possible-to-cut-parts-of-the-shape-geometry-away-in-three-js
In my case, I have a big box and I want to subtract a smaller one JSFIDDLE example:
var material = new THREE.MeshBasicMaterial({color: 0xffff00});
var faceMaterial_Y = new THREE.MeshLambertMaterial( { color: 0x0087E6 } );
var faceMaterial = new THREE.MeshLambertMaterial( { color: 0x0087E6 } );
var geometry_Y = new THREE.BoxBufferGeometry( 1.5, 1.5, 0.99 );
var faceMaterial_Y = new THREE.MeshLambertMaterial( { color: 0xffff00 } );
var cube_Y = new THREE.Mesh( geometry_Y, faceMaterial_Y);
scene.add(cube_Y);
var geometry_A = new THREE.BoxBufferGeometry( 0.7, 0.7, 0.7 );
material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
var faceMaterial_A = new THREE.MeshLambertMaterial( { color: 0x00ff00 } );
var cubeA = new THREE.Mesh( geometry_A, material );
cubeA.position.set( 0.5, 0.5, 0 );
// HOW TO SUBTRACT cube_Y - cubeA?
//create a group and add the three cubes
var group = new THREE.Group();
group.add( cubeA );
group.add( cube_Y );
scene.add( group );
Thanks for helping me!
An option is to use ThreeCSG / ThreeBSP to subtract geometries.
Create ThreeBSP objects form the cube geometries:
var geometry_Y = new THREE.BoxBufferGeometry( 1.5, 1.5, 0.99 );
var geometry_A = new THREE.BoxBufferGeometry( 0.7, 0.7, 0.7 );
geometry_A.translate( 0.5, 0.5, 0 );
var bsp_A = new ThreeBSP(geometry_A);
var bsp_Y = new ThreeBSP(geometry_Y);
Subtract the geometry and create a Mesh:
var bsp_YsubA = bsp_Y.subtract(bsp_A);
var bsp_mesh = bsp_YsubA.toMesh();
bsp_mesh.material = new THREE.MeshLambertMaterial( { color: 0x00ff00 } );
scene.add( bsp_mesh );
See the example:
(function onLoad() {
var container, camera, scene, renderer, controls;
init();
animate();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(3, 1, -1);
scene.add(camera);
window.onresize = function() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.x = 4;
directionalLight.position.y = 1;
directionalLight.position.z = -2;
scene.add( directionalLight );
controls = new THREE.OrbitControls(camera, renderer.domElement);
addGridHelper();
createModel();
}
function createModel() {
var geometry_Y = new THREE.BoxBufferGeometry( 1.5, 1.5, 0.99 );
var geometry_A = new THREE.BoxBufferGeometry( 0.7, 0.7, 0.7 );
geometry_A.translate( 0.5, 0.5, 0 );
var bsp_A = new ThreeBSP(geometry_A);
var bsp_Y = new ThreeBSP(geometry_Y);
var bsp_YsubA = bsp_Y.subtract(bsp_A);
var bsp_mesh = bsp_YsubA.toMesh();
bsp_mesh.material = new THREE.MeshLambertMaterial( { color: 0x00ff00 } );
scene.add( bsp_mesh );
}
function addGridHelper() {
var helper = new THREE.GridHelper(10, 10);
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper(100);
scene.add(axis);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<!--script src="https://threejs.org/build/three.js"></!--script-->
<script src="https://rawcdn.githack.com/mrdoob/three.js/r124/build/three.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r124/examples/js/controls/OrbitControls.js"></script>
<script src="https://rawgit.com/Wilt/ThreeCSG/develop/ThreeCSG.js"></script>
<div id="container"></div>
See also
Unexpected result using ThreeCSG
After using the threeBSP method, the created spheres are not smooth
https://github.com/manthrax/THREE-CSGMesh
You could try my CSG library. It is more robust than the other threejs csg solutions.

Three.js: Trouble Casting Basic Shadow

I'm sorry to ask such a basic question about three, but I can't see what I'm missing. I'm trying to make a torus cast a shadow on a plane, but the shadow isn't appearing.
Can anyone see what I'm missing? Any pointers would be greatly appreciated!
// generate a scene object
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);
// generate a camera
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 1000);
camera.position.set(0, 1, -150);
// generate a renderer
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio); // <3 retina
renderer.setSize(window.innerWidth, window.innerHeight); // canvas size
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
// generate controls
var controls = new THREE.TrackballControls(camera, renderer.domElement);
// generate some lights
var ambientLight = new THREE.AmbientLight(0xeeeeee);
scene.add(ambientLight);
// create light that casts shadows
var light = new THREE.PointLight(0xffffff);
light.position.set(0, 0, -100);
light.castShadow = true;
scene.add(light);
// render loop
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
controls.update();
};
// draw some geometries
var geometry = new THREE.TorusGeometry( 10, 3, 16, 100 );
var material = new THREE.MeshNormalMaterial( { color: 0xffff00 } );
var torus = new THREE.Mesh( geometry, material );
torus.position.set(0, 0, -10);
torus.castShadow = true;
scene.add( torus );
var geometry = new THREE.PlaneGeometry( 200, 200, 32 );
var material = new THREE.MeshBasicMaterial(
{color: 0xffff00, side: THREE.DoubleSide} );
var plane = new THREE.Mesh( geometry, material );
plane.receiveShadow = true;
scene.add( plane );
render();
html, body { width: 100%; height: 100%; background: #000; }
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
<body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js'></script>
<script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>
</body>
MeshBasicMaterial doesn't react to light. Any color you assign to it basically behaves as an emissive color. Maybe you meant to use MeshStandardMaterial?
// generate a scene object
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);
// generate a camera
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 1000);
camera.position.set(0, 1, -150);
// generate a renderer
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio); // <3 retina
renderer.setSize(window.innerWidth, window.innerHeight); // canvas size
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
// generate controls
var controls = new THREE.TrackballControls(camera, renderer.domElement);
// generate some lights
var ambientLight = new THREE.AmbientLight(0xeeeeee);
// scene.add(ambientLight);
// create light that casts shadows
var light = new THREE.PointLight(0xffffff);
light.position.set(0, 0, -100);
light.castShadow = true;
scene.add(light);
// render loop
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
controls.update();
};
// draw some geometries
var geometry = new THREE.TorusGeometry( 10, 3, 16, 100 );
var material = new THREE.MeshNormalMaterial( { color: 0xffff00 } );
var torus = new THREE.Mesh( geometry, material );
torus.position.set(0, 0, -10);
torus.castShadow = true;
scene.add( torus );
var geometry = new THREE.PlaneGeometry( 200, 200, 32 );
var material = new THREE.MeshStandardMaterial(
{color: 0xffff00, side: THREE.DoubleSide} );
var plane = new THREE.Mesh( geometry, material );
plane.receiveShadow = true;
scene.add( plane );
render();
html, body { width: 100%; height: 100%; background: #000; }
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
<body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js'></script>
<script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>
</body>

three js shape from transparent image

Hi I'm trying to create a 3d model with the upper and lower sides of a transparent image shape, and the others of single color (yellow in this example)
var texture = new THREE.TextureLoader().load( 'img.png' );
var img = new THREE.MeshBasicMaterial( { map: texture } );
var geom = new THREE.BoxGeometry(25,25,1);
https://jsfiddle.net/k2aoh7um/
I'd like to get this:
how can I do that?
The only way, that I can imagine how to achieve this, is to use THREE.Shape() and THREE.ExtrudeBufferGeometry():
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 1, 2);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x101010);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var center = new THREE.Vector2();
var starLong = new THREE.Vector2(0, 1);
var starShort = new THREE.Vector2(0, 0.5).rotateAround(center, THREE.Math.degToRad(36));
var angle = THREE.Math.degToRad(72);
var points = [];
for (var i = 0; i < 5; i++) {
points.push(starLong.clone().rotateAround(center, angle * i));
points.push(starShort.clone().rotateAround(center, angle * i));
}
var path = new THREE.Shape(points);
var geom = new THREE.ExtrudeBufferGeometry(path, {
steps: 1,
amount: 0.0625,
bevelEnabled: false
});
geom.rotateX(-Math.PI * 0.5);
var star = new THREE.Mesh(geom, new THREE.MeshBasicMaterial({
color: "orange",
wireframe: true
}));
scene.add(star);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

three.js multiple images on cylinder face

I am trying to display multiple images on the outside (not the top or bottom) of a rotating cylinder using three.js. I am able to display 1 image, but my goal is to display several side by side. I have added 3 textures to my materials array, but only the first is displayed. Any help is appreciated.
<html>
<head>
<title>My first three.js app</title>
<span>Test</span>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.y = 24;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var diameter = 20;
var geometry = new THREE.CylinderGeometry( diameter, diameter, 15, 32 );
var texture1 = new THREE.TextureLoader().load( 'images/image1.jpg' );
var texture2 = new THREE.TextureLoader().load( 'images/image2.jpg' );
var texture3 = new THREE.TextureLoader().load( 'images/image3.png' );
texture1.wrapS = THREE.RepeatWrapping;
//texture.wrapT = THREE.RepeatWrapping;
//texture.repeat.set( 1, 4 );
var materials = [];
materials.push(new THREE.MeshBasicMaterial({ map: texture1 }));
materials.push(new THREE.MeshBasicMaterial({ map: texture2 }));
materials.push(new THREE.MeshBasicMaterial({ map: texture3 }));
var cylinder = new THREE.Mesh( geometry, materials );
cylinder.position.y = 25;
scene.add( cylinder);
camera.position.z = 40;
function render() {
requestAnimationFrame(render);
//cylinder.rotation.z += 0.05;
cylinder.rotation.y += 0.005;
renderer.render(scene, camera);
}
render();
</script>
</body>
You want to apply three textures to your cylinder.
If you don't want to merge your textures into a single texture, one easy solution is to render three cylinder wedges, each with its own texture. Use a pattern like the following:
var group = new THREE.Group();
scene.add( group );
var geometry = new THREE.CylinderBufferGeometry( 5, 5, 10, 16, 1, false, 0, 2 * Math.PI / 3 ); // 1/3 cylinder wedge
var endCapMaterial = new THREE.MeshBasicMaterial();
// mesh
mesh = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { map: texture1 } ), endCapMaterial, endCapMaterial ] );
mesh.rotation.set( 0, 0, 0 );
group.add( mesh );
mesh = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { map: texture2 } ), endCapMaterial, endCapMaterial ] );
mesh.rotation.set( 0, 2 * Math.PI / 3, 0 );
group.add( mesh );
mesh = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { map: texture3 } ), endCapMaterial, endCapMaterial ] );
mesh.rotation.set( 0, 4 * Math.PI / 3, 0 );
group.add( mesh );
three.js r.89
Another way is to assign textures to each face of your geometry using geometry.faces[i].materialIndex property. In this case you should use the number of radial segments that is a multiple of three (if you have 3 textures).
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
<html>
<head>
<title>My first three.js app</title>
<style>
body { margin: 0; overflow:hidden;}
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.y = 24;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var diameter = 20;
var radialSegments = 33;
var geometry = new THREE.CylinderGeometry( diameter, diameter, 15, radialSegments );
var img1 = "http://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX9108127.jpg";
var img2 = "http://d2gg9evh47fn9z.cloudfront.net/thumb_COLOURBOX8923432.jpg";
var img3 = "http://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX19377428.jpg";
var texture1 = new THREE.TextureLoader().load( img1 );
var texture2 = new THREE.TextureLoader().load( img2 );
var texture3 = new THREE.TextureLoader().load( img3 );
THREE.DefaultLoadingManager.onLoad = function () {
var materials = [];
materials.push(new THREE.MeshBasicMaterial({ map: texture1 }));
materials.push(new THREE.MeshBasicMaterial({ map: texture2 }));
materials.push(new THREE.MeshBasicMaterial({ map: texture3 }));
var l = geometry.faces.length;
for (var i = 0; i < l; i++) {
if (geometry.faces[i].normal.y !== 0) {
// these are caps
geometry.faces[i].materialIndex = 0;
} else {
// each segment has 2 faces
geometry.faces[i].materialIndex = Math.floor(i * 3 / (radialSegments * 2));
}
}
var cylinder = new THREE.Mesh( geometry, materials);
cylinder.position.y = 25;
scene.add( cylinder);
camera.position.z = 40;
function render() {
requestAnimationFrame(render);
cylinder.rotation.y += 0.005;
renderer.render(scene, camera);
}
render();
}
</script>
</body>

Three.js - Why is csg.js not working?

I tried to use csg.js-functions to cut a sphere out of a box, but it is not working? I read the tutorial on http://learningthreejs.com/blog/2011/12/10/constructive-solid-geometry-with-csg-js/ but its still not working.
<html>
<head>
<title>Experiment</title>
</head>
<body>
<script src="three_js\build\three.min.js"></script>
<script src="ThreeCSG.js"></script>
<script src="csg.js"></script>
<script type="text/javascript">
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-20, window.innerHeight -20);
document.body.appendChild( renderer.domElement );
var geometry1 = new THREE.BoxGeometry( 10, 10, 10);
var material = new THREE.MeshPhongMaterial( {specular: "#fdfb57", color: "#d8d613", emissive: "#6b6a0d", side: THREE.DoubleSide} );
var box = new THREE.Mesh(geometry1, material);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(5, 32, 32), material);
scene.add(box);
scene.add(sphere);
var boxCsg = THREE.CSG.toCSG(box);
var sphereCsg = THREE.CSG.toCSG(sphere);
boxCsg.substract(sphereCsg);
box = THREE.CSG.fromCSG(boxCsg);
camera.position.z = 50;
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set( 5, 10, 5 );
scene.add( directionalLight );
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
//Hier wird die Größe des Fensters manipuliert!
renderer.setSize(window.innerWidth - 20, window.innerHeight - 20);
};
render();
</script>
</body>
</html>
The article is outdated, this is the new syntax:
var box = new THREE.Mesh( new THREE.BoxGeometry( 10, 1, 10 ) );
var box_bsp = new ThreeBSP( box );
var cutgeo = new THREE.SphereGeometry( 1, 16, 8 );
var sub = new THREE.Mesh( cutgeo );
var subtract_bsp = new ThreeBSP( sub );
var result_bsp = box_bsp.subtract( substract_bsp );
var result = result_bsp.toMesh();
scene.add( result );
Three.js r107:
http://jsfiddle.net/r7suq1mv/2/

Categories

Resources