BlendMode

Enum BlendMode 

Source
pub enum BlendMode {
    Replace,
    Alpha,
    PremultipliedAlpha,
    Additive,
    Multiply,
    Custom(BlendState),
}
Expand description

Predefined blend modes for common use cases.

Use these to configure how source and destination colors are combined during rendering.

Variants§

§

Replace

No blending - source completely replaces destination.

§

Alpha

Standard alpha blending for transparent content.

Formula: src.rgb * src.a + dst.rgb * (1 - src.a)

Use for: Transparent UI over game content, sprites with transparency.

§

PremultipliedAlpha

Premultiplied alpha blending.

Formula: src.rgb + dst.rgb * (1 - src.a)

Use for: Blitting framebuffers with premultiplied alpha, compositing.

§

Additive

Additive blending - colors are added together.

Formula: src.rgb + dst.rgb

Use for: Glow effects, particles, light sources.

§

Multiply

Multiplicative blending.

Formula: src.rgb * dst.rgb

Use for: Shadows, color tinting.

§

Custom(BlendState)

Custom blend state for advanced use cases.

Implementations§

Source§

impl BlendMode

Source

pub fn to_blend_state(self) -> Option<BlendState>

Convert to wgpu BlendState.

Source

pub fn to_color_target_state(self, format: TextureFormat) -> ColorTargetState

Create a color target state with this blend mode.

