mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
update wgpu to 0.13 (#5168)
# Objective - Update wgpu to 0.13 - ~~Wait, is wgpu 0.13 released? No, but I had most of the changes already ready since playing with webgpu~~ well it has been released now - Also update parking_lot to 0.12 and naga to 0.9 ## Solution - Update syntax for wgsl shaders https://github.com/gfx-rs/wgpu/blob/master/CHANGELOG.md#wgsl-syntax - Add a few options, remove some references: https://github.com/gfx-rs/wgpu/blob/master/CHANGELOG.md#other-breaking-changes - fragment inputs should now exactly match vertex outputs for locations, so I added exports for those to be able to reuse them https://github.com/gfx-rs/wgpu/pull/2704
This commit is contained in:
parent
c43295af80
commit
814f8d1635
70 changed files with 665 additions and 774 deletions
2
.github/bors.toml
vendored
2
.github/bors.toml
vendored
|
@ -16,7 +16,7 @@ status = [
|
|||
"miri",
|
||||
"check-compiles",
|
||||
"build-and-install-on-iOS",
|
||||
"run-examples-on-windows",
|
||||
"run-examples-on-windows-dx12",
|
||||
]
|
||||
|
||||
use_squash_merge = true
|
||||
|
|
6
.github/workflows/validation-jobs.yml
vendored
6
.github/workflows/validation-jobs.yml
vendored
|
@ -61,9 +61,9 @@ jobs:
|
|||
- name: Build APK
|
||||
run: cargo apk build --example android_example
|
||||
|
||||
run-examples-on-windows:
|
||||
run-examples-on-windows-dx12:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 30
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
@ -91,7 +91,7 @@ jobs:
|
|||
for example in .github/example-run/*.ron; do
|
||||
example_name=`basename $example .ron`
|
||||
echo "running $example_name - "`date`
|
||||
time CI_TESTING_CONFIG=$example cargo run --example $example_name --features "bevy_ci_testing"
|
||||
time WGPU_BACKEND=dx12 CI_TESTING_CONFIG=$example cargo run --example $example_name --features "bevy_ci_testing"
|
||||
sleep 10
|
||||
done
|
||||
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
#import bevy_pbr::mesh_types
|
||||
#import bevy_pbr::mesh_view_bindings
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> mesh: Mesh;
|
||||
|
||||
// NOTE: Bindings must come before functions that use them!
|
||||
#import bevy_pbr::mesh_functions
|
||||
|
||||
struct Vertex {
|
||||
[[location(0)]] position: vec3<f32>;
|
||||
[[location(1)]] normal: vec3<f32>;
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
@location(2) uv: vec2<f32>,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
[[builtin(position)]] clip_position: vec4<f32>;
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) uv: vec2<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(vertex: Vertex) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.clip_position = mesh_position_local_to_clip(mesh.model, vec4<f32>(vertex.position, 1.0));
|
||||
|
@ -28,9 +28,9 @@ fn vertex(vertex: Vertex) -> VertexOutput {
|
|||
|
||||
|
||||
struct Time {
|
||||
time_since_startup: f32;
|
||||
time_since_startup: f32,
|
||||
};
|
||||
[[group(2), binding(0)]]
|
||||
@group(2) @binding(0)
|
||||
var<uniform> time: Time;
|
||||
|
||||
|
||||
|
@ -54,8 +54,8 @@ fn oklab_to_linear_srgb(c: vec3<f32>) -> vec3<f32> {
|
|||
);
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let speed = 2.0;
|
||||
let t_1 = sin(time.time_since_startup * speed) * 0.5 + 0.5;
|
||||
let t_2 = cos(time.time_since_startup * speed);
|
||||
|
|
|
@ -8,27 +8,19 @@
|
|||
#import bevy_pbr::shadows
|
||||
#import bevy_pbr::pbr_functions
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var my_array_texture: texture_2d_array<f32>;
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var my_array_texture_sampler: sampler;
|
||||
|
||||
struct FragmentInput {
|
||||
[[builtin(front_facing)]] is_front: bool;
|
||||
[[builtin(position)]] frag_coord: vec4<f32>;
|
||||
[[location(0)]] world_position: vec4<f32>;
|
||||
[[location(1)]] world_normal: vec3<f32>;
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] world_tangent: vec4<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
[[location(4)]] color: vec4<f32>;
|
||||
#endif
|
||||
@builtin(front_facing) is_front: bool,
|
||||
@builtin(position) frag_coord: vec4<f32>,
|
||||
#import bevy_pbr::mesh_vertex_output
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
||||
let layer = i32(in.world_position.x) & 0x3;
|
||||
|
||||
// Prepare a 'processed' StandardMaterial by sampling all textures to resolve
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
struct CustomMaterial {
|
||||
color: vec4<f32>;
|
||||
color: vec4<f32>,
|
||||
};
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> material: CustomMaterial;
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var base_color_texture: texture_2d<f32>;
|
||||
[[group(1), binding(2)]]
|
||||
@group(1) @binding(2)
|
||||
var base_color_sampler: sampler;
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment([[location(2)]] uv: vec2<f32>) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(
|
||||
#import bevy_pbr::mesh_vertex_output
|
||||
) -> @location(0) vec4<f32> {
|
||||
return material.color * textureSample(base_color_texture, base_color_sampler, uv);
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
#import bevy_pbr::mesh_view_bindings
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var texture: texture_2d<f32>;
|
||||
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var our_sampler: sampler;
|
||||
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment([[builtin(position)]] position: vec4<f32>) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(
|
||||
@builtin(position) position: vec4<f32>,
|
||||
#import bevy_sprite::mesh2d_vertex_output
|
||||
) -> @location(0) vec4<f32> {
|
||||
// Get screen position with coordinates from 0 to 1
|
||||
let uv = position.xy / vec2<f32>(view.width, view.height);
|
||||
let offset_strength = 0.02;
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
#import bevy_pbr::mesh_view_bindings
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var texture: texture_2d<f32>;
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var texture_sampler: sampler;
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment([[builtin(position)]] position: vec4<f32>) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(
|
||||
@builtin(position) position: vec4<f32>,
|
||||
#import bevy_pbr::mesh_vertex_output
|
||||
) -> @location(0) vec4<f32> {
|
||||
let uv = position.xy / vec2<f32>(view.width, view.height);
|
||||
let color = textureSample(texture, texture_sampler, uv);
|
||||
return color;
|
||||
|
|
|
@ -2,25 +2,25 @@
|
|||
#import bevy_pbr::mesh_bindings
|
||||
|
||||
struct CustomMaterial {
|
||||
color: vec4<f32>;
|
||||
color: vec4<f32>,
|
||||
};
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> material: CustomMaterial;
|
||||
|
||||
// NOTE: Bindings must come before functions that use them!
|
||||
#import bevy_pbr::mesh_functions
|
||||
|
||||
struct Vertex {
|
||||
[[location(0)]] position: vec3<f32>;
|
||||
[[location(1)]] blend_color: vec4<f32>;
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) blend_color: vec4<f32>,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
[[builtin(position)]] clip_position: vec4<f32>;
|
||||
[[location(0)]] blend_color: vec4<f32>;
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) blend_color: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(vertex: Vertex) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.clip_position = mesh_position_local_to_clip(mesh.model, vec4<f32>(vertex.position, 1.0));
|
||||
|
@ -29,10 +29,10 @@ fn vertex(vertex: Vertex) -> VertexOutput {
|
|||
}
|
||||
|
||||
struct FragmentInput {
|
||||
[[location(0)]] blend_color: vec4<f32>;
|
||||
@location(0) blend_color: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(input: FragmentInput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(input: FragmentInput) -> @location(0) vec4<f32> {
|
||||
return material.color * input.blend_color;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var texture: texture_storage_2d<rgba8unorm, read_write>;
|
||||
|
||||
fn hash(value: u32) -> u32 {
|
||||
|
@ -15,8 +15,8 @@ fn randomFloat(value: u32) -> f32 {
|
|||
return f32(hash(value)) / 4294967295.0;
|
||||
}
|
||||
|
||||
[[stage(compute), workgroup_size(8, 8, 1)]]
|
||||
fn init([[builtin(global_invocation_id)]] invocation_id: vec3<u32>, [[builtin(num_workgroups)]] num_workgroups: vec3<u32>) {
|
||||
@compute @workgroup_size(8, 8, 1)
|
||||
fn init(@builtin(global_invocation_id) invocation_id: vec3<u32>, @builtin(num_workgroups) num_workgroups: vec3<u32>) {
|
||||
let location = vec2<i32>(i32(invocation_id.x), i32(invocation_id.y));
|
||||
let location_f32 = vec2<f32>(f32(invocation_id.x), f32(invocation_id.y));
|
||||
|
||||
|
@ -28,24 +28,24 @@ fn init([[builtin(global_invocation_id)]] invocation_id: vec3<u32>, [[builtin(nu
|
|||
}
|
||||
|
||||
|
||||
fn get(location: vec2<i32>, offset_x: i32, offset_y: i32) -> i32 {
|
||||
fn is_alive(location: vec2<i32>, offset_x: i32, offset_y: i32) -> i32 {
|
||||
let value: vec4<f32> = textureLoad(texture, location + vec2<i32>(offset_x, offset_y));
|
||||
return i32(value.x);
|
||||
}
|
||||
|
||||
fn count_alive(location: vec2<i32>) -> i32 {
|
||||
return get(location, -1, -1) +
|
||||
get(location, -1, 0) +
|
||||
get(location, -1, 1) +
|
||||
get(location, 0, -1) +
|
||||
get(location, 0, 1) +
|
||||
get(location, 1, -1) +
|
||||
get(location, 1, 0) +
|
||||
get(location, 1, 1);
|
||||
return is_alive(location, -1, -1) +
|
||||
is_alive(location, -1, 0) +
|
||||
is_alive(location, -1, 1) +
|
||||
is_alive(location, 0, -1) +
|
||||
is_alive(location, 0, 1) +
|
||||
is_alive(location, 1, -1) +
|
||||
is_alive(location, 1, 0) +
|
||||
is_alive(location, 1, 1);
|
||||
}
|
||||
|
||||
[[stage(compute), workgroup_size(8, 8, 1)]]
|
||||
fn update([[builtin(global_invocation_id)]] invocation_id: vec3<u32>) {
|
||||
@compute @workgroup_size(8, 8, 1)
|
||||
fn update(@builtin(global_invocation_id) invocation_id: vec3<u32>) {
|
||||
let location = vec2<i32>(i32(invocation_id.x), i32(invocation_id.y));
|
||||
|
||||
let n_alive = count_alive(location);
|
||||
|
@ -55,7 +55,7 @@ fn update([[builtin(global_invocation_id)]] invocation_id: vec3<u32>) {
|
|||
if (n_alive == 3) {
|
||||
alive = true;
|
||||
} else if (n_alive == 2) {
|
||||
let currently_alive = get(location, 0, 0);
|
||||
let currently_alive = is_alive(location, 0, 0);
|
||||
alive = bool(currently_alive);
|
||||
} else {
|
||||
alive = false;
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
#import bevy_pbr::mesh_types
|
||||
#import bevy_pbr::mesh_view_bindings
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> mesh: Mesh;
|
||||
|
||||
// NOTE: Bindings must come before functions that use them!
|
||||
#import bevy_pbr::mesh_functions
|
||||
|
||||
struct Vertex {
|
||||
[[location(0)]] position: vec3<f32>;
|
||||
[[location(1)]] normal: vec3<f32>;
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
@location(2) uv: vec2<f32>,
|
||||
|
||||
[[location(3)]] i_pos_scale: vec4<f32>;
|
||||
[[location(4)]] i_color: vec4<f32>;
|
||||
@location(3) i_pos_scale: vec4<f32>,
|
||||
@location(4) i_color: vec4<f32>,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
[[builtin(position)]] clip_position: vec4<f32>;
|
||||
[[location(0)]] color: vec4<f32>;
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) color: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(vertex: Vertex) -> VertexOutput {
|
||||
let position = vertex.position * vertex.i_pos_scale.w + vertex.i_pos_scale.xyz;
|
||||
var out: VertexOutput;
|
||||
|
@ -30,7 +30,7 @@ fn vertex(vertex: Vertex) -> VertexOutput {
|
|||
return out;
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
return in.color;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
struct CustomMaterial {
|
||||
color: vec4<f32>;
|
||||
color: vec4<f32>,
|
||||
};
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> material: CustomMaterial;
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment() -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(
|
||||
#import bevy_pbr::mesh_vertex_output
|
||||
) -> @location(0) vec4<f32> {
|
||||
#ifdef IS_RED
|
||||
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||
#else
|
||||
|
|
|
@ -31,7 +31,7 @@ thiserror = "1.0"
|
|||
downcast-rs = "1.2.0"
|
||||
fastrand = "1.7.0"
|
||||
notify = { version = "=5.0.0-pre.11", optional = true }
|
||||
parking_lot = "0.11.0"
|
||||
parking_lot = "0.12.1"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wasm-bindgen = { version = "0.2" }
|
||||
|
|
|
@ -19,7 +19,7 @@ bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }
|
|||
# other
|
||||
anyhow = "1.0.4"
|
||||
rodio = { version = "0.15", default-features = false }
|
||||
parking_lot = "0.11.0"
|
||||
parking_lot = "0.12.1"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
rodio = { version = "0.15", default-features = false, features = ["wasm-bindgen"] }
|
||||
|
|
|
@ -64,7 +64,7 @@ impl Node for MainPass2dNode {
|
|||
let _main_pass_2d = info_span!("main_pass_2d").entered();
|
||||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("main_pass_2d"),
|
||||
color_attachments: &[target.get_color_attachment(Operations {
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: match camera_2d.clear_color {
|
||||
ClearColorConfig::Default => {
|
||||
LoadOp::Clear(world.resource::<ClearColor>().0.into())
|
||||
|
@ -73,7 +73,7 @@ impl Node for MainPass2dNode {
|
|||
ClearColorConfig::None => LoadOp::Load,
|
||||
},
|
||||
store: true,
|
||||
})],
|
||||
}))],
|
||||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
|
@ -102,10 +102,10 @@ impl Node for MainPass2dNode {
|
|||
let _reset_viewport_pass_2d = info_span!("reset_viewport_pass_2d").entered();
|
||||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("reset_viewport_pass_2d"),
|
||||
color_attachments: &[target.get_color_attachment(Operations {
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
})],
|
||||
}))],
|
||||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ impl Node for MainPass3dNode {
|
|||
label: Some("main_opaque_pass_3d"),
|
||||
// NOTE: The opaque pass loads the color
|
||||
// buffer as well as writing to it.
|
||||
color_attachments: &[target.get_color_attachment(Operations {
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: match camera_3d.clear_color {
|
||||
ClearColorConfig::Default => {
|
||||
LoadOp::Clear(world.resource::<ClearColor>().0.into())
|
||||
|
@ -82,7 +82,7 @@ impl Node for MainPass3dNode {
|
|||
ClearColorConfig::None => LoadOp::Load,
|
||||
},
|
||||
store: true,
|
||||
})],
|
||||
}))],
|
||||
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
|
||||
view: &depth.view,
|
||||
// NOTE: The opaque main pass loads the depth buffer and possibly overwrites it
|
||||
|
@ -119,10 +119,10 @@ impl Node for MainPass3dNode {
|
|||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("main_alpha_mask_pass_3d"),
|
||||
// NOTE: The alpha_mask pass loads the color buffer as well as overwriting it where appropriate.
|
||||
color_attachments: &[target.get_color_attachment(Operations {
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
})],
|
||||
}))],
|
||||
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
|
||||
view: &depth.view,
|
||||
// NOTE: The alpha mask pass loads the depth buffer and possibly overwrites it
|
||||
|
@ -158,10 +158,10 @@ impl Node for MainPass3dNode {
|
|||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("main_transparent_pass_3d"),
|
||||
// NOTE: The transparent pass loads the color buffer as well as overwriting it where appropriate.
|
||||
color_attachments: &[target.get_color_attachment(Operations {
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
})],
|
||||
}))],
|
||||
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
|
||||
view: &depth.view,
|
||||
// NOTE: For the transparent pass we load the depth buffer. There should be no
|
||||
|
@ -202,10 +202,10 @@ impl Node for MainPass3dNode {
|
|||
let _reset_viewport_pass_3d = info_span!("reset_viewport_pass_3d").entered();
|
||||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("reset_viewport_pass_3d"),
|
||||
color_attachments: &[target.get_color_attachment(Operations {
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
})],
|
||||
}))],
|
||||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
|
|
|
@ -97,14 +97,14 @@ use std::marker::PhantomData;
|
|||
///
|
||||
/// ```wgsl
|
||||
/// struct CustomMaterial {
|
||||
/// color: vec4<f32>;
|
||||
/// color: vec4<f32>,
|
||||
/// };
|
||||
///
|
||||
/// [[group(1), binding(0)]]
|
||||
/// @group(1) @binding(0)
|
||||
/// var<uniform> material: CustomMaterial;
|
||||
/// [[group(1), binding(1)]]
|
||||
/// @group(1) @binding(1)
|
||||
/// var color_texture: texture_2d<f32>;
|
||||
/// [[group(1), binding(2)]]
|
||||
/// @group(1) @binding(2)
|
||||
/// var color_sampler: sampler;
|
||||
/// ```
|
||||
pub trait Material: AsBindGroup + Send + Sync + Clone + TypeUuid + Sized + 'static {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#import bevy_pbr::mesh_view_types
|
||||
#import bevy_pbr::mesh_types
|
||||
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> mesh: Mesh;
|
||||
|
||||
#ifdef SKINNED
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var<uniform> joint_matrices: SkinnedMesh;
|
||||
#import bevy_pbr::skinning
|
||||
#endif
|
||||
|
@ -17,18 +17,18 @@ var<uniform> joint_matrices: SkinnedMesh;
|
|||
#import bevy_pbr::mesh_functions
|
||||
|
||||
struct Vertex {
|
||||
[[location(0)]] position: vec3<f32>;
|
||||
@location(0) position: vec3<f32>,
|
||||
#ifdef SKINNED
|
||||
[[location(4)]] joint_indices: vec4<u32>;
|
||||
[[location(5)]] joint_weights: vec4<f32>;
|
||||
@location(4) joint_indices: vec4<u32>,
|
||||
@location(5) joint_weights: vec4<f32>,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
[[builtin(position)]] clip_position: vec4<f32>;
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(vertex: Vertex) -> VertexOutput {
|
||||
#ifdef SKINNED
|
||||
let model = skin_model(vertex.joint_indices, vertex.joint_weights);
|
||||
|
|
|
@ -37,6 +37,8 @@ const MAX_JOINTS: usize = 256;
|
|||
const JOINT_SIZE: usize = std::mem::size_of::<Mat4>();
|
||||
pub(crate) const JOINT_BUFFER_SIZE: usize = MAX_JOINTS * JOINT_SIZE;
|
||||
|
||||
pub const MESH_VERTEX_OUTPUT: HandleUntyped =
|
||||
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 2645551199423808407);
|
||||
pub const MESH_VIEW_TYPES_HANDLE: HandleUntyped =
|
||||
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 8140454348013264787);
|
||||
pub const MESH_VIEW_BINDINGS_HANDLE: HandleUntyped =
|
||||
|
@ -54,6 +56,12 @@ pub const SKINNING_HANDLE: HandleUntyped =
|
|||
|
||||
impl Plugin for MeshRenderPlugin {
|
||||
fn build(&self, app: &mut bevy_app::App) {
|
||||
load_internal_asset!(
|
||||
app,
|
||||
MESH_VERTEX_OUTPUT,
|
||||
"mesh_vertex_output.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
load_internal_asset!(
|
||||
app,
|
||||
MESH_VIEW_TYPES_HANDLE,
|
||||
|
@ -601,11 +609,11 @@ impl SpecializedMeshPipeline for MeshPipeline {
|
|||
shader: MESH_SHADER_HANDLE.typed::<Shader>(),
|
||||
shader_defs,
|
||||
entry_point: "fragment".into(),
|
||||
targets: vec![ColorTargetState {
|
||||
targets: vec![Some(ColorTargetState {
|
||||
format: TextureFormat::bevy_default(),
|
||||
blend,
|
||||
write_mask: ColorWrites::ALL,
|
||||
}],
|
||||
})],
|
||||
}),
|
||||
layout: Some(bind_group_layout),
|
||||
primitive: PrimitiveState {
|
||||
|
|
|
@ -5,39 +5,29 @@
|
|||
#import bevy_pbr::mesh_functions
|
||||
|
||||
struct Vertex {
|
||||
[[location(0)]] position: vec3<f32>;
|
||||
[[location(1)]] normal: vec3<f32>;
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
#ifdef VERTEX_UVS
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
@location(2) uv: vec2<f32>,
|
||||
#endif
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] tangent: vec4<f32>;
|
||||
@location(3) tangent: vec4<f32>,
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
[[location(4)]] color: vec4<f32>;
|
||||
@location(4) color: vec4<f32>,
|
||||
#endif
|
||||
#ifdef SKINNED
|
||||
[[location(5)]] joint_indices: vec4<u32>;
|
||||
[[location(6)]] joint_weights: vec4<f32>;
|
||||
@location(5) joint_indices: vec4<u32>,
|
||||
@location(6) joint_weights: vec4<f32>,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
[[builtin(position)]] clip_position: vec4<f32>;
|
||||
[[location(0)]] world_position: vec4<f32>;
|
||||
[[location(1)]] world_normal: vec3<f32>;
|
||||
#ifdef VERTEX_UVS
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] world_tangent: vec4<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
[[location(4)]] color: vec4<f32>;
|
||||
#endif
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
#import bevy_pbr::mesh_vertex_output
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(vertex: Vertex) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
#ifdef SKINNED
|
||||
|
@ -63,22 +53,12 @@ fn vertex(vertex: Vertex) -> VertexOutput {
|
|||
}
|
||||
|
||||
struct FragmentInput {
|
||||
[[builtin(front_facing)]] is_front: bool;
|
||||
[[location(0)]] world_position: vec4<f32>;
|
||||
[[location(1)]] world_normal: vec3<f32>;
|
||||
#ifdef VERTEX_UVS
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] world_tangent: vec4<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
[[location(4)]] color: vec4<f32>;
|
||||
#endif
|
||||
@builtin(front_facing) is_front: bool,
|
||||
#import bevy_pbr::mesh_vertex_output
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
||||
#ifdef VERTEX_COLORS
|
||||
return in.color;
|
||||
#else
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
#import bevy_pbr::mesh_types
|
||||
|
||||
[[group(2), binding(0)]]
|
||||
@group(2) @binding(0)
|
||||
var<uniform> mesh: Mesh;
|
||||
#ifdef SKINNED
|
||||
[[group(2), binding(1)]]
|
||||
@group(2) @binding(1)
|
||||
var<uniform> joint_matrices: SkinnedMesh;
|
||||
#import bevy_pbr::skinning
|
||||
#endif
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#define_import_path bevy_pbr::mesh_types
|
||||
|
||||
struct Mesh {
|
||||
model: mat4x4<f32>;
|
||||
inverse_transpose_model: mat4x4<f32>;
|
||||
model: mat4x4<f32>,
|
||||
inverse_transpose_model: mat4x4<f32>,
|
||||
// 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
|
||||
flags: u32;
|
||||
flags: u32,
|
||||
};
|
||||
|
||||
#ifdef SKINNED
|
||||
struct SkinnedMesh {
|
||||
data: array<mat4x4<f32>, 256u>;
|
||||
data: array<mat4x4<f32>, 256u>,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
13
crates/bevy_pbr/src/render/mesh_vertex_output.wgsl
Normal file
13
crates/bevy_pbr/src/render/mesh_vertex_output.wgsl
Normal file
|
@ -0,0 +1,13 @@
|
|||
#define_import_path bevy_pbr::mesh_vertex_output
|
||||
|
||||
@location(0) world_position: vec4<f32>,
|
||||
@location(1) world_normal: vec3<f32>,
|
||||
#ifdef VERTEX_UVS
|
||||
@location(2) uv: vec2<f32>,
|
||||
#endif
|
||||
#ifdef VERTEX_TANGENTS
|
||||
@location(3) world_tangent: vec4<f32>,
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
@location(4) color: vec4<f32>,
|
||||
#endif
|
|
@ -2,41 +2,41 @@
|
|||
|
||||
#import bevy_pbr::mesh_view_types
|
||||
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
[[group(0), binding(1)]]
|
||||
@group(0) @binding(1)
|
||||
var<uniform> lights: Lights;
|
||||
#ifdef NO_ARRAY_TEXTURES_SUPPORT
|
||||
[[group(0), binding(2)]]
|
||||
@group(0) @binding(2)
|
||||
var point_shadow_textures: texture_depth_cube;
|
||||
#else
|
||||
[[group(0), binding(2)]]
|
||||
@group(0) @binding(2)
|
||||
var point_shadow_textures: texture_depth_cube_array;
|
||||
#endif
|
||||
[[group(0), binding(3)]]
|
||||
@group(0) @binding(3)
|
||||
var point_shadow_textures_sampler: sampler_comparison;
|
||||
#ifdef NO_ARRAY_TEXTURES_SUPPORT
|
||||
[[group(0), binding(4)]]
|
||||
@group(0) @binding(4)
|
||||
var directional_shadow_textures: texture_depth_2d;
|
||||
#else
|
||||
[[group(0), binding(4)]]
|
||||
@group(0) @binding(4)
|
||||
var directional_shadow_textures: texture_depth_2d_array;
|
||||
#endif
|
||||
[[group(0), binding(5)]]
|
||||
@group(0) @binding(5)
|
||||
var directional_shadow_textures_sampler: sampler_comparison;
|
||||
|
||||
#ifdef NO_STORAGE_BUFFERS_SUPPORT
|
||||
[[group(0), binding(6)]]
|
||||
@group(0) @binding(6)
|
||||
var<uniform> point_lights: PointLights;
|
||||
[[group(0), binding(7)]]
|
||||
@group(0) @binding(7)
|
||||
var<uniform> cluster_light_index_lists: ClusterLightIndexLists;
|
||||
[[group(0), binding(8)]]
|
||||
@group(0) @binding(8)
|
||||
var<uniform> cluster_offsets_and_counts: ClusterOffsetsAndCounts;
|
||||
#else
|
||||
[[group(0), binding(6)]]
|
||||
@group(0) @binding(6)
|
||||
var<storage> point_lights: PointLights;
|
||||
[[group(0), binding(7)]]
|
||||
@group(0) @binding(7)
|
||||
var<storage> cluster_light_index_lists: ClusterLightIndexLists;
|
||||
[[group(0), binding(8)]]
|
||||
@group(0) @binding(8)
|
||||
var<storage> cluster_offsets_and_counts: ClusterOffsetsAndCounts;
|
||||
#endif
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
#define_import_path bevy_pbr::mesh_view_types
|
||||
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
inverse_view_proj: mat4x4<f32>;
|
||||
view: mat4x4<f32>;
|
||||
inverse_view: mat4x4<f32>;
|
||||
projection: mat4x4<f32>;
|
||||
inverse_projection: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
width: f32;
|
||||
height: f32;
|
||||
view_proj: mat4x4<f32>,
|
||||
inverse_view_proj: mat4x4<f32>,
|
||||
view: mat4x4<f32>,
|
||||
inverse_view: mat4x4<f32>,
|
||||
projection: mat4x4<f32>,
|
||||
inverse_projection: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
width: f32,
|
||||
height: f32,
|
||||
};
|
||||
|
||||
struct PointLight {
|
||||
// For point lights: the lower-right 2x2 values of the projection matrix [2][2] [2][3] [3][2] [3][3]
|
||||
// For spot lights: the direction (x,z), spot_scale and spot_offset
|
||||
light_custom_data: vec4<f32>;
|
||||
color_inverse_square_range: vec4<f32>;
|
||||
position_radius: vec4<f32>;
|
||||
light_custom_data: vec4<f32>,
|
||||
color_inverse_square_range: vec4<f32>,
|
||||
position_radius: vec4<f32>,
|
||||
// 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
|
||||
flags: u32;
|
||||
shadow_depth_bias: f32;
|
||||
shadow_normal_bias: f32;
|
||||
spot_light_tan_angle: f32;
|
||||
flags: u32,
|
||||
shadow_depth_bias: f32,
|
||||
shadow_normal_bias: f32,
|
||||
spot_light_tan_angle: f32,
|
||||
};
|
||||
|
||||
let POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT: u32 = 1u;
|
||||
let POINT_LIGHT_FLAGS_SPOT_LIGHT_Y_NEGATIVE: u32 = 2u;
|
||||
|
||||
struct DirectionalLight {
|
||||
view_projection: mat4x4<f32>;
|
||||
color: vec4<f32>;
|
||||
direction_to_light: vec3<f32>;
|
||||
view_projection: mat4x4<f32>,
|
||||
color: vec4<f32>,
|
||||
direction_to_light: vec3<f32>,
|
||||
// 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
|
||||
flags: u32;
|
||||
shadow_depth_bias: f32;
|
||||
shadow_normal_bias: f32;
|
||||
flags: u32,
|
||||
shadow_depth_bias: f32,
|
||||
shadow_normal_bias: f32,
|
||||
};
|
||||
|
||||
let DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT: u32 = 1u;
|
||||
|
||||
struct Lights {
|
||||
// NOTE: this array size must be kept in sync with the constants defined bevy_pbr2/src/render/light.rs
|
||||
directional_lights: array<DirectionalLight, 1u>;
|
||||
ambient_color: vec4<f32>;
|
||||
directional_lights: array<DirectionalLight, 1u>,
|
||||
ambient_color: vec4<f32>,
|
||||
// x/y/z dimensions and n_clusters in w
|
||||
cluster_dimensions: vec4<u32>;
|
||||
cluster_dimensions: vec4<u32>,
|
||||
// xy are vec2<f32>(cluster_dimensions.xy) / vec2<f32>(view.width, view.height)
|
||||
//
|
||||
// For perspective projections:
|
||||
|
@ -56,32 +56,32 @@ struct Lights {
|
|||
// NOTE: near and far are +ve but -z is infront of the camera
|
||||
// z is -near
|
||||
// w is cluster_dimensions.z / (-far - -near)
|
||||
cluster_factors: vec4<f32>;
|
||||
n_directional_lights: u32;
|
||||
spot_light_shadowmap_offset: i32;
|
||||
cluster_factors: vec4<f32>,
|
||||
n_directional_lights: u32,
|
||||
spot_light_shadowmap_offset: i32,
|
||||
};
|
||||
|
||||
#ifdef NO_STORAGE_BUFFERS_SUPPORT
|
||||
struct PointLights {
|
||||
data: array<PointLight, 256u>;
|
||||
data: array<PointLight, 256u>,
|
||||
};
|
||||
struct ClusterLightIndexLists {
|
||||
// each u32 contains 4 u8 indices into the PointLights array
|
||||
data: array<vec4<u32>, 1024u>;
|
||||
data: array<vec4<u32>, 1024u>,
|
||||
};
|
||||
struct ClusterOffsetsAndCounts {
|
||||
// each u32 contains a 24-bit index into ClusterLightIndexLists in the high 24 bits
|
||||
// and an 8-bit count of the number of lights in the low 8 bits
|
||||
data: array<vec4<u32>, 1024u>;
|
||||
data: array<vec4<u32>, 1024u>,
|
||||
};
|
||||
#else
|
||||
struct PointLights {
|
||||
data: array<PointLight>;
|
||||
data: array<PointLight>,
|
||||
};
|
||||
struct ClusterLightIndexLists {
|
||||
data: array<u32>;
|
||||
data: array<u32>,
|
||||
};
|
||||
struct ClusterOffsetsAndCounts {
|
||||
data: array<vec4<u32>>;
|
||||
data: array<vec4<u32>>,
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -9,23 +9,13 @@
|
|||
#import bevy_pbr::pbr_functions
|
||||
|
||||
struct FragmentInput {
|
||||
[[builtin(front_facing)]] is_front: bool;
|
||||
[[builtin(position)]] frag_coord: vec4<f32>;
|
||||
[[location(0)]] world_position: vec4<f32>;
|
||||
[[location(1)]] world_normal: vec3<f32>;
|
||||
#ifdef VERTEX_UVS
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] world_tangent: vec4<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
[[location(4)]] color: vec4<f32>;
|
||||
#endif
|
||||
@builtin(front_facing) is_front: bool,
|
||||
@builtin(position) frag_coord: vec4<f32>,
|
||||
#import bevy_pbr::mesh_vertex_output
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
||||
var output_color: vec4<f32> = material.base_color;
|
||||
#ifdef VERTEX_COLORS
|
||||
output_color = output_color * in.color;
|
||||
|
|
|
@ -2,25 +2,25 @@
|
|||
|
||||
#import bevy_pbr::pbr_types
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> material: StandardMaterial;
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var base_color_texture: texture_2d<f32>;
|
||||
[[group(1), binding(2)]]
|
||||
@group(1) @binding(2)
|
||||
var base_color_sampler: sampler;
|
||||
[[group(1), binding(3)]]
|
||||
@group(1) @binding(3)
|
||||
var emissive_texture: texture_2d<f32>;
|
||||
[[group(1), binding(4)]]
|
||||
@group(1) @binding(4)
|
||||
var emissive_sampler: sampler;
|
||||
[[group(1), binding(5)]]
|
||||
@group(1) @binding(5)
|
||||
var metallic_roughness_texture: texture_2d<f32>;
|
||||
[[group(1), binding(6)]]
|
||||
@group(1) @binding(6)
|
||||
var metallic_roughness_sampler: sampler;
|
||||
[[group(1), binding(7)]]
|
||||
@group(1) @binding(7)
|
||||
var occlusion_texture: texture_2d<f32>;
|
||||
[[group(1), binding(8)]]
|
||||
@group(1) @binding(8)
|
||||
var occlusion_sampler: sampler;
|
||||
[[group(1), binding(9)]]
|
||||
@group(1) @binding(9)
|
||||
var normal_map_texture: texture_2d<f32>;
|
||||
[[group(1), binding(10)]]
|
||||
@group(1) @binding(10)
|
||||
var normal_map_sampler: sampler;
|
||||
|
|
|
@ -87,19 +87,19 @@ fn calculate_view(
|
|||
}
|
||||
|
||||
struct PbrInput {
|
||||
material: StandardMaterial;
|
||||
occlusion: f32;
|
||||
frag_coord: vec4<f32>;
|
||||
world_position: vec4<f32>;
|
||||
material: StandardMaterial,
|
||||
occlusion: f32,
|
||||
frag_coord: vec4<f32>,
|
||||
world_position: vec4<f32>,
|
||||
// Normalized world normal used for shadow mapping as normal-mapping is not used for shadow
|
||||
// mapping
|
||||
world_normal: vec3<f32>;
|
||||
world_normal: vec3<f32>,
|
||||
// Normalized normal-mapped world normal used for lighting
|
||||
N: vec3<f32>;
|
||||
N: vec3<f32>,
|
||||
// Normalized view vector in world space, pointing from the fragment world position toward the
|
||||
// view world position
|
||||
V: vec3<f32>;
|
||||
is_orthographic: bool;
|
||||
V: vec3<f32>,
|
||||
is_orthographic: bool,
|
||||
};
|
||||
|
||||
// Creates a PbrInput with default values
|
||||
|
|
|
@ -244,7 +244,7 @@ fn spot_light(
|
|||
R: vec3<f32>, F0: vec3<f32>, diffuseColor: vec3<f32>
|
||||
) -> vec3<f32> {
|
||||
// reuse the point light calculations
|
||||
let point = point_light(world_position, light, roughness, NdotV, N, V, R, F0, diffuseColor);
|
||||
let point_light = point_light(world_position, light, roughness, NdotV, N, V, R, F0, diffuseColor);
|
||||
|
||||
// reconstruct spot dir from x/z and y-direction flag
|
||||
var spot_dir = vec3<f32>(light.light_custom_data.x, 0.0, light.light_custom_data.y);
|
||||
|
@ -261,7 +261,7 @@ fn spot_light(
|
|||
let attenuation = saturate(cd * light.light_custom_data.z + light.light_custom_data.w);
|
||||
let spot_attenuation = attenuation * attenuation;
|
||||
|
||||
return point * spot_attenuation;
|
||||
return point_light * spot_attenuation;
|
||||
}
|
||||
|
||||
fn directional_light(light: DirectionalLight, roughness: f32, NdotV: f32, normal: vec3<f32>, view: vec3<f32>, R: vec3<f32>, F0: vec3<f32>, diffuseColor: vec3<f32>) -> vec3<f32> {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#define_import_path bevy_pbr::pbr_types
|
||||
|
||||
struct StandardMaterial {
|
||||
base_color: vec4<f32>;
|
||||
emissive: vec4<f32>;
|
||||
perceptual_roughness: f32;
|
||||
metallic: f32;
|
||||
reflectance: f32;
|
||||
base_color: vec4<f32>,
|
||||
emissive: vec4<f32>,
|
||||
perceptual_roughness: f32,
|
||||
metallic: f32,
|
||||
reflectance: f32,
|
||||
// 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
|
||||
flags: u32;
|
||||
alpha_cutoff: f32;
|
||||
flags: u32,
|
||||
alpha_cutoff: f32,
|
||||
};
|
||||
|
||||
let STANDARD_MATERIAL_FLAGS_BASE_COLOR_TEXTURE_BIT: u32 = 1u;
|
||||
|
|
|
@ -4,28 +4,14 @@
|
|||
|
||||
#define_import_path bevy_pbr::skinning
|
||||
|
||||
/// HACK: This works around naga not supporting matrix addition in SPIR-V
|
||||
// translations. See https://github.com/gfx-rs/naga/issues/1527
|
||||
fn add_matrix(
|
||||
a: mat4x4<f32>,
|
||||
b: mat4x4<f32>,
|
||||
) -> mat4x4<f32> {
|
||||
return mat4x4<f32>(
|
||||
a[0] + b[0],
|
||||
a[1] + b[1],
|
||||
a[2] + b[2],
|
||||
a[3] + b[3],
|
||||
);
|
||||
}
|
||||
|
||||
fn skin_model(
|
||||
indexes: vec4<u32>,
|
||||
weights: vec4<f32>,
|
||||
) -> mat4x4<f32> {
|
||||
var matrix = weights.x * joint_matrices.data[indexes.x];
|
||||
matrix = add_matrix(matrix, weights.y * joint_matrices.data[indexes.y]);
|
||||
matrix = add_matrix(matrix, weights.z * joint_matrices.data[indexes.z]);
|
||||
return add_matrix(matrix, weights.w * joint_matrices.data[indexes.w]);
|
||||
return weights.x * joint_matrices.data[indexes.x]
|
||||
+ weights.y * joint_matrices.data[indexes.y]
|
||||
+ weights.z * joint_matrices.data[indexes.z]
|
||||
+ weights.w * joint_matrices.data[indexes.w];
|
||||
}
|
||||
|
||||
fn inverse_transpose_3x3(in: mat3x3<f32>) -> mat3x3<f32> {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#import bevy_pbr::mesh_types
|
||||
#import bevy_pbr::mesh_view_bindings
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> mesh: Mesh;
|
||||
|
||||
#ifdef SKINNED
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var<uniform> joint_matrices: SkinnedMesh;
|
||||
#import bevy_pbr::skinning
|
||||
#endif
|
||||
|
@ -14,18 +14,18 @@ var<uniform> joint_matrices: SkinnedMesh;
|
|||
#import bevy_pbr::mesh_functions
|
||||
|
||||
struct Vertex {
|
||||
[[location(0)]] position: vec3<f32>;
|
||||
@location(0) position: vec3<f32>,
|
||||
#ifdef SKINNED
|
||||
[[location(4)]] joint_indexes: vec4<u32>;
|
||||
[[location(5)]] joint_weights: vec4<f32>;
|
||||
@location(4) joint_indexes: vec4<u32>,
|
||||
@location(5) joint_weights: vec4<f32>,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
[[builtin(position)]] clip_position: vec4<f32>;
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(vertex: Vertex) -> VertexOutput {
|
||||
#ifdef SKINNED
|
||||
let model = skin_model(vertex.joint_indexes, vertex.joint_weights);
|
||||
|
@ -38,7 +38,7 @@ fn vertex(vertex: Vertex) -> VertexOutput {
|
|||
return out;
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment() -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment() -> @location(0) vec4<f32> {
|
||||
return vec4<f32>(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }
|
|||
# other
|
||||
erased-serde = "0.3"
|
||||
downcast-rs = "1.2"
|
||||
parking_lot = "0.11.0"
|
||||
parking_lot = "0.12.1"
|
||||
thiserror = "1.0"
|
||||
once_cell = "1.11"
|
||||
serde = "1"
|
||||
|
|
|
@ -48,9 +48,9 @@ bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }
|
|||
image = { version = "0.24", default-features = false }
|
||||
|
||||
# misc
|
||||
wgpu = { version = "0.12.0", features = ["spirv"] }
|
||||
wgpu = { version = "0.13.1", features = ["spirv"] }
|
||||
codespan-reporting = "0.11.0"
|
||||
naga = { version = "0.8.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
|
||||
naga = { version = "0.9.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
bitflags = "1.2.1"
|
||||
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
||||
|
@ -62,7 +62,7 @@ futures-lite = "1.4.0"
|
|||
anyhow = "1.0"
|
||||
hex = "0.4.2"
|
||||
hexasphere = "7.2"
|
||||
parking_lot = "0.11.0"
|
||||
parking_lot = "0.12.1"
|
||||
regex = "1.5"
|
||||
copyless = "0.1.5"
|
||||
ddsfile = { version = "0.5.0", optional = true }
|
||||
|
|
|
@ -88,14 +88,14 @@ impl Node for CameraDriverNode {
|
|||
let _span = bevy_utils::tracing::info_span!("no_camera_clear_pass").entered();
|
||||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("no_camera_clear_pass"),
|
||||
color_attachments: &[RenderPassColorAttachment {
|
||||
color_attachments: &[Some(RenderPassColorAttachment {
|
||||
view: swap_chain_texture,
|
||||
resolve_target: None,
|
||||
ops: Operations {
|
||||
load: LoadOp::Clear(wgpu::Color::BLACK),
|
||||
store: true,
|
||||
},
|
||||
}],
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
|
|
|
@ -91,14 +91,14 @@ impl Deref for BindGroup {
|
|||
///
|
||||
/// ```wgsl
|
||||
/// struct CoolMaterial {
|
||||
/// color: vec4<f32>;
|
||||
/// color: vec4<f32>,
|
||||
/// };
|
||||
///
|
||||
/// [[group(1), binding(0)]]
|
||||
/// @group(1) @binding(0)
|
||||
/// var<uniform> material: CoolMaterial;
|
||||
/// [[group(1), binding(1)]]
|
||||
/// @group(1) @binding(1)
|
||||
/// var color_texture: texture_2d<f32>;
|
||||
/// [[group(1), binding(2)]]
|
||||
/// @group(1) @binding(2)
|
||||
/// var color_sampler: sampler;
|
||||
/// ```
|
||||
/// Note that the "group" index is determined by the usage context. It is not defined in [`AsBindGroup`]. For example, in Bevy material bind groups
|
||||
|
@ -165,11 +165,11 @@ impl Deref for BindGroup {
|
|||
/// In WGSL shaders, the binding would look like this:
|
||||
/// ```wgsl
|
||||
/// struct CoolMaterial {
|
||||
/// color: vec4<f32>;
|
||||
/// roughness: f32;
|
||||
/// color: vec4<f32>,
|
||||
/// roughness: f32,
|
||||
/// };
|
||||
///
|
||||
/// [[group(1), binding(0)]]
|
||||
/// @group(1) @binding(0)
|
||||
/// var<uniform> material: CoolMaterial;
|
||||
/// ```
|
||||
///
|
||||
|
|
|
@ -166,7 +166,7 @@ pub struct FragmentState {
|
|||
/// function with this name in the shader.
|
||||
pub entry_point: Cow<'static, str>,
|
||||
/// The color state of the render targets.
|
||||
pub targets: Vec<ColorTargetState>,
|
||||
pub targets: Vec<Option<ColorTargetState>>,
|
||||
}
|
||||
|
||||
/// Describes a compute pipeline.
|
||||
|
|
|
@ -155,7 +155,7 @@ impl ShaderCache {
|
|||
render_device
|
||||
.wgpu_device()
|
||||
.push_error_scope(wgpu::ErrorFilter::Validation);
|
||||
let shader_module = render_device.create_shader_module(&module_descriptor);
|
||||
let shader_module = render_device.create_shader_module(module_descriptor);
|
||||
let error = render_device.wgpu_device().pop_error_scope();
|
||||
|
||||
// `now_or_never` will return Some if the future is ready and None otherwise.
|
||||
|
@ -410,7 +410,7 @@ impl PipelineCache {
|
|||
Some((
|
||||
fragment_module,
|
||||
fragment.entry_point.deref(),
|
||||
&fragment.targets,
|
||||
fragment.targets.as_slice(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -557,26 +557,26 @@ mod tests {
|
|||
#[rustfmt::skip]
|
||||
const WGSL: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
#ifdef TEXTURE
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
#endif
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -587,29 +587,29 @@ fn vertex(
|
|||
|
||||
const WGSL_ELSE: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
#ifdef TEXTURE
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
#else
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d_array<f32>;
|
||||
#endif
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -620,28 +620,28 @@ fn vertex(
|
|||
|
||||
const WGSL_NESTED_IFDEF: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
# ifdef TEXTURE
|
||||
# ifdef ATTRIBUTE
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -652,31 +652,31 @@ fn vertex(
|
|||
|
||||
const WGSL_NESTED_IFDEF_ELSE: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
# ifdef TEXTURE
|
||||
# ifdef ATTRIBUTE
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
#else
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d_array<f32>;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -690,24 +690,24 @@ fn vertex(
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -732,22 +732,22 @@ fn vertex(
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -772,24 +772,24 @@ fn vertex(
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d_array<f32>;
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -937,22 +937,22 @@ void bar() { }
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -977,24 +977,24 @@ fn vertex(
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d_array<f32>;
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -1019,22 +1019,22 @@ fn vertex(
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -1059,22 +1059,22 @@ fn vertex(
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -1099,22 +1099,22 @@ fn vertex(
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -1139,24 +1139,24 @@ fn vertex(
|
|||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
|
|
@ -226,6 +226,9 @@ pub async fn initialize_renderer(
|
|||
max_compute_workgroups_per_dimension: limits
|
||||
.max_compute_workgroups_per_dimension
|
||||
.min(constrained_limits.max_compute_workgroups_per_dimension),
|
||||
max_buffer_size: limits
|
||||
.max_buffer_size
|
||||
.min(constrained_limits.max_buffer_size),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,8 @@ use crate::render_resource::{
|
|||
BindGroup, BindGroupLayout, Buffer, ComputePipeline, RawRenderPipelineDescriptor,
|
||||
RenderPipeline, Sampler, Texture,
|
||||
};
|
||||
use futures_lite::future;
|
||||
use std::sync::Arc;
|
||||
use wgpu::{util::DeviceExt, BufferBindingType};
|
||||
use wgpu::{util::DeviceExt, BufferAsyncError, BufferBindingType};
|
||||
|
||||
use super::RenderQueue;
|
||||
|
||||
|
@ -39,7 +38,7 @@ impl RenderDevice {
|
|||
|
||||
/// Creates a [`ShaderModule`](wgpu::ShaderModule) from either SPIR-V or WGSL source code.
|
||||
#[inline]
|
||||
pub fn create_shader_module(&self, desc: &wgpu::ShaderModuleDescriptor) -> wgpu::ShaderModule {
|
||||
pub fn create_shader_module(&self, desc: wgpu::ShaderModuleDescriptor) -> wgpu::ShaderModule {
|
||||
self.device.create_shader_module(desc)
|
||||
}
|
||||
|
||||
|
@ -170,13 +169,13 @@ impl RenderDevice {
|
|||
&self.device
|
||||
}
|
||||
|
||||
pub fn map_buffer(&self, buffer: &wgpu::BufferSlice, map_mode: wgpu::MapMode) {
|
||||
let data = buffer.map_async(map_mode);
|
||||
self.poll(wgpu::Maintain::Wait);
|
||||
assert!(
|
||||
future::block_on(data).is_ok(),
|
||||
"Failed to map buffer to host."
|
||||
);
|
||||
pub fn map_buffer(
|
||||
&self,
|
||||
buffer: &wgpu::BufferSlice,
|
||||
map_mode: wgpu::MapMode,
|
||||
callback: impl FnOnce(Result<(), BufferAsyncError>) + Send + 'static,
|
||||
) {
|
||||
buffer.map_async(map_mode, callback);
|
||||
}
|
||||
|
||||
pub fn align_copy_bytes_per_row(row_bytes: usize) -> usize {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use basis_universal::{
|
||||
BasisTextureType, DecodeFlags, TranscodeParameters, Transcoder, TranscoderTextureFormat,
|
||||
};
|
||||
use wgpu::{Extent3d, TextureDimension, TextureFormat};
|
||||
use wgpu::{AstcBlock, AstcChannel, Extent3d, TextureDimension, TextureFormat};
|
||||
|
||||
use super::{CompressedImageFormats, Image, TextureError};
|
||||
|
||||
|
@ -139,10 +139,13 @@ pub fn get_transcoded_formats(
|
|||
if supported_compressed_formats.contains(CompressedImageFormats::ASTC_LDR) {
|
||||
(
|
||||
TranscoderTextureFormat::ASTC_4x4_RGBA,
|
||||
if is_srgb {
|
||||
TextureFormat::Astc4x4RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc4x4RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B4x4,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
},
|
||||
)
|
||||
} else if supported_compressed_formats.contains(CompressedImageFormats::BC) {
|
||||
|
|
|
@ -742,36 +742,7 @@ impl CompressedImageFormats {
|
|||
| TextureFormat::EacR11Snorm
|
||||
| TextureFormat::EacRg11Unorm
|
||||
| TextureFormat::EacRg11Snorm => self.contains(CompressedImageFormats::ETC2),
|
||||
TextureFormat::Astc4x4RgbaUnorm
|
||||
| TextureFormat::Astc4x4RgbaUnormSrgb
|
||||
| TextureFormat::Astc5x4RgbaUnorm
|
||||
| TextureFormat::Astc5x4RgbaUnormSrgb
|
||||
| TextureFormat::Astc5x5RgbaUnorm
|
||||
| TextureFormat::Astc5x5RgbaUnormSrgb
|
||||
| TextureFormat::Astc6x5RgbaUnorm
|
||||
| TextureFormat::Astc6x5RgbaUnormSrgb
|
||||
| TextureFormat::Astc6x6RgbaUnorm
|
||||
| TextureFormat::Astc6x6RgbaUnormSrgb
|
||||
| TextureFormat::Astc8x5RgbaUnorm
|
||||
| TextureFormat::Astc8x5RgbaUnormSrgb
|
||||
| TextureFormat::Astc8x6RgbaUnorm
|
||||
| TextureFormat::Astc8x6RgbaUnormSrgb
|
||||
| TextureFormat::Astc10x5RgbaUnorm
|
||||
| TextureFormat::Astc10x5RgbaUnormSrgb
|
||||
| TextureFormat::Astc10x6RgbaUnorm
|
||||
| TextureFormat::Astc10x6RgbaUnormSrgb
|
||||
| TextureFormat::Astc8x8RgbaUnorm
|
||||
| TextureFormat::Astc8x8RgbaUnormSrgb
|
||||
| TextureFormat::Astc10x8RgbaUnorm
|
||||
| TextureFormat::Astc10x8RgbaUnormSrgb
|
||||
| TextureFormat::Astc10x10RgbaUnorm
|
||||
| TextureFormat::Astc10x10RgbaUnormSrgb
|
||||
| TextureFormat::Astc12x10RgbaUnorm
|
||||
| TextureFormat::Astc12x10RgbaUnormSrgb
|
||||
| TextureFormat::Astc12x12RgbaUnorm
|
||||
| TextureFormat::Astc12x12RgbaUnormSrgb => {
|
||||
self.contains(CompressedImageFormats::ASTC_LDR)
|
||||
}
|
||||
TextureFormat::Astc { .. } => self.contains(CompressedImageFormats::ASTC_LDR),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use ktx2::{
|
|||
BasicDataFormatDescriptor, ChannelTypeQualifiers, ColorModel, DataFormatDescriptorHeader,
|
||||
Header, SampleInformation,
|
||||
};
|
||||
use wgpu::{Extent3d, TextureDimension, TextureFormat};
|
||||
use wgpu::{AstcBlock, AstcChannel, Extent3d, TextureDimension, TextureFormat};
|
||||
|
||||
use super::{CompressedImageFormats, DataFormat, Image, TextureError, TranscodeFormat};
|
||||
|
||||
|
@ -239,10 +239,13 @@ pub fn get_transcoded_formats(
|
|||
if supported_compressed_formats.contains(CompressedImageFormats::ASTC_LDR) {
|
||||
(
|
||||
TranscoderBlockFormat::ASTC_4x4,
|
||||
if is_srgb {
|
||||
TextureFormat::Astc4x4RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc4x4RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B4x4,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
},
|
||||
)
|
||||
} else if supported_compressed_formats.contains(CompressedImageFormats::BC) {
|
||||
|
@ -1016,159 +1019,35 @@ pub fn ktx2_dfd_to_texture_format(
|
|||
)));
|
||||
}
|
||||
},
|
||||
Some(ColorModel::ASTC) => match data_format_descriptor.texel_block_dimensions[0] {
|
||||
4 => match data_format_descriptor.texel_block_dimensions[1] {
|
||||
4 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc4x4RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc4x4RgbaUnorm
|
||||
}
|
||||
}
|
||||
Some(ColorModel::ASTC) => TextureFormat::Astc {
|
||||
block: match (
|
||||
data_format_descriptor.texel_block_dimensions[0],
|
||||
data_format_descriptor.texel_block_dimensions[1],
|
||||
) {
|
||||
(4, 4) => AstcBlock::B4x4,
|
||||
(5, 4) => AstcBlock::B5x4,
|
||||
(5, 5) => AstcBlock::B5x5,
|
||||
(6, 5) => AstcBlock::B6x5,
|
||||
(8, 5) => AstcBlock::B8x5,
|
||||
(8, 8) => AstcBlock::B8x8,
|
||||
(10, 5) => AstcBlock::B10x5,
|
||||
(10, 6) => AstcBlock::B10x6,
|
||||
(10, 8) => AstcBlock::B10x8,
|
||||
(10, 10) => AstcBlock::B10x10,
|
||||
(12, 10) => AstcBlock::B12x10,
|
||||
(12, 12) => AstcBlock::B12x12,
|
||||
d => {
|
||||
return Err(TextureError::UnsupportedTextureFormat(format!(
|
||||
"Invalid ASTC y-dimension: {}",
|
||||
d
|
||||
"Invalid ASTC dimension: {} x {}",
|
||||
d.0, d.1
|
||||
)))
|
||||
}
|
||||
},
|
||||
5 => match data_format_descriptor.texel_block_dimensions[1] {
|
||||
4 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc5x4RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc5x4RgbaUnorm
|
||||
}
|
||||
}
|
||||
5 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc5x5RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc5x5RgbaUnorm
|
||||
}
|
||||
}
|
||||
d => {
|
||||
return Err(TextureError::UnsupportedTextureFormat(format!(
|
||||
"Invalid ASTC y-dimension: {}",
|
||||
d
|
||||
)))
|
||||
}
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
6 => match data_format_descriptor.texel_block_dimensions[1] {
|
||||
5 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc6x5RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc6x5RgbaUnorm
|
||||
}
|
||||
}
|
||||
6 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc6x6RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc6x6RgbaUnorm
|
||||
}
|
||||
}
|
||||
d => {
|
||||
return Err(TextureError::UnsupportedTextureFormat(format!(
|
||||
"Invalid ASTC y-dimension: {}",
|
||||
d
|
||||
)))
|
||||
}
|
||||
},
|
||||
8 => match data_format_descriptor.texel_block_dimensions[1] {
|
||||
5 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc8x5RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc8x5RgbaUnorm
|
||||
}
|
||||
}
|
||||
6 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc8x6RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc8x6RgbaUnorm
|
||||
}
|
||||
}
|
||||
8 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc8x8RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc8x8RgbaUnorm
|
||||
}
|
||||
}
|
||||
d => {
|
||||
return Err(TextureError::UnsupportedTextureFormat(format!(
|
||||
"Invalid ASTC y-dimension: {}",
|
||||
d
|
||||
)))
|
||||
}
|
||||
},
|
||||
10 => match data_format_descriptor.texel_block_dimensions[1] {
|
||||
5 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc10x5RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc10x5RgbaUnorm
|
||||
}
|
||||
}
|
||||
6 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc10x6RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc10x6RgbaUnorm
|
||||
}
|
||||
}
|
||||
8 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc10x8RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc10x8RgbaUnorm
|
||||
}
|
||||
}
|
||||
10 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc10x10RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc10x10RgbaUnorm
|
||||
}
|
||||
}
|
||||
d => {
|
||||
return Err(TextureError::UnsupportedTextureFormat(format!(
|
||||
"Invalid ASTC y-dimension: {}",
|
||||
d
|
||||
)))
|
||||
}
|
||||
},
|
||||
12 => match data_format_descriptor.texel_block_dimensions[1] {
|
||||
10 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc12x10RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc12x10RgbaUnorm
|
||||
}
|
||||
}
|
||||
12 => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc12x12RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc12x12RgbaUnorm
|
||||
}
|
||||
}
|
||||
d => {
|
||||
return Err(TextureError::UnsupportedTextureFormat(format!(
|
||||
"Invalid ASTC y-dimension: {}",
|
||||
d
|
||||
)))
|
||||
}
|
||||
},
|
||||
d => {
|
||||
return Err(TextureError::UnsupportedTextureFormat(format!(
|
||||
"Invalid ASTC x-dimension: {}",
|
||||
d
|
||||
)))
|
||||
}
|
||||
},
|
||||
Some(ColorModel::ETC1S) => {
|
||||
return Err(TextureError::FormatRequiresTranscodingError(
|
||||
|
@ -1362,101 +1241,143 @@ pub fn ktx2_format_to_texture_format(
|
|||
ktx2::Format::EAC_R11G11_UNORM_BLOCK => TextureFormat::EacRg11Unorm,
|
||||
ktx2::Format::EAC_R11G11_SNORM_BLOCK => TextureFormat::EacRg11Snorm,
|
||||
ktx2::Format::ASTC_4x4_UNORM_BLOCK | ktx2::Format::ASTC_4x4_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc4x4RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc4x4RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B4x4,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_5x4_UNORM_BLOCK | ktx2::Format::ASTC_5x4_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc5x4RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc5x4RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B5x4,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_5x5_UNORM_BLOCK | ktx2::Format::ASTC_5x5_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc5x5RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc5x5RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B5x5,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_6x5_UNORM_BLOCK | ktx2::Format::ASTC_6x5_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc6x5RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc6x5RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B6x5,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_6x6_UNORM_BLOCK | ktx2::Format::ASTC_6x6_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc6x6RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc6x6RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B6x6,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_8x5_UNORM_BLOCK | ktx2::Format::ASTC_8x5_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc8x5RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc8x5RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B8x5,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_8x6_UNORM_BLOCK | ktx2::Format::ASTC_8x6_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc8x6RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc8x6RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B8x6,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_8x8_UNORM_BLOCK | ktx2::Format::ASTC_8x8_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc8x8RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc8x8RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B8x8,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_10x5_UNORM_BLOCK | ktx2::Format::ASTC_10x5_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc10x5RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc10x5RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B10x5,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_10x6_UNORM_BLOCK | ktx2::Format::ASTC_10x6_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc10x6RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc10x6RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B10x6,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_10x8_UNORM_BLOCK | ktx2::Format::ASTC_10x8_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc10x8RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc10x8RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B10x8,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_10x10_UNORM_BLOCK | ktx2::Format::ASTC_10x10_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc10x10RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc10x10RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B10x10,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_12x10_UNORM_BLOCK | ktx2::Format::ASTC_12x10_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc12x10RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc12x10RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B12x10,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
ktx2::Format::ASTC_12x12_UNORM_BLOCK | ktx2::Format::ASTC_12x12_SRGB_BLOCK => {
|
||||
if is_srgb {
|
||||
TextureFormat::Astc12x12RgbaUnormSrgb
|
||||
} else {
|
||||
TextureFormat::Astc12x12RgbaUnorm
|
||||
TextureFormat::Astc {
|
||||
block: AstcBlock::B12x12,
|
||||
channel: if is_srgb {
|
||||
AstcChannel::UnormSrgb
|
||||
} else {
|
||||
AstcChannel::Unorm
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -169,6 +169,8 @@ pub fn prepare_windows(
|
|||
PresentMode::Fifo => wgpu::PresentMode::Fifo,
|
||||
PresentMode::Mailbox => wgpu::PresentMode::Mailbox,
|
||||
PresentMode::Immediate => wgpu::PresentMode::Immediate,
|
||||
PresentMode::AutoVsync => wgpu::PresentMode::AutoVsync,
|
||||
PresentMode::AutoNoVsync => wgpu::PresentMode::AutoNoVsync,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -2,41 +2,33 @@
|
|||
#import bevy_sprite::mesh2d_view_bindings
|
||||
|
||||
struct ColorMaterial {
|
||||
color: vec4<f32>;
|
||||
color: vec4<f32>,
|
||||
// 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
|
||||
flags: u32;
|
||||
flags: u32,
|
||||
};
|
||||
let COLOR_MATERIAL_FLAGS_TEXTURE_BIT: u32 = 1u;
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> material: ColorMaterial;
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var texture: texture_2d<f32>;
|
||||
[[group(1), binding(2)]]
|
||||
@group(1) @binding(2)
|
||||
var texture_sampler: sampler;
|
||||
|
||||
[[group(2), binding(0)]]
|
||||
@group(2) @binding(0)
|
||||
var<uniform> mesh: Mesh2d;
|
||||
|
||||
struct FragmentInput {
|
||||
[[builtin(front_facing)]] is_front: bool;
|
||||
[[location(0)]] world_position: vec4<f32>;
|
||||
[[location(1)]] world_normal: vec3<f32>;
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] world_tangent: vec4<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
[[location(4)]] colors: vec4<f32>;
|
||||
#endif
|
||||
@builtin(front_facing) is_front: bool,
|
||||
#import bevy_sprite::mesh2d_vertex_output
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
||||
var output_color: vec4<f32> = material.color;
|
||||
if ((material.flags & COLOR_MATERIAL_FLAGS_TEXTURE_BIT) != 0u) {
|
||||
#ifdef VERTEX_COLORS
|
||||
output_color = output_color * textureSample(texture, texture_sampler, in.uv) * in.colors;
|
||||
output_color = output_color * textureSample(texture, texture_sampler, in.uv) * in.color;
|
||||
#else
|
||||
output_color = output_color * textureSample(texture, texture_sampler, in.uv);
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,8 @@ impl From<Handle<Mesh>> for Mesh2dHandle {
|
|||
#[derive(Default)]
|
||||
pub struct Mesh2dRenderPlugin;
|
||||
|
||||
pub const MESH2D_VERTEX_OUTPUT: HandleUntyped =
|
||||
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 7646632476603252194);
|
||||
pub const MESH2D_VIEW_TYPES_HANDLE: HandleUntyped =
|
||||
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 12677582416765805110);
|
||||
pub const MESH2D_VIEW_BINDINGS_HANDLE: HandleUntyped =
|
||||
|
@ -52,6 +54,12 @@ pub const MESH2D_SHADER_HANDLE: HandleUntyped =
|
|||
|
||||
impl Plugin for Mesh2dRenderPlugin {
|
||||
fn build(&self, app: &mut bevy_app::App) {
|
||||
load_internal_asset!(
|
||||
app,
|
||||
MESH2D_VERTEX_OUTPUT,
|
||||
"mesh2d_vertex_output.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
load_internal_asset!(
|
||||
app,
|
||||
MESH2D_VIEW_TYPES_HANDLE,
|
||||
|
@ -344,11 +352,11 @@ impl SpecializedMeshPipeline for Mesh2dPipeline {
|
|||
shader: MESH2D_SHADER_HANDLE.typed::<Shader>(),
|
||||
shader_defs,
|
||||
entry_point: "fragment".into(),
|
||||
targets: vec![ColorTargetState {
|
||||
targets: vec![Some(ColorTargetState {
|
||||
format: TextureFormat::bevy_default(),
|
||||
blend: Some(BlendState::ALPHA_BLENDING),
|
||||
write_mask: ColorWrites::ALL,
|
||||
}],
|
||||
})],
|
||||
}),
|
||||
layout: Some(vec![self.view_layout.clone(), self.mesh_layout.clone()]),
|
||||
primitive: PrimitiveState {
|
||||
|
|
|
@ -5,31 +5,23 @@
|
|||
#import bevy_sprite::mesh2d_functions
|
||||
|
||||
struct Vertex {
|
||||
[[location(0)]] position: vec3<f32>;
|
||||
[[location(1)]] normal: vec3<f32>;
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
@location(2) uv: vec2<f32>,
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] tangent: vec4<f32>;
|
||||
@location(3) tangent: vec4<f32>,
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
[[location(4)]] colors: vec4<f32>;
|
||||
@location(4) color: vec4<f32>,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
[[builtin(position)]] clip_position: vec4<f32>;
|
||||
[[location(0)]] world_position: vec4<f32>;
|
||||
[[location(1)]] world_normal: vec3<f32>;
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] world_tangent: vec4<f32>;
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
[[location(4)]] colors: vec4<f32>;
|
||||
#endif
|
||||
};
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
#import bevy_sprite::mesh2d_vertex_output
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(vertex: Vertex) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex.uv;
|
||||
|
@ -40,22 +32,17 @@ fn vertex(vertex: Vertex) -> VertexOutput {
|
|||
out.world_tangent = mesh2d_tangent_local_to_world(vertex.tangent);
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
out.colors = vertex.colors;
|
||||
out.color = vertex.color;
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
|
||||
struct FragmentInput {
|
||||
[[builtin(front_facing)]] is_front: bool;
|
||||
[[location(0)]] world_position: vec4<f32>;
|
||||
[[location(1)]] world_normal: vec3<f32>;
|
||||
[[location(2)]] uv: vec2<f32>;
|
||||
#ifdef VERTEX_TANGENTS
|
||||
[[location(3)]] world_tangent: vec4<f32>;
|
||||
#endif
|
||||
@builtin(front_facing) is_front: bool,
|
||||
#import bevy_sprite::mesh2d_vertex_output
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
||||
return vec4<f32>(1.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
#import bevy_sprite::mesh2d_types
|
||||
|
||||
[[group(2), binding(0)]]
|
||||
@group(2) @binding(0)
|
||||
var<uniform> mesh: Mesh2d;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#define_import_path bevy_sprite::mesh2d_types
|
||||
|
||||
struct Mesh2d {
|
||||
model: mat4x4<f32>;
|
||||
inverse_transpose_model: mat4x4<f32>;
|
||||
model: mat4x4<f32>,
|
||||
inverse_transpose_model: mat4x4<f32>,
|
||||
// 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
|
||||
flags: u32;
|
||||
flags: u32,
|
||||
};
|
||||
|
|
11
crates/bevy_sprite/src/mesh2d/mesh2d_vertex_output.wgsl
Normal file
11
crates/bevy_sprite/src/mesh2d/mesh2d_vertex_output.wgsl
Normal file
|
@ -0,0 +1,11 @@
|
|||
#define_import_path bevy_sprite::mesh2d_vertex_output
|
||||
|
||||
@location(0) world_position: vec4<f32>,
|
||||
@location(1) world_normal: vec3<f32>,
|
||||
@location(2) uv: vec2<f32>,
|
||||
#ifdef VERTEX_TANGENTS
|
||||
@location(3) world_tangent: vec4<f32>,
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
@location(4) color: vec4<f32>,
|
||||
#endif
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
#import bevy_sprite::mesh2d_view_types
|
||||
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#define_import_path bevy_sprite::mesh2d_view_types
|
||||
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
view: mat4x4<f32>;
|
||||
inverse_view: mat4x4<f32>;
|
||||
projection: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
width: f32;
|
||||
height: f32;
|
||||
view_proj: mat4x4<f32>,
|
||||
view: mat4x4<f32>,
|
||||
inverse_view: mat4x4<f32>,
|
||||
projection: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
width: f32,
|
||||
height: f32,
|
||||
};
|
||||
|
|
|
@ -143,11 +143,11 @@ impl SpecializedRenderPipeline for SpritePipeline {
|
|||
shader: SPRITE_SHADER_HANDLE.typed::<Shader>(),
|
||||
shader_defs,
|
||||
entry_point: "fragment".into(),
|
||||
targets: vec![ColorTargetState {
|
||||
targets: vec![Some(ColorTargetState {
|
||||
format: TextureFormat::bevy_default(),
|
||||
blend: Some(BlendState::ALPHA_BLENDING),
|
||||
write_mask: ColorWrites::ALL,
|
||||
}],
|
||||
})],
|
||||
}),
|
||||
layout: Some(vec![self.view_layout.clone(), self.material_layout.clone()]),
|
||||
primitive: PrimitiveState {
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
#ifdef COLORED
|
||||
[[location(1)]] color: vec4<f32>;
|
||||
@location(1) color: vec4<f32>,
|
||||
#endif
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>,
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>,
|
||||
#ifdef COLORED
|
||||
[[location(2)]] vertex_color: vec4<f32>,
|
||||
@location(2) vertex_color: vec4<f32>,
|
||||
#endif
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
|
@ -30,13 +30,13 @@ fn vertex(
|
|||
return out;
|
||||
}
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var sprite_sampler: sampler;
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
var color = textureSample(sprite_texture, sprite_sampler, in.uv);
|
||||
#ifdef COLORED
|
||||
color = in.color * color;
|
||||
|
|
|
@ -86,11 +86,11 @@ impl SpecializedRenderPipeline for UiPipeline {
|
|||
shader: super::UI_SHADER_HANDLE.typed::<Shader>(),
|
||||
shader_defs,
|
||||
entry_point: "fragment".into(),
|
||||
targets: vec![ColorTargetState {
|
||||
targets: vec![Some(ColorTargetState {
|
||||
format: TextureFormat::bevy_default(),
|
||||
blend: Some(BlendState::ALPHA_BLENDING),
|
||||
write_mask: ColorWrites::ALL,
|
||||
}],
|
||||
})],
|
||||
}),
|
||||
layout: Some(vec![self.view_layout.clone(), self.image_layout.clone()]),
|
||||
primitive: PrimitiveState {
|
||||
|
|
|
@ -81,14 +81,14 @@ impl Node for UiPassNode {
|
|||
};
|
||||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("ui_pass"),
|
||||
color_attachments: &[RenderPassColorAttachment {
|
||||
color_attachments: &[Some(RenderPassColorAttachment {
|
||||
view: &target.view,
|
||||
resolve_target: None,
|
||||
ops: Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
},
|
||||
}],
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
view_proj: mat4x4<f32>,
|
||||
world_position: vec3<f32>,
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
@group(0) @binding(0)
|
||||
var<uniform> view: View;
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[location(1)]] color: vec4<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
@location(0) uv: vec2<f32>,
|
||||
@location(1) color: vec4<f32>,
|
||||
@builtin(position) position: vec4<f32>,
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>,
|
||||
[[location(2)]] vertex_color: vec4<f32>,
|
||||
@location(0) vertex_position: vec3<f32>,
|
||||
@location(1) vertex_uv: vec2<f32>,
|
||||
@location(2) vertex_color: vec4<f32>,
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
|
@ -24,13 +24,13 @@ fn vertex(
|
|||
return out;
|
||||
}
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
[[group(1), binding(1)]]
|
||||
@group(1) @binding(1)
|
||||
var sprite_sampler: sampler;
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
var color = textureSample(sprite_texture, sprite_sampler, in.uv);
|
||||
color = in.color * color;
|
||||
return color;
|
||||
|
|
|
@ -23,20 +23,34 @@ pub struct WindowId(Uuid);
|
|||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[doc(alias = "vsync")]
|
||||
pub enum PresentMode {
|
||||
/// Chooses FifoRelaxed -> Fifo based on availability.
|
||||
///
|
||||
/// Because of the fallback behavior, it is supported everywhere.
|
||||
AutoVsync = 0,
|
||||
/// Chooses Immediate -> Mailbox -> Fifo (on web) based on availability.
|
||||
///
|
||||
/// Because of the fallback behavior, it is supported everywhere.
|
||||
AutoNoVsync = 1,
|
||||
/// The presentation engine does **not** wait for a vertical blanking period and
|
||||
/// the request is presented immediately. This is a low-latency presentation mode,
|
||||
/// but visible tearing may be observed. Will fallback to `Fifo` if unavailable on the
|
||||
/// selected platform and backend. Not optimal for mobile.
|
||||
Immediate = 0,
|
||||
///
|
||||
/// Selecting this variant will panic if not supported, it is preferred to use
|
||||
/// [`PresentMode::AutoNoVsync`].
|
||||
Immediate = 2,
|
||||
/// The presentation engine waits for the next vertical blanking period to update
|
||||
/// the current image, but frames may be submitted without delay. This is a low-latency
|
||||
/// presentation mode and visible tearing will **not** be observed. Will fallback to `Fifo`
|
||||
/// if unavailable on the selected platform and backend. Not optimal for mobile.
|
||||
Mailbox = 1,
|
||||
///
|
||||
/// Selecting this variant will panic if not supported, it is preferred to use
|
||||
/// [`PresentMode::AutoNoVsync`].
|
||||
Mailbox = 3,
|
||||
/// The presentation engine waits for the next vertical blanking period to update
|
||||
/// the current image. The framerate will be capped at the display refresh rate,
|
||||
/// corresponding to the `VSync`. Tearing cannot be observed. Optimal for mobile.
|
||||
Fifo = 2, // NOTE: The explicit ordinal values mirror wgpu and the vulkan spec.
|
||||
Fifo = 4, // NOTE: The explicit ordinal values mirror wgpu.
|
||||
}
|
||||
|
||||
impl WindowId {
|
||||
|
|
|
@ -40,6 +40,8 @@ skip = [
|
|||
{ name = "ndk", version = "0.5" }, # from winit v0.26.1
|
||||
{ name = "ndk-glue", version = "0.5" }, # from winit v0.26.1
|
||||
{ name = "ndk-sys", version = "0.2" }, # from winit v0.26.1
|
||||
{ name = "parking_lot", version = "0.11" }, # from rodio v0.15.0
|
||||
{ name = "parking_lot_core", version = "0.8" }, # from rodio v0.15.0
|
||||
{ name = "stdweb", version = "0.1" }, # from rodio v0.15.0
|
||||
{ name = "nix", version = "0.23.1" }, # from alsa v0.6.0
|
||||
]
|
||||
|
|
|
@ -160,11 +160,11 @@ impl SpecializedRenderPipeline for ColoredMesh2dPipeline {
|
|||
shader: COLORED_MESH2D_SHADER_HANDLE.typed::<Shader>(),
|
||||
shader_defs: Vec::new(),
|
||||
entry_point: "fragment".into(),
|
||||
targets: vec![ColorTargetState {
|
||||
targets: vec![Some(ColorTargetState {
|
||||
format: TextureFormat::bevy_default(),
|
||||
blend: Some(BlendState::ALPHA_BLENDING),
|
||||
write_mask: ColorWrites::ALL,
|
||||
}],
|
||||
})],
|
||||
}),
|
||||
// Use the two standard uniforms for 2d meshes
|
||||
layout: Some(vec![
|
||||
|
@ -212,7 +212,7 @@ const COLORED_MESH2D_SHADER: &str = r"
|
|||
#import bevy_sprite::mesh2d_types
|
||||
#import bevy_sprite::mesh2d_view_bindings
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
@group(1) @binding(0)
|
||||
var<uniform> mesh: Mesh2d;
|
||||
|
||||
// NOTE: Bindings must come before functions that use them!
|
||||
|
@ -220,19 +220,19 @@ var<uniform> mesh: Mesh2d;
|
|||
|
||||
// The structure of the vertex buffer is as specified in `specialize()`
|
||||
struct Vertex {
|
||||
[[location(0)]] position: vec3<f32>;
|
||||
[[location(1)]] color: u32;
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) color: u32,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
// The vertex shader must set the on-screen position of the vertex
|
||||
[[builtin(position)]] clip_position: vec4<f32>;
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
// We pass the vertex color to the fragment shader in location 0
|
||||
[[location(0)]] color: vec4<f32>;
|
||||
@location(0) color: vec4<f32>,
|
||||
};
|
||||
|
||||
/// Entry point for the vertex shader
|
||||
[[stage(vertex)]]
|
||||
@vertex
|
||||
fn vertex(vertex: Vertex) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
// Project the world position of the mesh into screen position
|
||||
|
@ -245,12 +245,12 @@ fn vertex(vertex: Vertex) -> VertexOutput {
|
|||
// The input of the fragment shader must correspond to the output of the vertex shader for all `location`s
|
||||
struct FragmentInput {
|
||||
// The color is interpolated between vertices by default
|
||||
[[location(0)]] color: vec4<f32>;
|
||||
@location(0) color: vec4<f32>,
|
||||
};
|
||||
|
||||
/// Entry point for the fragment shader
|
||||
[[stage(fragment)]]
|
||||
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
|
||||
@fragment
|
||||
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
||||
return in.color;
|
||||
}
|
||||
";
|
||||
|
|
|
@ -25,7 +25,7 @@ fn main() {
|
|||
.insert_resource(ClearColor(Color::BLACK))
|
||||
.insert_resource(WindowDescriptor {
|
||||
// uncomment for unthrottled FPS
|
||||
// present_mode: bevy::window::PresentMode::Immediate,
|
||||
// present_mode: bevy::window::PresentMode::AutoNoVsync,
|
||||
..default()
|
||||
})
|
||||
.add_plugins(DefaultPlugins)
|
||||
|
@ -227,14 +227,14 @@ impl render_graph::Node for GameOfLifeNode {
|
|||
.get_compute_pipeline(pipeline.init_pipeline)
|
||||
.unwrap();
|
||||
pass.set_pipeline(init_pipeline);
|
||||
pass.dispatch(SIZE.0 / WORKGROUP_SIZE, SIZE.1 / WORKGROUP_SIZE, 1);
|
||||
pass.dispatch_workgroups(SIZE.0 / WORKGROUP_SIZE, SIZE.1 / WORKGROUP_SIZE, 1);
|
||||
}
|
||||
GameOfLifeState::Update => {
|
||||
let update_pipeline = pipeline_cache
|
||||
.get_compute_pipeline(pipeline.update_pipeline)
|
||||
.unwrap();
|
||||
pass.set_pipeline(update_pipeline);
|
||||
pass.dispatch(SIZE.0 / WORKGROUP_SIZE, SIZE.1 / WORKGROUP_SIZE, 1);
|
||||
pass.dispatch_workgroups(SIZE.0 / WORKGROUP_SIZE, SIZE.1 / WORKGROUP_SIZE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ fn main() {
|
|||
title: "BevyMark".to_string(),
|
||||
width: 800.,
|
||||
height: 600.,
|
||||
present_mode: PresentMode::Immediate,
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
resizable: true,
|
||||
..default()
|
||||
})
|
||||
|
|
|
@ -20,7 +20,7 @@ use bevy::{
|
|||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(WindowDescriptor {
|
||||
present_mode: PresentMode::Immediate,
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
..default()
|
||||
})
|
||||
.add_plugins(DefaultPlugins)
|
||||
|
|
|
@ -17,7 +17,7 @@ fn main() {
|
|||
App::new()
|
||||
.insert_resource(WindowDescriptor {
|
||||
title: "🦊🦊🦊 Many Foxes! 🦊🦊🦊".to_string(),
|
||||
present_mode: PresentMode::Immediate,
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
..default()
|
||||
})
|
||||
.add_plugins(DefaultPlugins)
|
||||
|
|
|
@ -17,7 +17,7 @@ fn main() {
|
|||
width: 1024.0,
|
||||
height: 768.0,
|
||||
title: "many_lights".to_string(),
|
||||
present_mode: PresentMode::Immediate,
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
..default()
|
||||
})
|
||||
.add_plugins(DefaultPlugins)
|
||||
|
|
|
@ -26,7 +26,7 @@ struct ColorTint(bool);
|
|||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(WindowDescriptor {
|
||||
present_mode: PresentMode::Immediate,
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
..default()
|
||||
})
|
||||
.insert_resource(ColorTint(
|
||||
|
|
|
@ -9,7 +9,7 @@ use bevy::{
|
|||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(WindowDescriptor {
|
||||
present_mode: PresentMode::Immediate,
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
..default()
|
||||
})
|
||||
.add_plugins(DefaultPlugins)
|
||||
|
|
|
@ -27,7 +27,7 @@ fn main() {
|
|||
})
|
||||
// Turn off vsync to maximize CPU/GPU usage
|
||||
.insert_resource(WindowDescriptor {
|
||||
present_mode: PresentMode::Immediate,
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
..default()
|
||||
})
|
||||
.insert_resource(ExampleMode::Game)
|
||||
|
|
|
@ -43,7 +43,7 @@ fn setup(
|
|||
descriptor: WindowDescriptor {
|
||||
width: 800.,
|
||||
height: 600.,
|
||||
present_mode: PresentMode::Immediate,
|
||||
present_mode: PresentMode::AutoNoVsync,
|
||||
title: "Second window".to_string(),
|
||||
..default()
|
||||
},
|
||||
|
|
|
@ -9,7 +9,7 @@ fn main() {
|
|||
title: "I am a window!".to_string(),
|
||||
width: 500.,
|
||||
height: 300.,
|
||||
present_mode: PresentMode::Fifo,
|
||||
present_mode: PresentMode::AutoVsync,
|
||||
..default()
|
||||
})
|
||||
.add_plugins(DefaultPlugins)
|
||||
|
|
Loading…
Reference in a new issue