Add subdivision to a geometry - three.js

I'm trying add subdivisions to a sphere like this:
http://stemkoski.github.com/Three.js/Subdivision-Cube.html
Here's my code: http://jsfiddle.net/mdrorum/HvFLw/
<script src="http://mrdoob.github.com/three.js/build/three.js"></script>
<script type="text/javascript">
var camera, scene, renderer;
var geometry, material, mesh;
var smooth, subdiv, modifier;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000;
scene = new THREE.Scene();
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
geometry = new THREE.SphereGeometry( 200 );
material = new THREE.MeshBasicMaterial( { color: 0x00ff00, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
var smooth = mesh.clone();
var subdiv = 3;
var modifier = new THREE.SubdivisionModifier( subdiv );
//modifier.modify( smooth );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
</script>
This works fine, but uncomment: //modifier.modify( smooth );
Nothing happens. :(
How I can add subdivisions?

Here you can find a good tutorial with a working demo. Citing the author:
// First we want to clone our original geometry.
// Just in case we want to get the low poly version back.
var smooth = THREE.GeometryUtils.clone( geometry );
// Next, we need to merge vertices to clean up any unwanted vertex.
smooth.mergeVertices();
// Create a new instance of the modifier and pass the number of divisions.
var divisions = 3;
var modifier = new THREE.SubdivisionModifier(divisions);
// Apply the modifier to our cloned geometry.
modifier.modify( smooth );
// Finally, add our new detailed geometry to a mesh object and add it to our scene.
var mesh = new THREE.Mesh( smooth, new THREE.MeshPhongMaterial( { color: 0x222222 } ) );
scene.add( mesh );

You are trying to modify a mesh. You need to modify a geometry.
modifier.modify( geometry );

Related

Render second scene to texture not working

I'm trying to learn something new in three.js. My goal is to be able to use what a second camera sees in a separate scene as a texture for the main scene.
Or alternatively to be able to use what a second camera sees in the main scene as a texture. But i only see a black screen. I posted my code for it here. I hope someone recognizes where my mistake is, because I just can't figure it out.
In 3 steps:
texture = second camera view
material use texture
apply material ordinary to a mesh
see below
var camera, controls, scene, renderer, container, aspect;
function main() {
init();
animate();
}
function init() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
container = document.getElementById('container');
renderer.setSize(container.clientWidth, container.clientHeight);
container.appendChild( renderer.domElement );
aspect = container.clientWidth / container.clientHeight;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x000000 );
camera = new THREE.PerspectiveCamera( 60, container.clientWidth / container.clientHeight, 1, 1000000 );
camera.position.set(0, 0, 200);
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableZoom = true;
controls.enabled = true;
controls.target.set(0, 0, 0);
//-----End three basic setups-----
var tex = generateTexture(renderer);
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry(100.0, 100.0),
new THREE.MeshBasicMaterial({
color: 0x00caff,
map: tex,
side: THREE.DoubleSide,
})
);
scene.add(plane);
}//-------End init----------
function animate() {
requestAnimationFrame( animate );
render();
}//-------End animate----------
function render() {
camera.updateMatrixWorld();
camera.updateProjectionMatrix();
renderer.render(scene, camera);
}//-------End render----------
function generateTexture(renderer) {
var resolution = 2000;
var textureScene = new THREE.Scene();
textureScene.background = new THREE.Color(0x404040);
var renderTarget = new THREE.WebGLRenderTarget(resolution, resolution, {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat});
var textureCamera = new THREE.PerspectiveCamera(60, aspect, 0.1, 100000.0);
textureCamera.position.set(0, 0, 200);
textureCamera.lookAt(0, 0, 0);
var geometry = new THREE.SphereGeometry( 60, 32, 16 );
var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
var sphere = new THREE.Mesh( geometry, material);
textureScene.add( sphere );
//---changes---
renderer.setRenderTarget( renderTarget );
renderer.clear();
renderer.render( textureScene, textureCamera );
renderer.setRenderTarget(null);
return renderTarget.texture;
//-------------
//---now it works fine---:)
}//----- End generateTexture ------
Are you copying this approach from a tutorial? What version of three.js are you using? I'm asking because you're using renderer.render(scene, camera, target, true); but the docs state that .render() only accepts two arguments, so passing a renderTarget doesn't do anything.
I recommend you copy the approach in this demo, you can see the source code by clicking on the < > icon. The essential part is as follows:
// Render first scene into texture
renderer.setRenderTarget( renderTarget );
renderer.clear();
renderer.render( textureScene, textureCamera );
// Render full scene to canvas
renderer.setRenderTarget( null );
renderer.clear();
renderer.render( scene, camera );

