2
votes

I am new to three.js, and I feel that my scene is close to finished, but when I render I just get the blank canvas element, with no errors in my console. Why isn't my code rendering my texture? I have follow the doc pretty close and and I am just getting hung up on this piece. Thanks for the help. Here is my js:

`var camera, scene, renderer, texture, fog; var mesh, geometry, material, buffer;

        var start_time = Date.now();

        init();
        animate();

        function init() {

            var container = $('#clouds');

            // Bg gradient

            var canvas = document.createElement( 'canvas' );
            canvas.width = 32;
            canvas.height = window.innerHeight;

            var context = canvas.getContext( '2d' );

            var gradient = context.createLinearGradient( 0, 0, 0, canvas.height );
            gradient.addColorStop(0, "#1e4877");
            gradient.addColorStop(0.5, "#4584b4");

            context.fillStyle = gradient;
            context.fillRect(0, 0, canvas.width, canvas.height);

            container.css('background', 'url(' + canvas.toDataURL('image/png') + ')');
            container.css('background-size', '32px 100%');

            //

            camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 3000 );
            camera.position.z = 6000;

            scene = new THREE.Scene();

            geometry = new THREE.Geometry();

            var texture = new THREE.TextureLoader().load( '/media/cloud-element.png', animate);
            THREE.LinearMipMapNearestFilter;
            THREE.LinearMipMapLinearFilter;

            var fog = new THREE.Fog( 0x4584b4, - 100, 3000 );

            material = new THREE.ShaderMaterial( {

                uniforms: {

                    "map": { type: "t", value: texture },
                    "fogColor" : { type: "c", value: fog.color },
                    "fogNear" : { type: "f", value: fog.near },
                    "fogFar" : { type: "f", value: fog.far },

                },
                depthWrite: false,
                depthTest: false,
                transparent: true,
                color: 0xf2f2f2

            } );

            var plane = new THREE.Mesh( new THREE.PlaneGeometry( 64, 64 ) );

            for ( var i = 0; i < 8000; i++ ) {

                plane.position.x = Math.random() * 1000 - 500;
                plane.position.y = - Math.random() * Math.random() * 200 - 15;
                plane.position.z = i;
                plane.rotation.z = Math.random() * Math.PI;
                plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5;

                THREE.GeometryUtils.merge(geometry, plane);
            }

            mesh = new THREE.Mesh( geometry, material );
            scene.add( mesh );

            mesh = new THREE.Mesh( geometry, material );
            mesh.position.z = - 8000;
            scene.add( mesh );

            renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );

            container.append( renderer.domElement );

            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize( event ) {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth, window.innerHeight );

        }

        function animate() {

            requestAnimationFrame( animate );

            var position = ( ( Date.now() - start_time ) * 0.03 ) % 8000;

            camera.position.x += (camera.position.x ) * 0.01;
            camera.position.y += (camera.position.y ) * 0.01;
            camera.position.z = - position + 8000;

            renderer.render( scene, camera );

        }

    }`
1
Can you explain this var plane = new THREE.Mesh( new THREE.PlaneGeometry( 64, 64 ) ); and this new THREE.BufferGeometry(geometry, plane);?prisoner849
This seems to be some leftover code from a bunch of trial and error that should have been removed. Originaly is had geometry.merge(geometry, plane); but when I add this I the the following error angular.js:14110 TypeError: Cannot read property '0' of undefinedSkylar Wuebker

1 Answers

1
votes

You have several warnings which you should probably resolve first. color is not an attribute of THREE.ShaderMaterial. THREE.GeometryUtils.merge(geometry, plane); has been moved to become an API on Geometry. Etc, etc.

I've stripped your code into a simple snippet which can run here (because we don't have access to your texture files).

A whole lost of take-aways from my changes:

  • I removed your initial canvas. You can replace that later. Notice that I added { alpha: true } to the WebGLRenderer parameters. This allows whatever is behind the renderer canvas to show through.
  • I see what you're doing with the new THREE.Mesh( new THREE.Plane(...) ). It's probably easier just to create a bunch of plane meshes, though that does create a bunch of draw calls as well.
  • I replaced your shader definition with a basic color just to get it working. We can work on your texture issue if this updated code doesn't give you any "aha moments." I do want to point out that you might not need a shader for this. THREE.MeshBasicMaterial has a map property which can accept a THREE.Texture (as provided by THREE.TextureLoader).
  • Notice how I handle merging the geometry together. Updating your plane's transformation properties doesn't update its vertices, which is what merge uses. Instead, I created a temporary THREE.Geometry object to hold your vertices, and then I apply your plane's updated transformation matrix to them. This "bakes in" the transform and allows merge to take in the re-positioned vertices.

Other than that, it's pretty much the same. Please take a look and try these techniques in your code. If you're still having trouble with your textures, leave a comment, and we'll revisit them.

var camera, scene, renderer, texture, fog;
var mesh, geometry, material, buffer;

var start_time = Date.now();

init();
animate();

function init() {

  var container = $('#clouds');

  camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 3000);
  camera.position.z = 6000;

  scene = new THREE.Scene();

  geometry = new THREE.Geometry();

  material = new THREE.MeshBasicMaterial({color: 0xf2f2f2, opacity: 0.5, transparent: true});

  var plane = new THREE.Mesh( new THREE.PlaneGeometry(64, 64) ),
    tempGeometry = new THREE.Geometry();

  for (var i = 0; i < 8000; i++) {

    plane.position.x = Math.random() * 1000 - 500;
    plane.position.y = -Math.random() * Math.random() * 200 - 15;
    plane.position.z = i;
    plane.rotation.z = Math.random() * Math.PI;
    plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5;
    // Warning: THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.
    //THREE.GeometryUtils.merge(geometry, plane);
    plane.updateMatrix();
    tempGeometry.copy(plane.geometry);
    tempGeometry.applyMatrix(plane.matrix);
    geometry.merge(tempGeometry);
  }

  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  mesh = new THREE.Mesh(geometry, material);
  mesh.position.z = -8000;
  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({ alpha: true });
  renderer.setSize(window.innerWidth, window.innerHeight);

  container.append(renderer.domElement);

  window.addEventListener('resize', onWindowResize, false);

}

function onWindowResize(event) {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);

}

function animate() {

  requestAnimationFrame(animate);

  var position = ((Date.now() - start_time) * 0.03) % 8000;

  camera.position.x += (camera.position.x) * 0.01;
  camera.position.y += (camera.position.y) * 0.01;
  camera.position.z = -position + 8000;

  renderer.render(scene, camera);

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://threejs.org/build/three.js"></script>
<div id="clouds" style="background: lightBlue;"></div>