javascript - 如何使顶点和片段着色器在 Three.js 中工作

标签 javascript three.js webgl

我已经开始阅读一本名为《WebGL:启动和运行》的书,该书使用我首选的 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 书籍的源代码中提取的。这些可能是错误的,但我怀疑这是我使用着色器的方式。据我了解,我应该看到太阳的纹理根据噪声遮挡图而变化,顶点位置有一些移动以使太阳产生脉冲。正如我所说,我可以看到一个球体,但它没有发光并且呈黑色。

我哪里出错了?

最佳答案

真可惜。这本书似乎已经过时了。

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

关于javascript - 如何使顶点和片段着色器在 Three.js 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14130796/

相关文章:

javascript - React Contenteditable - 如何将 onClick 分配给react-contenteditable 中的 <span> ?

javascript - 更改文本区域值不起作用

javascript - 我们如何使用 JavaScript 在单击网格时获取网格的像素颜色?

javascript - 如何将 Three.js 的纹理转换为 WebGL

three.js - 如何将新的相机旋转与之前的变换组合起来?

javascript - 使用 Javascript、WebGL 和 HTML 绘制正方形

javascript - 如何获得 AABB 顶点的三 Angular 形?

javascript - 是否有可能 'require' Node.js 中可以访问导入文件全局范围的对象?

javascript - 使用 jQuery 脚本将 CSS 样式应用到 angularjs 表达式

javascript - 在 webgl 中进行全屏手绘的正确方法是什么?