Skip to content

Conversation

defuz
Copy link
Contributor

@defuz defuz commented Aug 5, 2025

Objective

Testing

  • Ran the official atmosphere example on a MacBook M1 (see showcase below).
  • Toggled bloom on/off and tried intensities 0, 0.01, 1, and 10 — the sky looks correct and no warnings appear.
  • Noticed a small dark “hole” in the center of the sun disk under some settings; this artifact was present before these changes (often hidden by bloom) and probably deserves further investigation. (FIXED IN THIS PR)

I’m new to WGSL/shader code — please point out anything silly! 🙂


Showcase

  • Scene brightness changes with intensity only because bloom amplifies the bright disk; sky illumination stays unchanged.
  • With bloom disabled, the disk is the only thing that changes — the rest of the scene looks identical.
  • Raising intensity above 1.0 doesn’t affect the scene without bloom (the disk is already 100 % white) but boosts the bloom halo when bloom is enabled.
  • Lowering intensity reduces the bloom halo; drop it far enough and the disk blends into the sky, which is physically plausible for very dim suns.
1.0 (bloom on) — normal default 1 0
0.0 (bloom on) — no disk no sun 0 0
0.01 (bloom on) — low brightness, tiny bloom effect 0 21
0.00001 (bloom on) — disk blends into the sky 0 00001
10.0 (bloom on) — blinding glare 10
1.0 (bloom off) — normal sun with no bloom 1 no bloom
10.0 (bloom off) — indistinguishable from 1.0 when bloom is off 10 no bloom

Quick question for reviewers: (not part of this PR) I’ve already experimented with parameterizing the sun angular size and it works well. It could serve as a cool artistic control or let you match skies for planets that aren’t Earth. Would folks be interested in a follow‑up PR?

4× sun size 4x sun

Copy link
Contributor

github-actions bot commented Aug 5, 2025

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

@defuz defuz force-pushed the atmosphere-settings-sun-disk-intensity branch from 1de0f14 to 6c6bb45 Compare August 5, 2025 21:59
@alice-i-cecile alice-i-cecile added A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Aug 5, 2025
@alice-i-cecile alice-i-cecile requested a review from ecoskey August 5, 2025 22:00
@alice-i-cecile alice-i-cecile requested a review from mate-h August 5, 2025 22:00
@alice-i-cecile alice-i-cecile added X-Uncontroversial This work is generally agreed upon D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels Aug 5, 2025
@alice-i-cecile
Copy link
Member

Quick question for reviewers: (not part of this PR) I’ve already experimented with parameterizing the sun angular size and it works well. It could serve as a cool artistic control or let you match skies for planets that aren’t Earth. Would folks be interested in a follow‑up PR?

I'm very interested in this! Seems extremely useful artistically and very sensible to expose.

@mate-h
Copy link
Contributor

mate-h commented Aug 5, 2025

Hey everyone, this is a very neat! Thank you for putting together this PR. I do have a pending change to include the angular radius in directional light, as well as a new SunLight component. I could tac on this change to the SunLight component itself rather than the atmosphere settings. So there might be some conflicts. I will leave a more detailed response with my specific suggestions for the user facing API later as I have thought extensively about this problem based on all the feedback received so far. Also regarding integrating the atmosphere with probes, another problem area that I have addressed in my fork of Bevy, still needs to be reviewed and merged to main.

@atlv24
Copy link
Contributor

atlv24 commented Aug 5, 2025

#19037 is the relevant PR btw. Currently closed for rebasing and splitting

@defuz
Copy link
Contributor Author

defuz commented Aug 5, 2025

Hi @mate-h, thanks for the extra context!

I had a quick look at your PR and I’m a bit unsure about the ergonomics of the approach. If I’ve got it right, you’re proposing a SunLight component attached to a DirectionalLight entity:

pub struct SunLight {
    pub angular_size: f32,
    pub intensity: f32,
}

My initial aim was to let GI-probe cameras hide the sun disk while keeping it visible for the main camera. That fit well with Atmosphere/AtmosphereSettings live on the camera side, not the light side.

If sun-disk visibility is moved onto the DirectionalLight, turning it off would also hide the sun for the main camera. One workaround would be to use two DirectionalLight + SunLight pairs—one rendered only for the main view and one for the probes—but we’d need to confirm the new architecture can support that.

@mate-h
Copy link
Contributor

mate-h commented Aug 5, 2025

What is your current approach with GI probe cameras? I am also proposing to add another component called atmosphere environment map light that does that part. It is meant to upsample the sky view LUT (or do a raymarch) into a target cubemap texture, in a separated shader without the sun disk. Then it is plugged into the (recently merged) environment map filtering pipeline to get cubemap mip chain at different roughness levels. I could still see the need for a separate decoupled intensity setting for the sun disk itself. But it would only affect the composited sky in the main sky rendering pass, not the environment light. There the disk is deliberately excluded, and instead we sample the transmittance LUT in the pbr pipeline to tint the directional lights orange at sunset. In its present state Bevys atmosphere is only a composited effect but the changes I am proposing would fully integrate it with the PBR pipeline and environment reflections. Feel free to reach out on Discord (user mate_h) to discuss the approach and the details.

@mate-h
Copy link
Contributor

mate-h commented Aug 5, 2025

There is a newer , working version mate-h#10
Rebased onto more recent main.

But I need to work on splitting it up a bit more.

@JMS55
Copy link
Contributor

JMS55 commented Aug 6, 2025

Angular sun disk size for directional lights is also something I'm interested in. The code for it is already in Solari, it's just not exposed to users :)

Copy link
Contributor

@JMS55 JMS55 left a comment

Choose a reason for hiding this comment

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

Approved once the wording change I proposed is merged

@defuz defuz marked this pull request as draft August 6, 2025 03:35
@ecoskey
Copy link
Contributor

ecoskey commented Aug 6, 2025

I like the idea of having a stylistic adjustment for the sun-disc intensity, but I think I'd prefer something like @mate-h's proposed SunLight component. It feels easier to teach and reason about, even if a bit harder to implement :)

Also (and this is more editorial) maybe the intensity override should be an Option? I think in most cases we should nudge people towards matching the values.

Ivan Ivashchenko and others added 3 commits August 7, 2025 16:21
@defuz defuz force-pushed the atmosphere-settings-sun-disk-intensity branch from e7f8863 to 0a25380 Compare August 15, 2025 00:33
@JMS55
Copy link
Contributor

JMS55 commented Aug 15, 2025

I also added intensity adjustment to ExtractedDirectionalLight.luminance, although you didn’t mention it explicitly in your request. Is there any reason this should be avoided?

Isn't the itensity supposed to affect the SunDisk, and not the light itself?

@JMS55
Copy link
Contributor

JMS55 commented Aug 15, 2025

Fyi you can probably delete SUN_ANGULAR_DIAMETER_RADIANS now. Not sure why CI didn't warn that it's now unused 🤔.

@defuz
Copy link
Contributor Author

defuz commented Aug 15, 2025

Isn't the intensity supposed to affect the SunDisk, and not the light itself?

You are right, but the same argument is also applicable to SunLight::angular_size. If I understand correctly, SunLight::angular_size affects GpuDirectionalLight in a way that changes how soft shadows look with Solari.

But bevy::pbr renders soft shadows relying on DirectionalLight::soft_shadow_size: Option<angular_size> and is independent of SunLight::angular_size entirely, which is a bit awkward, but it represents a separation between the shadow and sky rendering implementations, while Solari rendering implementation is generally more “physically uniform”, which means users have fewer options to tweak things separately.

As result, in the current implementation, Solari relies on SunLight::angular_size for sun/world rendering, and ignores SunLight::intensity for sun/world rendering. And the classic render pass relies on both SunLight::angular_size/intensity for sun rendering, and ignores both for world rendering. This looks like a counterintuitive blend of two paradigms in usage of same entity.

I don’t have a better proposal, tbh, just highlighting the little mess we're creating here. I’d prefer to rely on your and @mate-h decision, anyway, since it highly depends on vision of final workflow of solary + atmosphere.

Copy link
Contributor

@mate-h mate-h left a comment

Choose a reason for hiding this comment

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

Great work on the new approach! looks solid with no blockers from my side.

  • Shadows vs sun disk size: Keep these independent in the raster pipeline for finer control.
  • Preserve physically-based default (intensity = 1.0 → physically derived values). Avoid extra SunLight APIs (e.g., separate color). For stylized/colored/extraplanetary disks, recommend a custom skybox or compute-to-cubemap; the atmosphere can composite over via dual-source blending.
  • Disk intensity falloff: Physically motivated but likely low visual impact—defer as a later experiment to avoid API bloat.
  • I sppreciated the forward-compatibility, correct fwidth AA, and center NaN fix. Feels robust and production-ready. Keep defaults to avoid breakage while offering customization; don’t over-expose knobs.
  • Directional light: For Solari, tying shadow blur to disk size makes sense. Consider adding angular size directly to DirectionalLight or introducing DirectionalDiskLight for generic infinite disk lights. For the Moon, prefer cubemap/skybox.
  • Please rename the component to SunDisk (it’s not a new light type). I’ll approve after the rename.
  • Sun disk rendering is niche; now that it’s decoupled from the atmosphere, consider generic use cases. Ensure users can disable the built-in disk and supply their own; sensible defaults should cover most needs.

let sun_intensity = (*light).intensity;
if sun_angular_size > 0.0 && sun_intensity > 0.0 {
let factor = 1 - smoothstep(sun_angular_size * 0.5 - w, sun_angular_size * 0.5 + w, angle_to_sun);
let sun_solid_angle = (sun_angular_size * sun_angular_size) * 0.25 * PI;
Copy link
Contributor

@mate-h mate-h Aug 15, 2025

Choose a reason for hiding this comment

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

This is the same expression as before, even though the PR description/comment above suggests otherwise.
FRAC_PI = 1 / PI

0.25 = 1 / 4

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's precisely reciprocal, no? 4/pi vs pi/4. :)

}

