Carmack on star fields in VR
twitter.com
twitter.com
In general, the higher level your graphics API, the harder it is to get horizontal and vertical lines to draw on the physical pixels. At the frame buffer level it is trivial. Cocoa and UIKit it is possible with some effort. SwiftUI it is impossible (you will end up using the escape hatch to Cocoa or UIKit). HTML is hopeless.
When printing meant writing some Postscript it was a little work, but doable. Getting it onto a printer through a modern printer API is essentially impossible.
Fundamentally this is why most graphs you see online look like they were drawn with a worn out felt tip marker. It hides the sins at the expense of limiting data density and precision.
About acronyms, I remember a company that won a bid for a company I worked with. Part of the reason they won is that their proposal was very clear, and one of the stated reason was the lack of acronyms.
To this day, I try to avoid using acronyms as much as possible. I also remember an argument at another company, someone was complaining of problems on the "VMS", the other was calling bullshit. It took a few minuted before they realized they were talking about two different things with the same acronym. There are only 17576 3-letter acronyms, if 200 of these are used, the chance of a collision is about 2/3 (see: birthday paradox), and that's assuming a uniform distribution, in reality, it is worse. Misunderstandings are inevitable.
I'm not even sure on Windows there is a way to render anything
A native application does not generally have these issues because by nature of being native it was built for the form factor it is being used on.
For instance, see the discussion on this "monitor calibration" shader: https://www.shadertoy.com/view/NsS3Rw
In that case, FireFox does not 100% provide some of the needed APIs in order to get pixel-perfect rendering. There's nothing you can do to fix that yourself.
"...Anyways, long story short, we need Firefox to implement 'devicePixelContentBoxSize' before we can have pixel exact rendering, deterministically, in that browser."
That's just one example.For something delicate like pixel-perfect rendering, every layer in the chain from hardware to OS -> libraryX -> libraryY -> libraryZ -> browser -> your code, all need to handle coordinates and thigs _perfectly_. If any one of those links in the chain messes things up, or doesn't provide the correct rounding, etc. then you are stuck.
It's not so terribly hard to do, but it has subtleties and edge cases, and everyone involved must handle them correctly. Also, if they handle them not-correctly, the result is still "good enough" for many purposes, so the fix doesn't get prioritized.
Brother printers (at least some) support BR-script which is Postscript without the trademark violation. It's supported at the driver level, I think, which would render the PS on the PC then send the rendered document as one of the hardware-supported languages like PCL.
I mention this as an interesting bit of info, and not to refute anything you said
So it's not about the number of layers of abstraction or general "high level"ness, but rather if those abstractions are trying to cover up mistakes made elsewhere.
On any real camera, stars always cover multiple pixels (the entire screen strictly speaking). This is described by a point-spread function (PSF), where the "least blurry" physically realizable PSF is the Airy disk. The bloom effect occurs due to the long tails of the PSF. Inasmuch as stars appear as perfect points to the eye, it's down to perceptual limits and (I suspect) heavy filtering in the visual cortex.
Not saying Carmack is wrong about VR and video game rendering here. Just that if you're trying to replicate real sensors, the right way is precisely what he says to avoid. You must somehow draw
> large, dim stars
During a recent effort to implement physically-accurate star rendering at work, I had access to a photograph of the night sky. Bright stars visibly and clearly covered 3x3 pixels- more in reality, due to the above.
Not to be confused with the upcoming game https://en.m.wikipedia.org/wiki/Starfield_(video_game)
The title should fix the capitalization and use two worlds
I presume that's basically the same fundamental problem as rendering line art and star fields...
> Stars (along with line art) are one of the most blatant tests for gamma correct rendering — if everything shimmers as you pan around, they are filtering in gamma space instead of linear space. It should all be rock solid.
Something to do with as the underlying values are shifted between pixels (as you pan around), they increase/decrease pixel brightness inconsistently if you're mapping the intrinsic values to some curve before calculating the appropriate pixel brightness? (I'm unfamiliar with "gamma correct rendering")
The relationship between perceived brightness and physical amount of light is approximately quadratic (~doubling amount of light is perceived as one incremental brightness step), which is called the gamma curve.
So in graphics you have to choose whether your numeric brightness values are on a scale relevant to humans (gamma compressed values), or whether they're on a scale that better models physical properties of light (AKA linear light).
This is generally confusing, and a lot of software gets it wrong (doesn't correct for the gamma curve where needed). For example, try blurring RGB red and green. In many programs it will give you a brown color, which is not the color of mixing red and green light, but a bad math on gamma-compressed values: √(A + B) ≠ √A + √B
This sounds logarithmic to me, similar to the decibel system for audio loudness perception
Imagine you want to represent a star with a single max brightness pixel. Suppose you want to smoothly pan that pixel to its neighbor. If you simply switch the pixel off and switch the neighbor on, it will look jumpy. So what you want to do is gradually dim the first pixel, while gradually brightening the second, so that the intensity smoothly moves over instead of jumping.
The catch: at all times, the sum of the light intensity from both pixels must be constant. You want the star to move, not flicker. Seems easy, right? Subtract 1 from the first pixel and add 1 to the second, keeping the sum the same?
Wrong! The relationship between the actual light emitted by a pixel and the number we use to represent it in software is not linear. It generally follows a power law, usually with an exponent of about 2.2, since this is a more efficient representation given that human perception also follows a power law. If 255 were actually twice as many photons as 127, you would find that they didn't actually look all that different - the range 0-255 would skew towards most values looking pretty bright. Instead the values "encode" the real brightness, and if you do math on these encoded values you are operating in "gamma space".
So, in order to correctly do our 1-pixel panning, we need to "decode" our pixel value to linear brightness by taking the logarithm (base 2.2), add 1 / subtract 1 there, and then raise it back up. This is what Carmack means by "filtering in linear space". Obviously, many programmers are not aware of the requirement to do this, and just treat the pixel values as if they were real brightness values. Result: flicker.
It seems like this was a necessity to allow for a larger range of representable colours in a single byte. Is this system largely a carry over from more constrained hardware days, or is it still appropriate for modern hardware? Like, we could represent colors with a few more bytes and toss out the gamma encoding to get back to the same level of control. Or am I overlooking more fundamental reasons why this is a good abstraction?
Modern rendering engines will use a mixture of 8bit, 10bit, and 16bit per color channel buffers - the final 'lit' color buffer is where you will generally write fp16 (8bytes per pixel) linear HDR color values, if you can spare the performance hit, as this is where you need the highest range.
sRGB has a badly defined gamma space of an encoding of { [0-15] (linear), [16-255] (power of 2.4 over [0-239] with an offset of 16) } with a decoding of 2.2 (but explicitly taking into account "dark room" ambient lighting, not the actual display response). This is often quoted as "power of 2.2 encoding and decoding", and this has never been correct. For modern viewing conditions with a 100 nits monitor in an ambient condition of "bright room", the proper interpretation of sRGB is to read as "actual monitor response of 2.4", which leads to....
bt1886 defines this as 2.4 encoding combined with a 2.2 and 2.4 decoding where the crossover point is calculated in a way that takes into account actual black levels observed on the device to maintain perceptual quality while avoiding black and white crush (devices with actually zero black (ex: CRT, Plasma, OLED) would just be pure 2.4 decoding). This allows all commercial content (NTSC, PAL, and BT709/BT2020) to display favorably no matter how badly it was mastered originally and no matter how bad the viewing conditions actually are.
BBC, taking into account "ye average display over the past 30 years", encodes as 2.35 to take into account NTSC, PAL, 2.2, 2.4, and actually-sRGB displays. This is arguably the most correct approach: bt1886 and sRGB/bt709 on displays that are too dark will be too dark but perceptually correct on displays that are too bright; "encode as 2.2" (which is still wrong) will be very dark on every display; 2.35 will look correct on "wrong, but too dark", "wrong, but too light", "actually sRGB", and "actually bt1886" monitors.
There also is a third (fourth?) standard of 2.6 that is purely found in extremely low display light (40 nits or less), zero ambient completely blacked out conditions, used for movie theatres, due to perceptual changes in human eyesight; sRGB, bt1886, and 2.35 would all be too dark and/or too undersaturated here otherwise.
...
But that isn't true rofl. Stars are, in fact, (extremely) large spheres, and can take up more than one pixel if your pixels are small enough.
But indeed, not all stars are "point light": the sun as seen from the earth is not. And it is a good thing, because otherwise that would make our sun like a laser, our retinas won't last long...
I think you are mistaking cause end effect. If the sun were a point source, the layout of our eyes (and our behaviours) would have evolved differently to compensate.
Alternatively, if the diameter of the sun (or the apparent diameter of the sun) quickly changed that much, our eyesight is the least of our worries.
The Oculus Quest 2 has a horizontal FOV of 97 degrees. In order for α Centauri to cover two pixels, you would need a display with 6.2179487x10^26 horizontal pixels. 621 yottapixels. Something like a hundred sextillion times "4K" resolution. And that's linear resolution, tag on some more orders of magnitude for display area.
There is a reason parallax is used to measure distance to stars, rather than directly measuring their visual diameter.
Even in outer space, with no atmospheric aberration, there will be some blur for anyone with less than absolutely perfect eyesight.
There will be a point-spread-function because our optics are not ideal (especially with bright point sources), and blur will result from a variety of causes.
Computer graphics are meant to be perceived through human eyeballs. So we can count on the eyes continuing to blur point lights whether you're looking at a screen or at outer space.
Also, the game might be simulating an experience from a character's point of view, and expect the player to be wearing glasses to correct their personal vision defects (to the extent possible).
(The calculated horizontal resolution required for a 2 pixel wide star from the original post should instead be 100,009,624)
The corrected number for star apparent diameter should be 0.006983 arcsec. Depending on how finely you want to resolve the disk, that would take somewhere between a 70 to 140m wide telescope. (With 400nm light)
The largest optical telescope currently under construction is 39.3m wide: https://en.wikipedia.org/wiki/Extremely_Large_Telescope
They are too far away.
It's clearly evident if you look at them in a telescope, especially in observatory.