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

realistic Rayleigh/Mie atmospheric scattering #5617

Merged
merged 19 commits into from
Jan 27, 2024

Conversation

Mc-Pain
Copy link
Contributor

@Mc-Pain Mc-Pain commented Aug 30, 2023

Experimental shaders for atmospheres on terrestrial planets.

TO-DO list:

  • Partial depth calculation: shadow cylinder cuts the far side of ray
  • Eclipse handling: use atmosDiffuse when sampling the ray instead of multiplying the overall result
  • Use atmospheric density in calculations
  • Use star luminosity. We don't want to make atmosphere bright from M-class star thousands AU away as if it was 0.5 AU away
  • Add RGB matrix (For non-Nitrogen atmospheres?)

@bszlrd
Copy link
Contributor

bszlrd commented Aug 30, 2023

Could you post some screenshots, I'm curious.

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Aug 30, 2023

Found the old one but shaders has been reworked since.
изображение

I'll post actual screenshots later (this evening?)

@impaktor
Copy link
Member

Just checking: our eclipse at Epsilon Eridani still works?
Also, something @Web-eWorks to check on your system-editor branch, if planets and planes and unspecified parameters are being changed.

@zonkmachine
Copy link
Member

zonkmachine commented Aug 30, 2023

Sunset at Mars. Before and after.

martiansunset2
martiansunset

@Zireael07
Copy link

What's the performance like? Most Rayleigh/Mie implementations I've seen are performance intensive...

@bszlrd
Copy link
Contributor

bszlrd commented Aug 30, 2023

How cool is that! Never thought it is missing until I saw what's missing.
If it is a performace hog, maybe it could be useful to tie it to make it togglable in settings?

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Aug 30, 2023

What's the performance like? Most Rayleigh/Mie implementations I've seen are performance intensive...

Actually, I don't like its performance.
Currently, numSamples = 16, which does not impact performance heavily, but if you fly to ~10 km altitude and look at horizon - you'll see a completely black atmosphere appearing from horizon.
Increasing samples to 64 would fix this "black horizon" issue but it'll drop FPS to ~20 for me.

It should be heavily optimized/approximated in order to show truly greatest pictures of atmosphere.

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Aug 30, 2023

Just checking: our eclipse at Epsilon Eridani still works?

Did a quick check: it works. I was afraid if it broke eclipses.

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Aug 30, 2023

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Aug 30, 2023

изображение
Epsilon Eridani, eclipse

@Web-eWorks
Copy link
Member

Thanks for taking a crack at this! There are a few "problems" which are why I've not already tried to implement this before:

  • Obviously, as you've mentioned, performance. Trying to brute-force Rayleigh-Mie is pretty much impossible to do outside of an offline raytracer, which is what that article was originally written for. There are plenty of papers available discussing ways to make it more performant for real-time rendering, but more on that later.
  • The reference Rayleigh/Mie coefficients used by most implementations (and this one specifically) are (AFAIK) only appropriate for an oxygenated / earth-like atmosphere and will not produce visually correct results in CO2 / Methane atmospheres or in different atmospheric densities. Without some approximation to generate semi-physically-based Rayleigh / Mie coefficients there's not much point to introducing "realistic" atmospheric scattering.
  • Have you verified if "aerial perspective" AKA views from space work correctly? Depending on the implementation of the Nishita model those are sometimes not handled correctly.

If you're interested in addressing the first problem while still implementing the Nishita model, you'll be interested in this GpuGems2 chapter which manages to cram the necessary math down into something a little more performant.

I cannot promise this PR will be merged however, as even if performance improves on desktop our min-spec target is semi-recent laptop/integrated GPUs, and this PR would both need to address the second point above and provide this as an "experimental" toggleable option.

The other reason I can't promise to merge the PR is that we instead intend to implement A Scalable and Production Ready Sky and Atmosphere Rendering Technique (by Sebastien Hillaire, described here and here) which is a physically-based model designed for real-time game rendering on everything from mobile to high-end PC. Hillaire's model provides better performance and integrates better with other atmospheric effects like cloud rendering. The implementation is not possible until required plumbing work is done in both the render API and scene rendering code sections however, so the usual caveat of "no ETA" applies.

If you are interested in getting some extremely useful code merged, starting with a way to procedurally generate at least semi-accurate Rayleigh/Mie coefficients for our various atmospheric exoplanets would be very worthwhile regardless of which rendering model gets implemented.

@Web-eWorks
Copy link
Member

ADDENDUM: the above reads as more dour and glum than I originally intended. I'm very glad to see someone else tackle planet and sky rendering in Pioneer, and by no means do I think you should abandon this PR just because we have plans to do it differently in a few years time. Feel free to keep working on this, just keep in mind that it'd be merged as a "v1" implementation with the intent to replace it with a more complex "v2" implementation later.

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Aug 30, 2023

There are several reasons why this PR is marked WIP.

  • Obviously, as you've mentioned, performance. Trying to brute-force Rayleigh-Mie is pretty much impossible to do outside of an offline raytracer, which is what that article was originally written for. There are plenty of papers available discussing ways to make it more performant for real-time rendering, but more on that later.

That's one of them.
Looking at the code and trying to figure out what went wrong I became aware of what this model does and how it works. Myself, without looking at the original paper.
The quality of image could be performed via increasing numSamples, but I think it could be easier to solve an integral and get a single solution with given parameters, reducing complexity from O(n^2) to O(n).

  • The reference Rayleigh/Mie coefficients used by most implementations (and this one specifically) are (AFAIK) only appropriate for an oxygenated / earth-like atmosphere and will not produce visually correct results in CO2 / Methane atmospheres or in different atmospheric densities. Without some approximation to generate semi-physically-based Rayleigh / Mie coefficients there's not much point to introducing "realistic" atmospheric scattering.

Atmosphere's color can be used for adjusting these coefficients (does it change between planets with similar composition?)

Have you verified if "aerial perspective" AKA views from space work correctly? Depending on the implementation of the Nishita model those are sometimes not handled correctly.

That's another one but it might stuck without help of whoever wrote this shader or know what some vars mean and do.

@Web-eWorks
Copy link
Member

Web-eWorks commented Aug 30, 2023

but I think it could be easier to solve an integral and get a single solution with given parameters, reducing complexity from O(n^2) to O(n).

That's another one but it might stuck without help of whoever wrote this shader or know what some vars mean and do.

Read this: https://developer.nvidia.com/gpugems/gpugems2/part-ii-shading-lighting-and-shadows/chapter-16-accurate-atmospheric-scattering - it's another implementation of the same atmospheric scattering model using an LUT instead of brute-forcing the integral. It also "correctly" handles aerial perspective. You'll have to transcribe the code from Cg if you want to crib off of it, but I recommend implementing it from the article's description instead.

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Aug 31, 2023

You'll have to transcribe the code from Cg if you want to crib off of it, but I recommend implementing it from the article's description instead.

Read the whole article. Not understood where's the difference between this and mine (except for the LUP mentioned above)

@Zireael07
Copy link

I agree with @Web-eWorks, most Rayleigh implementations are for Earth-like atmospheres only.

@Web-eWorks does the Hillare model handle non-Earth-like atmospheres? From a quick look at the pdf, it assumes Earth (with possible density changes but still oxygenated)

@Web-eWorks
Copy link
Member

Read the whole article. Not understood where's the difference between this and mine (except for the LUP mentioned above)

The LUT or parameterization of such is the major difference - it replaces the loop calculating for (j = 0; j < numSamplesLight; ++j) with a single lookup or calculation to retrieve the full optical depth between the sample position of the outer loop step and the light source rather than substepping it. Otherwise the two (up to about heading 16.4) are similar implementations of the same model. I was suggesting the article because it includes some interesting options to solve the optical depth integral (outscattering) in question; however the version you've implemented has another interesting method to iteratively calculate the optical depth between the camera and the sample position instead of looking it up in a table.

Slightly unrelated, but the current version of the PR only provides Rayleigh+Mie scattering for the atmosphere - rendering proper atmospheric contribution (i.e. hue shifts) onto terrain + bodies will require computing scattering for the camera->surface ray in geosphere_terrain.frag and multi.frag.

They're currently using the same approximation that atmosphere rendering was using, which is responsible for the blue-looking terrain in your original comparison screenshot.

does the Hillare model handle non-Earth-like atmospheres? From a quick look at the pdf, it assumes Earth (with possible density changes but still oxygenated)

It's a general-purpose model operating on Rayleigh-Mie phase functions which determine the behavior of light in the medium. If the coefficients can be derived, it can handle any kind of atmosphere. The only problem (and one that any atmospheric model will have) is finding the scientific data to describe how light behaves in a non-oxygen atmosphere.

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Aug 31, 2023

I am very suspicious of "density function along the vector" being similar to normal distribution.

@impaktor
Copy link
Member

impaktor commented Sep 1, 2023

If we include this, it might even be "too much" to put the on/off in the settings menu, might belong in debug menu instead, for developers / people who want to render a scene for screen shot. just a thought.

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Sep 1, 2023

Instead, I built my own model for atmospheric density.

