Hi! I’m using CesiumTileExcluder to only render a specific area of my map, like a table.
From this amazing PR I created a shader that modifies the fragment alpha value so everything outside the bounds of my specific area is not visible. This works fine if I’m using Pointclouds normally but once I enable the Attenuation boolean it breaks and renders regardless if it’s outside or not.
Does Attenuation use a different material than the 3DTiles opaqueMaterial? Or is that a bug?
Appreciate the help
Hi @JanikCodes ,
It looks like you’re correct: it’s a bug (or a missing feature, at any rate) that custom materials aren’t used for attenuated point clouds. There’s a mention of this in the last comment in this issue:
opened 10:31PM - 03 Feb 23 UTC
enhancement
Intro
---
Building off of #197, we'll want to add something akin to [`PointC… loudShading` in CesiumJS](https://cesium.com/learn/cesiumjs/ref-doc/PointCloudShading.html) 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:
- **attenuation**, which allows more control over point size (points are currently drawn as a single pixel)
- **eye dome lighting (EDL)**, which shades points so that they appear to have more depth. This will be important when we allow users to increase point size, since constant-color point clouds will appear like big globs of color without it.
This [Sandcastle](https://sandcastle.cesium.com/?src=3D%20Tiles%20Point%20Cloud%20Shading.html) demonstrates `PointCloudShading`'s effects.
| No shading | Attenuation only | Attenuation + EDL |
| ---------- | --------------- | ---------------- |
|  |  |  |
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](https://github.com/CesiumGS/cesium/blob/27abb992eb5a434f1c9391f5e926643473ebc985/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js)) So to summarize, the following is necessary to implement point cloud shading:
- a way to visualize points at larger sizes
- the ability to write to two outputs, depth + color
- the ability to blend the two outputs together
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.
- ❌ Use the PSIZE attribute in a Unity shader
- This involves [forcing Unity to use OpenGL](https://answers.unity.com/questions/807548/how-do-i-use-psize-in-a-unity-454-shader.html), which is pretty unideal.
- ❌ Write a geometry shader to expand the points to quads
- Geometry shaders are not [supported by Metal](https://developer.apple.com/forums/thread/88325).
- ❔ Draw instanced quad meshes wherever the point positions are
- This only works with [`DrawMeshInstanced`](https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstanced.html). I was not able to get [`DrawMeshInstancedProcedural`](https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstancedProcedural.html) or [`DrawMeshInstancedIndirect`](https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstancedIndirect.html) to work because apparently the instance ID attribute is not available in those functions, so it's 0 for every instance 🤔
- This method involves some duplication of data, since one of the arguments to `DrawMeshInstanced` is a `Matrix4x4[]` array.
- You'd have to convert the desired point size to an actual world scale for each quad -- something like the way [`minimumPixelSize` affects a model's scale in CesiumJS](https://github.com/CesiumGS/cesium/blob/828d6799916196a6f9c79dd8e5b001d58305e093/packages/engine/Source/Scene/Model/Model.js#L2092).
- This _is_ compatible with Shader Graph, so it might be easier to integrate with what we do for #200.
- I haven't looked into how I'd extract the depth values with this method yet, if it's possible.
- ❔ Use a compute shader to compute point size, then expand the points to quads.
- This should be supported by all the platforms Cesium for Unity supports, according to the [documentation](https://docs.unity3d.com/Manual/class-ComputeShader.html).
- This can be used as an alternative to a geometry shader, and can also help with rendering to multiple outputs.
- This _isn't_ compatible with Shader Graph, since it only expects one position output. This could have implications for #200.
I'll update this issue as I go so I can document my various approaches / struggles / woes with the Unity implementation.
1 Like
Ive replied to the issue. Having shader support for that would be amazing.