最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to set up image background in three.js? - Stack Overflow

programmeradmin0浏览0评论

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!

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!

Share Improve this question edited Aug 1, 2017 at 20:36 Pop-A-Stash 6,6525 gold badges29 silver badges54 bronze badges asked Aug 1, 2017 at 16:32 Elena EpsteinElena Epstein 753 silver badges12 bronze badges 2
  • Can you elaborate a little? What is the actual issue? What do you see on the screen? Also, consider creating a plunker(plnkr.co) with your script, HTML, and CSS so we can all be on the same page. – Pop-A-Stash Commented Aug 1, 2017 at 16:46
  • Here is a plunker with your code: plnkr.co/edit/i9gcDMuVAGQ5CqbVDlES?p=preview It has some errors with all available versions of THREE – Pop-A-Stash Commented Aug 1, 2017 at 16:57
Add a ment  | 

4 Answers 4

Reset to default 2

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, ment 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/wikipedia/mons/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/wikipedia/mons/6/62/Starsinthesky.jpg);
  background-color: black;
  margin: 0px;
  overflow: hidden;
}
<script src="https://threejs/build/three.js"></script>
<script src="https://threejs/examples/js/renderers/Projector.js"></script>
<script src="https://threejs/examples/js/libs/stats.min.js"></script>
<div id="container"></div>

three.js r86

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

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./photos/110854/pexels-photo-110854.jpeg?auto=press&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./photos/110854/pexels-photo-110854.jpeg",
      "https://images.pexels./photos/110854/pexels-photo-110854.jpeg",
      "https://images.pexels./photos/110854/pexels-photo-110854.jpeg",
      "https://images.pexels./photos/110854/pexels-photo-110854.jpeg",
      "https://images.pexels./photos/110854/pexels-photo-110854.jpeg",
      "https://images.pexels./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.

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;
  });
发布评论

评论列表(0)

  1. 暂无评论