1

I'm trying to rewrite the example3-3 of the book WebGL: Up and running (http://shop.oreilly.com/product/0636920024729.do) without using sim.js. But I'm getting a problem with the textures.

I just can't make it work using ShaderMaterial to get the normal and specular effects, I have almost the same thing with MeshPhongMaterial and it works fine, but right now this is the render I'm getting using ShaderMaterial : https://i.sstatic.net/IvHpJ.jpg

And this is my code:

var camera,
    scene,
    renderer,
    sunLight,
    earthMesh,
    cloudsMesh,
    earthGroup;

function init() {
    var fieldOfView = 60,
        aspectRatio = window.innerWidth/window.innerHeight,
        near = 1,
        far = 4000;

    // Renderer
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth,window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // Scene
    scene = new THREE.Scene();

    // Earth group
    earthGroup = new THREE.Object3D();

    // Camera
    camera = new THREE.PerspectiveCamera(fieldOfView, aspectRatio, near, far);
    camera.position.set( 0, 0, 3.5 );
    scene.add(camera);

    // Earths creation
    var surfaceMap = THREE.ImageUtils.loadTexture( "earth_surface_2048.jpg" );
    var normalMap = THREE.ImageUtils.loadTexture( "earth_normal_2048.jpg" );
    var specularMap = THREE.ImageUtils.loadTexture( "earth_specular_2048.jpg" );

    var shader = THREE.ShaderUtils.lib[ "normal" ],
        uniforms = THREE.UniformsUtils.clone( shader.uniforms );

    uniforms[ "tNormal" ].texture = normalMap;
    uniforms[ "tDiffuse" ].texture = surfaceMap;
    uniforms[ "tSpecular" ].texture = specularMap;
    uniforms[ "enableDiffuse" ].value = true;
    uniforms[ "enableSpecular" ].value = true;

    var shaderMaterial = new THREE.ShaderMaterial({
        fragmentShader: shader.fragmentShader,
        vertexShader: shader.vertexShader,
        uniforms: uniforms,
        lights: true
    });

    var geometry = new THREE.SphereGeometry(1, 32, 32);
    geometry.computeTangents();

    earthMesh = new THREE.Mesh( geometry, shaderMaterial );

    earthGroup.add(earthMesh);

    // Clouds
    var cloudsMap = THREE.ImageUtils.loadTexture( "earth_clouds_1024.png" );
    var cloudsMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff,
        map: cloudsMap,
        transparent:true 
    });

    var cloudsGeometry = new THREE.SphereGeometry(1.1, 32, 32);

    cloudsMesh = new THREE.Mesh( cloudsGeometry, cloudsMaterial );

    earthGroup.add(cloudsMesh);

    earthGroup.rotation.x = 0.5;

    // Add earth and clouds to the scene
    scene.add(earthGroup);

    // Lights
    // Basic ambient light
    scene.add( new THREE.AmbientLight("rgb(35,35,35)") ); 

    // Sun light
    sunLight = new THREE.PointLight( "rgb(255,230,200)", 2, 100 );
    sunLight.position.set(-10, 0, 20);
    scene.add(sunLight);

    // Render
    run();
}

function run() {
    // Render
    renderer.render( scene, camera );

    // Rotating earth and clouds for the next frame
    earthMesh.rotation.y += 0.005;
    cloudsMesh.rotation.y += 0.003;

    // Ask for another frame
    requestAnimationFrame(run);
}

init();

I don't think is a problem with the lights, it really looks like is something with the textures.

1
  • The Up and Running book is out of date. Learn from the three.js examples that work with the current version of the library. Like this one: threejs.org/examples/misc_controls_fly.html Commented Oct 9, 2013 at 20:08

1 Answer 1

1

I just dealt with the same problem and found a solution, as I am working on the same example in the book.

You have a couple problems:

  • THREE.ShaderUtils.lib is now THREE.ShaderLib
  • Use "normalmap" instead of "normal" for your shader
  • There is no .texture property on the tNormal, tDiffuse, and tSpecular properties of the uniform. Directly set the texture by adjusting the .value property.

So, the affected code should look like this instead:

var shader = THREE.ShaderLib[ "normalmap" ];
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

uniforms[ "tNormal" ].value = normalMap;
uniforms[ "tDiffuse" ].value = surfaceMap;
uniforms[ "tSpecular" ].value = specularMap;

uniforms[ "enableDiffuse" ].value = true;
uniforms[ "enableSpecular" ].value = true;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.