Three.js: group of geometry

1.I want to combine the geometry,what should i do ?
By using position? And i even want to let the group of geometry move in the scene together what should i do? By using add()?For example: the group of demond
Why my triangle failed to draw?
my code:
var mesh, renderer, scene, camera, controls;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 20, 20, 20 );
// controls
controls = new THREE.OrbitControls( camera );
// ambient
scene.add( new THREE.AmbientLight( 0x00ffff ) );
// light
var light = new THREE.DirectionalLight( 0x00ffff, 1 );
light.position.set(10, 10, 0 );
//scene.add( light );
// axes
scene.add( new THREE.AxisHelper( 20 ) );
var verticesOfTriangle1 = new THREE.Vector3(1,0,0);
var verticesOfTriangle2 = new THREE.Vector3(0,0,0.3);
var verticesOfTriangle3 = new THREE.Vector3(0,0,-0.3);
var geometry = new THREE.Triangle(verticesOfTriangle1, verticesOfTriangle2, verticesOfTriangle3);
// material
var material = new THREE.MeshPhongMaterial( {
color: 0x00ffff,
shading: THREE.FlatShading,
transparent: true,
opacity: 0.7,
} );
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
the message from chrome:The error message
Use THREE.Group() to combine objects and move them together.
You can use THREE.ShapeGeometry() to create a triangle. To create a mesh your geometry should inherit properties of THREE.Geometry(). Look into geometries of threejs documentation for default geometries supported.

Three.js - Camera collision with scene

This is my first question in StackOverflow, but I've been browsing it for some years now, so I kindly ask you to bear with me. :)
I've been experimenting with Three.js to create a 3D world, and everything looked fine until I needed to control the camera. Since I'm using this lib to avoid having to do matricial calculations myself I found and added TrackballControls to my code aswell. It worked fine but then my camera could pass through the 3D shapes, and also below terrain. Unfortunately, although the movement is exactly what I needed, it didn't serve the purpose of allowing camera to respect collision.
My scene is simply the ground (thin BoxGeometry) and a cube (normal-sized BoxGeometry), and a rotating sphere that shares directionalLight position for a "sun light" effect. Some people here suggested adding Physijs to the code and simulate() physics within the scene, and adding a BoxMesh to the camera to make the physics apply to it aswell, but it simply didn't work (scene turned blank).
My working code so far (without Physijs) is:
window.onload = function() {
var renderer, scene, camera, ground, box, sphere, ambient_light, sun_light, controls;
var angle = 0;
var clock = new THREE.Clock();
init();
render();
function init(){
// Create renderer and add it to the page
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xffffff );
renderer.shadowMapEnabled = true;
document.body.appendChild( renderer.domElement );
// Create a scene to hold our awesome 3D world
scene = new THREE.Scene();
/*** 3D WORLD ***/
// Objects
ground = new THREE.Mesh(
new THREE.BoxGeometry(50, 1, 50),
new THREE.MeshLambertMaterial({ color: 0x33CC33 }),
0 // mass
);
ground.receiveShadow = true;
scene.add( ground );
box = new THREE.Mesh(
new THREE.BoxGeometry( 10, 10, 10 ),
new THREE.MeshLambertMaterial({ color: 0xDD3344 })
);
box.position.y = 5;
box.castShadow = true;
scene.add( box );
sphere = new THREE.Mesh(
new THREE.SphereGeometry( 3, 32, 32 ),
new THREE.MeshBasicMaterial({ color: 0xFFBB00 })
);
sphere.position.set( 1, 15.5, 5 );
scene.add( sphere );
// Light
ambient_light = new THREE.AmbientLight( 0x333333 );
ambient_light.mass = 0;
scene.add( ambient_light );
sun_light = new THREE.DirectionalLight( 0xBBBBBB );
sun_light.position.set( 1, 15.5, 5 );
sun_light.castShadow = true;
sun_light.shadowCameraNear = 1;
sun_light.shadowCameraFar = 100;
sun_light.shadowCameraLeft = -50;
sun_light.shadowCameraRight = 50;
sun_light.shadowCameraTop = -50;
sun_light.shadowCameraBottom = 50;
sun_light.shadowBias = -.01;
scene.add( sun_light );
// Create a camera
camera = new THREE.PerspectiveCamera(
45, // FOV
window.innerWidth / window.innerHeight, // Aspect Ratio
1, // Near plane
1000 // Far plane
);
camera.position.set( 30, 30, 30 ); // Position camera
camera.lookAt( box.position ); // Look at the scene origin
scene.add(camera);
// After swapping THREE.Mesh to Physijs.BoxMesh, this is where I'd attach a BoxMesh to the camera
window.addEventListener( 'resize', onWindowResize, false );
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 4.0;
controls.panSpeed = 0.3;
controls.staticMoving = true; // No sliding after-effects
}
function render() {
// use requestAnimationFrame to create a render loop
angle += .007;
var oscillateZ = Math.sin(angle * (Math.PI*4));
var oscillateX = -Math.cos(angle * (Math.PI*4));
//console.log(oscillateZ);
sphere.position.setZ( sphere.position.z + oscillateZ );
sphere.position.setX( sphere.position.x + oscillateX );
sun_light.position.setZ( sun_light.position.z + oscillateZ );
sun_light.position.setX( sun_light.position.x + oscillateX );
requestAnimationFrame( render );
controls.update();
renderer.render( scene, camera );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
};
Can you guys enlighten me? Thank you for your time!
#Edit
Physijs attempt

