-
-
Notifications
You must be signed in to change notification settings - Fork 634
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
base: globe
Are you sure you want to change the base?
Conversation
Can you please add some render tests (and maybe unit test) and resolve conflict before I review this thoroughly? |
I resolve conflict. I will add some tests. |
Codecov ReportAttention: Patch coverage is
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. |
private _globePosition: vec3 = [0, 0, 0]; | ||
private _globeRadiusPixels: number = 0.0; | ||
|
||
private _projMatrix: mat4 = mat4.create(); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 cameraPosition
directly, but this position include the projection effect. I need the globe position in the camera frame without the projection effect.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.ts
into mercator.ts
.
But I propose to not do that in the frame of this PR and do this into a refactoring PR.
There was a problem hiding this comment.
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)
… inv projection matrix.
I propose to wait the dicussion on maplibre/maplibre-style-spec#163 before adding some render test with the proposed style. |
Sure, that's a good idea. |
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 :) |
Can this PR be updated? |
Based on the updated atmosphere style spec, sure ! |
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.
CHANGELOG.md
under the## main
section.