THREE.MeshBasicMaterial渲染,但THREE.MeshLambertMaterial没有

时间:2014-09-12 03:04:33

标签: javascript three.js material

我正在制作一个制作一种随机纸张的项目。它存储x,y和z坐标的数组,并在点之间绘制三角形。你可以在this screenshot中看到这个很好用。

我使用MeshBasicMaterial制作该表,但想切换到MeshLambertMaterial以利用光照。当我尝试这个时,我得到一张看起来like this的表。

这是绿色瓷砖上的基本网格代码:

for(j = 0; j < h-1; j++) {      //h is the number of tiles vertically
    for(i = 0; i < w-1; i++) {  //w is the number of tiles horizontally
        o = ((j%2==1)?1:0);     //checks if the row is odd
        var geom = new THREE.Geometry();
        var a = new THREE.Vector3(x[i][j],      y[i][j]     ,z[i][j]);
        var b = new THREE.Vector3(x[i+1][j],    y[i+1][j]   ,z[i+1][j]);
        var c = new THREE.Vector3(x[i+o][j+1],  y[i+o][j+1] ,z[i+o][j+1]);
        geom.vertices.push(a);
        geom.vertices.push(b);
        geom.vertices.push(c);
        geom.faces.push(new THREE.Face3(0,1,2));
        tile1[i][j] = new THREE.Mesh(
            geom,
            new THREE.MeshBasicMaterial({color: 'green'})
        );
        scene.add(tile1[i][j]);
    }
}

这是红色瓷砖上失败的Lambert Mesh代码(请注意,我只更改了&#39; Basic&#39;以及#39; Lambert&#39;):

for(j = 0; j < h-1; j++) {      //h is the number of tiles vertically
    for(i = 0; i < w-1; i++) {  //w is the number of tiles horizontally
        o = ((j%2==1)?0:1);     //checks if the row is even
        var geom = new THREE.Geometry();
        var a = new THREE.Vector3(x[i+o][j],    y[i+o][j]   ,z[i+o][j]);
        var b = new THREE.Vector3(x[i+1][j+1],  y[i+1][j+1] ,z[i+1][j+1]);
        var c = new THREE.Vector3(x[i][j+1],    y[i][j+1]   ,z[i][j+1]);
        geom.vertices.push(a);
        geom.vertices.push(b);
        geom.vertices.push(c);
        geom.faces.push(new THREE.Face3(0,1,2));
        tile2[i][j] = new THREE.Mesh(
            geom,
            new THREE.MeshLambertMaterial({color: 'red'})
        );
        scene.add(tile2[i][j]);
    }
}

使用以下Lambert Mesh创建的立方体可以正常工作并正确捕捉光线。

scene.add(new THREE.Mesh(new THREE.BoxGeometry(10,1000,5),new THREE.MeshLambertMaterial({color:'red'})));

为什么Lambert Mesh不适用于Basic Mesh工作的几何体?

编辑:我在工作表下面放了一个彩色的盒子来测试盒子对照明的反应,发现它上面的瓷砖没有渲染,但只是黑色。它们是不透明的,但不要像盒子那样使用颜色或拾光。

1 个答案:

答案 0 :(得分:2)

你的场景应该有灯光从THREE.LambertMaterial中获利。您是否正确设置了场景照明?

修改

我发现了你的问题所在。您应该为面添加法线,否则WebGL渲染器不知道如何渲染曲面上THREE.LambertMaterial的光弹跳。所以改变你的代码:

face = new THREE.Face3( 0, 1, 2 );
face.normal = new THREE.Vector3().crossVectors(
    new THREE.Vector3().subVectors( b, a ),
    new THREE.Vector3().subVectors( c, b )
).normalize();
geom.faces.push( face );

现在你的面孔应该呈现。

您可以使用几何方法计算它们,而不是手动执行此操作:

geometry.computeFaceNormals();
geometry.computeVertexNormals();