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

Merge New Renderer #3175

Merged
merged 97 commits into from
Nov 24, 2021
Merged

Merge New Renderer #3175

merged 97 commits into from
Nov 24, 2021

Conversation

cart
Copy link
Member

@cart cart commented Nov 23, 2021

This merges the pipelined-rendering branch into main, which adds the new Bevy renderer as an opt-in alternative to the current renderer. This can be tested by adding PipelinedDefaultPlugins instead of DefaultPlugins (and using the types from the crates in the pipelined folder).

The many changes here are not intended to be reviewed in this PR. They have already been through the normal review process, just on the pipelined-rendering branch. Generally if you do find an issue, open a bug and we can resolve it in a follow up PR prior to making the new renderer the default. If you find a change that you believe shouldn't be merged now (especially if it affects the user experience in DefaultPlugins), feel free to call it out and we can adjust if we need to.

Also note that there is still plenty of work to merge before release and the new render isn't quite ready for all scenarios yet. The point of this PR is to move all development on to main and start preparing for the Bevy 0.6 release.

For more context on the new renderer, the discussions / prs that brought us here, and the remaining work to be done check out this tracking issue: #2535.

This is irregular, but this PR will not be merged with bors (or squash merged). I want to preserve the history to properly credit the people involved and to more accurately capture the history of the renderer's development.

cart and others added 30 commits July 24, 2021 16:43
Renamed PipelineDescriptor to RenderPipelineDescriptor
StandardMaterial flat values
* bevy_pbr2: Add support for most of the StandardMaterial textures

Normal maps are not included here as they require tangents in a vertex attribute.

* bevy_pbr2: Ensure RenderCommandQueue is ready for PbrShaders init

* texture_pipelined: Add a light to the scene so we can see stuff

* WIP bevy_pbr2: back to front sorting hack

* bevy_pbr2: Uniform control flow for texture sampling in pbr.frag

From 'fintelia' on the Bevy Render Rework Round 2 discussion:

"My understanding is that GPUs these days never use the "execute both branches
and select the result" strategy. Rather, what they do is evaluate the branch
condition on all threads of a warp, and jump over it if all of them evaluate to
false. If even a single thread needs to execute the if statement body, however,
then the remaining threads are paused until that is completed."

* bevy_pbr2: Simplify texture and sampler names

The StandardMaterial_ prefix is no longer needed

* bevy_pbr2: Match default 'AmbientColor' of current bevy_pbr for now

* bevy_pbr2: Convert from non-linear to linear sRGB for the color uniform

* bevy_pbr2: Add pbr_pipelined example

* Fix view vector in pbr frag to work in ortho

* bevy_pbr2: Use a 90 degree y fov and light range projection for lights

* bevy_pbr2: Add AmbientLight resource

* bevy_pbr2: Convert PointLight color to linear sRGB for use in fragment shader

* bevy_pbr2: pbr.frag: Rename PointLight.projection to view_projection

The uniform contains the view_projection matrix so this was incorrect.

* bevy_pbr2: PointLight is an OmniLight as it has a radius

* bevy_pbr2: Factoring out duplicated code

* bevy_pbr2: Implement RenderAsset for StandardMaterial

* Remove unnecessary texture and sampler clones

* fix comment formatting

* remove redundant Buffer:from

* Don't extract meshes when their material textures aren't ready

* make missing textures in the queue step an error

Co-authored-by: Aevyrie <aevyrie@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Force main thread for prepare_windows system
bevy_pbr2: Fix light uniforms
* bevy_sprite2/_pbr2: Do not queue sprites/meshes if there are no views
* Fix writing less than the full capacity to the staging buffer

* Add missing TrackedRenderPass::draw command
Directional light and shadow
jakobhellermann and others added 9 commits November 13, 2021 21:46
…#3122)

Matrix swizzles like `mat.x.xyz` are not supported in WGSL and accepted in naga by accident: <https://gpuweb.github.io/gpuweb/wgsl/#matrix-access-expr>
…#3072)

# Objective

Add depth prepass and support for opaque, alpha mask, and alpha blend modes for the 3D PBR target.

## Solution

NOTE: This is based on top of bevyengine#2861 frustum culling. Just lining it up to keep @cart loaded with the review train. 🚂 

There are a lot of important details here. Big thanks to @cwfitzgerald of wgpu, naga, and rend3 fame for explaining how to do it properly!

* An `AlphaMode` component is added that defines whether a material should be considered opaque, an alpha mask (with a cutoff value that defaults to 0.5, the same as glTF), or transparent and should be alpha blended
* Two depth prepasses are added:
  * Opaque does a plain vertex stage
  * Alpha mask does the vertex stage but also a fragment stage that samples the colour for the fragment and discards if its alpha value is below the cutoff value
  * Both are sorted front to back, not that it matters for these passes. (Maybe there should be a way to skip sorting?)
* Three main passes are added:
  * Opaque and alpha mask passes use a depth comparison function of Equal such that only the geometry that was closest is processed further, due to early-z testing
  * The transparent pass uses the Greater depth comparison function so that only transparent objects that are closer than anything opaque are rendered
  * The opaque fragment shading is as before except that alpha is explicitly set to 1.0
  * Alpha mask fragment shading sets the alpha value to 1.0 if it is equal to or above the cutoff, as defined by glTF
  * Opaque and alpha mask are sorted front to back (again not that it matters as we will skip anything that is not equal... maybe sorting is no longer needed here?)
  * Transparent is sorted back to front. Transparent fragment shading uses the alpha blending over operator

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective

Fix nested shader defs. For example, in:
```rust
#ifdef A
#ifdef B
some code here
#endif
#endif
```
...before this PR, if `A` *is not* defined, and `B` *is* defined, then `some code here` will be output.

## Solution

- Combine the logic of whether the parent and child scope guards are defined and use that as the resulting child scope guard boolean value
This is a squash-and-rebase of @Ku95's documentation of the new renderer onto the latest `pipelined-rendering` branch.

Original PR is bevyengine#2884.

Co-authored-by: dataphract <dataphract@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
## Shader Imports

This adds "whole file" shader imports. These come in two flavors:

### Asset Path Imports

```rust
// /assets/shaders/custom.wgsl

#import "shaders/custom_material.wgsl"

[[stage(fragment)]]
fn fragment() -> [[location(0)]] vec4<f32> {
    return get_color();
}
```

```rust
// /assets/shaders/custom_material.wgsl

[[block]]
struct CustomMaterial {
    color: vec4<f32>;
};
[[group(1), binding(0)]]
var<uniform> material: CustomMaterial;
```

### Custom Path Imports

Enables defining custom import paths. These are intended to be used by crates to export shader functionality:

```rust
// bevy_pbr2/src/render/pbr.wgsl

#import bevy_pbr::mesh_view_bind_group
#import bevy_pbr::mesh_bind_group

[[block]]
struct StandardMaterial {
    base_color: vec4<f32>;
    emissive: vec4<f32>;
    perceptual_roughness: f32;
    metallic: f32;
    reflectance: f32;
    flags: u32;
};

/* rest of PBR fragment shader here */
```

```rust
impl Plugin for MeshRenderPlugin {
    fn build(&self, app: &mut bevy_app::App) {
        let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
        shaders.set_untracked(
            MESH_BIND_GROUP_HANDLE,
            Shader::from_wgsl(include_str!("mesh_bind_group.wgsl"))
                .with_import_path("bevy_pbr::mesh_bind_group"),
        );
        shaders.set_untracked(
            MESH_VIEW_BIND_GROUP_HANDLE,
            Shader::from_wgsl(include_str!("mesh_view_bind_group.wgsl"))
                .with_import_path("bevy_pbr::mesh_view_bind_group"),
        );
```

By convention these should use rust-style module paths that start with the crate name. Ultimately we might enforce this convention.

Note that this feature implements _run time_ import resolution. Ultimately we should move the import logic into an asset preprocessor once Bevy gets support for that.

## Decouple Mesh Logic from PBR Logic via MeshRenderPlugin

This breaks out mesh rendering code from PBR material code, which improves the legibility of the code, decouples mesh logic from PBR logic, and opens the door for a future `MaterialPlugin<T: Material>` that handles all of the pipeline setup for arbitrary shader materials.

## Removed `RenderAsset<Shader>` in favor of extracting shaders into RenderPipelineCache

This simplifies the shader import implementation and removes the need to pass around `RenderAssets<Shader>`.

##  RenderCommands are now fallible

This allows us to cleanly handle pipelines+shaders not being ready yet. We can abort a render command early in these cases, preventing bevy from trying to bind group / do draw calls for pipelines that couldn't be bound. This could also be used in the future for things like "components not existing on entities yet". 

# Next Steps

* Investigate using Naga for "partial typed imports" (ex: `#import bevy_pbr::material::StandardMaterial`, which would import only the StandardMaterial struct)
* Implement `MaterialPlugin<T: Material>` for low-boilerplate custom material shaders
* Move shader import logic into the asset preprocessor once bevy gets support for that.

Fixes bevyengine#3132
# Objective

Allow shadow mapping to be enabled/disabled per-light.

## Solution

- NOTE: This PR is on top of bevyengine#3072
- Add `shadows_enabled` boolean property to `PointLight` and `DirectionalLight` components.
- Do not update the frusta for the light if shadows are disabled.
- Do not check for visible entities for the light if shadows are disabled.
- Do not fetch shadows for lights with shadows disabled.
- I reworked a few types for clarity: `ViewLight` -> `ShadowView`, the bulk of `ViewLights` members -> `ViewShadowBindings`, the entities Vec in `ViewLights` -> `ViewLightEntities`, the uniform offset in `ViewLights` for `GpuLights` -> `ViewLightsUniformOffset`

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
I need to queue my own textures up for font rendering(texture arrays) and I noticed a bunch of `ImageX`, like `ImageDataLayout`, were missing from the render resources exports.

## Solution
Add new exports to render resources.
# Objective

- Use `std140_size_static()` everywhere instead of manual sizes as the crevice rewrite appears to have fixed all the problems as it claimed to do.

I've tested `3d_scene_pipelined`, `bevymark_pipelined`, and `load_gltf_pipelined` and all three look fine.
@cart cart added the A-Rendering Drawing game state to the screen label Nov 23, 2021
@cart cart added this to the Bevy 0.6 milestone Nov 23, 2021
@github-actions github-actions bot added the S-Needs-Triage This issue needs to be labelled label Nov 23, 2021
@cart cart removed the S-Needs-Triage This issue needs to be labelled label Nov 23, 2021
@alice-i-cecile
Copy link
Member

So the plan for now is to let them both operate in parallel, then fully remove the old renderer in time for the release?

What are we missing for feature parity? Just UI?

@cart
Copy link
Member Author

cart commented Nov 23, 2021

So the plan for now is to let them both operate in parallel, then fully remove the old renderer in time for the release?

Yup! I'd like to remove the current renderer ASAP though. As soon as we have feature parity.

What are we missing for feature parity? Just UI?

Yup UI is the last piece!

@TheRawMeatball TheRawMeatball mentioned this pull request Nov 23, 2021
@kirawi
Copy link

kirawi commented Nov 23, 2021

:O I can't wait to try this soon!

@cart cart merged commit 0bf90bb into bevyengine:main Nov 24, 2021
@parasyte
Copy link
Contributor

@cart If I'm not mistaken, I think this PR is missing #3165 (which I accidentally pulled into one of my rebases). So that PR is currently not merged into the main branch.

@cart
Copy link
Member Author

cart commented Nov 25, 2021

Oof very nice catch. @DJMcNab I can create a new pr on your behalf (with your commit intact) or you can create a new one targeting main. Your call!

@cart
Copy link
Member Author

cart commented Nov 25, 2021

Looks like thats the only missing commit (because I merged that after creating the branch in this pr).

@DJMcNab
Copy link
Member

DJMcNab commented Nov 25, 2021

I'm not bothered either way

I won't be able to make a new PR until much later today, if I can do so today.

bors bot pushed a commit that referenced this pull request Nov 25, 2021
See #3165 and #3175

# Objective

- @superdump was having trouble with this loop in the GLTF loader.

## Solution

- Make it probably linear.
- Measured times: 
- Old: 40s, new: 200ms

I think there's still room for improvement. For example, I think making the nodes be in `Arc`s could be a significant gain, since currently there's duplication all the way down the tree.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
HackerFoo pushed a commit to HackerFoo/bevy that referenced this pull request Nov 26, 2021
See bevyengine#3165 and bevyengine#3175

# Objective

- @superdump was having trouble with this loop in the GLTF loader.

## Solution

- Make it probably linear.
- Measured times: 
- Old: 40s, new: 200ms

I think there's still room for improvement. For example, I think making the nodes be in `Arc`s could be a significant gain, since currently there's duplication all the way down the tree.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
bors bot pushed a commit that referenced this pull request Dec 18, 2021
# Objective

- The multiple windows example which was viciously murdered in #3175.
- cart asked me to

## Solution

- Rework the example to work on pipelined-rendering, based on the work from #2898
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.