three.js - 使用 MeshLambertMaterial 和点光源绘制自定义网格

Posted

技术标签:

【中文标题】three.js - 使用 MeshLambertMaterial 和点光源绘制自定义网格【英文标题】:three.js - Draw custom mesh with MeshLambertMaterial and point light 【发布时间】:2014-03-12 18:31:38 【问题描述】:

我目前正在学习 webGL 和 three.js。因此,出于测试原因,我尝试创建一个平面几何图形和两个立方体几何图形以及一个点光源:

function initLights () 
    var c = context;

    var pointLight = new THREE.PointLight( 0xffffff, 1, 100 );
    pointLight.position.set( 10, 10, 10 );

    c.scene.add(pointLight);


function initObjects () 
    var c = context;

    /**
     * Defining the materials
     */

    var lambertRedMaterial = new THREE.MeshLambertMaterial(
            color  : 0xff0000
            , side : THREE.DoubleSide
        );

    var lambertWhiteMaterial = new THREE.MeshLambertMaterial(
            color     : 0xffffff
            , side    : THREE.DoubleSide
        );

    /**
     * Defining the floor
     */
    var floorGeometry = new THREE.Geometry();

    floorGeometry.vertices.push(new THREE.Vector3(-5.0, 0.0, -5.0));
    floorGeometry.vertices.push(new THREE.Vector3( 5.0, 0.0, -5.0));
    floorGeometry.vertices.push(new THREE.Vector3( 5.0, 0.0,  5.0));
    floorGeometry.vertices.push(new THREE.Vector3(-5.0, 0.0,  5.0));
    floorGeometry.faces.push(new THREE.Face3(2, 1, 0));
    floorGeometry.faces.push(new THREE.Face3(3, 2, 0));


    var floorMesh = new THREE.Mesh(floorGeometry, lambertWhiteMaterial);
    floorMesh.position.set(0.0, 0.0, 0.0);

    /**
     * Defining a cube
     */
    var cubeGeometry1 = new THREE.CubeGeometry(2.0,0.25,1);
    var cube1 = new THREE.Mesh( cubeGeometry1, lambertRedMaterial );
    cube1.position.set(0.0, 1.0, 0.0);

    var cubeGeometry2 = new THREE.CubeGeometry(2.0,0.25,1);
    var cube2 = new THREE.Mesh( cubeGeometry2, lambertRedMaterial );
    cube2.position.set(0.0, 1.35, 0.0);

    c.scene.add(floorMesh);
    c.scene.add(cube1);
    c.scene.add(cube2);

相机和场景的上下文是之前定义的。 奇怪的是,立方体显示正确,但平面没有显示。

当我将平面的 y 位置设置为 1.0 时,我可以看到它与下部立方体相交。另外,当我使用MeshBasicMaterial时会显示,但出于照明原因,我想使用MeshLambertMaterial。

如果我忘记了什么,或者问题可能是什么,有人知道吗?

非常感谢。

【问题讨论】:

首先,请致电geometry.computeFaceNormals();。然后拨打scene.add( new THREE.FaceNormalsHelper( floorMesh ); 是的,太好了! geometry.computeFaceNormals();成功了!你能解释一下,为什么我需要打电话给这个? scene.add( new THREE.FaceNormalsHelper( floorMesh ); 不是必需的。如果我把它放到我的代码中,它会画一条黄线。我猜这条线是归一化正交向量的表示。 【参考方案1】:

MeshLambertMaterial 需要面法线或顶点法线进行光照计算。

面法线用于“平面着色”,顶点法线用于“平滑着色”。

您可以通过调用geometry.computeFaceNormals(); 来计算人脸法线。对于顶点法线,您可以调用geometry.computeVertexNormals();

对于视觉提示,使用 three.js 助手,例如这个:

scene.add( new THREE.FaceNormalsHelper( mesh ) );

另外,如果您只是学习,this answer 中的建议可能对您有所帮助。

three.js r.65

【讨论】:

你说“如果你只是在学习......”是什么意思,你会为以后的项目推荐一种不同的方式吗? 您在第一句话中说您正在学习WebGL和three.js,所以我认为其他答案中的建议会对您有所帮助。 :-) 我改写了我的帖子。 是的,我已经阅读了这个问题和答案。感谢您的提示,它们真的很有帮助! :-)

以上是关于three.js - 使用 MeshLambertMaterial 和点光源绘制自定义网格的主要内容,如果未能解决你的问题,请参考以下文章

There.js入门系列之React中使用Three.js

three.js 入门详解

three.js 入门详解

Three.js实现可透视的水面效果

无法使用 three.js 渲染 GLTF 对象

使用three.js设置透明背景