Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make pointcloud attenuation dependent on geometricError/lod-level #912

Open
jo-chemla opened this issue Jan 8, 2025 · 3 comments
Open
Labels
enhancement New feature or request

Comments

@jo-chemla
Copy link
Contributor

Is your feature request related to a problem? Please describe.

Current implementation of the OGC 3Dtiles pointcloud rendering relies on threejs PointsMaterial where a parameter sizeAttenuation specifies whether points' size is attenuated by the camera depth - therefore consist of a switch whether material.pointSize is expressed as pixel screen units or scene world units.

const pointsMaterial = new PointsMaterial();
pointsMaterial.size = originalMaterial.size;
pointsMaterial.sizeAttenuation = originalMaterial.sizeAttenuation;

Describe the solution you'd like

For better rendering of multi-resolution pointcloud tilesets, it could be helpful to have that point-size-attenuation be dependent on the geometricError or level of the tile within the hierarchy - the same way it is currently implemented within cesiumjs (+ plugins) or potree:

Describe alternatives you've considered

This would probably involves developing a custom pointcloud shader that would account for point-sizing and attenuation per vertex, given the lod-level passed as uniform.

Additional context

Note another useful feature of the Potree Renderer is HQ Splats rendering, which resembles antialiasing, although done differently - see HQSplatRenderer, main related bits of the vertex-shader and fragement-shader highlighted

@jo-chemla jo-chemla added the enhancement New feature or request label Jan 8, 2025
@gkjohnson
Copy link
Contributor

Do you have an example of what specifically you're interested in the points behaving like? The Cesium example uses screen-space sizing (PointsMaterial.sizeAttenuation === false) while the potree example(s) use world-space sizing (sizeAttenuation === true). Right now the behavior is left to the default three.js behavior when loading a PNTS or GLTF file with points.

In either case there should be no need for a new shader to scale based on LoD or geometric error. The points material "size" value can be adjusted by a factor based on either tile value. Regarding "HQ splats" from potree - from this issue it seems that the points are just being rendered with the depth of a sphere so the points intersect, though this would require shader modifications.

Either way everything you're suggesting can already be implemented, though, using a plugin or by modifying the tile content geometry using the load-model event.

@jo-chemla
Copy link
Contributor Author

jo-chemla commented Jan 20, 2025

Hi Garrett, sorry it took me so long to get back - and I hope everything is ok with you and your colleagues after the recent events around JPL. Here is a quick screencast of the different ways the following libs operate visually (in the correct order):

  • Cesium with PointCloudShading.attenuation = true
  • Potree with pointSizeType = ADAPTIVE
  • and 3DTilesRendererJS with PointsMaterial.sizeAttenuation = true where size is measured in scene units rather than screen space pixels, whatever the level in the hierarchy.

Both above libraries result in point size being dependent on the level of the node within the hierarchy - which is great at filling the voids when only tiles at lower zoom levels are loaded and rendered. The threejs PointsMaterial.sizeAttenuation results in pointSize being measured in scene units, so it makes sense to set pointSize to be the order of magnitude of the highest detail / point sampling distance at highest zoom level - eg 1cm when 3dscan have 1cm GSD. But when only tiles at lower zoom levels are loaded, then the render appear to lack detail - while the way potree and cesium set a pointSize dependent on the tile hierarchy helps give the illusion of filling the voids - see tiles at lower zoom levels being loaded eg on the trees vs tiles at the center of the screen on the monument with higher detail, and smaller pixel size.

Hope the video helps see the differences in implementation, below are one screen per library.

CesiumJS Potree Standard Potree HQ Splats 3DTilesRendererJS
Image Image Image Image

@gkjohnson
Copy link
Contributor

Thanks for the clarification. It looks like there are a few separable things contributing to the improved look and apparent quality of the point cloud rendering in the different apps. Scaling of points is definitely a part of it:

  1. LoD Scale: Scale points based on LoD / GeometricError
  2. Eye Dome Lighting: Use "Eye Dome Lighting" rendering (ref) (I don't really understand the name but at a basic level this seems to be adding edge finding / ao based on point depth in a post process step)
  3. Spherical Points: Render points as round balls with depth (optionally with lighting) to improve point cloud form, point overlap (ref, demo)
  4. Blurred Normals / Edges: Render points as round balls with depth, normals and perform a screen space blur (ref issue, looks akin to screen space blur for fluid rendering)

I think the above items are sorted in order of contribution to improving the points legibility, as well. 1 & 3 can be easily done currently using a custom material / shader assigned via plugin. 2 & 4 require some kind of post processing effect applied only to the points.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants