-
Notifications
You must be signed in to change notification settings - Fork 309
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
Physically based star rendering #1948
Comments
What to do with the faintest apparent magnitude currently in use?
br_limit = 1 / (255 * 12.92)
def faintestMag2exposure(faintestMag):
return br_limit * 10**(0.4*faintestMag)
def exposure2faintestMag(exposure):
return 2.5 * np.log10(exposure/br_limit) |
As exposure and faintestMag are mutually convertible it doesn't matter what variable to use. But I think that for user convenience it's better to keep faintestMag. |
Outdated. See original post for up-to-date information. There is an even better solution for the last PSF design: you can calculate the square size depending on the brightness, in the range from 0.012° to 1.5°. For example, for def PSF_max_theta(br: float):
return 0.012 + 1.488 / (np.sqrt(br_limit * 10e6 / (11 * br)) + 1) and changes in # glare render on < 3°×3° field
square_half_size = ceil(PSF_max_theta(color0.max()) / degree_per_px) Why not to calculate the square size for all the angles, not just in 3°?
|
In the future, it may be necessary to link the “convenient linear brightness scale” to the physical one. Let me formalize how I introduce a “convenient scale”: the green color component for a 0 magnitude star illuminates exactly one pixel (exposure=1 everywhere). Let's link the zero magnitude to the Vegan spectrum from the CALSPEC database as a standard, and also assume that the green component of the pixel completely follows the green sensitivity curve of the eye. Correctly multiplying one curve by another, I obtain that the unit of the “convenient brightness scale” corresponds to 3.844750664631218e-11 W/m² in SI. |
It turned out that the function |
After doing a little research, I was able to achieve a single optimized PSF work at any brightness, and, most importantly, that zeroes at an angle, determined from the brightness. Original post updated. |
I have implemented the same in c++ and glsl - https://github.com/CelestiaProject/Celestia/pull/1952/files (windows artifacts at https://github.com/CelestiaProject/Celestia/actions/runs/6658496014). Problems - |
some thoughts. taking into account limited point sizes and that inside solar systems suns are too bright, at some faintestMag-P, where P > M, radii should grow much slower. |
It's possible, but there are many problems. The main one is it’s difficult to make the “blur” and “radius” functions visually pleasing. The transition will be sharp and noticeable. Also, for gamma correction, the function must very smoothly go to limited zero. Polynomials will not work, nor will exponential. I think the current implementation is one of the most optimal possible for glowing within a few tens to hundreds of pixels, but the high brightness problem is real. What about, as soon as a star with a magnitude higher than P appears in the field of view, to force the magnitude limit so as never to exceed P? |
Sounds ok for me |
There is another optimization that (for now) can significantly reduce the size of the square: to determine the if srgb:
br_limit = 1 / (255 * 12.92)
else:
br_limit = 1 / 255 |
Updates:
To make the code and the issue easier to maintain, I made a separate repository: https://github.com/Askaniy/CelestiaStarRenderer
For Celestia, I recommend using the
Bounded
algorithm.The information in this post is recorded as of October 2023.
What is the problem:
What were ways to solve:
The problem was already noticed and described by Chris Layrel, 2010 forum discussion is here. In a roundabout way, it led to this branch. But, as onetwothree said, "it's buggy and slow". One of the problems was the squares around bright stars (Gaussians don't have a limit on the angular size, but the shader does):
What I suggest:
I've developed a rendering algorithm that solves this problem. Unfortunately, I've virtually no knowledge of the C/C++, and have limited time. Therefore, I'm creating the issue to document the current developments, perhaps I'll return to this later.
The render below shows three columns of stars renderings of different magnitudes. The first is based on the Chris's formula given on the forum, and in fact consists of two independent Gaussians. The second is an implementation of the photopic point source function (PSF) from this paper. The third column is my attempt to optimize the formula and create a constraint on the angular size (to fix the squares bug). The render is gamma corrected and enlarged three times without interpolation.
Python functions that implement optimized eye's PSF: https://github.com/Askaniy/CelestiaStarRenderer/blob/master/algorithms.py
For example, an exposure of 1 means that Vega occupies a single pixel with no glow, and 5 means that this is true for a star 5 times dimmer than Vega, while Vega itself have a noticeable glow. A general logic looks like this:
What are known problems:
A bug with squares was fixed by adding a hard limit on the glare angular diameter of 1°. However, this also resulted in very large exposures being unpresentable compared to the original PSF function.Fixed.The text was updated successfully, but these errors were encountered: