Search code examples
node.jsgoogle-chromeopengl-esthree.jstextures

Add material to mesh from node server


While I understand many of you may not have messed around with OWF (Ozone Widge Framework), it's merely wigetized html pages that communicate through a subscription service on the server.

Simple example I'm working with: http://blog.thematicmapping.org/2013/10/textural-terrains-with-threejs.html

I can successfully add a texture via THREE.ImageUtils.loadTexture() while navigating to the html page in Google Chrome. However, when I use OWF in Google Chrome and point my widget to the html page, I can only get it to load the mesh. If I attempt to load the texture, it's completely black. Therefore, it has nothing to do with (chrome --allow-file-access-from-files). I have verified this happens for the few examples I've tried from threejs.org. Obviously, it has something to do with the OWF implementation, but I was under the impression that these frameworks inherited the properties of the browser it was being run in (I could be completely wrong)... therefore, I assumed it would work.

EDIT: I made the poor mistake of assuming it was the widgetized framework causing the trouble. I linked one of the widgets directly to the node website and could not successfully render the terrain material. Then, I tried accessing it through a node.js server with no success.

Here's the code if anyone can tell me why it's black....

<!doctype html>
<html lang="en">
<head>
<title>three.js - Jotunheimen</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: 0; overflow: hidden; }
</style>
</head>
<body>
<div id="webgl"></div>
<script src="jsANDcss/3D/three.min.js"></script>
<script src="jsANDcss/3D/TrackballControls.js"></script> 
<script src="jsANDcss/3D/TerrainLoader.js"></script> 
<script>

    window.addEventListener( 'resize', onWindowResize, false );
    var width  = window.innerWidth,
        height = window.innerHeight;

    var scene = new THREE.Scene();
    /*scene.add(new THREE.AmbientLight(0xeeeeee));*/

    var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
    camera.position.set(0, -30, 30);
    var controls = new THREE.TrackballControls(camera); 

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);

    var material;
    var texture;
    var terrainLoader = new THREE.TerrainLoader();
    terrainLoader.load('jsANDcss/3D/jotunheimen.bin', function(data) {

        var geometry = new THREE.PlaneGeometry(60, 60, 199, 199);

        for (var i = 0, l = geometry.vertices.length; i < l; i++) {
            geometry.vertices[i].z = data[i] / 65535 * 5;
        }

        var texture = THREE.ImageUtils.loadTexture('jsANDcss/3D/jotunheimen-texture.jpg');
        var material = new THREE.MeshPhongMaterial({
            map: texture

            /*wireframe: true*/
        });


        var plane = new THREE.Mesh(geometry, material);
        material.needsUpdate = true;
        scene.add(plane);

    });





    render();
    document.getElementById('webgl').appendChild(renderer.domElement);


    function render() {
        controls.update();    
        requestAnimationFrame(render);
        renderer.render(scene, camera);
    }
    function onWindowResize() {

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

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

        controls.handleResize();

    }

</script>
</body>
</html>

Solution

  • If you use MeshPhongMaterial, you need to add a light to the scene. If you do not want to add a light, then use MeshBasicMaterial.

    Also, do not set material.needsUpdate = true;. The loader does that for you. Loading is asynchronous, and the needsUpdate flag needs to be set at the right time.

    Consider adding the plane to the scene in the loader callback, instead.

    Also, if you are modifying the vertices, you need to recompute some things:

    geometry.computeCentroids();
    geometry.computeFaceNormals();
    geometry.computeVertexNormals();    // required if you want your terrain "smooth"
    

    three.js r.62