Examples found in repository?
examples/renderer_api.rs (line 135)
29fn main() {
30    logging::init();
31
32    run_app(|ctx| {
33        let graphics_ctx = GraphicsContext::new_owned_sync_or_panic();
34        let renderer = Renderer::new(graphics_ctx.clone());
35
36        let window = ctx
37            .create_window(WindowDescriptor {
38                title: "Renderer API Example".to_string(),
39                size: Some(WinitPhysicalSize::new(800.0, 600.0)),
40                ..Default::default()
41            })
42            .expect("Failed to create window");
43
44        let window = RenderableWindow::new_with_descriptor(
45            window,
46            graphics_ctx.clone(),
47            WindowContextDescriptor {
48                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
49                ..Default::default()
50            },
51        ).expect("Failed to create renderable window");
52
53        let window_id = window.id();
54
55        // Create shader using Renderer API
56        let shader = renderer.create_shader(Some("Color Shader"), SHADER_SOURCE);
57
58        // Create texture using Renderer helper
59        let texture_data = create_gradient_texture();
60        let texture = renderer.create_texture_2d(
61            Some("Gradient Texture"),
62            256,
63            256,
64            wgpu::TextureFormat::Rgba8UnormSrgb,
65            wgpu::TextureUsages::TEXTURE_BINDING,
66            &texture_data,
67        );
68
69        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
70        let sampler = renderer.create_linear_sampler(Some("Linear Sampler"));
71
72        // Create bind group using Renderer API
73        let bind_group_layout = renderer.create_bind_group_layout(
74            Some("Texture Bind Group Layout"),
75            &[
76                wgpu::BindGroupLayoutEntry {
77                    binding: 0,
78                    visibility: wgpu::ShaderStages::FRAGMENT,
79                    ty: wgpu::BindingType::Texture {
80                        multisampled: false,
81                        view_dimension: wgpu::TextureViewDimension::D2,
82                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
83                    },
84                    count: None,
85                },
86                wgpu::BindGroupLayoutEntry {
87                    binding: 1,
88                    visibility: wgpu::ShaderStages::FRAGMENT,
89                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
90                    count: None,
91                },
92            ],
93        );
94
95        let bind_group = renderer.create_bind_group(
96            Some("Texture Bind Group"),
97            &bind_group_layout,
98            &[
99                wgpu::BindGroupEntry {
100                    binding: 0,
101                    resource: wgpu::BindingResource::TextureView(&texture_view),
102                },
103                wgpu::BindGroupEntry {
104                    binding: 1,
105                    resource: wgpu::BindingResource::Sampler(&sampler),
106                },
107            ],
108        );
109
110        let pipeline_layout = renderer.create_pipeline_layout(
111            Some("Render Pipeline Layout"),
112            &[&bind_group_layout],
113            &[],
114        );
115
116        // Create pipeline using Renderer API with BlendMode
117        let pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
118            label: Some("Render Pipeline"),
119            layout: Some(&pipeline_layout),
120            vertex: wgpu::VertexState {
121                module: &shader,
122                entry_point: Some("vs_main"),
123                buffers: &[wgpu::VertexBufferLayout {
124                    array_stride: 4 * 4,
125                    step_mode: wgpu::VertexStepMode::Vertex,
126                    attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
127                }],
128                compilation_options: wgpu::PipelineCompilationOptions::default(),
129            },
130            fragment: Some(wgpu::FragmentState {
131                module: &shader,
132                entry_point: Some("fs_main"),
133                // Use BlendMode for transparent rendering
134                targets: &[Some(
135                    BlendMode::Alpha.to_color_target_state(wgpu::TextureFormat::Rgba8UnormSrgb),
136                )],
137                compilation_options: wgpu::PipelineCompilationOptions::default(),
138            }),
139            primitive: wgpu::PrimitiveState {
140                topology: wgpu::PrimitiveTopology::TriangleList,
141                strip_index_format: None,
142                front_face: wgpu::FrontFace::Ccw,
143                cull_mode: Some(wgpu::Face::Back),
144                polygon_mode: wgpu::PolygonMode::Fill,
145                unclipped_depth: false,
146                conservative: false,
147            },
148            depth_stencil: None,
149            multisample: wgpu::MultisampleState {
150                count: 1,
151                mask: !0,
152                alpha_to_coverage_enabled: false,
153            },
154            multiview: None,
155            cache: None,
156        });
157
158        #[rustfmt::skip]
159        let vertices: &[f32] = &[
160            -0.8, -0.8,  0.0, 1.0,
161             0.8, -0.8,  1.0, 1.0,
162             0.8,  0.8,  1.0, 0.0,
163            -0.8, -0.8,  0.0, 1.0,
164             0.8,  0.8,  1.0, 0.0,
165            -0.8,  0.8,  0.0, 0.0,
166        ];
167
168        // Create vertex buffer using Renderer helper
169        let vertex_buffer = renderer.create_vertex_buffer(Some("Vertex Buffer"), vertices);
170
171        // Create offscreen framebuffer using the new Framebuffer abstraction
172        let offscreen_fb = Framebuffer::builder(400, 300)
173            .format(wgpu::TextureFormat::Rgba8UnormSrgb)
174            .label("Offscreen FB")
175            .build(&graphics_ctx);
176
177        // Create blit shader and pipeline for rendering framebuffer to surface
178        let blit_shader = renderer.create_shader(Some("Blit Shader"), BLIT_SHADER_SOURCE);
179
180        let blit_bind_group_layout = renderer.create_bind_group_layout(
181            Some("Blit Bind Group Layout"),
182            &[
183                wgpu::BindGroupLayoutEntry {
184                    binding: 0,
185                    visibility: wgpu::ShaderStages::FRAGMENT,
186                    ty: wgpu::BindingType::Texture {
187                        multisampled: false,
188                        view_dimension: wgpu::TextureViewDimension::D2,
189                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
190                    },
191                    count: None,
192                },
193                wgpu::BindGroupLayoutEntry {
194                    binding: 1,
195                    visibility: wgpu::ShaderStages::FRAGMENT,
196                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
197                    count: None,
198                },
199            ],
200        );
201
202        let blit_bind_group = renderer.create_bind_group(
203            Some("Blit Bind Group"),
204            &blit_bind_group_layout,
205            &[
206                wgpu::BindGroupEntry {
207                    binding: 0,
208                    resource: wgpu::BindingResource::TextureView(offscreen_fb.color_view()),
209                },
210                wgpu::BindGroupEntry {
211                    binding: 1,
212                    resource: wgpu::BindingResource::Sampler(&sampler),
213                },
214            ],
215        );
216
217        let blit_pipeline_layout = renderer.create_pipeline_layout(
218            Some("Blit Pipeline Layout"),
219            &[&blit_bind_group_layout],
220            &[],
221        );
222
223        let blit_pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
224            label: Some("Blit Pipeline"),
225            layout: Some(&blit_pipeline_layout),
226            vertex: wgpu::VertexState {
227                module: &blit_shader,
228                entry_point: Some("vs_main"),
229                buffers: &[],
230                compilation_options: wgpu::PipelineCompilationOptions::default(),
231            },
232            fragment: Some(wgpu::FragmentState {
233                module: &blit_shader,
234                entry_point: Some("fs_main"),
235                // Use PremultipliedAlpha for framebuffer blitting
236                targets: &[Some(
237                    BlendMode::PremultipliedAlpha
238                        .to_color_target_state(wgpu::TextureFormat::Bgra8UnormSrgb),
239                )],
240                compilation_options: wgpu::PipelineCompilationOptions::default(),
241            }),
242            primitive: wgpu::PrimitiveState {
243                topology: wgpu::PrimitiveTopology::TriangleList,
244                ..Default::default()
245            },
246            depth_stencil: None,
247            multisample: wgpu::MultisampleState::default(),
248            multiview: None,
249            cache: None,
250        });
251
252        tracing::info!("Renderer initialized successfully");
253        tracing::info!("Device: {:?}", renderer.context().info());
254
255        Box::new(RendererApp {
256            context: graphics_ctx,
257            renderer,
258            window,
259            window_id,
260            pipeline,
261            bind_group,
262            vertex_buffer,
263            offscreen_fb,
264            blit_pipeline,
265            blit_bind_group,
266            time: 0.0,
267        })
268    });
269}

Trait Implementations§

Source§

impl Clone for BlendMode

Source§

fn clone(&self) -> BlendMode

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BlendMode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for BlendMode

Source§

fn default() -> BlendMode

Returns the “default value” for a type. Read more
Source§

impl From<BlendMode> for Option<BlendState>

Source§

fn from(mode: BlendMode) -> Self

Converts to this type from the input type.
Source§

impl From<BlendState> for BlendMode

Source§

fn from(state: BlendState) -> Self

Converts to this type from the input type.
Source§

impl Hash for BlendMode

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for BlendMode

Source§

fn eq(&self, other: &BlendMode) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for BlendMode

Source§

impl Eq for BlendMode

Source§

impl StructuralPartialEq for BlendMode

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,