Found out this:

  1. density from outside atmosphere can be approximated: k*exp(h*b) where h = distance of closest point of the ray to geosphereCenter
  2. density from inside could be multiplied by erf(t), where t is parameter from -e to e:
    t = -e - no atmosphere along the ray
    t = 0 - half of atmosphere along the ray (we're at the closest point)
    t = e - everything is along the ray.

Pretty close to each other
pioneer-atmosphere

@fluffyfreak
Copy link
Contributor

This is a very exciting development!
There was, long ago, another attempt to do atmospheric scattering but it was... 😱 12 years ago...

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Sep 6, 2023

Pushed some optimization but it looks like I messed up some math and scattering looks unexpectedly different.

Could use some fresh look at this

@impaktor
Copy link
Member

@Mc-Pain Usually, devs don't even have time for their own code, so best to "self review" / leave it to future self.

@Mc-Pain
Copy link
Contributor Author

Mc-Pain commented Sep 16, 2023

@Mc-Pain Usually, devs don't even have time for their own code, so best to "self review" / leave it to future self.

well, I'll try it myself then. Got to my high-end PC, look what happens at very high sample count

@Web-eWorks Web-eWorks self-requested a review September 16, 2023 19:29
@Web-eWorks
Copy link
Member

I intend to review this PR at some point in the near future, but I've not yet had a chance to get to it.

@bszlrd bszlrd added the Rendering Everything related to rendering label Jan 8, 2024
Copy link
Member

@Web-eWorks Web-eWorks left a comment

Choose a reason for hiding this comment

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

First of all, thank you for taking the time and effort to implement this as far as you have!

Regarding prior discussion on IRC about this PR's state, I'm generally willing to merge this for the upcoming release in its current condition as an experimental option. While it still requires significant further improvements to match terrain rendering with atmosphere rendering before I consider it a feature-complete replacement for our current atmosphere rendering, those improvements can be added in after its inclusion in the upcoming release.

To that end, I've pushed several commits to add "hot swapping" the used atmosphere shader from the settings menu and to clearly indicate that the Rayleigh/Mie shader is experimental.

I'd like to see the attached comments be addressed before merging, but if you consider this in a good enough state to merge for the upcoming release then I'll sign off on it.

data/shaders/opengl/basesphere_uniforms.glsl Outdated Show resolved Hide resolved
data/shaders/opengl/rayleigh.glsl Outdated Show resolved Hide resolved
data/shaders/opengl/rayleigh.glsl Outdated Show resolved Hide resolved
data/shaders/opengl/rayleigh.glsl Outdated Show resolved Hide resolved
src/galaxy/SystemBody.cpp Outdated Show resolved Hide resolved
src/galaxy/SystemBody.cpp Outdated Show resolved Hide resolved
@impaktor
Copy link
Member

Just checking: Could this PR cause crashes? My main thinking is: if someone opens a bug report, and attach output.txt, will we see they've enabled the "Experimental" option?

@Web-eWorks
Copy link
Member

Just checking: Could this PR cause crashes? My main thinking is: if someone opens a bug report, and attach output.txt, will we see they've enabled the "Experimental" option?

Very unlikely. This PR mainly makes changes to shaders and the experimental option simply influences which shader is chosen.

@Mc-Pain Mc-Pain force-pushed the rayleigh-shaders branch 2 times, most recently from 4bd9e80 to 4e2c417 Compare January 19, 2024 15:38
Copy link
Member

@Web-eWorks Web-eWorks left a comment

Choose a reason for hiding this comment

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

@Mc-Pain please go ahead and start squashing related / iterative-work commits down into feature-level commits. Ideally all "rename" and "fix" commits related to the new rayleigh scattering code should be condensed into a small number of commits adding a major feature. Generally unrelated or standalone commits (e.g. "Add experimental label to Rayleigh/Mie scattering option") can be left as-is.

I generally consider this PR as approved, but the commit history will need to be cleaned up before merge. The sooner the better - once the history has been cleaned up I consider this PR good to merge for whoever is able to hit the button first.

Mc-Pain and others added 19 commits January 26, 2024 19:07
- Perform all calculations in planet space
- Factor out common code into separate functions
- Planets use Blinn-Phong to render specular highlight on water
- Support arbitrary scaling of rendered planets
- Cull front-face of atmosphere mesh to avoid doubling atmosphere intensity when outside atmosphere
- Convert incoming color constants from sRGB into linear space
- Tonemap before converting back to sRGB for writeback to the buffer
- Match the API usage patterns of the other Drawables classes
- Add additional checks for the validity of the atmosphere material before attempting to draw atmospheres
@Web-eWorks Web-eWorks merged commit 22c0b09 into pioneerspacesim:master Jan 27, 2024
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Rendering Everything related to rendering
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants