CesiumGS / cesium-unity

Bringing the 3D geospatial ecosystem to Unity
https://cesium.com/platform/cesium-for-unity/
Apache License 2.0
347 stars 83 forks source link

Point cloud shading #201

Open j9liu opened 1 year ago

j9liu commented 1 year ago

Intro


Building off of #197, we'll want to add something akin to PointCloudShading in CesiumJS to Cesium for Unity. This will improve the visual quality of point clouds in Unity, should users choose to add it to their point clouds.

The main benefits of point cloud shading are:

This Sandcastle demonstrates PointCloudShading's effects.

No shading Attenuation only Attenuation + EDL
image image image

In CesiumJS, attenuation accounts for various factors and adjusts the gl_pointSize accordingly. EDL is accomplished by rendering the depth values of the point cloud to a separate texture, then blending them with the point cloud colors. (CesiumJS implementation here) So to summarize, the following is necessary to implement point cloud shading:

Unity implementation -- Points are currently rendered just like other tilesets. The only difference is that the mesh is constructed with MeshTopology.Points instead of MeshTopology.Triangles. This is a great start, but there's no way to control the size of the points that are rendered. I also don't know how to get the depth values of only the points that are rendered

Here, I'm chronicling all of the methods I've considered / tried.

I'll update this issue as I go so I can document my various approaches / struggles / woes with the Unity implementation.

kring commented 1 year ago

One more implementation idea: Turn every point into four vertex (all at the same location, the location of the point) and two triangles (connecting the four triangles into a quad) on the CPU. Add a vertex attribute that indicates which "corner" each vertex corresponds to (i.e. top-left, top-right, bottom-left, bottom-right). Render as a single mesh. In the vertex shader, displace the vertices according to the corner and desired point size. Cozzi describes the technique in chapter 9 of the virtual globe book, and I think this is what CesiumJS does due to the lack of geometry shaders in WebGL. The only part that might be challenging in Unity is that extra vertex attribute for the corner indicator.

j9liu commented 1 year ago

For the record: attenuation was added in #218, but we still don't support eye dome lighting.

j9liu commented 1 year ago

I'm concerned with how users will want to apply a material to a point cloud AND apply attenuation. Attenuation is hardcoded in a single material that doesn't flex for other user inputs. I wonder if it's possible to convert attenuation to a shader subgraph (building off of #265), and attaching it to the default tileset shader, as a branch that is traversed when attenuation is enabled. (Of course, it will only be functional if a tileset actually contains points.)

So maybe it's worth looking into #265 again and seeing how it interacts with the default shader. If it can be made into a subgraph then hopefully a user can plug it into their own materials, should they need a custom shader effect with attenuation.