Reputation: 75
I am trying to set up image background for my scene with globe in three.js, but unfortunately, when I did it the main object of my scene also became black (the same colour with background.
I used method:
renderer = new THREE.WebGLRenderer({ antialias: false, alpha:true });
Which makes default background transparent. And then I added image-background in CSS part.
My whole script for the scene looks like this:
var container, stats;
var camera, scene, renderer;
var group;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
//closer
camera.position.z = 500;
scene = new THREE.Scene();
group = new THREE.Group();
scene.add( group );
// earth
var loader = new THREE.TextureLoader();
loader.load( 'textures/mapnew1.jpg', function ( texture ) {
var geometry = new THREE.SphereGeometry( 180, 32, 32 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
} );
// shadow
var canvas = document.createElement( 'canvas' );
canvas.width = 128;
canvas.height = 128;
var context = canvas.getContext( '2d' );
var gradient = context.createRadialGradient(
canvas.width / 2,
canvas.height / 2,
0,
canvas.width / 2,
canvas.height / 2,
canvas.width / 2
);
gradient.addColorStop( 0.1, '#000000' );
gradient.addColorStop( 1, '#000000' );
context.fillStyle = gradient;
context.fillRect( 0, 0, canvas.width, canvas.height );
var texture = new THREE.CanvasTexture( canvas );
var geometry = new THREE.PlaneBufferGeometry( 300, 300, 3, 3 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 200;
mesh.rotation.x = - Math.PI / 2;
group.add( mesh );
renderer = new THREE.CanvasRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer = new THREE.WebGLRenderer({ antialias: false, alpha:true });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor(0x000000, 0);
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * 0.08;
camera.position.y += ( - mouseY - camera.position.y ) * 0.08;
camera.lookAt( scene.position );
group.rotation.y -= 0.003;
renderer.render( scene, camera );
}
</script>
This is my CSS:
body {
color: #ffffff;
font-family:'Futura';
font-size:20px;
text-align: center;
background-image: url(textures/starfield.png);
background-color: black;
margin: 0px;
overflow: hidden;
}
Do you have any ideas how to fix it and make globe visible?
Thank you very much!
Upvotes: 2
Views: 6838
Reputation: 75
The previous solutions didn't work for me, they miss the using of callback so at least from v.0.124 of the library, this is how you can set the background image for the scene:
var texture_bg = new THREE.TextureLoader().load("img/bg.jpg", () => {
scene.background = texture_bg;
});
Upvotes: 0
Reputation: 45062
There are two ways to do it
1) Load a image using TextureLoader
and set it as background. This will result into static background which may not look very realistic.
var texture = new THREE.TextureLoader().load(
"https://images.pexels.com/photos/110854/pexels-photo-110854.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"
);
scene.background = texture;
2) Use skybox
to load images for top, left, right bottom, front back sides. Then set them inside a cube or sphere geometry
var urls = [
"https://images.pexels.com/photos/110854/pexels-photo-110854.jpeg",
"https://images.pexels.com/photos/110854/pexels-photo-110854.jpeg",
"https://images.pexels.com/photos/110854/pexels-photo-110854.jpeg",
"https://images.pexels.com/photos/110854/pexels-photo-110854.jpeg",
"https://images.pexels.com/photos/110854/pexels-photo-110854.jpeg",
"https://images.pexels.com/photos/110854/pexels-photo-110854.jpeg"
];
var materialArray = [];
for (var i = 0; i < 6; i++)
materialArray.push(
new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load(urls[i]),
side: THREE.BackSide
})
);
var skyGeometry = new THREE.SphereGeometry(400, 32, 32);
var skyMaterial = new THREE.MeshFaceMaterial(materialArray);
var skybox = new THREE.Mesh(skyGeometry, skyMaterial);
scene.add(skybox);
This will give a sphere with images as texture on backside. Just replace THREE.SphereGeometry
with THREE.CubeGeometry
and you can emulate envMap.
Upvotes: 2
Reputation: 1114
Since a while, there is:
var texture = new THREE.TextureLoader().load( "textures/bg.jpg" );
scene.background = texture;
I'm using three.js v 0.87
Upvotes: 2
Reputation: 8866
Regarding the background image, you are setting the alpha
value for WebGLRenderer
, which is correct. You didn't post your CSS, but ensure you're setting the background image on your container
, not on the canvas.
Also, comment out this line:
renderer.setClearColor(0x000000, 0);
You don't need to set a clear color, since you are clearing to transparency, not a color. That should resolve the background image issue.
Regarding the all-black model, you need a light in your scene. Try adding this to your init
method:
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
This will add a light source at the location of your camera (and will follow the camera as it moves).
Edit to add snippet:
var container, stats;
var camera, scene, renderer;
var group;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 2000);
//closer
camera.position.z = 500;
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
scene = new THREE.Scene();
group = new THREE.Group();
scene.add(group);
// earth
var loader = new THREE.TextureLoader();
loader.crossOrigin = '';
loader.load('https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Equirectangular_projection_SW.jpg/640px-Equirectangular_projection_SW.jpg', function(texture) {
var geometry = new THREE.SphereGeometry(180, 32, 32);
var material = new THREE.MeshBasicMaterial({
map: texture,
overdraw: 0.5
});
var mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
});
// shadow
var canvas = document.createElement('canvas');
canvas.width = 128;
canvas.height = 128;
var context = canvas.getContext('2d');
var gradient = context.createRadialGradient(
canvas.width / 2,
canvas.height / 2,
0,
canvas.width / 2,
canvas.height / 2,
canvas.width / 2
);
gradient.addColorStop(0.1, '#000000');
gradient.addColorStop(1, '#000000');
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
var texture = new THREE.CanvasTexture(canvas);
var geometry = new THREE.PlaneBufferGeometry(300, 300, 3, 3);
var material = new THREE.MeshBasicMaterial({
map: texture,
overdraw: 0.5
});
var mesh = new THREE.Mesh(geometry, material);
mesh.position.y = -200;
mesh.rotation.x = -Math.PI / 2;
group.add(mesh);
renderer = new THREE.WebGLRenderer({
antialias: false,
alpha: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
//renderer.setClearColor(0x000000, 0);
container.appendChild(renderer.domElement);
stats = new Stats();
container.appendChild(stats.dom);
document.addEventListener('mousemove', onDocumentMouseMove, false);
//
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX);
mouseY = (event.clientY - windowHalfY);
}
//
function animate() {
requestAnimationFrame(animate);
render();
stats.update();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.08;
camera.position.y += (-mouseY - camera.position.y) * 0.08;
camera.lookAt(scene.position);
group.rotation.y -= 0.003;
renderer.render(scene, camera);
}
body {
color: #ffffff;
font-family: 'Futura';
font-size: 20px;
text-align: center;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/6/62/Starsinthesky.jpg);
background-color: black;
margin: 0px;
overflow: hidden;
}
<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/renderers/Projector.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<div id="container"></div>
three.js r86
Upvotes: 2