mirror of
https://github.com/Zenithsiz/zsw.git
synced 2026-02-03 17:52:15 +00:00
Fade shader now renders the 3 images separately.
This commit is contained in:
parent
40188d9f4e
commit
9cf59df867
@ -1,17 +1,77 @@
|
||||
//! Fade shader
|
||||
//! None shader
|
||||
|
||||
// Imports
|
||||
#import fade::vertex
|
||||
#import fade::frag
|
||||
#import fade::stage_io::{VertexInput, VertexOutput, FragOutput}
|
||||
/// Uniforms
|
||||
struct Uniforms {
|
||||
pos_matrix: mat4x4<f32>,
|
||||
image_ratio: vec2<f32>,
|
||||
progress: f32,
|
||||
alpha: f32,
|
||||
|
||||
#ifdef FADE_WHITE
|
||||
mix_strength: f32,
|
||||
#else ifdef FADE_OUT
|
||||
strength: f32,
|
||||
#else ifdef FADE_IN
|
||||
strength: f32,
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Uniforms
|
||||
@group(0) @binding(0)
|
||||
var<uniform> uniforms: Uniforms;
|
||||
|
||||
/// Vertex output
|
||||
struct VertexOutput {
|
||||
@builtin(position)
|
||||
pos: vec4<f32>,
|
||||
|
||||
@location(0)
|
||||
uvs: vec2<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||
return vertex::main(in);
|
||||
fn vs_main(
|
||||
@location(0) pos: vec2<f32>,
|
||||
@location(1) uvs: vec2<f32>,
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.pos = uniforms.pos_matrix * vec4<f32>(pos, 0.0, 1.0);
|
||||
out.uvs = uvs;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Image
|
||||
@group(1) @binding(0) var image: texture_2d<f32>;
|
||||
@group(1) @binding(1) var image_sampler: sampler;
|
||||
|
||||
@fragment
|
||||
fn fs_main(in: VertexOutput) -> FragOutput {
|
||||
return frag::main(in);
|
||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
// Calculate the uvs for this pixel
|
||||
let uvs_offset = (vec2(1.0, 1.0) - uniforms.image_ratio) * uniforms.progress;
|
||||
var uvs = in.uvs * uniforms.image_ratio + uvs_offset;
|
||||
|
||||
#ifdef FADE_OUT
|
||||
let mid = uniforms.image_ratio / 2.0 + uvs_offset;
|
||||
uvs = mid + (uvs - mid) * pow(uniforms.alpha, uniforms.strength);
|
||||
#else ifdef FADE_IN
|
||||
let mid = uniforms.image_ratio / 2.0 + uvs_offset;
|
||||
uvs = mid + (uvs - mid) / pow(uniforms.alpha, uniforms.strength);
|
||||
#endif
|
||||
|
||||
// If we'd sample outside the image, discard this pixel instead
|
||||
// TODO: Set alpha to 0 instead of discarding?
|
||||
if any(uvs < vec2(0.0, 0.0) | uvs > vec2(1.0, 1.0)) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// Otherwise, we'll sample and return the color
|
||||
var color = textureSample(image, image_sampler, uvs);
|
||||
#ifdef FADE_WHITE
|
||||
color = mix(
|
||||
color,
|
||||
vec4(1.0, 1.0, 1.0, 1.0),
|
||||
uniforms.mix_strength,
|
||||
);
|
||||
#endif
|
||||
return vec4(color.rgb, uniforms.alpha);
|
||||
}
|
||||
|
||||
@ -1,112 +0,0 @@
|
||||
//! Frag shader
|
||||
|
||||
// Imports
|
||||
#import fade::stage_io::{VertexOutput, FragOutput}
|
||||
#import fade::uniforms::{uniforms, ImageUniforms}
|
||||
|
||||
// Bindings
|
||||
@group(1) @binding(0) var image_prev: texture_2d<f32>;
|
||||
@group(1) @binding(1) var image_cur: texture_2d<f32>;
|
||||
@group(1) @binding(2) var image_next: texture_2d<f32>;
|
||||
@group(1) @binding(3) var image_sampler: sampler;
|
||||
|
||||
struct Sampled {
|
||||
color: vec4<f32>,
|
||||
uvs : vec2<f32>,
|
||||
}
|
||||
|
||||
// Samples an image
|
||||
fn sample(image: texture_2d<f32>, in_uvs: vec2<f32>, image_uniforms: ImageUniforms, progress_raw: f32, alpha: f32) -> Sampled {
|
||||
var sampled: Sampled;
|
||||
var uvs = in_uvs;
|
||||
|
||||
var progress: f32;
|
||||
if image_uniforms.swap_dir == 0 {
|
||||
progress = progress_raw;
|
||||
} else {
|
||||
progress = 1.0 - progress_raw;
|
||||
}
|
||||
|
||||
// Then apply the image ratio and delta
|
||||
let uvs_delta = (vec2<f32>(1.0, 1.0) - image_uniforms.image_ratio) * progress;
|
||||
uvs = uvs * image_uniforms.image_ratio + uvs_delta;
|
||||
|
||||
// Offset it, if necessary
|
||||
#ifdef FADE_OUT
|
||||
let mid = vec2<f32>(image_uniforms.image_ratio.x / 2.0 + uvs_delta.x, image_uniforms.image_ratio.y / 2.0 + uvs_delta.y);
|
||||
uvs = (uvs.xy - mid) * pow(alpha, uniforms.strength) + mid;
|
||||
|
||||
#else ifdef FADE_IN
|
||||
let mid = vec2<f32>(image_uniforms.image_ratio.x / 2.0 + uvs_delta.x, image_uniforms.image_ratio.y / 2.0 + uvs_delta.y);
|
||||
uvs = (uvs.xy - mid) / pow(alpha, uniforms.strength) + mid;
|
||||
|
||||
#endif
|
||||
|
||||
sampled.color = textureSample(image, image_sampler, uvs);
|
||||
sampled.uvs = uvs;
|
||||
|
||||
return sampled;
|
||||
}
|
||||
|
||||
fn main(in: VertexOutput) -> FragOutput {
|
||||
var out: FragOutput;
|
||||
|
||||
let p = uniforms.progress;
|
||||
let f = uniforms.fade_duration;
|
||||
|
||||
// Full duration an image is on screen (including the fades)
|
||||
let d = 1.0 + 2.0 * f;
|
||||
|
||||
let progress_prev = 1.0 - max((f - p) / d, 0.0);
|
||||
let progress_cur = (p + f) / d;
|
||||
let progress_next = max((p - 1.0 + f) / d, 0.0);
|
||||
|
||||
let alpha_prev = 0.5 * saturate(1.0 - ( p) / f);
|
||||
let alpha_next = 0.5 * saturate(1.0 - (1.0 - p) / f);
|
||||
let alpha_cur = 1.0 - max(alpha_prev, alpha_next);
|
||||
|
||||
// Sample the images
|
||||
let sample_prev = sample(image_prev, in.uvs, uniforms.prev, progress_prev, alpha_prev);
|
||||
let sample_cur = sample( image_cur, in.uvs, uniforms.cur , progress_cur , alpha_cur );
|
||||
let sample_next = sample(image_next, in.uvs, uniforms.next, progress_next, alpha_next);
|
||||
|
||||
// Then mix the color
|
||||
// TODO: Don't repeat this once we're able to use `defined(FADE_BASIC) || defined(FADE_OUT)`
|
||||
#ifdef FADE_BASIC
|
||||
out.color =
|
||||
alpha_prev * sample_prev.color +
|
||||
alpha_cur * sample_cur .color +
|
||||
alpha_next * sample_next.color;
|
||||
out.color.a = 1.0;
|
||||
#else ifdef FADE_OUT
|
||||
out.color =
|
||||
alpha_prev * sample_prev.color +
|
||||
alpha_cur * sample_cur .color +
|
||||
alpha_next * sample_next.color;
|
||||
out.color.a = 1.0;
|
||||
|
||||
#else ifdef FADE_WHITE
|
||||
out.color =
|
||||
alpha_prev * sample_prev.color +
|
||||
alpha_cur * sample_cur .color +
|
||||
alpha_next * sample_next.color;
|
||||
out.color = mix(
|
||||
out.color,
|
||||
vec4(1.0, 1.0, 1.0, 1.0),
|
||||
uniforms.strength * max(4.0 * alpha_cur * alpha_prev, 4.0 * alpha_cur * alpha_next)
|
||||
);
|
||||
out.color.a = 1.0;
|
||||
|
||||
#else ifdef FADE_IN
|
||||
let contained_prev = sample_prev.uvs.x >= 0.0 && sample_prev.uvs.x <= 1.0 && sample_prev.uvs.y >= 0.0 && sample_prev.uvs.y <= 1.0;
|
||||
let contained_cur = sample_cur .uvs.x >= 0.0 && sample_cur .uvs.x <= 1.0 && sample_cur .uvs.y >= 0.0 && sample_cur .uvs.y <= 1.0;
|
||||
let contained_next = sample_next.uvs.x >= 0.0 && sample_next.uvs.x <= 1.0 && sample_next.uvs.y >= 0.0 && sample_next.uvs.y <= 1.0;
|
||||
out.color =
|
||||
alpha_prev * sample_prev.color * f32(contained_prev) +
|
||||
alpha_cur * sample_cur .color * f32(contained_cur ) +
|
||||
alpha_next * sample_next.color * f32(contained_next) ;
|
||||
out.color.a = f32(contained_prev || contained_cur || contained_next);
|
||||
#endif
|
||||
|
||||
return out;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
//! Stage Input/Output
|
||||
|
||||
// Vertex input
|
||||
struct VertexInput {
|
||||
@location(0)
|
||||
pos: vec2<f32>,
|
||||
|
||||
@location(1)
|
||||
uvs: vec2<f32>,
|
||||
};
|
||||
|
||||
// Vertex output / Frag Input
|
||||
struct VertexOutput {
|
||||
@builtin(position)
|
||||
pos: vec4<f32>,
|
||||
|
||||
@location(0)
|
||||
uvs: vec2<f32>,
|
||||
};
|
||||
|
||||
// Frag output
|
||||
struct FragOutput {
|
||||
@location(0)
|
||||
color: vec4<f32>,
|
||||
};
|
||||
@ -1,30 +0,0 @@
|
||||
//! Uniforms
|
||||
|
||||
/// Uniforms for each image
|
||||
struct ImageUniforms {
|
||||
image_ratio: vec2<f32>,
|
||||
swap_dir: u32,
|
||||
}
|
||||
|
||||
/// Uniforms
|
||||
struct Uniforms {
|
||||
pos_matrix: mat4x4<f32>,
|
||||
prev: ImageUniforms,
|
||||
cur: ImageUniforms,
|
||||
next: ImageUniforms,
|
||||
fade_duration: f32,
|
||||
progress: f32,
|
||||
|
||||
// TODO: Reduce this repetition
|
||||
#ifdef FADE_WHITE
|
||||
strength: f32,
|
||||
#else ifdef FADE_OUT
|
||||
strength: f32,
|
||||
#else ifdef FADE_IN
|
||||
strength: f32,
|
||||
#endif
|
||||
};
|
||||
|
||||
// Uniforms
|
||||
@group(0) @binding(0)
|
||||
var<uniform> uniforms: Uniforms;
|
||||
@ -1,15 +0,0 @@
|
||||
//! Vertex shader
|
||||
|
||||
// Imports
|
||||
#import fade::stage_io::{VertexInput, VertexOutput}
|
||||
#import fade::uniforms::uniforms
|
||||
|
||||
// Vertex entry
|
||||
fn main(in: VertexInput) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
|
||||
out.pos = uniforms.pos_matrix * vec4<f32>(in.pos, 0.0, 1.0);
|
||||
out.uvs = in.uvs;
|
||||
|
||||
return out;
|
||||
}
|
||||
@ -2,14 +2,17 @@
|
||||
|
||||
// Imports
|
||||
use {
|
||||
crate::metrics::{
|
||||
FrameTimes,
|
||||
RenderPanelFrameTime,
|
||||
RenderPanelGeometryFadeFrameTime,
|
||||
RenderPanelGeometryFrameTime,
|
||||
RenderPanelGeometryNoneFrameTime,
|
||||
RenderPanelGeometrySlideFrameTime,
|
||||
RenderPanelsFrameTime,
|
||||
crate::{
|
||||
metrics::{
|
||||
FrameTimes,
|
||||
RenderPanelFrameTime,
|
||||
RenderPanelGeometryFadeImageFrameTime,
|
||||
RenderPanelGeometryFrameTime,
|
||||
RenderPanelGeometryNoneFrameTime,
|
||||
RenderPanelGeometrySlideFrameTime,
|
||||
RenderPanelsFrameTime,
|
||||
},
|
||||
panel::state::fade::PanelFadeImageSlot,
|
||||
},
|
||||
core::{iter, time::Duration},
|
||||
itertools::Itertools,
|
||||
@ -27,7 +30,10 @@ pub fn draw(ui: &mut egui::Ui, render_frame_times: &mut FrameTimes<RenderPanelsF
|
||||
panels: HashMap<usize, DurationPanelIdxTree>,
|
||||
}
|
||||
struct DurationPanelIdxTree {
|
||||
geometries: HashSet<usize>,
|
||||
geometries: HashMap<usize, DurationPanelGeometryIdxTree>,
|
||||
}
|
||||
struct DurationPanelGeometryIdxTree {
|
||||
images: HashSet<PanelFadeImageSlot>,
|
||||
}
|
||||
let duration_idxs_tree = DurationIdxTree {
|
||||
panels: render_frame_times
|
||||
@ -35,7 +41,23 @@ pub fn draw(ui: &mut egui::Ui, render_frame_times: &mut FrameTimes<RenderPanelsF
|
||||
.flat_map(|frame_time| {
|
||||
frame_time.panels.iter().map(|(&panel_idx, panel)| {
|
||||
let panel = DurationPanelIdxTree {
|
||||
geometries: panel.geometries.keys().copied().collect(),
|
||||
geometries: panel
|
||||
.geometries
|
||||
.iter()
|
||||
.map(|(&geometry_idx, geometry)| {
|
||||
let geometry = DurationPanelGeometryIdxTree {
|
||||
#[expect(clippy::match_same_arms, reason = "They won't be in the future")]
|
||||
images:
|
||||
match geometry {
|
||||
RenderPanelGeometryFrameTime::None(_) => HashSet::new(),
|
||||
RenderPanelGeometryFrameTime::Fade(images) =>
|
||||
images.images.iter().map(|(&image_slot, _image)| image_slot).collect(),
|
||||
RenderPanelGeometryFrameTime::Slide(_) => HashSet::new(),
|
||||
},
|
||||
};
|
||||
(geometry_idx, geometry)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
(panel_idx, panel)
|
||||
})
|
||||
@ -51,7 +73,7 @@ pub fn draw(ui: &mut egui::Ui, render_frame_times: &mut FrameTimes<RenderPanelsF
|
||||
iter::chain(
|
||||
// Panel specific indices
|
||||
[DurationPanelIdx::UpdatePanel, DurationPanelIdx::CreateRenderPipeline],
|
||||
panel.geometries.into_iter().flat_map(|geometry_idx| {
|
||||
panel.geometries.into_iter().flat_map(|(geometry_idx, geometry)| {
|
||||
// Panel & geometry specific indices
|
||||
iter_chain!(
|
||||
[
|
||||
@ -59,11 +81,13 @@ pub fn draw(ui: &mut egui::Ui, render_frame_times: &mut FrameTimes<RenderPanelsF
|
||||
DurationPanelGeometryNoneIdx::Draw,
|
||||
]
|
||||
.map(move |inner| DurationPanelGeometryIdx::None { inner }),
|
||||
[
|
||||
DurationPanelGeometryFadeIdx::WriteUniforms,
|
||||
DurationPanelGeometryFadeIdx::Draw,
|
||||
]
|
||||
.map(move |inner| DurationPanelGeometryIdx::Fade { inner }),
|
||||
geometry.images.into_iter().flat_map(|image_slot| {
|
||||
[
|
||||
DurationPanelGeometryFadeIdx::WriteUniforms,
|
||||
DurationPanelGeometryFadeIdx::Draw,
|
||||
]
|
||||
.map(move |inner| DurationPanelGeometryIdx::Fade { image_slot, inner })
|
||||
}),
|
||||
[
|
||||
DurationPanelGeometrySlideIdx::WriteUniforms,
|
||||
DurationPanelGeometrySlideIdx::Draw,
|
||||
@ -152,16 +176,23 @@ impl DurationPanelIdx {
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
|
||||
enum DurationPanelGeometryIdx {
|
||||
None { inner: DurationPanelGeometryNoneIdx },
|
||||
Fade { inner: DurationPanelGeometryFadeIdx },
|
||||
Slide { inner: DurationPanelGeometrySlideIdx },
|
||||
None {
|
||||
inner: DurationPanelGeometryNoneIdx,
|
||||
},
|
||||
Fade {
|
||||
image_slot: PanelFadeImageSlot,
|
||||
inner: DurationPanelGeometryFadeIdx,
|
||||
},
|
||||
Slide {
|
||||
inner: DurationPanelGeometrySlideIdx,
|
||||
},
|
||||
}
|
||||
|
||||
impl DurationPanelGeometryIdx {
|
||||
pub fn name(self, panel_idx: usize, geometry_idx: usize) -> String {
|
||||
match self {
|
||||
Self::None { inner } => inner.name(panel_idx, geometry_idx),
|
||||
Self::Fade { inner } => inner.name(panel_idx, geometry_idx),
|
||||
Self::Fade { image_slot, inner } => inner.name(panel_idx, geometry_idx, image_slot),
|
||||
Self::Slide { inner } => inner.name(panel_idx, geometry_idx),
|
||||
}
|
||||
}
|
||||
@ -169,7 +200,10 @@ impl DurationPanelGeometryIdx {
|
||||
pub fn duration(self, frame_time: &RenderPanelGeometryFrameTime) -> Option<Duration> {
|
||||
match (self, frame_time) {
|
||||
(Self::None { inner }, RenderPanelGeometryFrameTime::None(frame_time)) => inner.duration(frame_time),
|
||||
(Self::Fade { inner }, RenderPanelGeometryFrameTime::Fade(frame_time)) => inner.duration(frame_time),
|
||||
(Self::Fade { image_slot, inner }, RenderPanelGeometryFrameTime::Fade(frame_time)) => frame_time
|
||||
.images
|
||||
.get(&image_slot)
|
||||
.and_then(|image| inner.duration(image)),
|
||||
(Self::Slide { inner }, RenderPanelGeometryFrameTime::Slide(frame_time)) => inner.duration(frame_time),
|
||||
_ => None,
|
||||
}
|
||||
@ -206,15 +240,17 @@ enum DurationPanelGeometryFadeIdx {
|
||||
}
|
||||
|
||||
impl DurationPanelGeometryFadeIdx {
|
||||
pub fn name(self, panel_idx: usize, geometry_idx: usize) -> String {
|
||||
pub fn name(self, panel_idx: usize, geometry_idx: usize, image_slot: PanelFadeImageSlot) -> String {
|
||||
match self {
|
||||
Self::WriteUniforms =>
|
||||
format!("[Panel${panel_idx}] [Geometry${geometry_idx}] [Shader$Fade] Write uniforms"),
|
||||
Self::Draw => format!("[Panel${panel_idx}] [Geometry${geometry_idx}] [Shader$Fade] Draw"),
|
||||
Self::WriteUniforms => format!(
|
||||
"[Panel${panel_idx}] [Geometry${geometry_idx}] [Shader$Fade] [Image${image_slot:?}] Write uniforms"
|
||||
),
|
||||
Self::Draw =>
|
||||
format!("[Panel${panel_idx}] [Geometry${geometry_idx}] [Shader$Fade] [Image${image_slot:?}] Draw"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn duration(self, frame_time: &RenderPanelGeometryFadeFrameTime) -> Option<Duration> {
|
||||
pub fn duration(self, frame_time: &RenderPanelGeometryFadeImageFrameTime) -> Option<Duration> {
|
||||
match self {
|
||||
Self::WriteUniforms => Some(frame_time.write_uniforms),
|
||||
Self::Draw => Some(frame_time.draw),
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
// Imports
|
||||
use {
|
||||
crate::panel::state::fade::PanelFadeImageSlot,
|
||||
core::{ops::DerefMut, time::Duration},
|
||||
std::collections::{HashMap, VecDeque},
|
||||
tokio::sync::{Mutex, MutexGuard},
|
||||
@ -174,6 +175,12 @@ pub struct RenderPanelGeometryNoneFrameTime {
|
||||
/// Render panel geometry fade frame time.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RenderPanelGeometryFadeFrameTime {
|
||||
pub images: HashMap<PanelFadeImageSlot, RenderPanelGeometryFadeImageFrameTime>,
|
||||
}
|
||||
|
||||
/// Render panel geometry fade image frame time.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RenderPanelGeometryFadeImageFrameTime {
|
||||
pub write_uniforms: Duration,
|
||||
pub draw: Duration,
|
||||
}
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
//! Panel geometry
|
||||
|
||||
// Imports
|
||||
use {std::collections::HashMap, tokio::sync::OnceCell, winit::window::WindowId};
|
||||
use {
|
||||
crate::panel::state::fade::PanelFadeImageSlot,
|
||||
std::collections::HashMap,
|
||||
tokio::sync::OnceCell,
|
||||
winit::window::WindowId,
|
||||
};
|
||||
|
||||
/// Panel geometry
|
||||
#[derive(Debug)]
|
||||
@ -14,7 +19,7 @@ pub struct PanelGeometry {
|
||||
#[derive(Default, Debug)]
|
||||
pub struct PanelGeometryUniforms {
|
||||
pub none: OnceCell<PanelGeometryNoneUniforms>,
|
||||
pub fade: OnceCell<PanelGeometryFadeUniforms>,
|
||||
pub fade: PanelGeometryFadeUniforms,
|
||||
pub slide: OnceCell<PanelGeometrySlideUniforms>,
|
||||
}
|
||||
|
||||
@ -29,8 +34,15 @@ pub struct PanelGeometryNoneUniforms {
|
||||
}
|
||||
|
||||
/// Panel geometry fade uniforms
|
||||
#[derive(Debug)]
|
||||
#[derive(Default, Debug)]
|
||||
pub struct PanelGeometryFadeUniforms {
|
||||
/// Images
|
||||
pub images: HashMap<PanelFadeImageSlot, PanelGeometryFadeImageUniforms>,
|
||||
}
|
||||
|
||||
/// Panel geometry fade image uniforms
|
||||
#[derive(Debug)]
|
||||
pub struct PanelGeometryFadeImageUniforms {
|
||||
/// Buffer
|
||||
pub buffer: wgpu::Buffer,
|
||||
|
||||
|
||||
@ -9,17 +9,16 @@ pub use self::{uniform::MAX_UNIFORM_SIZE, vertex::PanelVertex};
|
||||
|
||||
// Imports
|
||||
use {
|
||||
self::uniform::PanelFadeImageUniforms,
|
||||
super::{
|
||||
PanelState,
|
||||
Panels,
|
||||
geometry::{PanelGeometryFadeUniforms, PanelGeometryNoneUniforms, PanelGeometrySlideUniforms},
|
||||
state::fade::PanelFadeImagesShared,
|
||||
geometry::{PanelGeometryFadeImageUniforms, PanelGeometryNoneUniforms, PanelGeometrySlideUniforms},
|
||||
state::fade::{PanelFadeImagesShared, images::PanelFadeImageSlot},
|
||||
},
|
||||
crate::{
|
||||
display::DisplayGeometry,
|
||||
metrics::{self, Metrics},
|
||||
panel::{PanelGeometry, state::fade::PanelFadeImage},
|
||||
panel::PanelGeometry,
|
||||
time,
|
||||
},
|
||||
app_error::Context,
|
||||
@ -51,6 +50,7 @@ pub struct PanelsRendererShared {
|
||||
/// Index buffer
|
||||
indices: wgpu::Buffer,
|
||||
|
||||
// TODO: Move these to the respective shader shared types
|
||||
/// Uniforms none bind group layout
|
||||
none_uniforms_bind_group_layout: wgpu::BindGroupLayout,
|
||||
|
||||
@ -357,91 +357,111 @@ impl PanelsRenderer {
|
||||
})
|
||||
},
|
||||
PanelState::Fade(panel_state) => {
|
||||
let geometry_uniforms = geometry_uniforms
|
||||
.fade
|
||||
.get_or_init(async || {
|
||||
self::create_geometry_fade_uniforms(wgpu, &shared.fade_uniforms_bind_group_layout)
|
||||
})
|
||||
.await;
|
||||
let p = panel_state.progress_norm();
|
||||
let f = panel_state.fade_duration_norm();
|
||||
|
||||
let image_uniforms = |image: Option<&PanelFadeImage>| {
|
||||
let (size, swap_dir) = match image {
|
||||
None => (Vector2::new(0, 0), false),
|
||||
Some(image) => {
|
||||
let texture = image.texture_view.texture();
|
||||
let size = Vector2::new(texture.width(), texture.height());
|
||||
(size, image.swap_dir)
|
||||
},
|
||||
// Full duration an image is on screen (including the fades)
|
||||
let d = 1.0 + 2.0 * f;
|
||||
|
||||
let mut image_metrics = HashMap::new();
|
||||
for (panel_image_slot, panel_image) in panel_state.images().iter() {
|
||||
let geometry_uniforms =
|
||||
geometry_uniforms
|
||||
.fade
|
||||
.images
|
||||
.entry(panel_image_slot)
|
||||
.or_insert_with(|| {
|
||||
self::create_geometry_fade_image_uniforms(wgpu, &shared.fade_uniforms_bind_group_layout)
|
||||
});
|
||||
|
||||
let progress = match panel_image_slot {
|
||||
PanelFadeImageSlot::Prev => 1.0 - f32::max((f - p) / d, 0.0),
|
||||
PanelFadeImageSlot::Cur => (p + f) / d,
|
||||
PanelFadeImageSlot::Next => f32::max((p - 1.0 + f) / d, 0.0),
|
||||
};
|
||||
let progress = match panel_image.swap_dir {
|
||||
true => 1.0 - progress,
|
||||
false => progress,
|
||||
};
|
||||
|
||||
let ratio = display_geometry.image_ratio(size);
|
||||
PanelFadeImageUniforms::new(ratio, swap_dir)
|
||||
};
|
||||
let alpha_prev = 0.5 * f32::clamp(1.0 - p / f, 0.0, 1.0);
|
||||
let alpha_next = 0.5 * f32::clamp(1.0 - (1.0 - p) / f, 0.0, 1.0);
|
||||
let alpha_cur = 1.0 - f32::max(alpha_prev, alpha_next);
|
||||
let alpha = match panel_image_slot {
|
||||
PanelFadeImageSlot::Prev => alpha_prev,
|
||||
PanelFadeImageSlot::Cur => alpha_cur,
|
||||
PanelFadeImageSlot::Next => alpha_next,
|
||||
};
|
||||
|
||||
let prev = image_uniforms(panel_state.images().prev.as_ref());
|
||||
let cur = image_uniforms(panel_state.images().cur.as_ref());
|
||||
let next = image_uniforms(panel_state.images().next.as_ref());
|
||||
// If the alpha is 0, we can skip this image
|
||||
// TODO: If alpha of a previous layer is 1, should we also skip it?
|
||||
// Right now that's fine, since with alpha 1, we always cover the
|
||||
// whole screen, but that's not guaranteed in the future.
|
||||
if alpha == 0.0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let fade_duration = panel_state.fade_duration_norm();
|
||||
let progress = panel_state.progress_norm();
|
||||
#[time(write_uniforms)]
|
||||
let () = match panel_state.shader() {
|
||||
PanelFadeShader::Basic => Self::write_uniforms(wgpu, &geometry_uniforms.buffer, uniform::Fade {
|
||||
pos_matrix,
|
||||
prev,
|
||||
cur,
|
||||
next,
|
||||
fade_duration,
|
||||
progress,
|
||||
_unused: [0; 2],
|
||||
}),
|
||||
PanelFadeShader::White { strength } =>
|
||||
Self::write_uniforms(wgpu, &geometry_uniforms.buffer, uniform::FadeWhite {
|
||||
pos_matrix,
|
||||
prev,
|
||||
cur,
|
||||
next,
|
||||
fade_duration,
|
||||
progress,
|
||||
strength,
|
||||
_unused: 0,
|
||||
}),
|
||||
PanelFadeShader::Out { strength } =>
|
||||
Self::write_uniforms(wgpu, &geometry_uniforms.buffer, uniform::FadeOut {
|
||||
pos_matrix,
|
||||
prev,
|
||||
cur,
|
||||
next,
|
||||
fade_duration,
|
||||
progress,
|
||||
strength,
|
||||
_unused: 0,
|
||||
}),
|
||||
PanelFadeShader::In { strength } =>
|
||||
Self::write_uniforms(wgpu, &geometry_uniforms.buffer, uniform::FadeIn {
|
||||
pos_matrix,
|
||||
prev,
|
||||
cur,
|
||||
next,
|
||||
fade_duration,
|
||||
progress,
|
||||
strength,
|
||||
_unused: 0,
|
||||
}),
|
||||
};
|
||||
// Calculate the position matrix for the panel
|
||||
let image_size = panel_image.texture_view.texture().size();
|
||||
let image_size = Vector2::new(image_size.width, image_size.height);
|
||||
let image_ratio = display_geometry.image_ratio(image_size);
|
||||
|
||||
// Bind the geometry uniforms
|
||||
render_pass.set_bind_group(0, &geometry_uniforms.bind_group, &[]);
|
||||
#[time(write_uniforms)]
|
||||
let () = match panel_state.shader() {
|
||||
PanelFadeShader::Basic =>
|
||||
Self::write_uniforms(wgpu, &geometry_uniforms.buffer, uniform::FadeBasic {
|
||||
pos_matrix,
|
||||
image_ratio: uniform::Vec2(image_ratio.into()),
|
||||
progress,
|
||||
alpha,
|
||||
}),
|
||||
PanelFadeShader::White { strength } =>
|
||||
Self::write_uniforms(wgpu, &geometry_uniforms.buffer, uniform::FadeWhite {
|
||||
pos_matrix,
|
||||
image_ratio: uniform::Vec2(image_ratio.into()),
|
||||
progress,
|
||||
alpha,
|
||||
mix_strength: strength * 4.0 * f32::max(alpha_cur * alpha_prev, alpha_cur * alpha_next),
|
||||
_unused: [0; _],
|
||||
}),
|
||||
PanelFadeShader::Out { strength } =>
|
||||
Self::write_uniforms(wgpu, &geometry_uniforms.buffer, uniform::FadeOut {
|
||||
pos_matrix,
|
||||
image_ratio: uniform::Vec2(image_ratio.into()),
|
||||
progress,
|
||||
alpha,
|
||||
strength,
|
||||
_unused: [0; _],
|
||||
}),
|
||||
PanelFadeShader::In { strength } =>
|
||||
Self::write_uniforms(wgpu, &geometry_uniforms.buffer, uniform::FadeIn {
|
||||
pos_matrix,
|
||||
image_ratio: uniform::Vec2(image_ratio.into()),
|
||||
progress,
|
||||
alpha,
|
||||
strength,
|
||||
_unused: [0; _],
|
||||
}),
|
||||
};
|
||||
|
||||
// Bind the image uniforms
|
||||
render_pass.set_bind_group(1, panel_state.images().image_bind_group(wgpu, &shared.fade).await, &[]);
|
||||
// Bind the geometry uniforms
|
||||
render_pass.set_bind_group(0, &geometry_uniforms.bind_group, &[]);
|
||||
|
||||
#[time(draw)]
|
||||
render_pass.draw_indexed(0..6, 0, 0..1);
|
||||
// Bind the image uniforms
|
||||
let sampler = panel_state.images().image_sampler(wgpu).await;
|
||||
render_pass.set_bind_group(1, panel_image.bind_group(wgpu, sampler, &shared.fade).await, &[]);
|
||||
|
||||
#[time(draw)]
|
||||
render_pass.draw_indexed(0..6, 0, 0..1);
|
||||
|
||||
_ = image_metrics.insert(panel_image_slot, metrics::RenderPanelGeometryFadeImageFrameTime {
|
||||
write_uniforms,
|
||||
draw,
|
||||
});
|
||||
}
|
||||
|
||||
metrics::RenderPanelGeometryFrameTime::Fade(metrics::RenderPanelGeometryFadeFrameTime {
|
||||
write_uniforms,
|
||||
draw,
|
||||
images: image_metrics,
|
||||
})
|
||||
},
|
||||
PanelState::Slide(_panel_state) => {
|
||||
@ -503,8 +523,8 @@ fn create_geometry_none_uniforms(wgpu: &Wgpu, layout: &wgpu::BindGroupLayout) ->
|
||||
PanelGeometryNoneUniforms { buffer, bind_group }
|
||||
}
|
||||
|
||||
/// Creates the panel fade geometry uniforms
|
||||
fn create_geometry_fade_uniforms(wgpu: &Wgpu, layout: &wgpu::BindGroupLayout) -> PanelGeometryFadeUniforms {
|
||||
/// Creates the panel fade image geometry uniforms
|
||||
fn create_geometry_fade_image_uniforms(wgpu: &Wgpu, layout: &wgpu::BindGroupLayout) -> PanelGeometryFadeImageUniforms {
|
||||
// Create the uniforms
|
||||
let buffer_descriptor = wgpu::BufferDescriptor {
|
||||
label: Some("zsw-panel-fade-geometry-uniforms-buffer"),
|
||||
@ -525,7 +545,7 @@ fn create_geometry_fade_uniforms(wgpu: &Wgpu, layout: &wgpu::BindGroupLayout) ->
|
||||
};
|
||||
let bind_group = wgpu.device.create_bind_group(&bind_group_descriptor);
|
||||
|
||||
PanelGeometryFadeUniforms { buffer, bind_group }
|
||||
PanelGeometryFadeImageUniforms { buffer, bind_group }
|
||||
}
|
||||
|
||||
/// Creates the panel slide geometry uniforms
|
||||
|
||||
@ -21,26 +21,6 @@ pub struct Vec4(pub [f32; 4]);
|
||||
#[repr(C, align(16))]
|
||||
pub struct Matrix4x4(pub [[f32; 4]; 4]);
|
||||
|
||||
/// Panel fade image uniforms
|
||||
#[derive(PartialEq, Clone, Copy, Default, Debug)]
|
||||
#[derive(Zeroable, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct PanelFadeImageUniforms {
|
||||
ratio: Vec2,
|
||||
swap_dir: u32,
|
||||
_unused: u32,
|
||||
}
|
||||
|
||||
impl PanelFadeImageUniforms {
|
||||
pub fn new(ratio: impl Into<[f32; 2]>, swap_dir: bool) -> Self {
|
||||
Self {
|
||||
ratio: Vec2(ratio.into()),
|
||||
swap_dir: swap_dir.into(),
|
||||
_unused: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// None
|
||||
#[derive(PartialEq, Clone, Copy, Default, Debug)]
|
||||
#[derive(Zeroable, Pod)]
|
||||
@ -54,15 +34,11 @@ pub struct None {
|
||||
#[derive(PartialEq, Clone, Copy, Default, Debug)]
|
||||
#[derive(Zeroable, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct Fade {
|
||||
pub pos_matrix: Matrix4x4,
|
||||
pub prev: PanelFadeImageUniforms,
|
||||
pub cur: PanelFadeImageUniforms,
|
||||
pub next: PanelFadeImageUniforms,
|
||||
pub fade_duration: f32,
|
||||
pub progress: f32,
|
||||
|
||||
pub _unused: [u32; 2],
|
||||
pub struct FadeBasic {
|
||||
pub pos_matrix: Matrix4x4,
|
||||
pub image_ratio: Vec2,
|
||||
pub progress: f32,
|
||||
pub alpha: f32,
|
||||
}
|
||||
|
||||
/// Fade-white
|
||||
@ -70,15 +46,13 @@ pub struct Fade {
|
||||
#[derive(Zeroable, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct FadeWhite {
|
||||
pub pos_matrix: Matrix4x4,
|
||||
pub prev: PanelFadeImageUniforms,
|
||||
pub cur: PanelFadeImageUniforms,
|
||||
pub next: PanelFadeImageUniforms,
|
||||
pub fade_duration: f32,
|
||||
pub progress: f32,
|
||||
pub strength: f32,
|
||||
pub pos_matrix: Matrix4x4,
|
||||
pub image_ratio: Vec2,
|
||||
pub progress: f32,
|
||||
pub alpha: f32,
|
||||
pub mix_strength: f32,
|
||||
|
||||
pub _unused: u32,
|
||||
pub _unused: [u32; 3],
|
||||
}
|
||||
|
||||
/// Fade-out
|
||||
@ -86,15 +60,13 @@ pub struct FadeWhite {
|
||||
#[derive(Zeroable, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct FadeOut {
|
||||
pub pos_matrix: Matrix4x4,
|
||||
pub prev: PanelFadeImageUniforms,
|
||||
pub cur: PanelFadeImageUniforms,
|
||||
pub next: PanelFadeImageUniforms,
|
||||
pub fade_duration: f32,
|
||||
pub progress: f32,
|
||||
pub strength: f32,
|
||||
pub pos_matrix: Matrix4x4,
|
||||
pub image_ratio: Vec2,
|
||||
pub progress: f32,
|
||||
pub alpha: f32,
|
||||
pub strength: f32,
|
||||
|
||||
pub _unused: u32,
|
||||
pub _unused: [u32; 3],
|
||||
}
|
||||
|
||||
/// Fade-in
|
||||
@ -102,15 +74,13 @@ pub struct FadeOut {
|
||||
#[derive(Zeroable, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct FadeIn {
|
||||
pub pos_matrix: Matrix4x4,
|
||||
pub prev: PanelFadeImageUniforms,
|
||||
pub cur: PanelFadeImageUniforms,
|
||||
pub next: PanelFadeImageUniforms,
|
||||
pub fade_duration: f32,
|
||||
pub progress: f32,
|
||||
pub strength: f32,
|
||||
pub pos_matrix: Matrix4x4,
|
||||
pub image_ratio: Vec2,
|
||||
pub progress: f32,
|
||||
pub alpha: f32,
|
||||
pub strength: f32,
|
||||
|
||||
pub _unused: u32,
|
||||
pub _unused: [u32; 3],
|
||||
}
|
||||
|
||||
/// Slide
|
||||
@ -124,7 +94,7 @@ pub struct Slide {
|
||||
/// The maximum uniform size
|
||||
pub const MAX_UNIFORM_SIZE: usize = zsw_util::array_max(&[
|
||||
size_of::<None>(),
|
||||
size_of::<Fade>(),
|
||||
size_of::<FadeBasic>(),
|
||||
size_of::<FadeWhite>(),
|
||||
size_of::<FadeOut>(),
|
||||
size_of::<FadeIn>(),
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
pub mod images;
|
||||
|
||||
// Exports
|
||||
pub use self::images::{PanelFadeImage, PanelFadeImages, PanelFadeImagesShared};
|
||||
pub use self::images::{PanelFadeImage, PanelFadeImageSlot, PanelFadeImages, PanelFadeImagesShared};
|
||||
|
||||
// Imports
|
||||
use {
|
||||
|
||||
@ -43,9 +43,6 @@ pub struct PanelFadeImages {
|
||||
/// Image sampler
|
||||
pub image_sampler: OnceCell<wgpu::Sampler>,
|
||||
|
||||
/// Image bind group
|
||||
pub image_bind_group: OnceCell<wgpu::BindGroup>,
|
||||
|
||||
/// Next image
|
||||
pub next_image: Loadable<ImageLoadRes>,
|
||||
}
|
||||
@ -56,6 +53,9 @@ pub struct PanelFadeImage {
|
||||
/// Texture view
|
||||
pub texture_view: wgpu::TextureView,
|
||||
|
||||
/// Bind group
|
||||
pub bind_group: OnceCell<wgpu::BindGroup>,
|
||||
|
||||
/// Swap direction
|
||||
pub swap_dir: bool,
|
||||
|
||||
@ -63,20 +63,47 @@ pub struct PanelFadeImage {
|
||||
pub path: Arc<Path>,
|
||||
}
|
||||
|
||||
impl PanelFadeImage {
|
||||
/// Gets the bind group, or initializes it, if uninitialized
|
||||
pub async fn bind_group(
|
||||
&self,
|
||||
wgpu: &Wgpu,
|
||||
sampler: &wgpu::Sampler,
|
||||
shared: &PanelFadeImagesShared,
|
||||
) -> &wgpu::BindGroup {
|
||||
self.bind_group
|
||||
.get_or_init(async || {
|
||||
let layout = shared.image_bind_group_layout(wgpu).await;
|
||||
self::create_image_bind_group(wgpu, layout, &self.texture_view, sampler)
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl PanelFadeImages {
|
||||
/// Creates a new panel
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
prev: None,
|
||||
cur: None,
|
||||
next: None,
|
||||
image_sampler: OnceCell::new(),
|
||||
image_bind_group: OnceCell::new(),
|
||||
next_image: Loadable::new(),
|
||||
prev: None,
|
||||
cur: None,
|
||||
next: None,
|
||||
image_sampler: OnceCell::new(),
|
||||
next_image: Loadable::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over all images
|
||||
pub fn iter(&self) -> impl Iterator<Item = (PanelFadeImageSlot, &PanelFadeImage)> {
|
||||
[
|
||||
(PanelFadeImageSlot::Prev, &self.prev),
|
||||
(PanelFadeImageSlot::Cur, &self.cur),
|
||||
(PanelFadeImageSlot::Next, &self.next),
|
||||
]
|
||||
.into_iter()
|
||||
.filter_map(|(slot, img)| img.as_ref().map(|img| (slot, img)))
|
||||
}
|
||||
|
||||
/// Steps to the previous image, if any
|
||||
///
|
||||
/// If successful, starts loading any missing images
|
||||
@ -87,7 +114,6 @@ impl PanelFadeImages {
|
||||
mem::swap(&mut self.cur, &mut self.next);
|
||||
mem::swap(&mut self.prev, &mut self.cur);
|
||||
self.prev = None;
|
||||
self.image_bind_group = OnceCell::new();
|
||||
self.load_missing(playlist_player, wgpu);
|
||||
|
||||
Ok(())
|
||||
@ -107,7 +133,6 @@ impl PanelFadeImages {
|
||||
mem::swap(&mut self.prev, &mut self.cur);
|
||||
mem::swap(&mut self.cur, &mut self.next);
|
||||
self.next = None;
|
||||
self.image_bind_group = OnceCell::new();
|
||||
self.load_missing(playlist_player, wgpu);
|
||||
|
||||
Ok(())
|
||||
@ -120,19 +145,6 @@ impl PanelFadeImages {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Gets the image bind group, or initializes it, if uninitialized
|
||||
pub async fn image_bind_group(&self, wgpu: &Wgpu, shared: &PanelFadeImagesShared) -> &wgpu::BindGroup {
|
||||
self.image_bind_group
|
||||
.get_or_init(async || {
|
||||
let [prev, cur, next] = [&self.prev, &self.cur, &self.next]
|
||||
.map(|img| img.as_ref().map_or(&wgpu.empty_texture_view, |img| &img.texture_view));
|
||||
let image_sampler = self.image_sampler(wgpu).await;
|
||||
let layout = shared.image_bind_group_layout(wgpu).await;
|
||||
self::create_image_bind_group(wgpu, layout, prev, cur, next, image_sampler)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// Loads any missing images, prioritizing the current, then next, then previous.
|
||||
///
|
||||
/// Requests images if missing any.
|
||||
@ -164,9 +176,9 @@ impl PanelFadeImages {
|
||||
// Get which slot to load the image into
|
||||
let slot = {
|
||||
match res.playlist_pos {
|
||||
pos if Some(pos) == playlist_player.prev_pos() => Some(Slot::Prev),
|
||||
pos if pos == playlist_player.cur_pos() => Some(Slot::Cur),
|
||||
pos if pos == playlist_player.next_pos() => Some(Slot::Next),
|
||||
pos if Some(pos) == playlist_player.prev_pos() => Some(PanelFadeImageSlot::Prev),
|
||||
pos if pos == playlist_player.cur_pos() => Some(PanelFadeImageSlot::Cur),
|
||||
pos if pos == playlist_player.next_pos() => Some(PanelFadeImageSlot::Next),
|
||||
pos => {
|
||||
tracing::warn!(
|
||||
pos,
|
||||
@ -192,14 +204,14 @@ impl PanelFadeImages {
|
||||
texture_view,
|
||||
swap_dir: rand::random(),
|
||||
path: res.path,
|
||||
bind_group: OnceCell::new(),
|
||||
};
|
||||
|
||||
match slot {
|
||||
Slot::Prev => self.prev = Some(image),
|
||||
Slot::Cur => self.cur = Some(image),
|
||||
Slot::Next => self.next = Some(image),
|
||||
PanelFadeImageSlot::Prev => self.prev = Some(image),
|
||||
PanelFadeImageSlot::Cur => self.cur = Some(image),
|
||||
PanelFadeImageSlot::Next => self.next = Some(image),
|
||||
}
|
||||
self.image_bind_group = OnceCell::new();
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,8 +267,8 @@ impl PanelFadeImages {
|
||||
}
|
||||
|
||||
/// Image slot
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
enum Slot {
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
|
||||
pub enum PanelFadeImageSlot {
|
||||
Prev,
|
||||
Cur,
|
||||
Next,
|
||||
@ -310,26 +322,6 @@ fn create_bind_group_layout(wgpu: &Wgpu) -> wgpu::BindGroupLayout {
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
multisampled: false,
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
multisampled: false,
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 3,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
},
|
||||
@ -343,9 +335,7 @@ fn create_bind_group_layout(wgpu: &Wgpu) -> wgpu::BindGroupLayout {
|
||||
fn create_image_bind_group(
|
||||
wgpu: &Wgpu,
|
||||
bind_group_layout: &wgpu::BindGroupLayout,
|
||||
view_prev: &wgpu::TextureView,
|
||||
view_cur: &wgpu::TextureView,
|
||||
view_next: &wgpu::TextureView,
|
||||
view: &wgpu::TextureView,
|
||||
sampler: &wgpu::Sampler,
|
||||
) -> wgpu::BindGroup {
|
||||
let descriptor = wgpu::BindGroupDescriptor {
|
||||
@ -354,18 +344,10 @@ fn create_image_bind_group(
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::TextureView(view_prev),
|
||||
resource: wgpu::BindingResource::TextureView(view),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::TextureView(view_cur),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: wgpu::BindingResource::TextureView(view_next),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 3,
|
||||
resource: wgpu::BindingResource::Sampler(sampler),
|
||||
},
|
||||
],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user