SkyAtmosphere and World Rebasing

@SebHillaire, I cherry-picked your cl and the Sky Atmosphere does now properly work with origin-rebasing. Thank you for fixing this so swiftly :slight_smile: it is very much appreciated!

Seb could you also lower the minimum world size to 1km (or just remove the clamp at all)? The 100km minimum it is now is still way too big and severely limits the creative use of the sky atmosphere for spherical worlds. Thank you!

Just wanted to mention as a workaround that you can set the size to whatever you want via cpp. Pretty sure there is a “soft” minimum and maximum size where the rendering side of the sky atmosphere doesn’t play well.

I sadly don’t use a cpp project, blueprint only. And Seb said in a previous comment in this discussion that he could lower it to 1km.

Hi,
Yes, this has been done for 4.26 already. The radius slider can go down to 1km now, IIRC you can go lower, down to 100 meters but problems can start to show.

If you go with a lower radius, you will likely have to increase the sample count when tracing the atmosphere (to catch higher frequency details and planet shadows). There is now a quality slider on the SkyAtmosphere component that you can use.

I did some experiments and it looks like it’s purely because the skyAtmoshphere does not aware the world origin has been changed and I have found workaround. After you call “SetWorldOriginLocation” you just need to change a variable a little bit(i.e. Call “SetMieAbsorption” and add a small value say 0.001) to force the skyAtmosphere component to rebuild its status.

Thank you for adding that option, you are my hero!

Now I just have to “impatiently” wait for 4.26… :frowning:

With the news of Large World Coordinates I decided I wanted to try this again, as I won’t have to worry about origin shift / world rebasing anymore. I’m now using UE5 Preview 2.

Everything is working really well - except for the SkyAtmosphere/DirectionalLight/SkyLight setup.
For some reason, it seems all of these are affected by the notion that Z+ is up.

This planet is exactly the size of the earth, and thus uses the default size for the atmosphere:

When having the sun light up the planet from different direction, some very weird lighting occurs.
This is exactly the same picture, just with a different angle on the directional light.


After having tested a lot of angles, I have concluded that the reason everything gets a red tint in the second picture is because the “north pole” (being the only place on the planet that has Z+ as up) has a sunset. And since this engine is so hard-coded to make Z+ as up, it somehow applies the sunset-tint to the entire scene, including a cube that is thousands of kilometers outside the planet/atmosphere.

@SebHillaire Do you have any input on why the DirectionalLight’s angle is causing this?

(To reproduce, spawn a DirectionalLight in C++ e.g on BeginPlay, with ZeroVector location and ZeroRotator rotation. When playing in PIE and selecting the DirectionalLight, notice that the rotation of the DirectionalLight is somehow changed to {0, -46, 0} and that it has an angle (actually realistic). Change it to 0,0,0 to get a completely vertical shadow, e.g the sun will always go perfectly on the equator, and see this tint happening everywhere. It happens with a lot of other angles as well, this is just one of them that’s easy to reproduce.)

Hi,
Yes, this is because by default we compute the directional light illuminance affected by transmittance on CPU for the world (as an optimization). If you want transmittance to be evaluated per pixel (a bit more expensive on GPU), you will need to enable that on the directional light. Documentation is showing this: Sky Atmosphere | Unreal Engine 4.27 Documentation .

1 Like

Oh, thank you! That fixed it immediately.

I’m also seeing very strange behavior from SkyLight (regardless of “per-pixel transmittance”).

The effect of the SkyLight seems to be highly dependent on where the SkyLight actor/component is placed relative to the center of the SkyAtmosphere, and only works for the “north” part of the planet (where Z+ is up).
Testing with an atmosphere placed at 0,0,0 (and TransformMode = Planet Center at Component Transform), with the default 6360km Ground Radius. SkyLight with Real Time Capture = true.
I placed a cube at {0,0,636000000} (essentially the North Pole). No terrain.

SkyLight at {0,0,0}
Literally no effect from the SkyLight. The cube is completely black:
image

SkyLight at {0,0,1} (or {0,0,636000000}, same result)
Perfect lighting:
image

SkyLight at {1,1,1}
Unexpected white light coming from everywhere:

This was weird, but based on the second image and its SkyLight-locations I figured that I could just place and move the SkyLight-actor to always be on the same vector as the player relative to the planet/atmosphere center. Essentially just attach the SkyLight to the player.
However, the images above are only for the north pole. If I am located anywhere else on the planet, nothing seems to work properly.

Cube at {0,0,-636000000}, essentially the South Pole:
SkyLight at {0,0,-1} (or {0,0,-636000000}):
image
(Can’t flip the camera in Editor, so it’s upside down)
So, my assumption about having the SkyLight at the same direction as the cube relative to the AtmosphereCenter is wrong. There is no light at all. The same as {0,0,0}.

