ThreeJS Points (Point Cloud) with Lighting using custom Shader Material

ThreeJS Points (Point Cloud) with Lighting using custom Shader Material

编码使用:

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

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

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

下面是我的代码的示例: Sample App on StackBlitz showing my current attempt 在此代码中,我使用点云数据、法线和颜色的示例值,但其他一切都与我的实际应用程序相似。我可以看到 3D 对象,但需要使用法线进行更适当的照明。

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

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

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

    中显示光 shine/shading 效果

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

请指教how/if 我可以为点云获取基于法线的光照。谢谢

注意:我看过这个,但它只处理改变点的 alpha/transparency 而不是照明。

向自定义 material 添加照明是一个非常复杂的过程。特别是因为您可以使用 Phong、Lambert 或物理光照方法,并且需要从顶点传递到片段着色器的大量计算。例如,this segment of shader code is just a small part of what you'd need.

与其尝试从头开始重新创建光照,我建议您使用您喜欢的 material(Phong、Lambert、Physical 等...)创建一个 PlaneGeometry 并且使用 InstancedMesh 创建数千个实例,just like in this example.

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

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