2

我已经开始阅读一本名为 WebGL:Up and Running 的书,它使用我首选的 THREE.js 解决方案在浏览器中呈现 3D 对象。我试图模仿书中他介绍着色器以制作动态、明亮的太阳的部分,但当我尝试时,我得到的只是一个黑色球体。使着色器更简单(如 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 处于 alpha 阶段,并且正在迅速变化。而是从 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。

三.js r.54

于 2013-01-03T00:18:31.567 回答