However…
SkyLight at {0,0,1} (or 0,0,636000000}, the same location that worked for the North Pole:


It almost seem to work, except that the light is completely flipped. The cube’s “sky face” is dark. And the cube’s “ground face” is lit up (not pictured).
If I further simulate the sunset:
image

The sun has passed beyond the horizon, but the cube is brighter. As if the sky was turning brighter.
In other words, the cube is lit up exactly as it should be lit up if it was placed on the North Pole (where the sky IS brighter). However, it is on the South Pole. Where the sky is darker.

And these were just tests with North and South Pole, where the light is just flipped. If I use any other place on the planet, everything gets much weirder.

Here is a cube at the XPos-pole (636000000, 0, 0}, where the sun is slightly below what would’ve been the surface if you were at the North Pole:
image

And here is when the sun would be exactly at the surface as seen from the North Pole:

And here it is slightly above the surface as seen from the North Pole:

However, from the perspective of this cube, the sun is just gliding across the planet surface, with no change in atmospheric color. The atmosphere is acting perfectly, but the SkyLight is lighting it up as if it was somewhere else.

These last tests were all with the SkyLight at {0,0,1}. If I move it to {1,0,0} it does appear more correct for this specific cube, but still acts weird when the sun changes angle, like the SouthPole-cube did.

Also, moving the SkyLight in runtime based on the player’s position doesn’t seem viable, as moving it actually doesn’t update the lighting. It only works when moving it in-editor, which essentially creates a new instance (or calls OnConstruct or something). Calling SetActorLocation does not trigger light-updates. So to make this “work” (although not really) I have to create a NEW SkyLight instance every so often, and destroy the previous one, which obviously is a terrible idea.

I really hope you know about another boolean value like per-pixel-transmittance that I haven’t found

Hi,

The lighting is taken from the skylight position as far as I remember. At least that is how it works for the real time capture option that is sure. You can real time capture with the skylight following the camera, that is efficient. You might find some latency issue if you move super fast so to fix that you would need to disable capture time slicing (and pay the full GPU cost each frame).

Skylight is not something local but global. the captured environment is taken for the skylight position and applied on everything, then AO or Lumen would deal with local occlusion/GI. That is what you should do today. Maybe the best is to capture the sky light always projected on the ground for instance.

Not sure why the cube is bright though that is a bit weird, I would need to investigate at some point.

I would like to, at some point, implement ambient diffuse illuminance via SH that takes into account the position on the planet w.r.t. to the sun but that would only work for diffuse and not specular. The best bet for you is to use the method I describe in the previous paragraph today I’d say (might need more thinking also).

Thank you very much. You were right. I was able to programmatically move it and call MarkComponentsRenderStateDirty() to make it update properly. The time slicing optimization does seem preferable rather than full GPU cost, but I’ll play around with it.

Now I’m faced with yet another peculiar phenomenon related to the SkyAtmosphere.
flicker
The sun is flickering/flashing/blinking whenever I rotate the DirectionalLight at certain speeds. Per now I’m just testing by doing
DirectionalLight->AddActorLocalRotation(FRotator(0, DeltaSeconds * 4, 0)); in the Tick-function.

Actually, even when the sun is not rotating I still get flickering, if I move fast enough.
flicker2
For reference, the planet on the left side is Earth-sized, so I’m moving quite fast.
From what I can measure, this starts happening somewhere between movement of 1km/s and 4km/s (100000-400000 units per second), and gets gradually worse the faster I move.

I have not enabled any type of bloom. I’ve played around with values on both DirectionalLight and SkyAtmosphere without finding a solution. The only thing that makes the flickering less noticeable is to increase the “DirectionalLight->SourceAngle” to e.g 3.0, but this will obviously make the sun way too prominent.
nonflicker

Another thing; the sun looks very good from within the atmosphere, but it’s not very pretty when viewed from space. It’s pretty low-res and weird.
sun
Is there a way to alter its visual style for only outside the atmosphere, or should I somehow swap between two different suns (one from SkyAtmosphere, and one I make myself somehow) when crossing the atmosphere?

Cool that you have been able to move forward.

Sun: this is called aliasing because the sun is too small and too bright. Some pixel are sometimes on or off. This with their high luminance when on makes the bloom flickers, even with a TAA process on it.

If you would use a skydome mesh, you could replace the sun with whatever. Only two solutions I see to counter that for your case: use the “Atmosphere Sun Disk Color Scale” from the dir light detail panel and lower that to something small like 0.005 for instance. Another solution is to draw an opaque object you want where the sun is as far as possible (and make the sun disk size 0 for instance.