1

编码使用:

  • 使用 ThreeJS v0.130.1
  • 框架:Angular 12,但这与问题无关。
  • 在 Chrome 浏览器上测试。

我正在构建一个获得超过 100K 点的应用程序。我使用这些点在屏幕上渲染一个THREE.Points对象。

我发现默认的 THREE.PointsMaterial不支持光照(无论是否在场景中添加灯光,这些点都是可见的)。

所以我尝试实现一个自定义ShaderMaterial。但是我找不到向渲染对象添加照明的方法。

这是我的代码正在执行的 示例: StackBlitz 上的示例应用程序显示了我当前的尝试 在此代码中,我使用点云数据、法线和颜色的示例值,但其他一切都与我的实际应用程序相似。我可以看到 3D 对象,但需要使用法线进行更适当的照明。

我需要帮助或指导来实施以下内容:

  1. 为自定义着色器材质添加光照。我用谷歌搜索并尝试了很多东西,到目前为止没有成功。

  2. 使用法线,展示光照的效果(在这个示例代码中,法线是固定在 Y 轴方向的,但我在实际应用中是根据一些矢量逻辑计算它们的)。所以计算法线已经完成,但我想用它们在自定义着色器材质中显示光照/阴影效果。

在这个示例中,颜色属性设置为固定的红色,但在实际应用中,我可以使用从纹理到颜色属性的 UV 范围应用颜色。

请告知我如何/是否可以根据点云的法线获得照明。谢谢。

注意:我查看了这个Stackoveflow 问题,但它只涉及更改点的 alpha/透明度,而不涉及照明。

4

1 回答 1

1

为自定义材质添加光照是一个非常复杂的过程。特别是因为您可以使用 Phong、Lambert 或物理光照方法,并且需要从顶点传递到片段着色器的大量计算。例如,这部分着色器代码只是您需要的一小部分

与其尝试从头开始重新创建光照,我建议您PlaneGeometry使用您想要的材质(Phong、Lambert、Physical 等)创建一个并使用一个InstancedMesh创建数千个实例,就像在这个示例中一样。

基于该示例,如何实现类似效果的伪代码如下所示:

const count = 100000;
const geometry = new PlaneGeometry();
const material = new THREE.MeshPhongMaterial();

mesh = new THREE.InstancedMesh( geometry, material, count );
mesh.instanceMatrix.setUsage( THREE.DynamicDrawUsage ); // will be updated every frame
scene.add( mesh );

const dummy = new THREE.Object3D();
update() {
    // Sets the rotation so it's always perpendicular to camera
    dummy.lookAt(camera);

    // Updates positions of each plane
    for (let i = 0; i < count; i++){
        dummy.position.set( x, y, z );

        dummy.updateMatrix();

        mesh.setMatrixAt( i ++, dummy.matrix );
    }
}

循环将for()是每一帧中最昂贵的部分,因此如果您需要在每一帧上更新它,您可能希望在顶点着色器中计算它,但这完全是另一个问题。

于 2021-08-12T20:02:14.003 回答