2013-10-09 206 views
1

我想重寫本書WebGL的示例3-3:啓動並運行(http://shop.oreilly.com/product/0636920024729.do),而不使用sim.js.但是我遇到了紋理問題。ShaderMaterial渲染three.js

我只是不能使用ShaderMaterial工作來獲得正常和鏡面效果,我幾乎與MeshPhongMaterial一樣,它工作正常,但現在這是我使用ShaderMaterial的渲染:http://imgur.com/vts9X3k

這是我的代碼:

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(); 

我不認爲是燈光的問題,它確實看起來是一些與紋理。

+0

的_UP和Running_本書是過時的。學習適用於當前版本庫的three.js示例。像這樣:http://threejs.org/examples/misc_controls_fly.html – WestLangley

回答

1

我剛剛處理了同樣的問題,並找到了解決方案,因爲我正在處理書中的同一個示例。

你有幾個問題:

  • THREE.ShaderUtils.lib現在是THREE.ShaderLib
  • 使用 「法線貼圖」,而不是 「正常」 的着色器
  • 沒有.texture財產上的tNormaltDiffusetSpecular制服的屬性。通過調整.value屬性直接設置紋理。

因此,受影響的代碼看起來應該是這樣,而不是:

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;