ThreeJS Points (Point Cloud) with Lighting using custom Shader Material
ThreeJS Points (Point Cloud) with Lighting using custom Shader Material
编码使用:
- 使用 ThreeJS v0.130.1
- 框架:Angular12,但这与问题无关。
- 正在 Chrome 浏览器上测试。
我正在构建一个获得超过 100K 点的应用程序。我使用这些点在屏幕上渲染一个 THREE.Points 对象。
我发现默认的THREE.PointsMaterial是不支持光照的(无论场景是否加光,点都是可见的)
所以我尝试实现一个自定义的ShaderMaterial。但是我找不到为渲染对象添加光照的方法。
下面是我的代码的示例:
Sample App on StackBlitz showing my current attempt
在此代码中,我使用点云数据、法线和颜色的示例值,但其他一切都与我的实际应用程序相似。我可以看到 3D 对象,但需要使用法线进行更适当的照明。
我需要帮助或指导来实施以下内容:
向自定义着色器添加光照 material。我用谷歌搜索并尝试了很多东西,到目前为止没有成功。
使用法线,展示光照效果(本示例代码中,法线固定在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()
循环将是每一帧中最昂贵的部分,因此如果您需要在每一帧上更新它,您可能需要在顶点着色器中计算它,但这完全是另一个问题。
编码使用:
- 使用 ThreeJS v0.130.1
- 框架:Angular12,但这与问题无关。
- 正在 Chrome 浏览器上测试。
我正在构建一个获得超过 100K 点的应用程序。我使用这些点在屏幕上渲染一个 THREE.Points 对象。
我发现默认的THREE.PointsMaterial是不支持光照的(无论场景是否加光,点都是可见的)
所以我尝试实现一个自定义的ShaderMaterial。但是我找不到为渲染对象添加光照的方法。
下面是我的代码的示例: Sample App on StackBlitz showing my current attempt 在此代码中,我使用点云数据、法线和颜色的示例值,但其他一切都与我的实际应用程序相似。我可以看到 3D 对象,但需要使用法线进行更适当的照明。
我需要帮助或指导来实施以下内容:
向自定义着色器添加光照 material。我用谷歌搜索并尝试了很多东西,到目前为止没有成功。
使用法线,展示光照效果(本示例代码中,法线固定在Y轴方向,实际应用中我是根据一些矢量逻辑计算的)。所以计算法线已经完成,但我想用它们在自定义着色器 material.
中显示光 shine/shading 效果
在此示例中,颜色属性设置为固定的红色,但在实际应用中,我可以使用从纹理到颜色属性的 UV 范围来应用颜色。
请指教how/if 我可以为点云获取基于法线的光照。谢谢
注意:我看过这个
向自定义 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()
循环将是每一帧中最昂贵的部分,因此如果您需要在每一帧上更新它,您可能需要在顶点着色器中计算它,但这完全是另一个问题。