impl SunLight {
pub const SUN: SunLight = SunLight {
Copy link
Contributor

Choose a reason for hiding this comment

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

typing out SunLight:SUN or SunDisk:SUN feels a bit awkward, but I don't have a better idea. maybe SunDisk:EARTH ? since this is exactly 1 AU away? I am adding martian atmosphere eventually so there can be a SunDisk:MARS too that has different values.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe SunDisk::VIEWED_FROM_EARTH

Copy link
Contributor Author

@defuz defuz Aug 16, 2025

Choose a reason for hiding this comment

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

Renamed to ::EARTH.

VIEWED_FROM_EARTH sounds too verbose to me. "Viewed from" is the meaning of SunDisk component, so SunDisk::EARTH is unambiguous.

@JMS55
Copy link
Contributor

JMS55 commented Aug 16, 2025

You are right, but the same argument is also applicable to SunLight::angular_size. If I understand correctly, SunLight::angular_size affects GpuDirectionalLight in a way that changes how soft shadows look with Solari.

Yes, but Solari doesn't render a sun disk, so the SunDisk::intensity field shouldn't matter, right? Whereas angular_size does affect something that Solari uses.

But bevy::pbr renders soft shadows relying on DirectionalLight::soft_shadow_size: Option<angular_size> and is independent of SunLight::angular_size entirely, which is a bit awkward, but it represents a separation between the shadow and sky rendering implementations, while Solari rendering implementation is generally more “physically uniform”, which means users have fewer options to tweak things separately.

Yes, it's a little awkward. For now just leave it. PCSS (which is what soft_shadow_size is used for) were never really working anyways.

As result, in the current implementation, Solari relies on SunLight::angular_size for sun/world rendering, and ignores SunLight::intensity for sun/world rendering. And the classic render pass relies on both SunLight::angular_size/intensity for sun rendering, and ignores both for world rendering. This looks like a counterintuitive blend of two paradigms in usage of same entity.

Solari doesn't render the sun disk, so intensity doesn't matter.

The standard renderer doesn't render the sun disk, or have physically accurate directional light shadows, so both angular_size and intensity don't matter.

@defuz defuz changed the title Add bevy_light::SunLight Add bevy_light::SunDisk Aug 16, 2025
@defuz
Copy link
Contributor Author

defuz commented Aug 16, 2025

Hi folks! Thanks a lot for all your comments. They were extremely helpful to me, especially in narrowing down the approach and aligning it with Bevy’s vision. Also very insightful!


  • Renamed SunLight to SunDisk.
  • Renamed the constant ::SUN to ::EARTH.
  • Not discussed previously: Added a SunDisk::OFF constant (angular_size = 0, intensity = 0). I think it fits well with Bevy’s approach and provides a very intuitive answer to the question “How do I disable sun-disk rendering for my directional light?” → “Just add SunDisk::OFF to it.”
  • Rename fields in ExtractedDirectionalLight to reduce ambiguity.

For now, I don’t see anything else that needs to be fixed in the PR before merging. If I’m missing anything, please let me know!


@mate-h Your comments look 100% reasonable to me; I have nothing to add.

@JMS55

Solari doesn't render the sun disk, so intensity doesn't matter.

You’re right. I misunderstood this initially. Now everything looks much more reasonable to me.

@JMS55
Copy link
Contributor

JMS55 commented Aug 16, 2025

I don't have the knowledge to review the atmosphere changes, but the rest is almost ready! Just some minor doc suggestions.

defuz and others added 2 commits August 16, 2025 21:48
Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Aug 16, 2025
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Aug 16, 2025
Merged via the queue into bevyengine:main with commit 3da4116 Aug 16, 2025
34 checks passed
@mrec
Copy link

mrec commented Sep 21, 2025

or let you match skies for planets that aren’t Earth

Of course, once you start down that path people are going to want multiple-sun support for all their Tatooine-rendering needs . This is actually a rare case where the "two is an impossible number" rule (things are either 0, 1 or arbitrary N) might reasonably be relaxed on scientifically plausible grounds: a planet orbiting a close binary is possible, close trinary systems aren't stable.

github-merge-queue bot pushed a commit that referenced this pull request Sep 21, 2025
# Objective

- #20434 is really cool, and deserves a bit of a showcase.
- Fixes #21125.

## Solution

- Write release notes.
- Also add a note to the docs that this plays nicely with bloom.

---------

Co-authored-by: Emerson Coskey <emerson@coskey.dev>
mockersf pushed a commit that referenced this pull request Sep 21, 2025
# Objective

- #20434 is really cool, and deserves a bit of a showcase.
- Fixes #21125.

## Solution

- Write release notes.
- Also add a note to the docs that this plays nicely with bloom.

---------

Co-authored-by: Emerson Coskey <emerson@coskey.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Uncontroversial This work is generally agreed upon

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants