Implement the remaining Porter-Duff compositing operators
This commit is contained in:
parent
e7de50eb67
commit
1deb53fa9c
|
@ -12,11 +12,11 @@
|
||||||
|
|
||||||
use pathfinder_color::ColorU;
|
use pathfinder_color::ColorU;
|
||||||
use pathfinder_content::dash::OutlineDash;
|
use pathfinder_content::dash::OutlineDash;
|
||||||
use pathfinder_content::effects::BlendMode;
|
use pathfinder_content::effects::{BlendMode, CompositeOp, Effects, Filter};
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_content::gradient::Gradient;
|
use pathfinder_content::gradient::Gradient;
|
||||||
use pathfinder_content::outline::{ArcDirection, Contour, Outline};
|
use pathfinder_content::outline::{ArcDirection, Contour, Outline};
|
||||||
use pathfinder_content::pattern::Pattern;
|
use pathfinder_content::pattern::{Pattern, RenderTargetId};
|
||||||
use pathfinder_content::stroke::{LineCap, LineJoin as StrokeLineJoin};
|
use pathfinder_content::stroke::{LineCap, LineJoin as StrokeLineJoin};
|
||||||
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
||||||
use pathfinder_geometry::line_segment::LineSegment2F;
|
use pathfinder_geometry::line_segment::LineSegment2F;
|
||||||
|
@ -24,7 +24,7 @@ use pathfinder_geometry::vector::Vector2F;
|
||||||
use pathfinder_geometry::rect::RectF;
|
use pathfinder_geometry::rect::RectF;
|
||||||
use pathfinder_geometry::transform2d::Transform2F;
|
use pathfinder_geometry::transform2d::Transform2F;
|
||||||
use pathfinder_renderer::paint::{Paint, PaintId};
|
use pathfinder_renderer::paint::{Paint, PaintId};
|
||||||
use pathfinder_renderer::scene::{ClipPath, ClipPathId, DrawPath, Scene};
|
use pathfinder_renderer::scene::{ClipPath, ClipPathId, DrawPath, RenderTarget, Scene};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
@ -233,8 +233,11 @@ impl CanvasRenderingContext2D {
|
||||||
fn push_path(&mut self, outline: Outline, paint_id: PaintId, fill_rule: FillRule) {
|
fn push_path(&mut self, outline: Outline, paint_id: PaintId, fill_rule: FillRule) {
|
||||||
let clip_path = self.current_state.clip_path;
|
let clip_path = self.current_state.clip_path;
|
||||||
let blend_mode = self.current_state.global_composite_operation.to_blend_mode();
|
let blend_mode = self.current_state.global_composite_operation.to_blend_mode();
|
||||||
|
let composite_op = self.current_state.global_composite_operation.to_composite_op();
|
||||||
|
|
||||||
if !self.current_state.shadow_paint.is_fully_transparent() {
|
if !self.current_state.shadow_paint.is_fully_transparent() {
|
||||||
|
let render_target_id = self.push_render_target_if_needed(composite_op);
|
||||||
|
|
||||||
let paint = self.current_state.resolve_paint(&self.current_state.shadow_paint);
|
let paint = self.current_state.resolve_paint(&self.current_state.shadow_paint);
|
||||||
let paint_id = self.scene.push_paint(&paint);
|
let paint_id = self.scene.push_paint(&paint);
|
||||||
|
|
||||||
|
@ -245,15 +248,44 @@ impl CanvasRenderingContext2D {
|
||||||
clip_path,
|
clip_path,
|
||||||
fill_rule,
|
fill_rule,
|
||||||
blend_mode,
|
blend_mode,
|
||||||
String::new()))
|
String::new()));
|
||||||
|
|
||||||
|
self.composite_render_target_if_needed(composite_op, render_target_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let render_target_id = self.push_render_target_if_needed(composite_op);
|
||||||
|
|
||||||
self.scene.push_path(DrawPath::new(outline,
|
self.scene.push_path(DrawPath::new(outline,
|
||||||
paint_id,
|
paint_id,
|
||||||
clip_path,
|
clip_path,
|
||||||
fill_rule,
|
fill_rule,
|
||||||
blend_mode,
|
blend_mode,
|
||||||
String::new()))
|
String::new()));
|
||||||
|
|
||||||
|
self.composite_render_target_if_needed(composite_op, render_target_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_render_target_if_needed(&mut self, composite_op: Option<CompositeOp>)
|
||||||
|
-> Option<RenderTargetId> {
|
||||||
|
if composite_op.is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let render_target_size = self.scene.view_box().size().ceil().to_i32();
|
||||||
|
Some(self.scene.push_render_target(RenderTarget::new(render_target_size, String::new())))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn composite_render_target_if_needed(&mut self,
|
||||||
|
composite_op: Option<CompositeOp>,
|
||||||
|
render_target_id: Option<RenderTargetId>) {
|
||||||
|
let composite_op = match composite_op {
|
||||||
|
None => return,
|
||||||
|
Some(composite_op) => composite_op,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.scene.pop_render_target();
|
||||||
|
self.scene.draw_render_target(render_target_id.unwrap(),
|
||||||
|
Effects::new(Filter::Composite(composite_op)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transformations
|
// Transformations
|
||||||
|
@ -532,6 +564,7 @@ pub enum CompositeOperation {
|
||||||
DestinationOut,
|
DestinationOut,
|
||||||
DestinationAtop,
|
DestinationAtop,
|
||||||
Lighter,
|
Lighter,
|
||||||
|
Copy,
|
||||||
Xor,
|
Xor,
|
||||||
Multiply,
|
Multiply,
|
||||||
Screen,
|
Screen,
|
||||||
|
@ -553,14 +586,9 @@ pub enum CompositeOperation {
|
||||||
impl CompositeOperation {
|
impl CompositeOperation {
|
||||||
fn to_blend_mode(self) -> BlendMode {
|
fn to_blend_mode(self) -> BlendMode {
|
||||||
match self {
|
match self {
|
||||||
CompositeOperation::SourceOver => BlendMode::SrcOver,
|
|
||||||
CompositeOperation::SourceIn => BlendMode::SrcIn,
|
|
||||||
CompositeOperation::SourceOut => BlendMode::SrcOut,
|
|
||||||
CompositeOperation::SourceAtop => BlendMode::SrcAtop,
|
CompositeOperation::SourceAtop => BlendMode::SrcAtop,
|
||||||
CompositeOperation::DestinationOver => BlendMode::DestOver,
|
CompositeOperation::DestinationOver => BlendMode::DestOver,
|
||||||
CompositeOperation::DestinationIn => BlendMode::DestIn,
|
|
||||||
CompositeOperation::DestinationOut => BlendMode::DestOut,
|
CompositeOperation::DestinationOut => BlendMode::DestOut,
|
||||||
CompositeOperation::DestinationAtop => BlendMode::DestAtop,
|
|
||||||
CompositeOperation::Xor => BlendMode::Xor,
|
CompositeOperation::Xor => BlendMode::Xor,
|
||||||
CompositeOperation::Lighter => BlendMode::Lighter,
|
CompositeOperation::Lighter => BlendMode::Lighter,
|
||||||
CompositeOperation::Multiply => BlendMode::Multiply,
|
CompositeOperation::Multiply => BlendMode::Multiply,
|
||||||
|
@ -578,6 +606,43 @@ impl CompositeOperation {
|
||||||
CompositeOperation::Saturation => BlendMode::Saturation,
|
CompositeOperation::Saturation => BlendMode::Saturation,
|
||||||
CompositeOperation::Color => BlendMode::Color,
|
CompositeOperation::Color => BlendMode::Color,
|
||||||
CompositeOperation::Luminosity => BlendMode::Luminosity,
|
CompositeOperation::Luminosity => BlendMode::Luminosity,
|
||||||
|
CompositeOperation::SourceOver |
|
||||||
|
CompositeOperation::SourceIn |
|
||||||
|
CompositeOperation::SourceOut |
|
||||||
|
CompositeOperation::DestinationIn |
|
||||||
|
CompositeOperation::DestinationAtop |
|
||||||
|
CompositeOperation::Copy => BlendMode::SrcOver,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_composite_op(self) -> Option<CompositeOp> {
|
||||||
|
match self {
|
||||||
|
CompositeOperation::SourceIn => Some(CompositeOp::SrcIn),
|
||||||
|
CompositeOperation::SourceOut => Some(CompositeOp::SrcOut),
|
||||||
|
CompositeOperation::DestinationIn => Some(CompositeOp::DestIn),
|
||||||
|
CompositeOperation::DestinationAtop => Some(CompositeOp::DestAtop),
|
||||||
|
CompositeOperation::Copy => Some(CompositeOp::Copy),
|
||||||
|
CompositeOperation::SourceOver |
|
||||||
|
CompositeOperation::SourceAtop |
|
||||||
|
CompositeOperation::DestinationOver |
|
||||||
|
CompositeOperation::DestinationOut |
|
||||||
|
CompositeOperation::Xor |
|
||||||
|
CompositeOperation::Lighter |
|
||||||
|
CompositeOperation::Multiply |
|
||||||
|
CompositeOperation::Screen |
|
||||||
|
CompositeOperation::Overlay |
|
||||||
|
CompositeOperation::Darken |
|
||||||
|
CompositeOperation::Lighten |
|
||||||
|
CompositeOperation::ColorDodge |
|
||||||
|
CompositeOperation::ColorBurn |
|
||||||
|
CompositeOperation::HardLight |
|
||||||
|
CompositeOperation::SoftLight |
|
||||||
|
CompositeOperation::Difference |
|
||||||
|
CompositeOperation::Exclusion |
|
||||||
|
CompositeOperation::Hue |
|
||||||
|
CompositeOperation::Saturation |
|
||||||
|
CompositeOperation::Color |
|
||||||
|
CompositeOperation::Luminosity => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,12 @@ pub struct Effects {
|
||||||
/// The shader that should be used when compositing this layer onto its destination.
|
/// The shader that should be used when compositing this layer onto its destination.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Filter {
|
pub enum Filter {
|
||||||
/// A compositing operation.
|
/// A Porter-Duff compositing operation.
|
||||||
|
///
|
||||||
|
/// The compositing operations here are the ones that can't be blend modes because they can
|
||||||
|
/// clear parts of the destination not overlapped by the source, plus the regular source-over.
|
||||||
Composite(CompositeOp),
|
Composite(CompositeOp),
|
||||||
|
|
||||||
/// Performs postprocessing operations useful for monochrome text.
|
/// Performs postprocessing operations useful for monochrome text.
|
||||||
Text {
|
Text {
|
||||||
/// The foreground color of the text.
|
/// The foreground color of the text.
|
||||||
|
@ -59,9 +63,24 @@ pub enum Filter {
|
||||||
pub enum CompositeOp {
|
pub enum CompositeOp {
|
||||||
/// The default.
|
/// The default.
|
||||||
SrcOver,
|
SrcOver,
|
||||||
|
/// No regions are enabled.
|
||||||
|
Clear,
|
||||||
|
/// Only the source will be present.
|
||||||
|
Copy,
|
||||||
|
/// The source that overlaps the destination replaces the destination.
|
||||||
|
SrcIn,
|
||||||
|
/// Destination which overlaps the source replaces the source.
|
||||||
|
DestIn,
|
||||||
|
/// Source is placed where it falls outside of the destination.
|
||||||
|
SrcOut,
|
||||||
|
/// Destination which overlaps the source replaces the source. Source is placed elsewhere.
|
||||||
|
DestAtop,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Blend modes that can be applied to individual paths.
|
/// Blend modes that can be applied to individual paths.
|
||||||
|
///
|
||||||
|
/// All blend modes preserve parts of the destination that are not overlapped by the source path.
|
||||||
|
/// Other Porter-Duff compositing operations are `CompositeOp`s.
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
pub enum BlendMode {
|
pub enum BlendMode {
|
||||||
// Supported by GPU blender
|
// Supported by GPU blender
|
||||||
|
@ -75,12 +94,6 @@ pub enum BlendMode {
|
||||||
Lighten,
|
Lighten,
|
||||||
Darken,
|
Darken,
|
||||||
|
|
||||||
// Porter-Duff
|
|
||||||
SrcIn,
|
|
||||||
DestIn,
|
|
||||||
SrcOut,
|
|
||||||
DestAtop,
|
|
||||||
|
|
||||||
// Overlay
|
// Overlay
|
||||||
Multiply,
|
Multiply,
|
||||||
Screen,
|
Screen,
|
||||||
|
@ -124,6 +137,13 @@ impl Default for BlendMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Effects {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(filter: Filter) -> Effects {
|
||||||
|
Effects { filter }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl BlendMode {
|
impl BlendMode {
|
||||||
/// Whether the backdrop is irrelevant when applying this blend mode (i.e. destination blend
|
/// Whether the backdrop is irrelevant when applying this blend mode (i.e. destination blend
|
||||||
/// factor is zero when source alpha is one).
|
/// factor is zero when source alpha is one).
|
||||||
|
@ -138,10 +158,6 @@ impl BlendMode {
|
||||||
BlendMode::Lighter |
|
BlendMode::Lighter |
|
||||||
BlendMode::Lighten |
|
BlendMode::Lighten |
|
||||||
BlendMode::Darken |
|
BlendMode::Darken |
|
||||||
BlendMode::SrcIn |
|
|
||||||
BlendMode::DestIn |
|
|
||||||
BlendMode::SrcOut |
|
|
||||||
BlendMode::DestAtop |
|
|
||||||
BlendMode::Multiply |
|
BlendMode::Multiply |
|
||||||
BlendMode::Screen |
|
BlendMode::Screen |
|
||||||
BlendMode::HardLight |
|
BlendMode::HardLight |
|
||||||
|
|
|
@ -12,13 +12,12 @@ use crate::gpu::debug::DebugUIPresenter;
|
||||||
use crate::gpu::options::{DestFramebuffer, RendererOptions};
|
use crate::gpu::options::{DestFramebuffer, RendererOptions};
|
||||||
use crate::gpu::shaders::{AlphaTileBlendModeProgram, AlphaTileDodgeBurnProgram};
|
use crate::gpu::shaders::{AlphaTileBlendModeProgram, AlphaTileDodgeBurnProgram};
|
||||||
use crate::gpu::shaders::{AlphaTileHSLProgram, AlphaTileOverlayProgram};
|
use crate::gpu::shaders::{AlphaTileHSLProgram, AlphaTileOverlayProgram};
|
||||||
use crate::gpu::shaders::{AlphaTilePorterDuffProgram, AlphaTileProgram, AlphaTileVertexArray};
|
use crate::gpu::shaders::{AlphaTileProgram, AlphaTileVertexArray, CopyTileProgram};
|
||||||
use crate::gpu::shaders::{CopyTileProgram, CopyTileVertexArray, FillProgram, FillVertexArray};
|
use crate::gpu::shaders::{CopyTileVertexArray, FillProgram, FillVertexArray, FilterBasicProgram};
|
||||||
use crate::gpu::shaders::{FilterBasicProgram, FilterBasicVertexArray, FilterTextProgram};
|
use crate::gpu::shaders::{FilterBasicVertexArray, FilterTextProgram, FilterTextVertexArray};
|
||||||
use crate::gpu::shaders::{FilterTextVertexArray, MAX_FILLS_PER_BATCH, MaskTileProgram};
|
use crate::gpu::shaders::{MAX_FILLS_PER_BATCH, MaskTileProgram, MaskTileVertexArray};
|
||||||
use crate::gpu::shaders::{MaskTileVertexArray, ReprojectionProgram, ReprojectionVertexArray};
|
use crate::gpu::shaders::{ReprojectionProgram, ReprojectionVertexArray, SolidTileProgram};
|
||||||
use crate::gpu::shaders::{SolidTileProgram, SolidTileVertexArray};
|
use crate::gpu::shaders::{SolidTileVertexArray, StencilProgram, StencilVertexArray};
|
||||||
use crate::gpu::shaders::{StencilProgram, StencilVertexArray};
|
|
||||||
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, MaskTile, PaintData, PaintPageContents};
|
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, MaskTile, PaintData, PaintPageContents};
|
||||||
use crate::gpu_data::{PaintPageId, RenderCommand, SolidTileVertex};
|
use crate::gpu_data::{PaintPageId, RenderCommand, SolidTileVertex};
|
||||||
use crate::options::BoundingQuad;
|
use crate::options::BoundingQuad;
|
||||||
|
@ -63,11 +62,6 @@ const OVERLAY_BLEND_MODE_SCREEN: i32 = 1;
|
||||||
const OVERLAY_BLEND_MODE_HARD_LIGHT: i32 = 2;
|
const OVERLAY_BLEND_MODE_HARD_LIGHT: i32 = 2;
|
||||||
const OVERLAY_BLEND_MODE_OVERLAY: i32 = 3;
|
const OVERLAY_BLEND_MODE_OVERLAY: i32 = 3;
|
||||||
|
|
||||||
const PORTER_DUFF_FACTOR_ZERO: i32 = 0;
|
|
||||||
const PORTER_DUFF_FACTOR_DEST_ALPHA: i32 = 1;
|
|
||||||
const PORTER_DUFF_FACTOR_SRC_ALPHA: i32 = 2;
|
|
||||||
const PORTER_DUFF_FACTOR_ONE_MINUS_DEST_ALPHA: i32 = 3;
|
|
||||||
|
|
||||||
pub struct Renderer<D>
|
pub struct Renderer<D>
|
||||||
where
|
where
|
||||||
D: Device,
|
D: Device,
|
||||||
|
@ -84,7 +78,6 @@ where
|
||||||
copy_tile_program: CopyTileProgram<D>,
|
copy_tile_program: CopyTileProgram<D>,
|
||||||
solid_tile_program: SolidTileProgram<D>,
|
solid_tile_program: SolidTileProgram<D>,
|
||||||
alpha_tile_program: AlphaTileProgram<D>,
|
alpha_tile_program: AlphaTileProgram<D>,
|
||||||
alpha_tile_porterduff_program: AlphaTilePorterDuffProgram<D>,
|
|
||||||
alpha_tile_overlay_program: AlphaTileOverlayProgram<D>,
|
alpha_tile_overlay_program: AlphaTileOverlayProgram<D>,
|
||||||
alpha_tile_dodgeburn_program: AlphaTileDodgeBurnProgram<D>,
|
alpha_tile_dodgeburn_program: AlphaTileDodgeBurnProgram<D>,
|
||||||
alpha_tile_softlight_program: AlphaTileBlendModeProgram<D>,
|
alpha_tile_softlight_program: AlphaTileBlendModeProgram<D>,
|
||||||
|
@ -96,7 +89,6 @@ where
|
||||||
copy_tile_vertex_array: CopyTileVertexArray<D>,
|
copy_tile_vertex_array: CopyTileVertexArray<D>,
|
||||||
solid_tile_vertex_array: SolidTileVertexArray<D>,
|
solid_tile_vertex_array: SolidTileVertexArray<D>,
|
||||||
alpha_tile_vertex_array: AlphaTileVertexArray<D>,
|
alpha_tile_vertex_array: AlphaTileVertexArray<D>,
|
||||||
alpha_tile_porterduff_vertex_array: AlphaTileVertexArray<D>,
|
|
||||||
alpha_tile_overlay_vertex_array: AlphaTileVertexArray<D>,
|
alpha_tile_overlay_vertex_array: AlphaTileVertexArray<D>,
|
||||||
alpha_tile_dodgeburn_vertex_array: AlphaTileVertexArray<D>,
|
alpha_tile_dodgeburn_vertex_array: AlphaTileVertexArray<D>,
|
||||||
alpha_tile_softlight_vertex_array: AlphaTileVertexArray<D>,
|
alpha_tile_softlight_vertex_array: AlphaTileVertexArray<D>,
|
||||||
|
@ -173,7 +165,6 @@ where
|
||||||
let copy_tile_program = CopyTileProgram::new(&device, resources);
|
let copy_tile_program = CopyTileProgram::new(&device, resources);
|
||||||
let solid_tile_program = SolidTileProgram::new(&device, resources);
|
let solid_tile_program = SolidTileProgram::new(&device, resources);
|
||||||
let alpha_tile_program = AlphaTileProgram::new(&device, resources);
|
let alpha_tile_program = AlphaTileProgram::new(&device, resources);
|
||||||
let alpha_tile_porterduff_program = AlphaTilePorterDuffProgram::new(&device, resources);
|
|
||||||
let alpha_tile_overlay_program = AlphaTileOverlayProgram::new(&device, resources);
|
let alpha_tile_overlay_program = AlphaTileOverlayProgram::new(&device, resources);
|
||||||
let alpha_tile_dodgeburn_program = AlphaTileDodgeBurnProgram::new(&device, resources);
|
let alpha_tile_dodgeburn_program = AlphaTileDodgeBurnProgram::new(&device, resources);
|
||||||
let alpha_tile_softlight_program = AlphaTileBlendModeProgram::new(&device,
|
let alpha_tile_softlight_program = AlphaTileBlendModeProgram::new(&device,
|
||||||
|
@ -238,12 +229,6 @@ where
|
||||||
&alpha_tile_vertex_buffer,
|
&alpha_tile_vertex_buffer,
|
||||||
&quads_vertex_indices_buffer,
|
&quads_vertex_indices_buffer,
|
||||||
);
|
);
|
||||||
let alpha_tile_porterduff_vertex_array = AlphaTileVertexArray::new(
|
|
||||||
&device,
|
|
||||||
&alpha_tile_porterduff_program.alpha_tile_blend_mode_program.alpha_tile_program,
|
|
||||||
&alpha_tile_vertex_buffer,
|
|
||||||
&quads_vertex_indices_buffer,
|
|
||||||
);
|
|
||||||
let alpha_tile_overlay_vertex_array = AlphaTileVertexArray::new(
|
let alpha_tile_overlay_vertex_array = AlphaTileVertexArray::new(
|
||||||
&device,
|
&device,
|
||||||
&alpha_tile_overlay_program.alpha_tile_blend_mode_program.alpha_tile_program,
|
&alpha_tile_overlay_program.alpha_tile_blend_mode_program.alpha_tile_program,
|
||||||
|
@ -341,7 +326,6 @@ where
|
||||||
copy_tile_program,
|
copy_tile_program,
|
||||||
solid_tile_program,
|
solid_tile_program,
|
||||||
alpha_tile_program,
|
alpha_tile_program,
|
||||||
alpha_tile_porterduff_program,
|
|
||||||
alpha_tile_overlay_program,
|
alpha_tile_overlay_program,
|
||||||
alpha_tile_dodgeburn_program,
|
alpha_tile_dodgeburn_program,
|
||||||
alpha_tile_softlight_program,
|
alpha_tile_softlight_program,
|
||||||
|
@ -353,7 +337,6 @@ where
|
||||||
copy_tile_vertex_array,
|
copy_tile_vertex_array,
|
||||||
solid_tile_vertex_array,
|
solid_tile_vertex_array,
|
||||||
alpha_tile_vertex_array,
|
alpha_tile_vertex_array,
|
||||||
alpha_tile_porterduff_vertex_array,
|
|
||||||
alpha_tile_overlay_vertex_array,
|
alpha_tile_overlay_vertex_array,
|
||||||
alpha_tile_dodgeburn_vertex_array,
|
alpha_tile_dodgeburn_vertex_array,
|
||||||
alpha_tile_softlight_vertex_array,
|
alpha_tile_softlight_vertex_array,
|
||||||
|
@ -791,12 +774,6 @@ where
|
||||||
|
|
||||||
let (alpha_tile_program, alpha_tile_vertex_array) = match blend_mode_program {
|
let (alpha_tile_program, alpha_tile_vertex_array) = match blend_mode_program {
|
||||||
BlendModeProgram::Regular => (&self.alpha_tile_program, &self.alpha_tile_vertex_array),
|
BlendModeProgram::Regular => (&self.alpha_tile_program, &self.alpha_tile_vertex_array),
|
||||||
BlendModeProgram::PorterDuff => {
|
|
||||||
(&self.alpha_tile_porterduff_program
|
|
||||||
.alpha_tile_blend_mode_program
|
|
||||||
.alpha_tile_program,
|
|
||||||
&self.alpha_tile_porterduff_vertex_array)
|
|
||||||
}
|
|
||||||
BlendModeProgram::Overlay => {
|
BlendModeProgram::Overlay => {
|
||||||
(&self.alpha_tile_overlay_program.alpha_tile_blend_mode_program.alpha_tile_program,
|
(&self.alpha_tile_overlay_program.alpha_tile_blend_mode_program.alpha_tile_program,
|
||||||
&self.alpha_tile_overlay_vertex_array)
|
&self.alpha_tile_overlay_vertex_array)
|
||||||
|
@ -853,11 +830,6 @@ where
|
||||||
|
|
||||||
match blend_mode_program {
|
match blend_mode_program {
|
||||||
BlendModeProgram::Regular => {}
|
BlendModeProgram::Regular => {}
|
||||||
BlendModeProgram::PorterDuff => {
|
|
||||||
self.set_uniforms_for_porter_duff_blend_mode(&mut textures,
|
|
||||||
&mut uniforms,
|
|
||||||
blend_mode);
|
|
||||||
}
|
|
||||||
BlendModeProgram::Overlay => {
|
BlendModeProgram::Overlay => {
|
||||||
self.set_uniforms_for_overlay_blend_mode(&mut textures, &mut uniforms, blend_mode);
|
self.set_uniforms_for_overlay_blend_mode(&mut textures, &mut uniforms, blend_mode);
|
||||||
}
|
}
|
||||||
|
@ -915,38 +887,6 @@ where
|
||||||
UniformData::TextureUnit(textures.len() as u32 - 1)));
|
UniformData::TextureUnit(textures.len() as u32 - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_uniforms_for_porter_duff_blend_mode<'a>(
|
|
||||||
&'a self,
|
|
||||||
textures: &mut Vec<&'a D::Texture>,
|
|
||||||
uniforms: &mut Vec<(&'a D::Uniform, UniformData)>,
|
|
||||||
blend_mode: BlendMode) {
|
|
||||||
let (src_factor, dest_factor) = match blend_mode {
|
|
||||||
BlendMode::SrcIn => {
|
|
||||||
(PORTER_DUFF_FACTOR_DEST_ALPHA, PORTER_DUFF_FACTOR_ZERO)
|
|
||||||
}
|
|
||||||
BlendMode::DestIn => {
|
|
||||||
(PORTER_DUFF_FACTOR_ZERO, PORTER_DUFF_FACTOR_SRC_ALPHA)
|
|
||||||
}
|
|
||||||
BlendMode::SrcOut => {
|
|
||||||
(PORTER_DUFF_FACTOR_ONE_MINUS_DEST_ALPHA, PORTER_DUFF_FACTOR_ZERO)
|
|
||||||
}
|
|
||||||
BlendMode::DestAtop => {
|
|
||||||
(PORTER_DUFF_FACTOR_ONE_MINUS_DEST_ALPHA, PORTER_DUFF_FACTOR_SRC_ALPHA)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
uniforms.push((&self.alpha_tile_porterduff_program.src_factor_uniform,
|
|
||||||
UniformData::Int(src_factor)));
|
|
||||||
uniforms.push((&self.alpha_tile_porterduff_program.dest_factor_uniform,
|
|
||||||
UniformData::Int(dest_factor)));
|
|
||||||
|
|
||||||
self.set_uniforms_for_blend_mode(textures,
|
|
||||||
uniforms,
|
|
||||||
&self.alpha_tile_porterduff_program
|
|
||||||
.alpha_tile_blend_mode_program);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_uniforms_for_overlay_blend_mode<'a>(&'a self,
|
fn set_uniforms_for_overlay_blend_mode<'a>(&'a self,
|
||||||
textures: &mut Vec<&'a D::Texture>,
|
textures: &mut Vec<&'a D::Texture>,
|
||||||
uniforms: &mut Vec<(&'a D::Uniform, UniformData)>,
|
uniforms: &mut Vec<(&'a D::Uniform, UniformData)>,
|
||||||
|
@ -1216,9 +1156,7 @@ where
|
||||||
(&self.filter_basic_program.source_uniform, UniformData::TextureUnit(0)),
|
(&self.filter_basic_program.source_uniform, UniformData::TextureUnit(0)),
|
||||||
];
|
];
|
||||||
|
|
||||||
let blend_state = match composite_op {
|
let blend_state = composite_op.to_blend_state();
|
||||||
CompositeOp::SrcOver => BlendMode::SrcOver.to_blend_state(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.device.draw_elements(6, &RenderState {
|
self.device.draw_elements(6, &RenderState {
|
||||||
target: &self.draw_render_target(),
|
target: &self.draw_render_target(),
|
||||||
|
@ -1530,11 +1468,11 @@ struct RenderTargetInfo<D> where D: Device {
|
||||||
must_preserve_contents: bool,
|
must_preserve_contents: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait BlendModeExt {
|
trait ToBlendState {
|
||||||
fn to_blend_state(self) -> Option<BlendState>;
|
fn to_blend_state(self) -> Option<BlendState>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlendModeExt for BlendMode {
|
impl ToBlendState for BlendMode {
|
||||||
fn to_blend_state(self) -> Option<BlendState> {
|
fn to_blend_state(self) -> Option<BlendState> {
|
||||||
match self {
|
match self {
|
||||||
BlendMode::Clear => {
|
BlendMode::Clear => {
|
||||||
|
@ -1618,10 +1556,6 @@ impl BlendModeExt for BlendMode {
|
||||||
op: BlendOp::Min,
|
op: BlendOp::Min,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
BlendMode::SrcIn |
|
|
||||||
BlendMode::DestIn |
|
|
||||||
BlendMode::SrcOut |
|
|
||||||
BlendMode::DestAtop |
|
|
||||||
BlendMode::Multiply |
|
BlendMode::Multiply |
|
||||||
BlendMode::Screen |
|
BlendMode::Screen |
|
||||||
BlendMode::HardLight |
|
BlendMode::HardLight |
|
||||||
|
@ -1642,10 +1576,79 @@ impl BlendModeExt for BlendMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToBlendState for CompositeOp {
|
||||||
|
fn to_blend_state(self) -> Option<BlendState> {
|
||||||
|
match self {
|
||||||
|
CompositeOp::Clear => {
|
||||||
|
Some(BlendState {
|
||||||
|
src_rgb_factor: BlendFactor::Zero,
|
||||||
|
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
|
src_alpha_factor: BlendFactor::Zero,
|
||||||
|
dest_alpha_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CompositeOp::Copy => {
|
||||||
|
Some(BlendState {
|
||||||
|
src_rgb_factor: BlendFactor::One,
|
||||||
|
dest_rgb_factor: BlendFactor::Zero,
|
||||||
|
src_alpha_factor: BlendFactor::One,
|
||||||
|
dest_alpha_factor: BlendFactor::Zero,
|
||||||
|
..BlendState::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CompositeOp::SrcOver => {
|
||||||
|
Some(BlendState {
|
||||||
|
src_rgb_factor: BlendFactor::One,
|
||||||
|
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
|
src_alpha_factor: BlendFactor::One,
|
||||||
|
dest_alpha_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CompositeOp::SrcIn => {
|
||||||
|
Some(BlendState {
|
||||||
|
src_rgb_factor: BlendFactor::DestAlpha,
|
||||||
|
dest_rgb_factor: BlendFactor::Zero,
|
||||||
|
src_alpha_factor: BlendFactor::DestAlpha,
|
||||||
|
dest_alpha_factor: BlendFactor::Zero,
|
||||||
|
..BlendState::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CompositeOp::DestIn => {
|
||||||
|
Some(BlendState {
|
||||||
|
src_rgb_factor: BlendFactor::Zero,
|
||||||
|
dest_rgb_factor: BlendFactor::SrcAlpha,
|
||||||
|
src_alpha_factor: BlendFactor::Zero,
|
||||||
|
dest_alpha_factor: BlendFactor::SrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CompositeOp::SrcOut => {
|
||||||
|
Some(BlendState {
|
||||||
|
src_rgb_factor: BlendFactor::OneMinusDestAlpha,
|
||||||
|
dest_rgb_factor: BlendFactor::Zero,
|
||||||
|
src_alpha_factor: BlendFactor::OneMinusDestAlpha,
|
||||||
|
dest_alpha_factor: BlendFactor::Zero,
|
||||||
|
..BlendState::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CompositeOp::DestAtop => {
|
||||||
|
Some(BlendState {
|
||||||
|
src_rgb_factor: BlendFactor::OneMinusDestAlpha,
|
||||||
|
dest_rgb_factor: BlendFactor::SrcAlpha,
|
||||||
|
src_alpha_factor: BlendFactor::OneMinusDestAlpha,
|
||||||
|
dest_alpha_factor: BlendFactor::SrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub(crate) enum BlendModeProgram {
|
pub(crate) enum BlendModeProgram {
|
||||||
Regular,
|
Regular,
|
||||||
PorterDuff,
|
|
||||||
Overlay,
|
Overlay,
|
||||||
DodgeBurn,
|
DodgeBurn,
|
||||||
SoftLight,
|
SoftLight,
|
||||||
|
@ -1666,10 +1669,6 @@ impl BlendModeProgram {
|
||||||
BlendMode::Lighter |
|
BlendMode::Lighter |
|
||||||
BlendMode::Lighten |
|
BlendMode::Lighten |
|
||||||
BlendMode::Darken => BlendModeProgram::Regular,
|
BlendMode::Darken => BlendModeProgram::Regular,
|
||||||
BlendMode::SrcIn |
|
|
||||||
BlendMode::DestIn |
|
|
||||||
BlendMode::SrcOut |
|
|
||||||
BlendMode::DestAtop => BlendModeProgram::PorterDuff,
|
|
||||||
BlendMode::Multiply |
|
BlendMode::Multiply |
|
||||||
BlendMode::Screen |
|
BlendMode::Screen |
|
||||||
BlendMode::HardLight |
|
BlendMode::HardLight |
|
||||||
|
@ -1689,7 +1688,6 @@ impl BlendModeProgram {
|
||||||
pub(crate) fn needs_readable_framebuffer(self) -> bool {
|
pub(crate) fn needs_readable_framebuffer(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
BlendModeProgram::Regular => false,
|
BlendModeProgram::Regular => false,
|
||||||
BlendModeProgram::PorterDuff |
|
|
||||||
BlendModeProgram::Overlay |
|
BlendModeProgram::Overlay |
|
||||||
BlendModeProgram::DodgeBurn |
|
BlendModeProgram::DodgeBurn |
|
||||||
BlendModeProgram::SoftLight |
|
BlendModeProgram::SoftLight |
|
||||||
|
|
|
@ -465,30 +465,6 @@ impl<D> AlphaTileBlendModeProgram<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AlphaTilePorterDuffProgram<D> where D: Device {
|
|
||||||
pub alpha_tile_blend_mode_program: AlphaTileBlendModeProgram<D>,
|
|
||||||
pub dest_factor_uniform: D::Uniform,
|
|
||||||
pub src_factor_uniform: D::Uniform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> AlphaTilePorterDuffProgram<D> where D: Device {
|
|
||||||
pub fn new(device: &D, resources: &dyn ResourceLoader) -> AlphaTilePorterDuffProgram<D> {
|
|
||||||
let alpha_tile_blend_mode_program =
|
|
||||||
AlphaTileBlendModeProgram::new(device, resources, "tile_alpha_porterduff");
|
|
||||||
let dest_factor_uniform =
|
|
||||||
device.get_uniform(&alpha_tile_blend_mode_program.alpha_tile_program.program,
|
|
||||||
"DestFactor");
|
|
||||||
let src_factor_uniform =
|
|
||||||
device.get_uniform(&alpha_tile_blend_mode_program.alpha_tile_program.program,
|
|
||||||
"SrcFactor");
|
|
||||||
AlphaTilePorterDuffProgram {
|
|
||||||
alpha_tile_blend_mode_program,
|
|
||||||
dest_factor_uniform,
|
|
||||||
src_factor_uniform,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AlphaTileHSLProgram<D> where D: Device {
|
pub struct AlphaTileHSLProgram<D> where D: Device {
|
||||||
pub alpha_tile_blend_mode_program: AlphaTileBlendModeProgram<D>,
|
pub alpha_tile_blend_mode_program: AlphaTileBlendModeProgram<D>,
|
||||||
pub blend_hsl_uniform: D::Uniform,
|
pub blend_hsl_uniform: D::Uniform,
|
||||||
|
|
|
@ -26,6 +26,7 @@ in vec2 vTexCoord;
|
||||||
out vec4 oFragColor;
|
out vec4 oFragColor;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
oFragColor = texture(uSource, vTexCoord);
|
vec4 color = texture(uSource, vTexCoord);
|
||||||
|
oFragColor = vec4(color . rgb * color . a, color . a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
#version {{version}}
|
|
||||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
precision highp float;
|
|
||||||
|
|
||||||
uniform int uDestFactor;
|
|
||||||
uniform int uSrcFactor;
|
|
||||||
|
|
||||||
out vec4 oFragColor;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uniform sampler2D uStencilTexture;
|
|
||||||
uniform sampler2D uPaintTexture;
|
|
||||||
uniform sampler2D uDest;
|
|
||||||
uniform vec2 uFramebufferSize;
|
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
|
||||||
in vec2 vMaskTexCoord;
|
|
||||||
|
|
||||||
|
|
||||||
vec4 sampleSrcColor(){
|
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
|
||||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 sampleDestColor(){
|
|
||||||
vec2 destTexCoord = gl_FragCoord . xy / uFramebufferSize;
|
|
||||||
return texture(uDest, destTexCoord);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec4 blendColors(vec4 destRGBA, vec4 srcRGBA, vec3 blendedRGB){
|
|
||||||
return vec4(srcRGBA . a *(1.0 - destRGBA . a)* srcRGBA . rgb +
|
|
||||||
srcRGBA . a * destRGBA . a * blendedRGB +
|
|
||||||
(1.0 - srcRGBA . a)* destRGBA . a * destRGBA . rgb,
|
|
||||||
1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 select3(bvec3 cond, vec3 a, vec3 b){
|
|
||||||
return vec3(cond . x ? a . x : b . x, cond . y ? a . y : b . y, cond . z ? a . z : b . z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec4 getFactor(int factor, vec4 destRGBA, vec4 srcRGBA){
|
|
||||||
if(factor == 0)
|
|
||||||
return vec4(0.0);
|
|
||||||
if(factor == 1)
|
|
||||||
return vec4(destRGBA . a);
|
|
||||||
if(factor == 2)
|
|
||||||
return vec4(srcRGBA . a);
|
|
||||||
return vec4(1.0 - destRGBA . a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main(){
|
|
||||||
vec4 srcRGBA = sampleSrcColor();
|
|
||||||
vec4 destRGBA = sampleDestColor();
|
|
||||||
|
|
||||||
vec4 destFactor = getFactor(uDestFactor, destRGBA, srcRGBA);
|
|
||||||
vec4 srcFactor = getFactor(uSrcFactor, destRGBA, srcRGBA);
|
|
||||||
|
|
||||||
vec4 blended = destFactor * destRGBA * vec4(destRGBA . aaa, 1.0)+
|
|
||||||
srcFactor * srcRGBA * vec4(srcRGBA . aaa, 1.0);
|
|
||||||
oFragColor = blended;
|
|
||||||
}
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ in vec2 vColorTexCoord;
|
||||||
out vec4 oFragColor;
|
out vec4 oFragColor;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
oFragColor = texture(uPaintTexture, vColorTexCoord);
|
vec4 color = texture(uPaintTexture, vColorTexCoord);
|
||||||
|
oFragColor = vec4(color . rgb * color . a, color . a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ struct main0_in
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
out.oFragColor = spvDescriptorSet0.uSource.sample(spvDescriptorSet0.uSourceSmplr, in.vTexCoord);
|
float4 color = spvDescriptorSet0.uSource.sample(spvDescriptorSet0.uSourceSmplr, in.vTexCoord);
|
||||||
|
out.oFragColor = float4(color.xyz * color.w, color.w);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
|
||||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
|
||||||
|
|
||||||
#include <metal_stdlib>
|
|
||||||
#include <simd/simd.h>
|
|
||||||
|
|
||||||
using namespace metal;
|
|
||||||
|
|
||||||
struct spvDescriptorSetBuffer0
|
|
||||||
{
|
|
||||||
texture2d<float> uStencilTexture [[id(0)]];
|
|
||||||
sampler uStencilTextureSmplr [[id(1)]];
|
|
||||||
texture2d<float> uPaintTexture [[id(2)]];
|
|
||||||
sampler uPaintTextureSmplr [[id(3)]];
|
|
||||||
constant float2* uFramebufferSize [[id(4)]];
|
|
||||||
texture2d<float> uDest [[id(5)]];
|
|
||||||
sampler uDestSmplr [[id(6)]];
|
|
||||||
constant int* uDestFactor [[id(7)]];
|
|
||||||
constant int* uSrcFactor [[id(8)]];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct main0_out
|
|
||||||
{
|
|
||||||
float4 oFragColor [[color(0)]];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct main0_in
|
|
||||||
{
|
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
|
||||||
};
|
|
||||||
|
|
||||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
|
||||||
{
|
|
||||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
|
||||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
|
||||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
|
||||||
{
|
|
||||||
float2 destTexCoord = gl_FragCoord.xy / uFramebufferSize;
|
|
||||||
return uDest.sample(uDestSmplr, destTexCoord);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 getFactor(thread const int& factor, thread const float4& destRGBA, thread const float4& srcRGBA)
|
|
||||||
{
|
|
||||||
if (factor == 0)
|
|
||||||
{
|
|
||||||
return float4(0.0);
|
|
||||||
}
|
|
||||||
if (factor == 1)
|
|
||||||
{
|
|
||||||
return float4(destRGBA.w);
|
|
||||||
}
|
|
||||||
if (factor == 2)
|
|
||||||
{
|
|
||||||
return float4(srcRGBA.w);
|
|
||||||
}
|
|
||||||
return float4(1.0 - destRGBA.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
|
||||||
{
|
|
||||||
main0_out out = {};
|
|
||||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
|
||||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
|
||||||
int param = (*spvDescriptorSet0.uDestFactor);
|
|
||||||
float4 param_1 = destRGBA;
|
|
||||||
float4 param_2 = srcRGBA;
|
|
||||||
float4 destFactor = getFactor(param, param_1, param_2);
|
|
||||||
int param_3 = (*spvDescriptorSet0.uSrcFactor);
|
|
||||||
float4 param_4 = destRGBA;
|
|
||||||
float4 param_5 = srcRGBA;
|
|
||||||
float4 srcFactor = getFactor(param_3, param_4, param_5);
|
|
||||||
float4 blended = ((destFactor * destRGBA) * float4(destRGBA.www, 1.0)) + ((srcFactor * srcRGBA) * float4(srcRGBA.www, 1.0));
|
|
||||||
out.oFragColor = blended;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ struct main0_in
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
out.oFragColor = spvDescriptorSet0.uPaintTexture.sample(spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
float4 color = spvDescriptorSet0.uPaintTexture.sample(spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
||||||
|
out.oFragColor = float4(color.xyz * color.w, color.w);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ SHADERS=\
|
||||||
tile_alpha_exclusion.fs.glsl \
|
tile_alpha_exclusion.fs.glsl \
|
||||||
tile_alpha_hsl.fs.glsl \
|
tile_alpha_hsl.fs.glsl \
|
||||||
tile_alpha_overlay.fs.glsl \
|
tile_alpha_overlay.fs.glsl \
|
||||||
tile_alpha_porterduff.fs.glsl \
|
|
||||||
tile_alpha_softlight.fs.glsl \
|
tile_alpha_softlight.fs.glsl \
|
||||||
tile_copy.fs.glsl \
|
tile_copy.fs.glsl \
|
||||||
tile_copy.vs.glsl \
|
tile_copy.vs.glsl \
|
||||||
|
|
|
@ -24,5 +24,6 @@ in vec2 vTexCoord;
|
||||||
out vec4 oFragColor;
|
out vec4 oFragColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
oFragColor = texture(uSource, vTexCoord);
|
vec4 color = texture(uSource, vTexCoord);
|
||||||
|
oFragColor = vec4(color.rgb * color.a, color.a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
#version 330
|
|
||||||
|
|
||||||
// pathfinder/shaders/tile_alpha_porterduff.fs.glsl
|
|
||||||
//
|
|
||||||
// Copyright © 2020 The Pathfinder Project Developers.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
// Porter-Duff blend modes not supported by the standard GPU blender.
|
|
||||||
|
|
||||||
#extension GL_GOOGLE_include_directive : enable
|
|
||||||
|
|
||||||
#define PORTER_DUFF_FACTOR_ZERO 0
|
|
||||||
#define PORTER_DUFF_FACTOR_DEST_ALPHA 1
|
|
||||||
#define PORTER_DUFF_FACTOR_SRC_ALPHA 2
|
|
||||||
#define PORTER_DUFF_FACTOR_ONE_MINUS_DEST_ALPHA 3
|
|
||||||
|
|
||||||
precision highp float;
|
|
||||||
|
|
||||||
uniform int uDestFactor;
|
|
||||||
uniform int uSrcFactor;
|
|
||||||
|
|
||||||
out vec4 oFragColor;
|
|
||||||
|
|
||||||
#include "tile_alpha_sample.inc.glsl"
|
|
||||||
|
|
||||||
vec4 getFactor(int factor, vec4 destRGBA, vec4 srcRGBA) {
|
|
||||||
if (factor == PORTER_DUFF_FACTOR_ZERO)
|
|
||||||
return vec4(0.0);
|
|
||||||
if (factor == PORTER_DUFF_FACTOR_DEST_ALPHA)
|
|
||||||
return vec4(destRGBA.a);
|
|
||||||
if (factor == PORTER_DUFF_FACTOR_SRC_ALPHA)
|
|
||||||
return vec4(srcRGBA.a);
|
|
||||||
return vec4(1.0 - destRGBA.a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 srcRGBA = sampleSrcColor();
|
|
||||||
vec4 destRGBA = sampleDestColor();
|
|
||||||
|
|
||||||
vec4 destFactor = getFactor(uDestFactor, destRGBA, srcRGBA);
|
|
||||||
vec4 srcFactor = getFactor(uSrcFactor, destRGBA, srcRGBA);
|
|
||||||
|
|
||||||
vec4 blended = destFactor * destRGBA * vec4(destRGBA.aaa, 1.0) +
|
|
||||||
srcFactor * srcRGBA * vec4(srcRGBA.aaa, 1.0);
|
|
||||||
oFragColor = blended;
|
|
||||||
}
|
|
|
@ -19,5 +19,6 @@ in vec2 vColorTexCoord;
|
||||||
out vec4 oFragColor;
|
out vec4 oFragColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
oFragColor = texture(uPaintTexture, vColorTexCoord);
|
vec4 color = texture(uPaintTexture, vColorTexCoord);
|
||||||
|
oFragColor = vec4(color.rgb * color.a, color.a);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue