wgpu: Stub out more blend modes

This commit is contained in:
Mike Welsh 2022-08-17 16:17:55 -07:00
parent 0861bc86eb
commit a6b70e60ea
1 changed files with 114 additions and 6 deletions

View File

@ -59,23 +59,131 @@ impl ShapePipeline {
} }
fn blend_mode_to_state(mode: BlendMode) -> Option<wgpu::BlendState> { fn blend_mode_to_state(mode: BlendMode) -> Option<wgpu::BlendState> {
// Use the GPU blend modes to roughly approximate Flash's blend modes.
// This should look reasonable for the most common cases, but full support requires
// rendering to an intermediate texture and custom shaders for the complex blend modes.
match mode { match mode {
BlendMode::Normal => Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), BlendMode::Normal => Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING),
BlendMode::Add => {
// TODO: Needs intermediate buffer.
BlendMode::Layer => Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING),
// dst * src
BlendMode::Multiply => Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::Dst,
dst_factor: wgpu::BlendFactor::Zero,
operation: wgpu::BlendOperation::Add,
},
alpha: wgpu::BlendComponent::OVER,
}),
// 1 - (1 - dst) * (1 - src)
// TODO: Needs shader. Rendererd as additive for now.
BlendMode::Screen => Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::One,
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Add,
},
alpha: wgpu::BlendComponent::OVER,
}),
// max(dst, src)
BlendMode::Lighten => Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::One,
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Max,
},
alpha: wgpu::BlendComponent::OVER,
}),
// min(dst, src)
BlendMode::Darken => Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::One,
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Min,
},
alpha: wgpu::BlendComponent::OVER,
}),
// abs(dst - src)
// TODO: Needs shader. Rendererd as subtract for now.
BlendMode::Difference => {
Some(wgpu::BlendState { Some(wgpu::BlendState {
// Add src and dst RGB values together // Add src and dst RGB values together
color: wgpu::BlendComponent { color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::One, src_factor: wgpu::BlendFactor::One,
dst_factor: wgpu::BlendFactor::One, dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Add, operation: wgpu::BlendOperation::ReverseSubtract,
}, },
alpha: wgpu::BlendComponent::OVER, alpha: wgpu::BlendComponent::OVER,
}) })
} }
_ => {
log::warn!("Webgpu backend does not yet support blend mode {:?}", mode); // dst + src
Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING) BlendMode::Add => Some(wgpu::BlendState {
} color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::One,
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Add,
},
alpha: wgpu::BlendComponent::OVER,
}),
// dst - src
BlendMode::Subtract => Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::One,
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::ReverseSubtract,
},
alpha: wgpu::BlendComponent::OVER,
}),
// 1 - dst
BlendMode::Invert => Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::Zero,
dst_factor: wgpu::BlendFactor::OneMinusDst,
operation: wgpu::BlendOperation::Add,
},
alpha: wgpu::BlendComponent::OVER,
}),
// TODO: Requires intermediate buffer.
// dst.alpha = src.alpha
// Parent display object needs to have Layer blend mode.
BlendMode::Alpha => Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING),
// TODO: Requires intermediate buffer.
// dst.alpha = 1 - src.alpha
// Parent display object needs to have Layer blend mode.
BlendMode::Erase => Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING),
// if src > .5 { 1 - (1 - dst) * (1 - src) } else { dst * src }
// TODO: Needs shader, rendered as multiply for now.
BlendMode::HardLight => Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::Dst,
dst_factor: wgpu::BlendFactor::Zero,
operation: wgpu::BlendOperation::Add,
},
alpha: wgpu::BlendComponent::OVER,
}),
// if dst > .5 { 1 - (1 - dst) * (1 - src) } else { dst * src }
// TODO: Needs shader, rendered as multiply for now.
BlendMode::Overlay => Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::Dst,
dst_factor: wgpu::BlendFactor::Zero,
operation: wgpu::BlendOperation::Add,
},
alpha: wgpu::BlendComponent::OVER,
}),
} }
} }