Texture in three.js no console errors still not working

I'm new to three.js and need to make a project for school. For this project I need a texture on my cube. But the screen stays black.. and there are no console errors! I did everything I can so this is kinda my last change haha.
My code:
<script src="js/three.min.js"></script>
<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 geometry = new THREE.BoxGeometry( 1, 1, 1 );
// +
var material = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('images/crate2.jpg')
})
// =
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.1;
cube.rotation.y += 0.05;
renderer.render(scene, camera);
};
render();
</script>
You do not have a light in your scene.
Adding one like below should work
// Create ambient light and add to scene.
var light = new THREE.AmbientLight(0xffffff); // white light
scene.add(light);
I would add a link to a js fiddle but it seems they have changed and I can not longer find where to get the link.
Anyway, just ad some sort of light.
Perhaps adding a light would help? That or try using THREE.MeshBasicMaterial

Three.js not showing my texture

I need to make a ball with a texture on it. I'm very new at WebGL and Three.js. The problem is that I see a White Sphere but not the texture on it. As a new user I am not able to submit a picture.
The code part is this:
function init() {
canvas = document.getElementById( 'canvas' );
camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000;
scene = new THREE.Scene();
camera.lookAt (scene.position);
var llum = new THREE.DirectionalLight();
llum.intensity=50;
llum.position.x=camera.position.x;
llum.position.y=camera.position.y;
llum.position.z=camera.position.z;
llum.lookAt(scene.position);
scene.add(llum);
var texture = THREE.ImageUtils.loadTexture('ull.jpg');
texture.needsUpdate = true;
var material = new THREE.MeshBasicMaterial( texture );
var quality = 16, step = 1024 / quality;
var geom = new THREE.SphereGeometry(500,100,100);
mesh = new THREE.Mesh( geom, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer({ antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
canvas.innerHTML = "";
//Afegim al canvas el que hem de renderitzar
canvas.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
Thanks in advance.
It should be like this:
var material = new THREE.MeshBasicMaterial( { map: texture } );
Since this is the first page that shows up in Google search results I will post what was solution in my case. I draw texture on square but the square was actually rotated backward so camera saw back of the square without texture, after fixing rotation everything worked fine.
var geometry = new THREE.PlaneGeometry(FLOOR_SIZE, FLOOR_SIZE, 10, 10);
var loader = new THREE.TextureLoader();
loader.load('images/floor.jpg', function ( texture ) {
var material = new THREE.MeshBasicMaterial({
map: texture,
overdraw: 0.5
});
var floor = new THREE.Mesh( geometry, material );
// ROTATION THAT MADE SQUARE INVISIBLE WAS Math.PI/2
floor.rotation.x = -Math.PI/2;
floor.position.y = -0.1;
scene.add(floor);
});

Resources