2013-01-02 93 views
2

已經開始通過一本名爲WebGL的書:Up and Running,它使用我首選的THREE.js解決方案在瀏覽器中呈現3D對象。我試圖模仿本書的一部分,他介紹着色器來製作一個充滿活力的光照太陽,但是當我嘗試的時候我得到的只是一個黑色的球體。使着色器變得更簡單(比如Lampert着色器)可以正常工作,所以它看起來並不像照明 - 只是着色器實現的方式。如何使頂點和片段着色器在three.js中工作

那麼我做錯了什麼?我的JavaScript代碼來設置場景

var renderer, scene, camera, sunMesh, clock, uniforms; 

$(function(){   

    //set scene size 
    var WIDTH = 1200, 
      HEIGHT = 800; 

    //set some camera attributes 
    var VIEW_ANGLE = 45, 
     ASPECT = WIDTH/HEIGHT, 
     NEAR = 0.1, 
     FAR = 10000; 

    // get the DOM element to attach to 
    // - assume we've got jQuery to hand 
    var $container = $('#container'); 

    // create a WebGL renderer, camera 
    // and a scene 
    renderer = new THREE.WebGLRenderer(); 
    camera = new THREE.PerspectiveCamera( VIEW_ANGLE, 
            ASPECT, 
            NEAR, 
            FAR ); 
    scene = new THREE.Scene(); 

    // the camera starts at 0,0,0 so pull it back 
    camera.position.z = 300; 

    // start the renderer 
    renderer.setSize(WIDTH, HEIGHT); 

    // attach the render-supplied DOM element 
    $container.append(renderer.domElement); 

    // Create a group to hold our sun mesh and light 
    var sunGroup = new THREE.Object3D(); 
    var SUNMAP = "./images/lavatile.jpg"; 
    var NOISEMAP = "./images/cloud.png"; 
    uniforms = { 
      time: { type: "f", value: 1.0 }, 
      texture1: { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture(NOISEMAP) }, 
      texture2: { type: "t", value: 1, texture: THREE.ImageUtils.loadTexture(SUNMAP) } 
    }; 

    uniforms.texture1.texture.wrapS = uniforms.texture1.texture.wrapT = THREE.Repeat; 
    uniforms.texture2.texture.wrapS = uniforms.texture2.texture.wrapT = THREE.Repeat; 
    var material = new THREE.ShaderMaterial({ 
      uniforms: uniforms, 
      vertexShader: document.getElementById('vertexShader').textContent, 
      fragmentShader: document.getElementById('fragmentShader').textContent 
    }); 

    //USING THIS MATERIAL WORKS, SO ITS DEFINITELY THE SHADER! 
    //var material = new THREE.MeshLambertMaterial(
    //{ 
    // color: 0x5B92E5 
    //}); 


    // Create our sun mesh 
    var geometry = new THREE.SphereGeometry(50, 64, 64); 
    sunMesh = new THREE.Mesh(geometry, material); 
    // Tuck away the uniforms so that we can animate them over time 
    // Set up a clock to drive the animation 
    clock = new THREE.Clock(); 
    // Create a point light to show off our solar system 
    var light = new THREE.PointLight(0xffffff); 
    light.position.set(0,0,100); 
    sunGroup.add(sunMesh); 
    sunGroup.add(light); 
    scene.add(sunGroup); 
    // and the camera 
    scene.add(camera); 

    renderer.render(scene, camera); 

    // setup an interval to loop the game loop 
    setInterval(gameloop, 50);  

}); 

function gameloop() { 
    var delta = clock.getDelta(); 
    uniforms.time.value += delta; 
    renderer.render(scene, camera); 
} 

我會保存完整的HTML(在http://pastebin.com/PGLXkzkA上市),但它包含我的着色器,我已經從WebGL的書源解除。這可能是錯誤的,但我懷疑它是我使用着色器的方式。從我所瞭解的情況來看,我應該看到一幅太陽的紋理會根據噪聲遮擋貼圖發生變化,並在頂點位置發生一些移動以產生太陽脈衝。正如我所說,我可以看到一個球體,但它沒有亮起而且是黑色的。

我哪裏出錯了?

回答

2

真是遺憾。這本書似乎已經過時了。

Three.js在alpha中,並且正在快速變化。 改爲從three.js例子中學習。他們永遠是最新的。

查看Migration Wiki以獲取升級到當前版本的幫助。

代碼中的一些明顯的錯誤:

texture1: { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture(NOISEMAP) }, 

應該

texture1: { type: "t", value: THREE.ImageUtils.loadTexture(NOISEMAP) }, 

THREE.RepeatTHREE.RepeatWrappinguniforms.texture1.texture應該是uniforms.texture1.value

對不起,您可能有其他問題,但我只能幫助您使用three.js的當前版本。

three.js所r.54

+0

感謝您的 - 我擔心的那樣多。將爲這些API沖刷API,但ShaderMaterial上的文檔很難/不可能找到。 – Fritz

+1

我最近在http://stemkoski.github.com/Three.js/Shader-Simple.html和http://stemkoski.github.com/Three.js/Shader-Explorer.html發佈了一些簡單的着色器示例,它的沒有替代文件,但它可能足以讓你開始。祝你好運! –

相關問題