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

Feature: Layer System #41

Closed
JonahPlusPlus opened this issue Jan 2, 2023 · 3 comments
Closed

Feature: Layer System #41

JonahPlusPlus opened this issue Jan 2, 2023 · 3 comments

Comments

@JonahPlusPlus
Copy link
Owner

I've been brainstorming ways to support stuff like night models, basic clouds (not volumetric) and far-away environments and I think supporting layers might be a good general solution.

The problem

I want to avoid hard-coding optional features as parameters directly into bevy_atmosphere.
For example, a hard coded solution to the aforementioned stuff would be to provide background, midground and foreground parameters for optional textures. To add a cloud texture, you would just set the midground to your texture and it would be overlaid on the sky texture. However, this is limiting, as it only allows for three textures and it wouldn't support animating them.

The solution

A layer system would support layering Atmospheric models on top of each other. A layer would comprise of the model and a color for controlling tint and transparency. (It could also have a mode for dictating how layers affect underlying layers, but since layers would be rendered top-down to avoid rendering hidden pixels, it would be complicated to implement).

For example, adding a cloud texture would be adding a image model on top of a sky model (like Nishita).

Implementation Strategy

The layer system could be another Atmospheric model that accepts other models. This means it would support sub-layers since it can accept itself.

It would look something like:

Layers::new()
    .add(Nishita::default(), Color::WHITE) // maybe I should rename models to have a -Model suffix?
    .add(ImageModel::new("clouds.png"), Color::rgba(1.0, 1.0, 1.0, 0.9))

It could also have a macro (layers![]) for quickly creating it (for instance, support just passing alpha instead of an entire color).

I've been thinking (I was going to do this anyways, even before the idea of layers) of revising the structure of atmosphere shaders to look like:

fn main(position: vec3<f32>) -> vec4<f32> {
    return vec4<f32>(0.5, 0.5, 0.5, 0.5);
}

This removes a lot of boilerplate from the shader. You might be wondering where that boilerplate went, since there is no #import statement. Well, since the layer model will need a custom preprocessor to load main functions from other models, it might as well handle adding the entry point code too.

This effectively separates the model logic from the runtime, which opens the doors for creating multiple runtimes. Currently, bevy_atmosphere pre-renders the sky texture using a compute shader. This technique is slow, since it has to render the entire sky texture instead of what is just on screen, but ultimately improves performance in games where atmospheric parameters change infrequently.

However, I have seen users who need to update parameters frequently, potentially every frame. In their cases, a realtime renderer is more performant, since it only needs to render what's on screen each frame. By separating the model logic from the runtime, it allows for supporting both a pre-renderer and realtime renderer. It would be a matter of moving the workload to and from the compute pipeline and skybox shader.

@JonahPlusPlus
Copy link
Owner Author

Hmmm... Layers need to be cached, so instead of injecting shader code into one big shader, maybe Atmospheric models need to specify how and what shaders run as well as how to cache their results. It increases the complexity of defining Atmospheric models, but gives a lot more control over how they run.

@JonahPlusPlus JonahPlusPlus mentioned this issue Jan 2, 2023
10 tasks
@JonahPlusPlus
Copy link
Owner Author

The layers system was overkill, instead, I'm going to focus on increasing shader modularization so users can create their own models. This is far simpler and performant.

@mattdm
Copy link

mattdm commented Sep 22, 2023

The layers system was overkill, instead, I'm going to focus on increasing shader modularization so users can create their own models. This is far simpler and performant.

Do you have an example for someone new to writing shaders? I'd like to do exactly the things you describe:

  • clouds, from cirrus to full cover gray and raining to to big fluffy cumulonimbus to storms with lightning
  • mountains in the distance, and kind of a general indistinct horizon
  • stars! (Starry starry night #27)

... but have no idea where to even get started with that. It'd be wonderful to see an example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants