I made a trial with basic scene of threejs but I can't understand why the canvas background is completely black.
<html>
<head>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100%;background-color: white; }
</style>
</head>
<body>
<script src="Stereos/threejs/three.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 );
</script>
</body>
</html>
EDIT:
Code at felpone.netsons.org
The color of the background of the canvas is not determined by the CSS value but using renderer.setClearColor (0xff0000, 1);
You can control the background color using css, but you must first set the "alpha" of your WebGLRenderer to "true".
In you example, I added the alpha option and set to true in the renderer, and I also added the background-color property in the body style.
<html>
<head>
<title>My first Three.js app</title>
<style>
body { margin: 0; background-color: white; }
canvas { width: 100%; height: 100%; background-color: white; }
</style>
</head>
<body>
<script src="Stereos/threejs/three.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( {alpha: true} );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
</script>
</body>
</html>
Better add the background to the scene directly which can be a texture or a THREE.Color!
From r78 versions onwards, you can use the code below to set your scene's background colour:
var scene = new THREE.Scene();
scene.background = new THREE.Color( 0x000000 );
Docs:
Scene.background
You made a scene, created a camera and created a renderer, but you're missing two important things: adding something to render, and actually rendering it.
After your last line, add
var cube = new THREE.Mesh(
new THREE.CubeGeometry( 1,1,1 ),
new THREE.MeshNormalMaterial()
);
scene.add( cube );
camera.position.set( 2,2,2 );
camera.lookAt( cube.position );
renderer.render( scene, camera );
That will create a cube on the origin ( 0,0,0 ), with size 1 unit; place the camera a bit away from it and pointed at the cube; and then call the renderer to render the cube.
Updating this for the latest version of ThreeJS (2019) -
After you instantiate your scene using:
scene = new THREE.Scene();
You can then access the "background" property of this object and set the hex color like this:
scene.background = new THREE.Color(0xf5f5f5);
#Jaume Sanchez is the correct answer. Although the others answers are factual, I don't think that they answer what you where asking as a person new to threeJS. the var rendereris just a reference to your render target. your code does not draw anthing. You also do not have a camera in your scene to look at anything. Creating a scene a tutorial for getting started
If for some reason:
renderer.setClearColor(0xff0000, 1);
does not work, try this:
const renderer = new THREE.WebGLRenderer();
renderer.domElement.className = "domElement";
and in css add a selector:
.domElement {
background-color: red; /* any color */
}
Related
I just updated to the latest version of three.js,
and THREE.ImageUtils.loadTexture doesn't work anymore.
So i searched for cubes with different faces but they all
use the old technique " new THREE.ImageUtils.loadTexture".
I tried making one with "new THREE.TextureLoader.load(' texture1.png ')".
This is what i have:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometry - cube</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 {
margin: 0px;
background-color: #000000;
overflow: hidden;
}
</style>
</head>
<body>
<script src="library/threejs/build/three.js"></script>
<script>
var camera, scene, renderer;
var head;
var loader = new THREE.TextureLoader();
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400;
scene = new THREE.Scene();
materials = [
new THREE.TextureLoader().load( 'textures/mob/zombie/zombie_headfront.png' ),
new THREE.TextureLoader().load( 'textures/mob/zombie/zombie_headback.png' ),
new THREE.TextureLoader().load( 'textures/mob/zombie/zombie_headleft.png' ),
new THREE.TextureLoader().load( 'textures/mob/zombie/zombie_headright.png' ),
new THREE.TextureLoader().load( 'textures/mob/zombie/zombie_headup.png' ),
new THREE.TextureLoader().load( 'textures/mob/zombie/zombie_headdown.png' )];
head = new THREE.Mesh(
new THREE.BoxBufferGeometry(80, 80, 80, 1, 1, 1, materials),
new THREE.MeshBasicMaterial({ map: materials })
);
scene.add( head );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
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 );
head.rotation.x += 0.005;
head.rotation.y += 0.01;
renderer.render( scene, camera );
}
</script>
</body>
</html>
but i'm getting the error:
TypeError: offset is undefined
and
THREE.WebGLShader: Shader couldn't compile
and also
THREE.WebGLShader: gl.getShaderInfoLog() fragment ERROR: 0:238:
'mapTexelToLinear' : no matching overloaded function found
So if you know how to fix this or just know how to make a cube with 6 different sides that would be awesome!
thanks!
THREE.js has an undocumented material, THREE.MeshFaceMaterial which has been deprecated for a while now but still works in r81.
// Make an array of six regular materials
var materials = [
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("https://i.imgur.com/8B1rYNY.png")}),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("https://i.imgur.com/8w6LAV6.png")}),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("https://i.imgur.com/aVCY4ne.png")}),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("https://i.imgur.com/tYOW02D.png")}),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("https://i.imgur.com/nVAIICM.png")}),
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load("https://i.imgur.com/EDr3ed3.png")})
];
var geometry = new THREE.BoxBufferGeometry(200, 200, 200);
// Use THREE.MeshFaceMaterial for the cube, using the array as the parameter
mesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
Demo
Apparently the way this works internally is by creating a THREE.BufferGeometry plane for each face of the cube and applying each material to a face (mrdoob himself). In other words, if this method stops working your alternative is to manually make a cube out of 6 planes, make them children of a null object so you can treat them as a single cube, and then apply your materials to each plane separately.
If you don't need to dynamically determine the cube faces at runtime and can "bake" them into a texture, a technically better (but more difficult) option is to use UV mapping.
I have the following Three.js code:
<html>
<head>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script src="js/optimer_regular.typeface.js"></script>
<script>
//Basic Three components
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 );
//Let´s add a cube
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
//Let´s add a text
var material2 = new THREE.MeshPhongMaterial({
color: 0x00ff00
});
var textGeom = new THREE.TextGeometry( 'Sitescope', {
font: 'optimer',
weight: 'normal'
});
var textMesh = new THREE.Mesh( textGeom, material2 );
scene.add( textMesh );
//Render scene
function render() {
requestAnimationFrame( render );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
}
render();
</script>
</body>
When i run my code, My cube renders well but my text does not appear anywhere.
The only output that i get in the javascript console is:
THREE.WebGLRenderer 69.
Could anyone tell me why my text does not appear? (I am a beginner in Three.js) Thanks!
When using a THREE.MeshPhongMaterial() you need a light in the scene. Otherwise the model will come out black. If your scene background is also black you will never know if the model was drawn or not. Take a look at this fiddle. I am using THREE.MeshNormalMaterial(). Replace it with PhongMaterial to see what I am talking about. You can see the text is being drawn with black color just because it is over the green cube.
I am new in three.js and using the following code I want to know how to change the background by clicking a button. So I think there is something different than using "switch" and "break". Here is something with .loadTexture am I right?
<html lang="en">
<head>
<title>gyroscopic</title>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, initial-scale=1">
<style>
body {
margin: 0px;
background-color: #000000;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="three.min.js"></script>
<script src="DeviceOrientationControls.js"></script>
<script>
(function() {
"use strict"
window.addEventListener('load', function() {
var container, camera, scene, renderer, controls, geometry, mesh;
var animate = function(){
window.requestAnimationFrame( animate );
controls.update();
renderer.render(scene, camera);
};
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 1100);
controls = new THREE.DeviceOrientationControls( camera );
scene = new THREE.Scene();
var geometry = new THREE.SphereGeometry( 500, 316, 18 );
geometry.applyMatrix( new THREE.Matrix4().makeScale( -1, 1, 1 ) );
var material = new THREE.MeshBasicMaterial( {
map: THREE.ImageUtils.loadTexture( 'pic.jpg' )
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
var geometry = new THREE.BoxGeometry( 100, 100, 100, 4, 4, 4 );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.domElement.style.position = 'absolute';
renderer.domElement.style.top = 0;
container.appendChild(renderer.domElement);
window.addEventListener('resize', function() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}, false);
animate();
}, false);
})();
</script>
</body>
</html>
You should be able to change the texture using .loadTexture on a button click listener.
So you would probably add something like this to your HTML:
<button id="change-background">Change Background</button>
Then in Javascript:
var backgroundButton = document.getElementById('change-background');
backgroundButton.addEventListener('click', function(){
material.map = THREE.ImageUtils.loadTexture('//new image path//');
});
You'll obviously need to replace the //new image path// with whatever URL you have for the new image.
The only question would be whether this updates the material on the mesh as well. I'm sure it does, but have no way of testing it at present.
I am trying to attempt to learn Three.js from their getting started guide: http://threejs.org/docs/index.html#Manual/Introduction/Creating_a_scene and I have the code as exactly from the site. I am using the latest code from their site, as for the library. The error in the console is as follows:
Uncaught TypeError: Object #<Object> has no method 'mergeVertices'
I am not really too sure on what the issue is
Here is the code that is from the site that I am using:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>First Three JS App</title>
<style>
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
// To be able to view anything with Three.js we need a scene, a camera, and a renderer
// -> To render the scene with the camera
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 = THREE.BoxGeometry(10, 10, 10 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 });
var cube = new THREE.Mesh( geometry, material);
scene.add( cube );
camera.position.z = 5;
var render = function render() {
requestAnimationFrame( render )
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render( scene, camera );
};
render();
</script>
</body>
</html>
From what #WestLangley suggested, I needed to review my code. I was missing a new in geometry declaration, and my renderer.setSize call needed 2 params instead of 1 (I was using a ratio) and the final var render = function.... I needed to take out the second render
Sometimes it is good to have a second pair of eyes.. Thanks again #WestLangley
I have a problem, I can't load DAE file in Three.js. Can anybody help please.
I have model.dae in the same directory as index.html and when I load page it shows only black screen.
I had a file FBX and I exported it with Maya to FBX_DAE
<html>
<head>
<title>My first Three.js app</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<style type="text/css">
html, body {
margin:0;
padding: 0;
}
</style>
<script src="js/three.min.js"></script>
<script src="js/ColladaLoader.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 );
loader = new THREE.ColladaLoader();
loader.load('model.DAE',function colladaReady( collada ){
player = collada.scene;
skin = collada.skins [ 0 ];
scene.add( player );
});
/*
var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
*/
camera.position.z = 5;
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
//cube.rotation.x += 0.1;
//cube.rotation.y += 0.1;
}
render();
</script>
</body>
</html>
This is just a guess, but I suspect you're not loading the ColladaLoader properly.
Should be this:
<script src="js/ColladaLoader.js"></script>
Instead of this:
<script src="js/ColladaLoader.min.js"></script>
If this is the case you should be seeing a error in the console.
You might have to run your sample on a web server to be able to load the .dae files, since JavaScript does not allow file access on a client for security reasons.
I´ve had the same issue with DAE-Files i had created in Cinema4D. I had to export a FBX from C4D, import it to Blender and export the DAE with Blender.
C4D´s DAE-Exporter seems broken