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

Add an Atmosphere layer for Globe (#3888) #4020

Open
wants to merge 17 commits into
base: globe
Choose a base branch
from

Conversation

Pheonor
Copy link
Contributor

@Pheonor Pheonor commented Apr 20, 2024

Launch Checklist

This PR add a realistic atmosphere layer to the Earth when using a globe projection.
Some options allows to change the zoom level to fade in and out the atmosphere.
By default, the sun position is computed based on current time.
An optionnal date and time allows to set the sun to any position.

Capture d’écran 2024-04-20 à 09 48 45
  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!
  • Briefly describe the changes in this PR.
  • Link to related issues.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Document any changes to public APIs.
  • Add an entry to CHANGELOG.md under the ## main section.

@HarelM
Copy link
Member

HarelM commented Apr 20, 2024

Can you please add some render tests (and maybe unit test) and resolve conflict before I review this thoroughly?

@Pheonor
Copy link
Contributor Author

Pheonor commented Apr 20, 2024

I resolve conflict. I will add some tests.

@codecov-commenter
Copy link

codecov-commenter commented Apr 20, 2024

Codecov Report

Attention: Patch coverage is 43.77510% with 140 lines in your changes are missing coverage. Please review.

Project coverage is 86.77%. Comparing base (518041f) to head (23a7af3).

Files Patch % Lines
src/render/draw_atmosphere.ts 10.34% 77 Missing and 1 partial ⚠️
src/geo/projection/globe.ts 58.92% 22 Missing and 1 partial ⚠️
src/render/program/atmosphere_program.ts 35.48% 18 Missing and 2 partials ⚠️
src/geo/projection/mercator.ts 29.41% 11 Missing and 1 partial ⚠️
src/render/painter.ts 82.60% 2 Missing and 2 partials ⚠️
src/ui/map.ts 86.36% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            globe    #4020      +/-   ##
==========================================
- Coverage   86.97%   86.77%   -0.20%     
==========================================
  Files         250      253       +3     
  Lines       34872    35099     +227     
  Branches     2118     2136      +18     
==========================================
+ Hits        30329    30458     +129     
- Misses       3542     3621      +79     
- Partials     1001     1020      +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

private _globePosition: vec3 = [0, 0, 0];
private _globeRadiusPixels: number = 0.0;

private _projMatrix: mat4 = mat4.create();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the atmosphere math can be done with matrices that were already present.

The _globeProjMatrix matrix assumes the globe is a unit sphere located at (0,0,0), unrotated (so the null island is always at the unit sphere's +Z (0,0,1), see _angularCoordinatesToVector ) and projects it to screen. The already present cameraPosition property is the camera position relative to the unit-sphere globe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The atmosphere math are performed into camera frame. I need the real globe position into the camera frame and to project each pixel as a ray into this frame also.
This is why I extract the projection matrix and compute the globe position.
The previously computed cameraPosition do not give me the expected value. I will try to reuse some other value to avoid a new computation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I try to view if I could use cameraPositiondirectly, but this position include the projection effect. I need the globe position in the camera frame without the projection effect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this shader could be helpful: https://github.com/maplibre/maplibre-gl-js/blob/globe/src/shaders/fill_extrusion.fragment.glsl

It computes ray-globe intersection for large fill-extrusions, which is very close to what atmopshere needs. The only part the linked shader doesn't do is getting the ray from a pixel, but your approach with the inverse matrix should work fine.

(The varying v_sphere_pos contains the current pixel's position on the globe, relative to the unit sphere, so a point on the surface would have distance 1 from 0,0,0, a point higher up would have greater distance. See the matching vertex shader for more details.)


export type ProjectionPreludeUniformsType = {
'u_projection_matrix': UniformMatrix4f;
'u_projection_tile_mercator_coords': Uniform4f;
'u_projection_clipping_plane': Uniform4f;
'u_projection_transition': Uniform1f;
'u_projection_fallback_matrix': UniformMatrix4f;
'u_globe_position': Uniform3f;
'u_globe_radius': Uniform1f;
'u_inv_proj_matrix': UniformMatrix4f;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these new uniforms would be better suited for atmosphereUniformsType. ProjectionData and ProjectionPreludeUniformsType is passed to every single shader, but the uniforms added here are only used by atmosphere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will do like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.
To be clean, it could be better to centralize all the projection code from transform.tsinto mercator.ts.
But I propose to not do that in the frame of this PR and do this into a refactoring PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also like to do that, I already started looking at adapting interactions (map panning, etc.) and animations (easeTo, etc.) for globe, changing the transform and refactoring this will definitely be required. As for controls, I would like to have a "globe" and "flat" control scheme (as opposed to "mercator"), since the flat controls would likely get used by all projections except globe. As suggested at the end of this comment: maplibre/maplibre-style-spec#568 (comment)

@Pheonor
Copy link
Contributor Author

Pheonor commented Apr 21, 2024

I propose to wait the dicussion on maplibre/maplibre-style-spec#163 before adding some render test with the proposed style.

@HarelM
Copy link
Member

HarelM commented Apr 21, 2024

Sure, that's a good idea.
I hope this discussion won't take too long...

@kubapelc
Copy link
Contributor

kubapelc commented Apr 22, 2024

I finally had the time to play with the example. It looks amazing!

I'm worried about performance though, I also tried to run it on my phone (Snapdragon 636, 1080x2280 pixel screen) and got framerate in the single digits, and the sunlight was missing for some reason.

Edit: also runs at low framerate on Intel HD 630.

@Pheonor
Copy link
Contributor Author

Pheonor commented Apr 22, 2024

I finally had the time to play with the example. It looks amazing!

I'm worried about performance though, I also tried to run it on my phone (Snapdragon 636, 1080x2280 pixel screen) and got framerate in the single digits, and the sunlight was missing for some reason.

Edit: also runs at low framerate on Intel HD 630.

Thank you :)
Effectively, I need to check if I could tune step parameters to improve performance.

@HarelM
Copy link
Member

HarelM commented May 30, 2024

Can this PR be updated?
I think we have finalized (hopefully) the sky definitions, so I think this can be pushed forward, right?
I'll work on merging the style spec changes for both projection and sky so that the style spec package will be up to date with latest definitions.

@Pheonor
Copy link
Contributor Author

Pheonor commented May 30, 2024

Based on the updated atmosphere style spec, sure !
@HarelM How to retrieve the style spec update from maplibre-gl-js ? Do I need to wait a new release ?

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

Successfully merging this pull request may close these issues.

None yet

4 participants