Rename "postprocessing" to "effects" and start initial work on composite ops
This commit is contained in:
parent
d9e994e46d
commit
16a2de88df
|
@ -1658,6 +1658,7 @@ dependencies = [
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_color 0.1.0",
|
"pathfinder_color 0.1.0",
|
||||||
|
"pathfinder_content 0.1.0",
|
||||||
"pathfinder_export 0.1.0",
|
"pathfinder_export 0.1.0",
|
||||||
"pathfinder_geometry 0.4.0",
|
"pathfinder_geometry 0.4.0",
|
||||||
"pathfinder_gl 0.1.0",
|
"pathfinder_gl 0.1.0",
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
// pathfinder/content/src/effects.rs
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
//! Special effects that can be applied to layers.
|
||||||
|
|
||||||
|
use pathfinder_color::ColorF;
|
||||||
|
|
||||||
|
/// This intentionally does not precisely match what Core Graphics does (a
|
||||||
|
/// Lanczos function), because we don't want any ringing artefacts.
|
||||||
|
pub static DEFRINGING_KERNEL_CORE_GRAPHICS: DefringingKernel =
|
||||||
|
DefringingKernel([0.033165660, 0.102074051, 0.221434336, 0.286651906]);
|
||||||
|
pub static DEFRINGING_KERNEL_FREETYPE: DefringingKernel =
|
||||||
|
DefringingKernel([0.0, 0.031372549, 0.301960784, 0.337254902]);
|
||||||
|
|
||||||
|
/// Should match macOS 10.13 High Sierra.
|
||||||
|
pub static STEM_DARKENING_FACTORS: [f32; 2] = [0.0121, 0.0121 * 1.25];
|
||||||
|
|
||||||
|
/// Should match macOS 10.13 High Sierra.
|
||||||
|
pub const MAX_STEM_DARKENING_AMOUNT: [f32; 2] = [0.3, 0.3];
|
||||||
|
|
||||||
|
/// This value is a subjective cutoff. Above this ppem value, no stem darkening is performed.
|
||||||
|
pub const MAX_STEM_DARKENING_PIXELS_PER_EM: f32 = 72.0;
|
||||||
|
|
||||||
|
/// Effects that can be applied to a layer.
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Effects {
|
||||||
|
/// The shader that should be used when compositing this layer onto its destination.
|
||||||
|
pub filter: Filter,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The shader that should be used when compositing this layer onto its destination.
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum Filter {
|
||||||
|
/// A compositing operation.
|
||||||
|
Composite(CompositeOp),
|
||||||
|
/// Performs postprocessing operations useful for monochrome text.
|
||||||
|
Text {
|
||||||
|
/// The foreground color of the text.
|
||||||
|
fg_color: ColorF,
|
||||||
|
/// The background color of the text.
|
||||||
|
bg_color: ColorF,
|
||||||
|
/// The kernel used for defringing, if subpixel AA is enabled.
|
||||||
|
defringing_kernel: Option<DefringingKernel>,
|
||||||
|
/// Whether gamma correction is used when compositing.
|
||||||
|
///
|
||||||
|
/// If this is enabled, stem darkening is advised.
|
||||||
|
gamma_correction: bool,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum CompositeOp {
|
||||||
|
/// The default.
|
||||||
|
SourceOver,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
|
pub struct DefringingKernel(pub [f32; 4]);
|
||||||
|
|
||||||
|
impl Default for CompositeOp {
|
||||||
|
#[inline]
|
||||||
|
fn default() -> CompositeOp {
|
||||||
|
CompositeOp::SourceOver
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ extern crate log;
|
||||||
|
|
||||||
pub mod clip;
|
pub mod clip;
|
||||||
pub mod dash;
|
pub mod dash;
|
||||||
|
pub mod effects;
|
||||||
pub mod fill;
|
pub mod fill;
|
||||||
pub mod gradient;
|
pub mod gradient;
|
||||||
pub mod orientation;
|
pub mod orientation;
|
||||||
|
|
|
@ -24,6 +24,9 @@ version = "0.4"
|
||||||
[dependencies.pathfinder_color]
|
[dependencies.pathfinder_color]
|
||||||
path = "../../color"
|
path = "../../color"
|
||||||
|
|
||||||
|
[dependencies.pathfinder_content]
|
||||||
|
path = "../../content"
|
||||||
|
|
||||||
[dependencies.pathfinder_export]
|
[dependencies.pathfinder_export]
|
||||||
path = "../../export"
|
path = "../../export"
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ use crate::device::{GroundProgram, GroundVertexArray};
|
||||||
use crate::ui::{DemoUIModel, DemoUIPresenter, ScreenshotInfo, ScreenshotType, UIAction};
|
use crate::ui::{DemoUIModel, DemoUIPresenter, ScreenshotInfo, ScreenshotType, UIAction};
|
||||||
use crate::window::{Event, Keycode, SVGPath, Window, WindowSize};
|
use crate::window::{Event, Keycode, SVGPath, Window, WindowSize};
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
|
use pathfinder_content::effects::{DEFRINGING_KERNEL_CORE_GRAPHICS, Effects};
|
||||||
|
use pathfinder_content::effects::{Filter, STEM_DARKENING_FACTORS};
|
||||||
use pathfinder_export::{Export, FileFormat};
|
use pathfinder_export::{Export, FileFormat};
|
||||||
use pathfinder_geometry::rect::RectF;
|
use pathfinder_geometry::rect::RectF;
|
||||||
use pathfinder_geometry::transform2d::Transform2F;
|
use pathfinder_geometry::transform2d::Transform2F;
|
||||||
|
@ -31,9 +33,8 @@ use pathfinder_gpu::resources::ResourceLoader;
|
||||||
use pathfinder_gpu::Device;
|
use pathfinder_gpu::Device;
|
||||||
use pathfinder_renderer::concurrent::scene_proxy::{RenderCommandStream, SceneProxy};
|
use pathfinder_renderer::concurrent::scene_proxy::{RenderCommandStream, SceneProxy};
|
||||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||||
use pathfinder_renderer::gpu::renderer::{PostprocessOptions, RenderStats, RenderTime, Renderer};
|
use pathfinder_renderer::gpu::renderer::{RenderStats, RenderTime, Renderer};
|
||||||
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
|
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
|
||||||
use pathfinder_renderer::post::{DEFRINGING_KERNEL_CORE_GRAPHICS, STEM_DARKENING_FACTORS};
|
|
||||||
use pathfinder_renderer::scene::Scene;
|
use pathfinder_renderer::scene::Scene;
|
||||||
use pathfinder_svg::BuiltSVG;
|
use pathfinder_svg::BuiltSVG;
|
||||||
use pathfinder_ui::{MousePosition, UIEvent};
|
use pathfinder_ui::{MousePosition, UIEvent};
|
||||||
|
@ -742,9 +743,7 @@ pub enum UIVisibility {
|
||||||
All,
|
All,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_scene(resource_loader: &dyn ResourceLoader,
|
fn load_scene(resource_loader: &dyn ResourceLoader, input_path: &SVGPath, effects: Option<Effects>)
|
||||||
input_path: &SVGPath,
|
|
||||||
effects: Option<PostprocessOptions>)
|
|
||||||
-> (BuiltSVG, Tree) {
|
-> (BuiltSVG, Tree) {
|
||||||
let mut data;
|
let mut data;
|
||||||
match *input_path {
|
match *input_path {
|
||||||
|
@ -761,7 +760,7 @@ fn load_scene(resource_loader: &dyn ResourceLoader,
|
||||||
(built_svg, tree)
|
(built_svg, tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_svg_tree(tree: &Tree, effects: Option<PostprocessOptions>) -> BuiltSVG {
|
fn build_svg_tree(tree: &Tree, effects: Option<Effects>) -> BuiltSVG {
|
||||||
let mut scene = Scene::new();
|
let mut scene = Scene::new();
|
||||||
if let Some(effects) = effects {
|
if let Some(effects) = effects {
|
||||||
scene.push_layer(effects);
|
scene.push_layer(effects);
|
||||||
|
@ -860,12 +859,13 @@ impl SceneMetadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_effects(ui_model: &DemoUIModel) -> Option<PostprocessOptions> {
|
fn build_effects(ui_model: &DemoUIModel) -> Option<Effects> {
|
||||||
if !ui_model.gamma_correction_effect_enabled && !ui_model.subpixel_aa_effect_enabled {
|
if !ui_model.gamma_correction_effect_enabled && !ui_model.subpixel_aa_effect_enabled {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(PostprocessOptions {
|
Some(Effects {
|
||||||
|
filter: Filter::Text {
|
||||||
fg_color: ui_model.foreground_color().to_f32(),
|
fg_color: ui_model.foreground_color().to_f32(),
|
||||||
bg_color: ui_model.background_color().to_f32(),
|
bg_color: ui_model.background_color().to_f32(),
|
||||||
gamma_correction: ui_model.gamma_correction_effect_enabled,
|
gamma_correction: ui_model.gamma_correction_effect_enabled,
|
||||||
|
@ -874,6 +874,7 @@ fn build_effects(ui_model: &DemoUIModel) -> Option<PostprocessOptions> {
|
||||||
Some(DEFRINGING_KERNEL_CORE_GRAPHICS)
|
Some(DEFRINGING_KERNEL_CORE_GRAPHICS)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
//! Packs data onto the GPU.
|
//! Packs data onto the GPU.
|
||||||
|
|
||||||
use crate::concurrent::executor::Executor;
|
use crate::concurrent::executor::Executor;
|
||||||
use crate::gpu::renderer::{MASK_TILES_ACROSS, PostprocessOptions};
|
use crate::gpu::renderer::MASK_TILES_ACROSS;
|
||||||
use crate::gpu_data::{AlphaTile, AlphaTileVertex, FillBatchPrimitive, MaskTile, MaskTileVertex};
|
use crate::gpu_data::{AlphaTile, AlphaTileVertex, FillBatchPrimitive, MaskTile, MaskTileVertex};
|
||||||
use crate::gpu_data::{RenderCommand, SolidTileVertex, TileObjectPrimitive};
|
use crate::gpu_data::{RenderCommand, SolidTileVertex, TileObjectPrimitive};
|
||||||
use crate::options::{PreparedBuildOptions, RenderCommandListener};
|
use crate::options::{PreparedBuildOptions, RenderCommandListener};
|
||||||
|
@ -20,6 +20,7 @@ use crate::scene::{DisplayItem, Scene};
|
||||||
use crate::tile_map::DenseTileMap;
|
use crate::tile_map::DenseTileMap;
|
||||||
use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH, Tiler, TilingPathInfo};
|
use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH, Tiler, TilingPathInfo};
|
||||||
use crate::z_buffer::ZBuffer;
|
use crate::z_buffer::ZBuffer;
|
||||||
|
use pathfinder_content::effects::Effects;
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_geometry::line_segment::{LineSegment2F, LineSegmentU4, LineSegmentU8};
|
use pathfinder_geometry::line_segment::{LineSegment2F, LineSegmentU4, LineSegmentU8};
|
||||||
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
||||||
|
@ -358,7 +359,7 @@ struct CulledTiles {
|
||||||
enum CulledDisplayItem {
|
enum CulledDisplayItem {
|
||||||
DrawSolidTiles(Vec<SolidTileVertex>),
|
DrawSolidTiles(Vec<SolidTileVertex>),
|
||||||
DrawAlphaTiles(Vec<AlphaTile>),
|
DrawAlphaTiles(Vec<AlphaTile>),
|
||||||
PushLayer { effects: PostprocessOptions },
|
PushLayer { effects: Effects },
|
||||||
PopLayer,
|
PopLayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,16 +10,17 @@
|
||||||
|
|
||||||
use crate::gpu::debug::DebugUIPresenter;
|
use crate::gpu::debug::DebugUIPresenter;
|
||||||
use crate::gpu::options::{DestFramebuffer, RendererOptions};
|
use crate::gpu::options::{DestFramebuffer, RendererOptions};
|
||||||
use crate::gpu::shaders::{FillProgram, AlphaTileProgram, AlphaTileVertexArray, FillVertexArray};
|
use crate::gpu::shaders::{AlphaTileProgram, AlphaTileVertexArray, FillProgram, FillVertexArray};
|
||||||
use crate::gpu::shaders::{MAX_FILLS_PER_BATCH, MaskTileProgram, MaskTileVertexArray};
|
use crate::gpu::shaders::{FilterBasicProgram, FilterBasicVertexArray, FilterTextProgram};
|
||||||
use crate::gpu::shaders::{PostprocessProgram, PostprocessVertexArray, ReprojectionProgram};
|
use crate::gpu::shaders::{FilterTextVertexArray, MAX_FILLS_PER_BATCH, MaskTileProgram};
|
||||||
use crate::gpu::shaders::{ReprojectionVertexArray, SolidTileProgram, SolidTileVertexArray};
|
use crate::gpu::shaders::{MaskTileVertexArray, ReprojectionProgram, ReprojectionVertexArray};
|
||||||
|
use crate::gpu::shaders::{SolidTileProgram, SolidTileVertexArray};
|
||||||
use crate::gpu::shaders::{StencilProgram, StencilVertexArray};
|
use crate::gpu::shaders::{StencilProgram, StencilVertexArray};
|
||||||
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, MaskTile, PaintData};
|
use crate::gpu_data::{AlphaTile, FillBatchPrimitive, MaskTile, PaintData};
|
||||||
use crate::gpu_data::{RenderCommand, SolidTileVertex};
|
use crate::gpu_data::{RenderCommand, SolidTileVertex};
|
||||||
use crate::post::DefringingKernel;
|
|
||||||
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
|
||||||
use pathfinder_color::{self as color, ColorF};
|
use pathfinder_color::{self as color, ColorF};
|
||||||
|
use pathfinder_content::effects::{CompositeOp, DefringingKernel, Effects, Filter};
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_geometry::vector::{Vector2I, Vector4F};
|
use pathfinder_geometry::vector::{Vector2I, Vector4F};
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
|
@ -79,9 +80,11 @@ where
|
||||||
paint_texture: Option<D::Texture>,
|
paint_texture: Option<D::Texture>,
|
||||||
layer_framebuffer_stack: Vec<LayerFramebufferInfo<D>>,
|
layer_framebuffer_stack: Vec<LayerFramebufferInfo<D>>,
|
||||||
|
|
||||||
// Postprocessing shader
|
// Filter shaders
|
||||||
postprocess_program: PostprocessProgram<D>,
|
filter_basic_program: FilterBasicProgram<D>,
|
||||||
postprocess_vertex_array: PostprocessVertexArray<D>,
|
filter_basic_vertex_array: FilterBasicVertexArray<D>,
|
||||||
|
filter_text_program: FilterTextProgram<D>,
|
||||||
|
filter_text_vertex_array: FilterTextVertexArray<D>,
|
||||||
gamma_lut_texture: D::Texture,
|
gamma_lut_texture: D::Texture,
|
||||||
|
|
||||||
// Stencil shader
|
// Stencil shader
|
||||||
|
@ -126,7 +129,8 @@ where
|
||||||
resources);
|
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 postprocess_program = PostprocessProgram::new(&device, resources);
|
let filter_basic_program = FilterBasicProgram::new(&device, resources);
|
||||||
|
let filter_text_program = FilterTextProgram::new(&device, resources);
|
||||||
let stencil_program = StencilProgram::new(&device, resources);
|
let stencil_program = StencilProgram::new(&device, resources);
|
||||||
let reprojection_program = ReprojectionProgram::new(&device, resources);
|
let reprojection_program = ReprojectionProgram::new(&device, resources);
|
||||||
|
|
||||||
|
@ -175,9 +179,15 @@ where
|
||||||
&solid_tile_program,
|
&solid_tile_program,
|
||||||
&quads_vertex_indices_buffer,
|
&quads_vertex_indices_buffer,
|
||||||
);
|
);
|
||||||
let postprocess_vertex_array = PostprocessVertexArray::new(
|
let filter_basic_vertex_array = FilterBasicVertexArray::new(
|
||||||
&device,
|
&device,
|
||||||
&postprocess_program,
|
&filter_basic_program,
|
||||||
|
&quad_vertex_positions_buffer,
|
||||||
|
&quad_vertex_indices_buffer,
|
||||||
|
);
|
||||||
|
let filter_text_vertex_array = FilterTextVertexArray::new(
|
||||||
|
&device,
|
||||||
|
&filter_text_program,
|
||||||
&quad_vertex_positions_buffer,
|
&quad_vertex_positions_buffer,
|
||||||
&quad_vertex_indices_buffer,
|
&quad_vertex_indices_buffer,
|
||||||
);
|
);
|
||||||
|
@ -229,8 +239,10 @@ where
|
||||||
paint_texture: None,
|
paint_texture: None,
|
||||||
layer_framebuffer_stack: vec![],
|
layer_framebuffer_stack: vec![],
|
||||||
|
|
||||||
postprocess_program,
|
filter_basic_program,
|
||||||
postprocess_vertex_array,
|
filter_basic_vertex_array,
|
||||||
|
filter_text_program,
|
||||||
|
filter_text_vertex_array,
|
||||||
gamma_lut_texture,
|
gamma_lut_texture,
|
||||||
|
|
||||||
stencil_program,
|
stencil_program,
|
||||||
|
@ -757,12 +769,13 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_layer(&mut self, effects: PostprocessOptions) {
|
fn push_layer(&mut self, effects: Effects) {
|
||||||
let main_framebuffer_size = self.main_viewport().size();
|
let main_framebuffer_size = self.main_viewport().size();
|
||||||
let framebuffer_size = if effects.defringing_kernel.is_some() {
|
let framebuffer_size = match effects.filter {
|
||||||
|
Filter::Text { defringing_kernel: Some(_), .. } => {
|
||||||
main_framebuffer_size.scale_xy(Vector2I::new(3, 1))
|
main_framebuffer_size.scale_xy(Vector2I::new(3, 1))
|
||||||
} else {
|
}
|
||||||
main_framebuffer_size
|
_ => main_framebuffer_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
let framebuffer = self.framebuffer_cache.create_framebuffer(&mut self.device,
|
let framebuffer = self.framebuffer_cache.create_framebuffer(&mut self.device,
|
||||||
|
@ -780,45 +793,106 @@ where
|
||||||
.pop()
|
.pop()
|
||||||
.expect("Where's the layer?");
|
.expect("Where's the layer?");
|
||||||
|
|
||||||
let clear_color = self.clear_color_for_draw_operation();
|
match layer_framebuffer_info.effects.filter {
|
||||||
|
Filter::Composite(composite_op) => {
|
||||||
|
self.composite_layer(&layer_framebuffer_info, composite_op)
|
||||||
|
}
|
||||||
|
Filter::Text { fg_color, bg_color, defringing_kernel, gamma_correction } => {
|
||||||
|
self.draw_text_layer(&layer_framebuffer_info,
|
||||||
|
fg_color,
|
||||||
|
bg_color,
|
||||||
|
defringing_kernel,
|
||||||
|
gamma_correction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let postprocess_source_framebuffer = &layer_framebuffer_info.framebuffer;
|
self.preserve_draw_framebuffer();
|
||||||
let source_texture = self
|
|
||||||
.device
|
self.framebuffer_cache.release_framebuffer(layer_framebuffer_info.framebuffer);
|
||||||
.framebuffer_texture(postprocess_source_framebuffer);
|
}
|
||||||
|
|
||||||
|
fn composite_layer(&self,
|
||||||
|
layer_framebuffer_info: &LayerFramebufferInfo<D>,
|
||||||
|
composite_op: CompositeOp) {
|
||||||
|
let clear_color = self.clear_color_for_draw_operation();
|
||||||
|
let source_framebuffer = &layer_framebuffer_info.framebuffer;
|
||||||
|
let source_texture = self.device.framebuffer_texture(source_framebuffer);
|
||||||
|
let source_texture_size = self.device.texture_size(source_texture);
|
||||||
|
let main_viewport = self.main_viewport();
|
||||||
|
|
||||||
|
let uniforms = vec![
|
||||||
|
(&self.filter_basic_program.framebuffer_size_uniform,
|
||||||
|
UniformData::Vec2(main_viewport.size().to_f32().0)),
|
||||||
|
(&self.filter_basic_program.source_uniform, UniformData::TextureUnit(0)),
|
||||||
|
(&self.filter_basic_program.source_size_uniform,
|
||||||
|
UniformData::Vec2(source_texture_size.0.to_f32x2())),
|
||||||
|
];
|
||||||
|
|
||||||
|
let blend_state = match composite_op {
|
||||||
|
CompositeOp::SourceOver => {
|
||||||
|
BlendState {
|
||||||
|
func: BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha,
|
||||||
|
..BlendState::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.device.draw_elements(6, &RenderState {
|
||||||
|
target: &self.draw_render_target(),
|
||||||
|
program: &self.filter_basic_program.program,
|
||||||
|
vertex_array: &self.filter_basic_vertex_array.vertex_array,
|
||||||
|
primitive: Primitive::Triangles,
|
||||||
|
textures: &[&source_texture],
|
||||||
|
uniforms: &uniforms,
|
||||||
|
viewport: main_viewport,
|
||||||
|
options: RenderOptions {
|
||||||
|
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
|
||||||
|
blend: Some(blend_state),
|
||||||
|
..RenderOptions::default()
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_text_layer(&self,
|
||||||
|
layer_framebuffer_info: &LayerFramebufferInfo<D>,
|
||||||
|
fg_color: ColorF,
|
||||||
|
bg_color: ColorF,
|
||||||
|
defringing_kernel: Option<DefringingKernel>,
|
||||||
|
gamma_correction: bool) {
|
||||||
|
let clear_color = self.clear_color_for_draw_operation();
|
||||||
|
let source_framebuffer = &layer_framebuffer_info.framebuffer;
|
||||||
|
let source_texture = self.device.framebuffer_texture(source_framebuffer);
|
||||||
let source_texture_size = self.device.texture_size(source_texture);
|
let source_texture_size = self.device.texture_size(source_texture);
|
||||||
let main_viewport = self.main_viewport();
|
let main_viewport = self.main_viewport();
|
||||||
|
|
||||||
let mut uniforms = vec![
|
let mut uniforms = vec![
|
||||||
(&self.postprocess_program.framebuffer_size_uniform,
|
(&self.filter_text_program.framebuffer_size_uniform,
|
||||||
UniformData::Vec2(main_viewport.size().to_f32().0)),
|
UniformData::Vec2(main_viewport.size().to_f32().0)),
|
||||||
(&self.postprocess_program.source_uniform, UniformData::TextureUnit(0)),
|
(&self.filter_text_program.source_uniform, UniformData::TextureUnit(0)),
|
||||||
(&self.postprocess_program.source_size_uniform,
|
(&self.filter_text_program.source_size_uniform,
|
||||||
UniformData::Vec2(source_texture_size.0.to_f32x2())),
|
UniformData::Vec2(source_texture_size.0.to_f32x2())),
|
||||||
(&self.postprocess_program.gamma_lut_uniform, UniformData::TextureUnit(1)),
|
(&self.filter_text_program.gamma_lut_uniform, UniformData::TextureUnit(1)),
|
||||||
(&self.postprocess_program.fg_color_uniform,
|
(&self.filter_text_program.fg_color_uniform, UniformData::Vec4(fg_color.0)),
|
||||||
UniformData::Vec4(layer_framebuffer_info.effects.fg_color.0)),
|
(&self.filter_text_program.bg_color_uniform, UniformData::Vec4(bg_color.0)),
|
||||||
(&self.postprocess_program.bg_color_uniform,
|
(&self.filter_text_program.gamma_correction_enabled_uniform,
|
||||||
UniformData::Vec4(layer_framebuffer_info.effects.bg_color.0)),
|
UniformData::Int(gamma_correction as i32)),
|
||||||
(&self.postprocess_program.gamma_correction_enabled_uniform,
|
|
||||||
UniformData::Int(layer_framebuffer_info.effects.gamma_correction as i32)),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
match layer_framebuffer_info.effects.defringing_kernel {
|
match defringing_kernel {
|
||||||
Some(ref kernel) => {
|
Some(ref kernel) => {
|
||||||
uniforms.push((&self.postprocess_program.kernel_uniform,
|
uniforms.push((&self.filter_text_program.kernel_uniform,
|
||||||
UniformData::Vec4(F32x4::from_slice(&kernel.0))));
|
UniformData::Vec4(F32x4::from_slice(&kernel.0))));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
uniforms.push((&self.postprocess_program.kernel_uniform,
|
uniforms.push((&self.filter_text_program.kernel_uniform,
|
||||||
UniformData::Vec4(F32x4::default())));
|
UniformData::Vec4(F32x4::default())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.device.draw_elements(6, &RenderState {
|
self.device.draw_elements(6, &RenderState {
|
||||||
target: &self.draw_render_target(),
|
target: &self.draw_render_target(),
|
||||||
program: &self.postprocess_program.program,
|
program: &self.filter_text_program.program,
|
||||||
vertex_array: &self.postprocess_vertex_array.vertex_array,
|
vertex_array: &self.filter_text_vertex_array.vertex_array,
|
||||||
primitive: Primitive::Triangles,
|
primitive: Primitive::Triangles,
|
||||||
textures: &[&source_texture, &self.gamma_lut_texture],
|
textures: &[&source_texture, &self.gamma_lut_texture],
|
||||||
uniforms: &uniforms,
|
uniforms: &uniforms,
|
||||||
|
@ -828,10 +902,6 @@ where
|
||||||
..RenderOptions::default()
|
..RenderOptions::default()
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
self.preserve_draw_framebuffer();
|
|
||||||
|
|
||||||
self.framebuffer_cache.release_framebuffer(layer_framebuffer_info.framebuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stencil_state(&self) -> Option<StencilState> {
|
fn stencil_state(&self) -> Option<StencilState> {
|
||||||
|
@ -847,7 +917,7 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_color_for_draw_operation(&mut self) -> Option<ColorF> {
|
fn clear_color_for_draw_operation(&self) -> Option<ColorF> {
|
||||||
let must_preserve_contents = match self.layer_framebuffer_stack.last() {
|
let must_preserve_contents = match self.layer_framebuffer_stack.last() {
|
||||||
Some(ref layer_framebuffer_info) => layer_framebuffer_info.must_preserve_contents,
|
Some(ref layer_framebuffer_info) => layer_framebuffer_info.must_preserve_contents,
|
||||||
None => {
|
None => {
|
||||||
|
@ -924,15 +994,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(pcwalton): Rename to `Effects` and move to `pathfinder_content`, perhaps?
|
|
||||||
#[derive(Clone, Copy, Default, Debug)]
|
|
||||||
pub struct PostprocessOptions {
|
|
||||||
pub fg_color: ColorF,
|
|
||||||
pub bg_color: ColorF,
|
|
||||||
pub defringing_kernel: Option<DefringingKernel>,
|
|
||||||
pub gamma_correction: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render stats
|
// Render stats
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
|
@ -1047,6 +1108,6 @@ impl<D> FramebufferCache<D> where D: Device {
|
||||||
|
|
||||||
struct LayerFramebufferInfo<D> where D: Device {
|
struct LayerFramebufferInfo<D> where D: Device {
|
||||||
framebuffer: D::Framebuffer,
|
framebuffer: D::Framebuffer,
|
||||||
effects: PostprocessOptions,
|
effects: Effects,
|
||||||
must_preserve_contents: bool,
|
must_preserve_contents: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,69 +388,44 @@ impl<D> AlphaTileProgram<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PostprocessProgram<D>
|
pub struct FilterBasicProgram<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub program: D::Program,
|
pub program: D::Program,
|
||||||
pub source_uniform: D::Uniform,
|
pub source_uniform: D::Uniform,
|
||||||
pub source_size_uniform: D::Uniform,
|
pub source_size_uniform: D::Uniform,
|
||||||
pub framebuffer_size_uniform: D::Uniform,
|
pub framebuffer_size_uniform: D::Uniform,
|
||||||
pub kernel_uniform: D::Uniform,
|
|
||||||
pub gamma_lut_uniform: D::Uniform,
|
|
||||||
pub gamma_correction_enabled_uniform: D::Uniform,
|
|
||||||
pub fg_color_uniform: D::Uniform,
|
|
||||||
pub bg_color_uniform: D::Uniform,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> PostprocessProgram<D>
|
impl<D> FilterBasicProgram<D> where D: Device {
|
||||||
where
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> FilterBasicProgram<D> {
|
||||||
D: Device,
|
let program = device.create_program_from_shader_names(resources,
|
||||||
{
|
"filter_basic",
|
||||||
pub fn new(device: &D, resources: &dyn ResourceLoader) -> PostprocessProgram<D> {
|
"filter",
|
||||||
let program = device.create_program(resources, "post");
|
"filter_basic");
|
||||||
let source_uniform = device.get_uniform(&program, "Source");
|
let source_uniform = device.get_uniform(&program, "Source");
|
||||||
let source_size_uniform = device.get_uniform(&program, "SourceSize");
|
let source_size_uniform = device.get_uniform(&program, "SourceSize");
|
||||||
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
||||||
let kernel_uniform = device.get_uniform(&program, "Kernel");
|
FilterBasicProgram {
|
||||||
let gamma_lut_uniform = device.get_uniform(&program, "GammaLUT");
|
|
||||||
let gamma_correction_enabled_uniform = device.get_uniform(&program,
|
|
||||||
"GammaCorrectionEnabled");
|
|
||||||
let fg_color_uniform = device.get_uniform(&program, "FGColor");
|
|
||||||
let bg_color_uniform = device.get_uniform(&program, "BGColor");
|
|
||||||
PostprocessProgram {
|
|
||||||
program,
|
program,
|
||||||
source_uniform,
|
source_uniform,
|
||||||
source_size_uniform,
|
source_size_uniform,
|
||||||
framebuffer_size_uniform,
|
framebuffer_size_uniform,
|
||||||
kernel_uniform,
|
|
||||||
gamma_lut_uniform,
|
|
||||||
gamma_correction_enabled_uniform,
|
|
||||||
fg_color_uniform,
|
|
||||||
bg_color_uniform,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PostprocessVertexArray<D>
|
pub struct FilterBasicVertexArray<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub vertex_array: D::VertexArray,
|
pub vertex_array: D::VertexArray,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> PostprocessVertexArray<D>
|
impl<D> FilterBasicVertexArray<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: &D,
|
device: &D,
|
||||||
postprocess_program: &PostprocessProgram<D>,
|
fill_basic_program: &FilterBasicProgram<D>,
|
||||||
quad_vertex_positions_buffer: &D::Buffer,
|
quad_vertex_positions_buffer: &D::Buffer,
|
||||||
quad_vertex_indices_buffer: &D::Buffer,
|
quad_vertex_indices_buffer: &D::Buffer,
|
||||||
) -> PostprocessVertexArray<D> {
|
) -> FilterBasicVertexArray<D> {
|
||||||
let vertex_array = device.create_vertex_array();
|
let vertex_array = device.create_vertex_array();
|
||||||
let position_attr = device.get_vertex_attr(&postprocess_program.program, "Position")
|
let position_attr = device.get_vertex_attr(&fill_basic_program.program, "Position")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
||||||
|
@ -465,7 +440,79 @@ where
|
||||||
});
|
});
|
||||||
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
PostprocessVertexArray { vertex_array }
|
FilterBasicVertexArray { vertex_array }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FilterTextProgram<D> where D: Device {
|
||||||
|
pub program: D::Program,
|
||||||
|
pub source_uniform: D::Uniform,
|
||||||
|
pub source_size_uniform: D::Uniform,
|
||||||
|
pub framebuffer_size_uniform: D::Uniform,
|
||||||
|
pub kernel_uniform: D::Uniform,
|
||||||
|
pub gamma_lut_uniform: D::Uniform,
|
||||||
|
pub gamma_correction_enabled_uniform: D::Uniform,
|
||||||
|
pub fg_color_uniform: D::Uniform,
|
||||||
|
pub bg_color_uniform: D::Uniform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> FilterTextProgram<D> where D: Device {
|
||||||
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> FilterTextProgram<D> {
|
||||||
|
let program = device.create_program_from_shader_names(resources,
|
||||||
|
"filter_text",
|
||||||
|
"filter",
|
||||||
|
"filter_text");
|
||||||
|
let source_uniform = device.get_uniform(&program, "Source");
|
||||||
|
let source_size_uniform = device.get_uniform(&program, "SourceSize");
|
||||||
|
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
||||||
|
let kernel_uniform = device.get_uniform(&program, "Kernel");
|
||||||
|
let gamma_lut_uniform = device.get_uniform(&program, "GammaLUT");
|
||||||
|
let gamma_correction_enabled_uniform = device.get_uniform(&program,
|
||||||
|
"GammaCorrectionEnabled");
|
||||||
|
let fg_color_uniform = device.get_uniform(&program, "FGColor");
|
||||||
|
let bg_color_uniform = device.get_uniform(&program, "BGColor");
|
||||||
|
FilterTextProgram {
|
||||||
|
program,
|
||||||
|
source_uniform,
|
||||||
|
source_size_uniform,
|
||||||
|
framebuffer_size_uniform,
|
||||||
|
kernel_uniform,
|
||||||
|
gamma_lut_uniform,
|
||||||
|
gamma_correction_enabled_uniform,
|
||||||
|
fg_color_uniform,
|
||||||
|
bg_color_uniform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FilterTextVertexArray<D> where D: Device {
|
||||||
|
pub vertex_array: D::VertexArray,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> FilterTextVertexArray<D> where D: Device {
|
||||||
|
pub fn new(
|
||||||
|
device: &D,
|
||||||
|
fill_text_program: &FilterTextProgram<D>,
|
||||||
|
quad_vertex_positions_buffer: &D::Buffer,
|
||||||
|
quad_vertex_indices_buffer: &D::Buffer,
|
||||||
|
) -> FilterTextVertexArray<D> {
|
||||||
|
let vertex_array = device.create_vertex_array();
|
||||||
|
let position_attr = device.get_vertex_attr(&fill_text_program.program, "Position")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
device.bind_buffer(&vertex_array, quad_vertex_positions_buffer, BufferTarget::Vertex);
|
||||||
|
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
||||||
|
size: 2,
|
||||||
|
class: VertexAttrClass::Int,
|
||||||
|
attr_type: VertexAttrType::I16,
|
||||||
|
stride: 4,
|
||||||
|
offset: 0,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
|
device.bind_buffer(&vertex_array, quad_vertex_indices_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
|
FilterTextVertexArray { vertex_array }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// pathfinder/renderer/src/gpu_data.rs
|
// pathfinder/renderer/src/gpu_data.rs
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2020 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
//! Packed data ready to be sent to the GPU.
|
//! Packed data ready to be sent to the GPU.
|
||||||
|
|
||||||
use crate::gpu::renderer::PostprocessOptions;
|
|
||||||
use crate::options::BoundingQuad;
|
use crate::options::BoundingQuad;
|
||||||
use pathfinder_color::ColorU;
|
use pathfinder_color::ColorU;
|
||||||
|
use pathfinder_content::effects::Effects;
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_geometry::line_segment::{LineSegmentU4, LineSegmentU8};
|
use pathfinder_geometry::line_segment::{LineSegmentU4, LineSegmentU8};
|
||||||
use pathfinder_geometry::vector::Vector2I;
|
use pathfinder_geometry::vector::Vector2I;
|
||||||
|
@ -25,7 +25,7 @@ pub enum RenderCommand {
|
||||||
AddFills(Vec<FillBatchPrimitive>),
|
AddFills(Vec<FillBatchPrimitive>),
|
||||||
FlushFills,
|
FlushFills,
|
||||||
RenderMaskTiles { tiles: Vec<MaskTile>, fill_rule: FillRule },
|
RenderMaskTiles { tiles: Vec<MaskTile>, fill_rule: FillRule },
|
||||||
PushLayer { effects: PostprocessOptions },
|
PushLayer { effects: Effects },
|
||||||
PopLayer,
|
PopLayer,
|
||||||
DrawAlphaTiles(Vec<AlphaTile>),
|
DrawAlphaTiles(Vec<AlphaTile>),
|
||||||
DrawSolidTiles(Vec<SolidTileVertex>),
|
DrawSolidTiles(Vec<SolidTileVertex>),
|
||||||
|
|
|
@ -20,7 +20,6 @@ pub mod gpu;
|
||||||
pub mod gpu_data;
|
pub mod gpu_data;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
pub mod paint;
|
pub mod paint;
|
||||||
pub mod post;
|
|
||||||
pub mod scene;
|
pub mod scene;
|
||||||
|
|
||||||
mod allocator;
|
mod allocator;
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
// pathfinder/renderer/src/post.rs
|
|
||||||
//
|
|
||||||
// Copyright © 2019 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.
|
|
||||||
|
|
||||||
//! Functionality related to postprocessing effects.
|
|
||||||
//!
|
|
||||||
//! Since these effects run on GPU as fragment shaders, this contains no
|
|
||||||
//! implementations, just shared declarations.
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
||||||
pub struct DefringingKernel(pub [f32; 4]);
|
|
||||||
|
|
||||||
/// This intentionally does not precisely match what Core Graphics does (a
|
|
||||||
/// Lanczos function), because we don't want any ringing artefacts.
|
|
||||||
pub static DEFRINGING_KERNEL_CORE_GRAPHICS: DefringingKernel =
|
|
||||||
DefringingKernel([0.033165660, 0.102074051, 0.221434336, 0.286651906]);
|
|
||||||
pub static DEFRINGING_KERNEL_FREETYPE: DefringingKernel =
|
|
||||||
DefringingKernel([0.0, 0.031372549, 0.301960784, 0.337254902]);
|
|
||||||
|
|
||||||
/// Should match macOS 10.13 High Sierra.
|
|
||||||
pub static STEM_DARKENING_FACTORS: [f32; 2] = [0.0121, 0.0121 * 1.25];
|
|
||||||
|
|
||||||
/// Should match macOS 10.13 High Sierra.
|
|
||||||
pub const MAX_STEM_DARKENING_AMOUNT: [f32; 2] = [0.3, 0.3];
|
|
||||||
|
|
||||||
/// This value is a subjective cutoff. Above this ppem value, no stem darkening is performed.
|
|
||||||
pub const MAX_STEM_DARKENING_PIXELS_PER_EM: f32 = 72.0;
|
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
use crate::builder::SceneBuilder;
|
use crate::builder::SceneBuilder;
|
||||||
use crate::concurrent::executor::Executor;
|
use crate::concurrent::executor::Executor;
|
||||||
use crate::gpu::renderer::PostprocessOptions;
|
|
||||||
use crate::options::{BuildOptions, PreparedBuildOptions};
|
use crate::options::{BuildOptions, PreparedBuildOptions};
|
||||||
use crate::options::{PreparedRenderTransform, RenderCommandListener};
|
use crate::options::{PreparedRenderTransform, RenderCommandListener};
|
||||||
use crate::paint::{Paint, PaintId, PaintInfo, Palette};
|
use crate::paint::{Paint, PaintId, PaintInfo, Palette};
|
||||||
|
use pathfinder_content::effects::Effects;
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_geometry::vector::Vector2F;
|
use pathfinder_geometry::vector::Vector2F;
|
||||||
use pathfinder_geometry::rect::RectF;
|
use pathfinder_geometry::rect::RectF;
|
||||||
|
@ -70,7 +70,7 @@ impl Scene {
|
||||||
clip_path_id
|
clip_path_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_layer(&mut self, effects: PostprocessOptions) {
|
pub fn push_layer(&mut self, effects: Effects) {
|
||||||
self.display_list.push(DisplayItem::PushLayer { effects });
|
self.display_list.push(DisplayItem::PushLayer { effects });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ pub struct ClipPathId(pub u32);
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum DisplayItem {
|
pub enum DisplayItem {
|
||||||
DrawPaths { start_index: u32, end_index: u32 },
|
DrawPaths { start_index: u32, end_index: u32 },
|
||||||
PushLayer { effects: PostprocessOptions },
|
PushLayer { effects: Effects },
|
||||||
PopLayer,
|
PopLayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#version {{version}}
|
||||||
|
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in ivec2 aPosition;
|
||||||
|
|
||||||
|
out vec2 vTexCoord;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec2 position = vec2(aPosition);
|
||||||
|
vTexCoord = position;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gl_Position = vec4(vec2(position)* 2.0 - 1.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#version {{version}}
|
||||||
|
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform sampler2D uSource;
|
||||||
|
uniform vec2 uSourceSize;
|
||||||
|
|
||||||
|
in vec2 vTexCoord;
|
||||||
|
|
||||||
|
out vec4 oFragColor;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
oFragColor = texture(uSource, vTexCoord);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
#version {{version}}
|
||||||
|
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform sampler2D uSource;
|
||||||
|
uniform vec2 uSourceSize;
|
||||||
|
uniform vec4 uFGColor;
|
||||||
|
uniform vec4 uBGColor;
|
||||||
|
uniform int uGammaCorrectionEnabled;
|
||||||
|
|
||||||
|
in vec2 vTexCoord;
|
||||||
|
|
||||||
|
out vec4 oFragColor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uniform sampler2D uGammaLUT;
|
||||||
|
|
||||||
|
float gammaCorrectChannel(float bgColor, float fgColor){
|
||||||
|
return texture(uGammaLUT, vec2(fgColor, 1.0 - bgColor)). r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 gammaCorrect(vec3 bgColor, vec3 fgColor){
|
||||||
|
return vec3(gammaCorrectChannel(bgColor . r, fgColor . r),
|
||||||
|
gammaCorrectChannel(bgColor . g, fgColor . g),
|
||||||
|
gammaCorrectChannel(bgColor . b, fgColor . b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uniform vec4 uKernel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float sample1Tap(float offset);
|
||||||
|
|
||||||
|
|
||||||
|
void sample9Tap(out vec4 outAlphaLeft,
|
||||||
|
out float outAlphaCenter,
|
||||||
|
out vec4 outAlphaRight,
|
||||||
|
float onePixel){
|
||||||
|
outAlphaLeft = vec4(uKernel . x > 0.0 ? sample1Tap(- 4.0 * onePixel): 0.0,
|
||||||
|
sample1Tap(- 3.0 * onePixel),
|
||||||
|
sample1Tap(- 2.0 * onePixel),
|
||||||
|
sample1Tap(- 1.0 * onePixel));
|
||||||
|
outAlphaCenter = sample1Tap(0.0);
|
||||||
|
outAlphaRight = vec4(sample1Tap(1.0 * onePixel),
|
||||||
|
sample1Tap(2.0 * onePixel),
|
||||||
|
sample1Tap(3.0 * onePixel),
|
||||||
|
uKernel . x > 0.0 ? sample1Tap(4.0 * onePixel): 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float convolve7Tap(vec4 alpha0, vec3 alpha1){
|
||||||
|
return dot(alpha0, uKernel)+ dot(alpha1, uKernel . zyx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float sample1Tap(float offset){
|
||||||
|
return texture(uSource, vec2(vTexCoord . x + offset, vTexCoord . y)). r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
|
||||||
|
vec3 alpha;
|
||||||
|
if(uKernel . w == 0.0){
|
||||||
|
alpha = texture(uSource, vTexCoord). rrr;
|
||||||
|
} else {
|
||||||
|
vec4 alphaLeft, alphaRight;
|
||||||
|
float alphaCenter;
|
||||||
|
sample9Tap(alphaLeft, alphaCenter, alphaRight, 1.0 / uSourceSize . x);
|
||||||
|
|
||||||
|
float r = convolve7Tap(alphaLeft, vec3(alphaCenter, alphaRight . xy));
|
||||||
|
float g = convolve7Tap(vec4(alphaLeft . yzw, alphaCenter), alphaRight . xyz);
|
||||||
|
float b = convolve7Tap(vec4(alphaLeft . zw, alphaCenter, alphaRight . x), alphaRight . yzw);
|
||||||
|
|
||||||
|
alpha = vec3(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(uGammaCorrectionEnabled != 0)
|
||||||
|
alpha = gammaCorrect(uBGColor . rgb, alpha);
|
||||||
|
|
||||||
|
|
||||||
|
oFragColor = vec4(mix(uBGColor . rgb, uFGColor . rgb, alpha), 1.0);
|
||||||
|
}
|
||||||
|
|
|
@ -24,8 +24,7 @@ fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuff
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float2 texCoordPx = fract(in.vTexCoord) / fwidth(in.vTexCoord);
|
float2 texCoordPx = fract(in.vTexCoord) / fwidth(in.vTexCoord);
|
||||||
bool4 _33 = bool4(any(texCoordPx <= float2(1.0)));
|
out.oFragColor = select((*spvDescriptorSet0.uGroundColor), (*spvDescriptorSet0.uGridlineColor), bool4(any(texCoordPx <= float2(1.0))));
|
||||||
out.oFragColor = float4(_33.x ? (*spvDescriptorSet0.uGridlineColor).x : (*spvDescriptorSet0.uGroundColor).x, _33.y ? (*spvDescriptorSet0.uGridlineColor).y : (*spvDescriptorSet0.uGroundColor).y, _33.z ? (*spvDescriptorSet0.uGridlineColor).z : (*spvDescriptorSet0.uGroundColor).z, _33.w ? (*spvDescriptorSet0.uGridlineColor).w : (*spvDescriptorSet0.uGroundColor).w);
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,8 @@ fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuff
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float2 from = in.vFrom;
|
float2 from = in.vFrom;
|
||||||
float2 to = in.vTo;
|
float2 to = in.vTo;
|
||||||
bool2 _29 = bool2(from.x < to.x);
|
float2 left = select(to, from, bool2(from.x < to.x));
|
||||||
float2 left = float2(_29.x ? from.x : to.x, _29.y ? from.y : to.y);
|
float2 right = select(from, to, bool2(from.x < to.x));
|
||||||
bool2 _39 = bool2(from.x < to.x);
|
|
||||||
float2 right = float2(_39.x ? to.x : from.x, _39.y ? to.y : from.y);
|
|
||||||
float2 window = fast::clamp(float2(from.x, to.x), float2(-0.5), float2(0.5));
|
float2 window = fast::clamp(float2(from.x, to.x), float2(-0.5), float2(0.5));
|
||||||
float offset = mix(window.x, window.y, 0.5) - left.x;
|
float offset = mix(window.x, window.y, 0.5) - left.x;
|
||||||
float t = offset / (right.x - left.x);
|
float t = offset / (right.x - left.x);
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float2 vTexCoord [[user(locn0)]];
|
||||||
|
float4 gl_Position [[position]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_in
|
||||||
|
{
|
||||||
|
int2 aPosition [[attribute(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
vertex main0_out main0(main0_in in [[stage_in]])
|
||||||
|
{
|
||||||
|
main0_out out = {};
|
||||||
|
float2 position = float2(in.aPosition);
|
||||||
|
out.vTexCoord = position;
|
||||||
|
position.y = 1.0 - position.y;
|
||||||
|
out.gl_Position = float4((float2(position) * 2.0) - float2(1.0), 0.0, 1.0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Automatically generated from files in pathfinder/shaders/. Do not edit!
|
||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct spvDescriptorSetBuffer0
|
||||||
|
{
|
||||||
|
texture2d<float> uSource [[id(0)]];
|
||||||
|
sampler uSourceSmplr [[id(1)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float4 oFragColor [[color(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_in
|
||||||
|
{
|
||||||
|
float2 vTexCoord [[user(locn0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||||
|
{
|
||||||
|
main0_out out = {};
|
||||||
|
out.oFragColor = spvDescriptorSet0.uSource.sample(spvDescriptorSet0.uSourceSmplr, in.vTexCoord);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
// 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> uGammaLUT [[id(0)]];
|
||||||
|
sampler uGammaLUTSmplr [[id(1)]];
|
||||||
|
constant float4* uKernel [[id(2)]];
|
||||||
|
texture2d<float> uSource [[id(3)]];
|
||||||
|
sampler uSourceSmplr [[id(4)]];
|
||||||
|
constant float2* uSourceSize [[id(5)]];
|
||||||
|
constant int* uGammaCorrectionEnabled [[id(6)]];
|
||||||
|
constant float4* uBGColor [[id(7)]];
|
||||||
|
constant float4* uFGColor [[id(8)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float4 oFragColor [[color(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_in
|
||||||
|
{
|
||||||
|
float2 vTexCoord [[user(locn0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
float sample1Tap(thread const float& offset, thread texture2d<float> uSource, thread const sampler uSourceSmplr, thread float2& vTexCoord)
|
||||||
|
{
|
||||||
|
return uSource.sample(uSourceSmplr, float2(vTexCoord.x + offset, vTexCoord.y)).x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sample9Tap(thread float4& outAlphaLeft, thread float& outAlphaCenter, thread float4& outAlphaRight, thread const float& onePixel, thread float4 uKernel, thread texture2d<float> uSource, thread const sampler uSourceSmplr, thread float2& vTexCoord)
|
||||||
|
{
|
||||||
|
float _89;
|
||||||
|
if (uKernel.x > 0.0)
|
||||||
|
{
|
||||||
|
float param = (-4.0) * onePixel;
|
||||||
|
_89 = sample1Tap(param, uSource, uSourceSmplr, vTexCoord);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_89 = 0.0;
|
||||||
|
}
|
||||||
|
float param_1 = (-3.0) * onePixel;
|
||||||
|
float param_2 = (-2.0) * onePixel;
|
||||||
|
float param_3 = (-1.0) * onePixel;
|
||||||
|
outAlphaLeft = float4(_89, sample1Tap(param_1, uSource, uSourceSmplr, vTexCoord), sample1Tap(param_2, uSource, uSourceSmplr, vTexCoord), sample1Tap(param_3, uSource, uSourceSmplr, vTexCoord));
|
||||||
|
float param_4 = 0.0;
|
||||||
|
outAlphaCenter = sample1Tap(param_4, uSource, uSourceSmplr, vTexCoord);
|
||||||
|
float param_5 = 1.0 * onePixel;
|
||||||
|
float param_6 = 2.0 * onePixel;
|
||||||
|
float param_7 = 3.0 * onePixel;
|
||||||
|
float _134;
|
||||||
|
if (uKernel.x > 0.0)
|
||||||
|
{
|
||||||
|
float param_8 = 4.0 * onePixel;
|
||||||
|
_134 = sample1Tap(param_8, uSource, uSourceSmplr, vTexCoord);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_134 = 0.0;
|
||||||
|
}
|
||||||
|
outAlphaRight = float4(sample1Tap(param_5, uSource, uSourceSmplr, vTexCoord), sample1Tap(param_6, uSource, uSourceSmplr, vTexCoord), sample1Tap(param_7, uSource, uSourceSmplr, vTexCoord), _134);
|
||||||
|
}
|
||||||
|
|
||||||
|
float convolve7Tap(thread const float4& alpha0, thread const float3& alpha1, thread float4 uKernel)
|
||||||
|
{
|
||||||
|
return dot(alpha0, uKernel) + dot(alpha1, uKernel.zyx);
|
||||||
|
}
|
||||||
|
|
||||||
|
float gammaCorrectChannel(thread const float& bgColor, thread const float& fgColor, thread texture2d<float> uGammaLUT, thread const sampler uGammaLUTSmplr)
|
||||||
|
{
|
||||||
|
return uGammaLUT.sample(uGammaLUTSmplr, float2(fgColor, 1.0 - bgColor)).x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 gammaCorrect(thread const float3& bgColor, thread const float3& fgColor, thread texture2d<float> uGammaLUT, thread const sampler uGammaLUTSmplr)
|
||||||
|
{
|
||||||
|
float param = bgColor.x;
|
||||||
|
float param_1 = fgColor.x;
|
||||||
|
float param_2 = bgColor.y;
|
||||||
|
float param_3 = fgColor.y;
|
||||||
|
float param_4 = bgColor.z;
|
||||||
|
float param_5 = fgColor.z;
|
||||||
|
return float3(gammaCorrectChannel(param, param_1, uGammaLUT, uGammaLUTSmplr), gammaCorrectChannel(param_2, param_3, uGammaLUT, uGammaLUTSmplr), gammaCorrectChannel(param_4, param_5, uGammaLUT, uGammaLUTSmplr));
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||||
|
{
|
||||||
|
main0_out out = {};
|
||||||
|
float3 alpha;
|
||||||
|
if ((*spvDescriptorSet0.uKernel).w == 0.0)
|
||||||
|
{
|
||||||
|
alpha = spvDescriptorSet0.uSource.sample(spvDescriptorSet0.uSourceSmplr, in.vTexCoord).xxx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float param_3 = 1.0 / (*spvDescriptorSet0.uSourceSize).x;
|
||||||
|
float4 param;
|
||||||
|
float param_1;
|
||||||
|
float4 param_2;
|
||||||
|
sample9Tap(param, param_1, param_2, param_3, (*spvDescriptorSet0.uKernel), spvDescriptorSet0.uSource, spvDescriptorSet0.uSourceSmplr, in.vTexCoord);
|
||||||
|
float4 alphaLeft = param;
|
||||||
|
float alphaCenter = param_1;
|
||||||
|
float4 alphaRight = param_2;
|
||||||
|
float4 param_4 = alphaLeft;
|
||||||
|
float3 param_5 = float3(alphaCenter, alphaRight.xy);
|
||||||
|
float r = convolve7Tap(param_4, param_5, (*spvDescriptorSet0.uKernel));
|
||||||
|
float4 param_6 = float4(alphaLeft.yzw, alphaCenter);
|
||||||
|
float3 param_7 = alphaRight.xyz;
|
||||||
|
float g = convolve7Tap(param_6, param_7, (*spvDescriptorSet0.uKernel));
|
||||||
|
float4 param_8 = float4(alphaLeft.zw, alphaCenter, alphaRight.x);
|
||||||
|
float3 param_9 = alphaRight.yzw;
|
||||||
|
float b = convolve7Tap(param_8, param_9, (*spvDescriptorSet0.uKernel));
|
||||||
|
alpha = float3(r, g, b);
|
||||||
|
}
|
||||||
|
if ((*spvDescriptorSet0.uGammaCorrectionEnabled) != 0)
|
||||||
|
{
|
||||||
|
float3 param_10 = (*spvDescriptorSet0.uBGColor).xyz;
|
||||||
|
float3 param_11 = alpha;
|
||||||
|
alpha = gammaCorrect(param_10, param_11, spvDescriptorSet0.uGammaLUT, spvDescriptorSet0.uGammaLUTSmplr);
|
||||||
|
}
|
||||||
|
out.oFragColor = float4(mix((*spvDescriptorSet0.uBGColor).xyz, (*spvDescriptorSet0.uFGColor).xyz, alpha), 1.0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
|
@ -14,8 +14,9 @@ SHADERS=\
|
||||||
mask.vs.glsl \
|
mask.vs.glsl \
|
||||||
mask_evenodd.fs.glsl \
|
mask_evenodd.fs.glsl \
|
||||||
mask_winding.fs.glsl \
|
mask_winding.fs.glsl \
|
||||||
post.fs.glsl \
|
filter.vs.glsl \
|
||||||
post.vs.glsl \
|
filter_basic.fs.glsl \
|
||||||
|
filter_text.fs.glsl \
|
||||||
reproject.fs.glsl \
|
reproject.fs.glsl \
|
||||||
reproject.vs.glsl \
|
reproject.vs.glsl \
|
||||||
stencil.fs.glsl \
|
stencil.fs.glsl \
|
||||||
|
@ -27,8 +28,8 @@ SHADERS=\
|
||||||
$(EMPTY)
|
$(EMPTY)
|
||||||
|
|
||||||
INCLUDES=\
|
INCLUDES=\
|
||||||
post_convolve.inc.glsl \
|
filter_text_convolve.inc.glsl \
|
||||||
post_gamma_correct.inc.glsl \
|
filter_text_gamma_correct.inc.glsl \
|
||||||
$(EMPTY)
|
$(EMPTY)
|
||||||
|
|
||||||
OUT=\
|
OUT=\
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// pathfinder/shaders/post.vs.glsl
|
// pathfinder/shaders/filter.vs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2020 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
@ -0,0 +1,29 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// pathfinder/shaders/filter_basic.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.
|
||||||
|
|
||||||
|
// TODO(pcwalton): This could be significantly optimized by operating on a
|
||||||
|
// sparse per-tile basis.
|
||||||
|
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform sampler2D uSource;
|
||||||
|
uniform vec2 uSourceSize;
|
||||||
|
|
||||||
|
in vec2 vTexCoord;
|
||||||
|
|
||||||
|
out vec4 oFragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
oFragColor = texture(uSource, vTexCoord);
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// pathfinder/shaders/post.fs.glsl
|
// pathfinder/shaders/filter_text.fs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
||||||
|
@ -27,8 +27,8 @@ in vec2 vTexCoord;
|
||||||
|
|
||||||
out vec4 oFragColor;
|
out vec4 oFragColor;
|
||||||
|
|
||||||
#include "post_gamma_correct.inc.glsl"
|
#include "filter_text_gamma_correct.inc.glsl"
|
||||||
#include "post_convolve.inc.glsl"
|
#include "filter_text_convolve.inc.glsl"
|
||||||
|
|
||||||
// Convolve horizontally in this pass.
|
// Convolve horizontally in this pass.
|
||||||
float sample1Tap(float offset) {
|
float sample1Tap(float offset) {
|
|
@ -1,4 +1,4 @@
|
||||||
// pathfinder/shaders/post_convolve.inc.glsl
|
// pathfinder/shaders/filter_text_convolve.inc.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
|
@ -1,4 +1,4 @@
|
||||||
// pathfinder/shaders/post_gamma_correct.inc.glsl
|
// pathfinder/shaders/filter_text_gamma_correct.inc.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
Loading…
Reference in New Issue