Skip to content

Add support for proper lunar mesh instead of the ellipse#4835

Open
10110111 wants to merge 6 commits into
Stellarium:masterfrom
10110111:moon-mesh
Open

Add support for proper lunar mesh instead of the ellipse#4835
10110111 wants to merge 6 commits into
Stellarium:masterfrom
10110111:moon-mesh

Conversation

@10110111
Copy link
Copy Markdown
Contributor

@10110111 10110111 commented Mar 22, 2026

This is a WIP implementation of the lunar mesh, which helps us get

  1. The proper silhouette of the Moon, and
  2. Better look of the rim during full Moon due to the back-faced parts of craters and mountains not being visible.

What's currently missing:

  1. This should obey flagUseObjModels and resort to the old sphere-based rendering when it's disabled. Or maybe add a separate feature flag, since the other models are much more lightweight?
  2. Surveys are still rendered as spheres (and I don't think this will be changed in this PR).

This implementation includes a 44 MiB lunar mesh in a custom binary format optimized for compressibility, so its 7zip archive is only 7 MiB. This archive is what's contained in the repo, and it gets extracted on installation, so the installers will get the 44 MiB input. I hope that in particular Inno Setup will be able to achieve a similar compression. Of all compressors only 7zip and lzma/xz achieve about 7 MiB size, others (bzip2, gzip) appear to be much less efficient (13 MiB and 21 MiB, respectively). I chose 7zip because CMake supports it out of the box.

The worst-case performance of displaying only the Moon fullscreen at 0.3° FoV on my ASUS ProArt PX13 (with AMD Radeon 890M) dropped from 42 FPS to 33 FPS, which seems fair for the improvement achieved. On Zenbook UX333F with Intel UHD Graphics 620 the drop is from 16 FPS to 4.4 FPS, which is why it's desirable to fix the ability to turn the feature off.

I don't intend for this to get into 26.1, since it's likely to break some other aspect of planet rendering, so I suppose it should aim at 26.2.

@github-actions
Copy link
Copy Markdown

Great PR! Please pay attention to the following items before merging:

Files matching src/**/*.cpp:

  • Are possibly unused includes removed?

This is an automatically generated QA checklist based on modified files.

@gzotti gzotti added this to the 26.2 milestone Mar 22, 2026
@gzotti
Copy link
Copy Markdown
Member

gzotti commented Mar 22, 2026

Sounds terrific, even before trying. But yes, a separate switch please for the "lighter" systems (2010 field laptops, Raspberries, ...).

@Atque
Copy link
Copy Markdown
Contributor

Atque commented Mar 22, 2026

Very nice! I'm not sure why, but for some reason the Earthlight is broken:

bild

@alex-w
Copy link
Copy Markdown
Member

alex-w commented Mar 23, 2026

Hmm... I see no changes when toggle support 3D models for SSO

@10110111
Copy link
Copy Markdown
Contributor Author

I see no changes when toggle support 3D models for SSO

Of course, I said in the OP that this switch is currently missing.

@alex-w
Copy link
Copy Markdown
Member

alex-w commented Mar 23, 2026

I see no changes when toggle support 3D models for SSO

Of course, I said in the OP that this switch is currently missing.

Oh, yeah! My eyes missed this part...

@10110111
Copy link
Copy Markdown
Contributor Author

OK, so now the toggle between the sphere and the proper mesh should work.

@10110111
Copy link
Copy Markdown
Contributor Author

The earthshine still seems to look different from master.

@10110111
Copy link
Copy Markdown
Contributor Author

The earthshine is fixed now too.

@github-actions
Copy link
Copy Markdown

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions Bot added the has conflicts The pull request has conflicts label Apr 11, 2026
This makes them mostly independent from mesh density, which is
especially noticeable near the poles when mesh density is low.
@github-actions
Copy link
Copy Markdown

Conflicts have been resolved. A maintainer will review the pull request shortly.

@github-actions github-actions Bot removed the has conflicts The pull request has conflicts label Apr 11, 2026
@10110111 10110111 marked this pull request as ready for review April 12, 2026 01:10
@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 14, 2026

Seems I'm missing something.

[ 382.970][CRIT] Failed to load model of the Moon: cannot find the model file

The moon is not rendered (stars are visible), but the Nomenclature marks (crater ovals) are there.


Ah, reading helps... :-) unpacked the mesh file, restarted.

