2

WebGL: Up and Running と呼ばれる本を読みながら作業を開始しました。この本では、ブラウザーで 3D オブジェクトをレンダリングするために私の好みのソリューションである THREE.js を使用しています。彼がシェーダーを紹介してダイナミックな、照らされた太陽を作る本の一部をエミュレートしようとしていますが、試してみると黒い球体しか得られません。シェーダーをより単純なもの (Lampert シェーダーなど) にすると正常に動作するため、シェーダーが実装されているように、照明ではないように見えます。

それで、私は何を間違っていますか?シーンをセットアップするための私の 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 ブックのソースから取得したシェーダーが含まれています。これらは間違っている可能性がありますが、シェーダーの使用方法に問題があるのではないかと思います。私が理解していることから、ノイズ オクルージョン マップに基づいてテクスチャが変化する太陽が表示され、頂点位置が移動して太陽が脈打つようになるはずです。私が言ったように、球体が見えますが、それは点灯しておらず、真っ黒です。

どこで間違ったのですか?

4

1 に答える 1

2

残念だ。この本はすでに古くなっているようです。

Three.js はアルファ版であり、急速に変化しています。代わりに、three.js の例から学んでください。それらは常に最新です。

現在のバージョンへのアップグレードについては、 Migration Wikiを参照してください。

コード内のいくつかの明らかなエラー:

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

する必要があります

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

THREE.RepeatあるべきでありTHREE.RepeatWrappinguniforms.texture1.textureあるべきですuniforms.texture1.value

申し訳ありませんが、他にも問題がある可能性がありますが、現在のバージョンの three.js についてのみお手伝いできます。

three.js r.54

于 2013-01-03T00:18:31.567 に答える