WOW! That lunar rim is simply insane! And now somebody has to observe occultations....

I still should test with RPi3/4 and my smaller field laptops.

@10110111
Copy link
Copy Markdown
Contributor Author

Ah, reading helps... :-) unpacked the mesh file, restarted.

Wait, what? Unpacking should happen automatically at CMake stage. Did it not work for you?

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 15, 2026

I did not investigate at which stage CMake would unpack. After switching to the branch, QtCreator detects new files and triggers CMake to prepare compilation (with previously configured plugins, NLS, PCH, etc.), then I compile and run inside QtCreator. No install step, if that's where unpacking might happen.

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 23, 2026

It works on my smaller notebook (Intel GPU). However, I noted that when nomenclature (crater labels) is on, they are now further north than the lunar shape. Switching off 3D all is fine. I know a long time ago I added a figure offset from some source (explanatory supplement, Meeus, ...?) because the Moon is not a fully homogeneous sphere, but cannot find it (a comment should give a clue.). Or is your object an off-center sphere?

@10110111
Copy link
Copy Markdown
Contributor Author

10110111 commented Apr 23, 2026 via email

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 23, 2026

Found it at end of EphemWrapper::get_lunar_parent_coordsv(). So this patches the position so that a sphere with asymmetrical center of gravity gets centered on the right spot. Not sure how to adjust your Lunar mesh. But what we can do is compare Bayley's Beads (2nd/3rd contact at Total Solar Eclipses) with your rim craters. Likewise, I have a few planet occultations; I hope with accurate-enough timestamps.

@10110111
Copy link
Copy Markdown
Contributor Author

But what we can do is compare Bayley's Beads (2nd/3rd contact at Total Solar Eclipses) with your rim craters.

Do you have any well-geopositioned and well-timed photos for these?

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 23, 2026

I have a few. 1999, 2001, 2006, 2008, 2017, 2024. Start on weekend...
EDIT:
2006 just not in focus at begin (2nd contact), and 3rd contact too overexposed.
2008 I see some possible matches, but also deviation, esp with recorded observation time.
2017: ingress featureless. Egress very few bright spots.
2024: ingress featureless (or 1/2s too late), egress has 4 beads, should have nothing according to Stellarium.

Needs more test with shifted/unshifted center.
Anyone else?

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 24, 2026

I think it's time to declare Raspberry3 no longer supported. It may still work under some circumstances, but it's no real fun, just too little memory. Probably ending with 24.4. On the RPi4 I get otherwise nice performance, but this branch has a shader error. See log:
log.txt

The fallback to just keep the moon as sphere is OK, but if there is no principal obstacle, having the mesh would be great

@10110111
Copy link
Copy Markdown
Contributor Author

OK, the GLES2 shader issue is now fixed.

And now I also see what shift you mean. It's so huge, but somehow I totally missed it. It's most likely a bug in my refraction code. Without atmosphere everything works OK. I don't remember seeing this when I was developing the refraction on GPU part, this might have been broken during one of the rebases...

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 24, 2026

Thanks, RPi4 is happy. If this was a GLES2 issue, it would have affected Qt5/ANGLE which I have also not tested yet.

Funny, Now I cannot reproduce the large shift (pre-last-commit)! refraction makes no difference.

@10110111
Copy link
Copy Markdown
Contributor Author

Funny, Now I cannot reproduce the large shift (pre-last-commit)! refraction makes no difference.

Haha, yeah. Scroll two hours back, and you'll see it :)

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 25, 2026

Just testing on an older i3-5xxx NUC (Ubuntu 24.04). Works well, but also has the refraction/shift problem with atmosphere.

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 26, 2026

I wonder about the coefficients in your sine variant. The usual Taylor series is x-x³/3!+x^5/5!-... , why do they deviate here?

@10110111
Copy link
Copy Markdown
Contributor Author

10110111 commented Apr 26, 2026

The usual Taylor series is x-x³/3!+x^5/5!-... , why do they deviate here?

Taylor series, while being a great tool for calculus, is often a bad choice for real-life approximations due to its very non-uniform scaling of error: O(xN). The approximation used in my code is close to a minimax polynomial instead, which can be approximated by a truncated Chebyshev series.

See the comparison of the errors between my approximation and the Taylor polynomial of the same order:

sines

Or, in the logarithmic scale, to see the full scale of the error of the Taylor polynomial at the domain edges:

sines-log

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 26, 2026

Ah right, I forgot about the [-1, 1] limit. Interesting "ugly" series. Just found: https://gist.github.com/publik-void/067f7f2fef32dbe5c27d6e215f824c91. Gives similar but slightly different series.

For whichever reasons, currently mesh and sphere behave well with/without atmosphere and with Nomenclature (which should not use the new formula, right?)

@10110111
Copy link
Copy Markdown
Contributor Author

Gives similar but slightly different series.

Actually, their series are quite interesting in the fact that they optimize the relative error, rather than absolute that mine does. But in any case, we can't expect anything much better than 10-7 error, since it's about the precision limit of float.

For whichever reasons, currently mesh and sphere behave well with/without atmosphere and with Nomenclature (which should not use the new formula, right?)

Nomenclature is not affected by my change, it continues to apply refraction as it used to do (on the CPU, I suppose). As for the mesh, as I said above, its position error depends on time, I still haven't investigated what exactly is going on here.

@10110111
Copy link
Copy Markdown
Contributor Author

OK, after several hours of debugging it appears that on Intel the error in asin(sin(x)) for x<80° reaches 0.03°, on AMD about 0.02°, while on NVIDIA, where the issue doesn't exist, it's less than 0.0006°.

Ugly stuff, but so is the reality with Intel and, surprisingly, AMD, which I thought would be on par with NVIDIA quality-wise.

@gzotti What GPUs did you see this problem on?

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 27, 2026

Ah, I wrote above

It works on my smaller notebook (Intel GPU). However, I noted ...

That is an Intel N150 CPU. later I wrote I cannot see it any longer, this was my main (Geforce) system. Also the RPi4 was OK. Then the Intel NUC i3-5xxx again showed it. I have another older Intel (Pentium Silver?) field notebook which I have to re-check. Would it help to add one more term to the series?

@gzotti
Copy link
Copy Markdown
Member

gzotti commented Apr 27, 2026

Weird. On the Pentium Silver N5030 on Win11 (with Intel UHD605, driver 31.0.101.2137) the effect is there but hardly discernible. On the NUC (Ubuntu 24.4, Intel HD5500 (BDW GT2), Mesa 25.2.8-0ubuntu0.24.04.1) it is shouting into my face.
BTW tested Adreno GPU (Windows for ARM): All OK.

OK, one more candidate, i5-4xxx, Win10, booting up to build... EDIT: HD Graphics 4600, Driver 20.19.15.5171. Works without any visible problem (observed with Lunar altitude near 40° and 70°).

I would rather not want to build on a 2010 first-gen Core-i5 (Win10, Qt5; test system for weekly/beta installers only), would have to setup environment first. Or you can build an installer for that? (Win/Qt5)

@10110111
Copy link
Copy Markdown
Contributor Author

Would it help to add one more term to the series?

No, this time it's asin that needs a custom implementation.

Or you can build an installer for that?

No need now. You've confirmed what I wanted to know.

10110111 and others added 2 commits April 28, 2026 10:28
The model is not in the Wavefront OBJ format, because the textual nature
would inflate the size of already rather large model and reduce loading
speed. Instead, the format is as follows:

0         uint32       number of vertices, N
4         uint32       number of indices, M
8         float32      minimum radius
12        float32      maximum radius
16        uint16[3*N]  array of altered spherical coordinates (see below)
16+3*2*N  uint32[M]    array of indices

The spherical coordinates are stored as triples of uint16, in the
following order:
1. Radial coordinate linearly remapped so that value=0 means rMin and
   value=65535 means rMax,
2. Elevation of the vertex linearly remapped so that value=0 means -PI/2
   and value=65535 means PI/2,
3. Azimuth of the vertex linearly remapped so that value=0 means -PI and
   value=65535 means PI.
This drastically improves performance of lunar mesh rendering on ASUS
ProArt PX13 with AMD Radeon 890M (from 8 FPS to 33 FPS).
10110111 and others added 3 commits April 28, 2026 10:51
The imprecision of the hardware implementation of sin leads to broken
geometry of the Moon every 0.9° of elevation.
The imprecision of the hardware implementation of asin (also observable
on AMD GPUs) leads to the Moon refracted altitude having time-dependent
shifts from the correct values.
Before this patch a model would be shown at the same time as a survey,
which would result in ugly overlapping and generally not make sense.
We require at least CMake 3.18 because of the use of ARCHIVE_EXTRACT.
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.

4 participants