Separate opacity out from paint.
This allows `globalAlpha` to work on render targets.
This commit is contained in:
parent
1deb53fa9c
commit
77b3555828
|
@ -103,12 +103,9 @@ impl CanvasRenderingContext2D {
|
|||
let paint = self.current_state.resolve_paint(&paint);
|
||||
let paint_id = self.scene.push_paint(&paint);
|
||||
|
||||
self.scene.push_path(DrawPath::new(outline,
|
||||
paint_id,
|
||||
None,
|
||||
FillRule::Winding,
|
||||
BlendMode::Clear,
|
||||
String::new()))
|
||||
let mut path = DrawPath::new(outline, paint_id);
|
||||
path.set_blend_mode(BlendMode::Clear);
|
||||
self.scene.push_path(path);
|
||||
}
|
||||
|
||||
// Line styles
|
||||
|
@ -224,8 +221,9 @@ impl CanvasRenderingContext2D {
|
|||
let mut outline = path.into_outline();
|
||||
outline.transform(&self.current_state.transform);
|
||||
|
||||
let clip_path_id = self.scene
|
||||
.push_clip_path(ClipPath::new(outline, fill_rule, String::new()));
|
||||
let mut clip_path = ClipPath::new(outline);
|
||||
clip_path.set_fill_rule(fill_rule);
|
||||
let clip_path_id = self.scene.push_clip_path(clip_path);
|
||||
|
||||
self.current_state.clip_path = Some(clip_path_id);
|
||||
}
|
||||
|
@ -234,6 +232,7 @@ impl CanvasRenderingContext2D {
|
|||
let clip_path = self.current_state.clip_path;
|
||||
let blend_mode = self.current_state.global_composite_operation.to_blend_mode();
|
||||
let composite_op = self.current_state.global_composite_operation.to_composite_op();
|
||||
let opacity = (self.current_state.global_alpha * 255.0) as u8;
|
||||
|
||||
if !self.current_state.shadow_paint.is_fully_transparent() {
|
||||
let render_target_id = self.push_render_target_if_needed(composite_op);
|
||||
|
@ -243,24 +242,24 @@ impl CanvasRenderingContext2D {
|
|||
|
||||
let mut outline = outline.clone();
|
||||
outline.transform(&Transform2F::from_translation(self.current_state.shadow_offset));
|
||||
self.scene.push_path(DrawPath::new(outline,
|
||||
paint_id,
|
||||
clip_path,
|
||||
fill_rule,
|
||||
blend_mode,
|
||||
String::new()));
|
||||
let mut path = DrawPath::new(outline, paint_id);
|
||||
path.set_clip_path(clip_path);
|
||||
path.set_fill_rule(fill_rule);
|
||||
path.set_blend_mode(blend_mode);
|
||||
path.set_opacity(opacity);
|
||||
self.scene.push_path(path);
|
||||
|
||||
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,
|
||||
paint_id,
|
||||
clip_path,
|
||||
fill_rule,
|
||||
blend_mode,
|
||||
String::new()));
|
||||
let mut path = DrawPath::new(outline, paint_id);
|
||||
path.set_clip_path(clip_path);
|
||||
path.set_fill_rule(fill_rule);
|
||||
path.set_blend_mode(blend_mode);
|
||||
path.set_opacity(opacity);
|
||||
self.scene.push_path(path);
|
||||
|
||||
self.composite_render_target_if_needed(composite_op, render_target_id);
|
||||
}
|
||||
|
@ -387,12 +386,11 @@ impl State {
|
|||
}
|
||||
|
||||
fn resolve_paint<'a>(&self, paint: &'a Paint) -> Cow<'a, Paint> {
|
||||
if self.global_alpha == 1.0 && (paint.is_color() || self.transform.is_identity()) {
|
||||
if self.transform.is_identity() {
|
||||
return Cow::Borrowed(paint);
|
||||
}
|
||||
|
||||
let mut paint = (*paint).clone();
|
||||
paint.set_opacity(self.global_alpha);
|
||||
paint.apply_transform(&self.transform);
|
||||
Cow::Owned(paint)
|
||||
}
|
||||
|
|
|
@ -148,12 +148,6 @@ impl Gradient {
|
|||
.lerp(upper_stop.color.to_f32(), (t - lower_stop.offset) / denom)
|
||||
.to_u8()
|
||||
}
|
||||
|
||||
pub fn set_opacity(&mut self, alpha: f32) {
|
||||
for stop in &mut self.stops.array {
|
||||
stop.color.a = (stop.color.a as f32 * alpha).round() as u8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ColorStop {
|
||||
|
|
|
@ -86,17 +86,6 @@ impl Image {
|
|||
pub fn is_opaque(&self) -> bool {
|
||||
self.is_opaque
|
||||
}
|
||||
|
||||
pub fn set_opacity(&mut self, alpha: f32) {
|
||||
debug_assert!(alpha >= 0.0 && alpha <= 1.0);
|
||||
if alpha == 1.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(pcwalton): Go four pixels at a time with SIMD.
|
||||
self.pixels.iter_mut().for_each(|pixel| pixel.a = (pixel.a as f32 * alpha).round() as u8);
|
||||
self.is_opaque = false;
|
||||
}
|
||||
}
|
||||
|
||||
impl PatternSource {
|
||||
|
@ -110,18 +99,6 @@ impl PatternSource {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_opacity(&mut self, alpha: f32) {
|
||||
match *self {
|
||||
PatternSource::Image(ref mut image) => image.set_opacity(alpha),
|
||||
PatternSource::RenderTarget(_) => {
|
||||
// TODO(pcwalton): We'll probably have to introduce and use an Opacity filter for
|
||||
// this.
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Image {
|
||||
|
|
|
@ -365,6 +365,9 @@ impl Device for MetalDevice {
|
|||
(VertexAttrClass::Int, VertexAttrType::I8, 1) => MTLVertexFormat::Char,
|
||||
(VertexAttrClass::Int, VertexAttrType::U8, 1) => MTLVertexFormat::UChar,
|
||||
(VertexAttrClass::FloatNorm, VertexAttrType::I8, 1) => MTLVertexFormat::CharNormalized,
|
||||
(VertexAttrClass::FloatNorm, VertexAttrType::U8, 1) => {
|
||||
MTLVertexFormat::UCharNormalized
|
||||
}
|
||||
(VertexAttrClass::Int, VertexAttrType::I16, 1) => MTLVertexFormat::Short,
|
||||
(VertexAttrClass::Int, VertexAttrType::U16, 1) => MTLVertexFormat::UShort,
|
||||
(VertexAttrClass::FloatNorm, VertexAttrType::U16, 1) => {
|
||||
|
|
|
@ -180,6 +180,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
TilingPathInfo::Draw {
|
||||
paint_metadata,
|
||||
blend_mode: path_object.blend_mode(),
|
||||
opacity: path_object.opacity(),
|
||||
built_clip_path,
|
||||
});
|
||||
|
||||
|
@ -670,27 +671,32 @@ impl ObjectBuilder {
|
|||
mask_tile_index: u16,
|
||||
tile_coords: Vector2I,
|
||||
object_index: u16,
|
||||
opacity: u8,
|
||||
paint_metadata: &PaintMetadata) {
|
||||
alpha_tiles.push(AlphaTile {
|
||||
upper_left: AlphaTileVertex::new(tile_coords,
|
||||
mask_tile_index,
|
||||
Vector2I::default(),
|
||||
object_index,
|
||||
opacity,
|
||||
paint_metadata),
|
||||
upper_right: AlphaTileVertex::new(tile_coords,
|
||||
mask_tile_index,
|
||||
Vector2I::new(1, 0),
|
||||
object_index,
|
||||
opacity,
|
||||
paint_metadata),
|
||||
lower_left: AlphaTileVertex::new(tile_coords,
|
||||
mask_tile_index,
|
||||
Vector2I::new(0, 1),
|
||||
object_index,
|
||||
opacity,
|
||||
paint_metadata),
|
||||
lower_right: AlphaTileVertex::new(tile_coords,
|
||||
mask_tile_index,
|
||||
Vector2I::splat(1),
|
||||
object_index,
|
||||
opacity,
|
||||
paint_metadata),
|
||||
});
|
||||
}
|
||||
|
@ -723,6 +729,7 @@ impl AlphaTileVertex {
|
|||
tile_index: u16,
|
||||
tile_offset: Vector2I,
|
||||
object_index: u16,
|
||||
opacity: u8,
|
||||
paint_metadata: &PaintMetadata)
|
||||
-> AlphaTileVertex {
|
||||
let tile_position = tile_origin + tile_offset;
|
||||
|
@ -737,6 +744,7 @@ impl AlphaTileVertex {
|
|||
mask_u: mask_uv.x() as u16,
|
||||
mask_v: mask_uv.y() as u16,
|
||||
object_index,
|
||||
opacity,
|
||||
pad: 0,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,6 +193,7 @@ impl<D> AlphaTileVertexArray<D> where D: Device {
|
|||
"ColorTexCoord").unwrap();
|
||||
let mask_tex_coord_attr = device.get_vertex_attr(&alpha_tile_program.program,
|
||||
"MaskTexCoord").unwrap();
|
||||
let opacity_attr = device.get_vertex_attr(&alpha_tile_program.program, "Opacity").unwrap();
|
||||
|
||||
device.bind_buffer(&vertex_array, alpha_tile_vertex_buffer, BufferTarget::Vertex);
|
||||
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
|
||||
|
@ -222,6 +223,15 @@ impl<D> AlphaTileVertexArray<D> where D: Device {
|
|||
divisor: 0,
|
||||
buffer_index: 0,
|
||||
});
|
||||
device.configure_vertex_attr(&vertex_array, &opacity_attr, &VertexAttrDescriptor {
|
||||
size: 1,
|
||||
class: VertexAttrClass::FloatNorm,
|
||||
attr_type: VertexAttrType::U8,
|
||||
stride: ALPHA_TILE_VERTEX_SIZE,
|
||||
offset: 14,
|
||||
divisor: 0,
|
||||
buffer_index: 0,
|
||||
});
|
||||
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
|
||||
|
||||
AlphaTileVertexArray { vertex_array }
|
||||
|
|
|
@ -173,7 +173,8 @@ pub struct AlphaTileVertex {
|
|||
pub color_u: u16,
|
||||
pub color_v: u16,
|
||||
pub object_index: u16,
|
||||
pub pad: u16,
|
||||
pub opacity: u8,
|
||||
pub pad: u8,
|
||||
}
|
||||
|
||||
impl Debug for RenderCommand {
|
||||
|
|
|
@ -113,18 +113,6 @@ impl Paint {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_opacity(&mut self, alpha: f32) {
|
||||
if alpha == 1.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
match *self {
|
||||
Paint::Color(ref mut color) => color.a = (color.a as f32 * alpha).round() as u8,
|
||||
Paint::Gradient(ref mut gradient) => gradient.set_opacity(alpha),
|
||||
Paint::Pattern(ref mut pattern) => pattern.source.set_opacity(alpha),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_transform(&mut self, transform: &Transform2F) {
|
||||
if transform.is_identity() {
|
||||
return;
|
||||
|
|
|
@ -226,6 +226,7 @@ pub struct DrawPath {
|
|||
clip_path: Option<ClipPathId>,
|
||||
fill_rule: FillRule,
|
||||
blend_mode: BlendMode,
|
||||
opacity: u8,
|
||||
name: String,
|
||||
}
|
||||
|
||||
|
@ -267,14 +268,16 @@ pub enum DisplayItem {
|
|||
|
||||
impl DrawPath {
|
||||
#[inline]
|
||||
pub fn new(outline: Outline,
|
||||
paint: PaintId,
|
||||
clip_path: Option<ClipPathId>,
|
||||
fill_rule: FillRule,
|
||||
blend_mode: BlendMode,
|
||||
name: String)
|
||||
-> DrawPath {
|
||||
DrawPath { outline, paint, clip_path, fill_rule, blend_mode, name }
|
||||
pub fn new(outline: Outline, paint: PaintId) -> DrawPath {
|
||||
DrawPath {
|
||||
outline,
|
||||
paint,
|
||||
clip_path: None,
|
||||
fill_rule: FillRule::Winding,
|
||||
blend_mode: BlendMode::SrcOver,
|
||||
opacity: !0,
|
||||
name: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -287,6 +290,11 @@ impl DrawPath {
|
|||
self.clip_path
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_clip_path(&mut self, new_clip_path: Option<ClipPathId>) {
|
||||
self.clip_path = new_clip_path
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn paint(&self) -> PaintId {
|
||||
self.paint
|
||||
|
@ -297,16 +305,41 @@ impl DrawPath {
|
|||
self.fill_rule
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_fill_rule(&mut self, new_fill_rule: FillRule) {
|
||||
self.fill_rule = new_fill_rule
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn blend_mode(&self) -> BlendMode {
|
||||
self.blend_mode
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_blend_mode(&mut self, new_blend_mode: BlendMode) {
|
||||
self.blend_mode = new_blend_mode
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn opacity(&self) -> u8 {
|
||||
self.opacity
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_opacity(&mut self, new_opacity: u8) {
|
||||
self.opacity = new_opacity
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_name(&mut self, new_name: String) {
|
||||
self.name = new_name
|
||||
}
|
||||
}
|
||||
|
||||
impl ClipPath {
|
||||
#[inline]
|
||||
pub fn new(outline: Outline, fill_rule: FillRule, name: String) -> ClipPath {
|
||||
ClipPath { outline, fill_rule, name }
|
||||
pub fn new(outline: Outline) -> ClipPath {
|
||||
ClipPath { outline, fill_rule: FillRule::Winding, name: String::new() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -318,6 +351,16 @@ impl ClipPath {
|
|||
pub(crate) fn fill_rule(&self) -> FillRule {
|
||||
self.fill_rule
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_fill_rule(&mut self, new_fill_rule: FillRule) {
|
||||
self.fill_rule = new_fill_rule
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_name(&mut self, new_name: String) {
|
||||
self.name = new_name
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderTarget {
|
||||
|
|
|
@ -46,6 +46,7 @@ pub(crate) enum TilingPathInfo<'a> {
|
|||
Draw {
|
||||
paint_metadata: &'a PaintMetadata,
|
||||
blend_mode: BlendMode,
|
||||
opacity: u8,
|
||||
built_clip_path: Option<&'a BuiltPath>,
|
||||
},
|
||||
}
|
||||
|
@ -127,10 +128,10 @@ impl<'a> Tiler<'a> {
|
|||
}
|
||||
|
||||
fn pack_and_cull_draw_path(&mut self) {
|
||||
let (paint_metadata, blend_mode, built_clip_path) = match self.path_info {
|
||||
let (paint_metadata, blend_mode, opacity, built_clip_path) = match self.path_info {
|
||||
TilingPathInfo::Clip => unreachable!(),
|
||||
TilingPathInfo::Draw { paint_metadata, blend_mode, built_clip_path } => {
|
||||
(paint_metadata, blend_mode, built_clip_path)
|
||||
TilingPathInfo::Draw { paint_metadata, blend_mode, opacity, built_clip_path } => {
|
||||
(paint_metadata, blend_mode, opacity, built_clip_path)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -181,7 +182,7 @@ impl<'a> Tiler<'a> {
|
|||
|
||||
// Next, if this is a solid tile that completely occludes the background, record
|
||||
// that fact and stop here.
|
||||
if paint_metadata.is_opaque && blend_mode.occludes_backdrop() {
|
||||
if paint_metadata.is_opaque && blend_mode.occludes_backdrop() && opacity == !0 {
|
||||
self.object_builder.built_path.solid_tiles.push(SolidTile::new(tile_coords));
|
||||
continue;
|
||||
}
|
||||
|
@ -209,6 +210,7 @@ impl<'a> Tiler<'a> {
|
|||
mask_tile_index,
|
||||
tile_coords,
|
||||
self.object_index,
|
||||
opacity,
|
||||
paint_metadata);
|
||||
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@ uniform vec2 uFramebufferSize;
|
|||
|
||||
in vec2 vColorTexCoord;
|
||||
in vec2 vMaskTexCoord;
|
||||
in float vOpacity;
|
||||
|
||||
|
||||
vec4 sampleSrcColor(){
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||
}
|
||||
|
||||
vec4 sampleDestColor(){
|
||||
|
|
|
@ -20,15 +20,18 @@ uniform vec2 uTileSize;
|
|||
in ivec2 aTilePosition;
|
||||
in vec2 aColorTexCoord;
|
||||
in vec2 aMaskTexCoord;
|
||||
in float aOpacity;
|
||||
|
||||
out vec2 vColorTexCoord;
|
||||
out vec2 vMaskTexCoord;
|
||||
out float vOpacity;
|
||||
|
||||
void main(){
|
||||
vec2 position = aTilePosition * uTileSize;
|
||||
|
||||
vMaskTexCoord = aMaskTexCoord;
|
||||
vColorTexCoord = aColorTexCoord;
|
||||
vOpacity = aOpacity;
|
||||
gl_Position = uTransform * vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,12 +38,13 @@ uniform vec2 uFramebufferSize;
|
|||
|
||||
in vec2 vColorTexCoord;
|
||||
in vec2 vMaskTexCoord;
|
||||
in float vOpacity;
|
||||
|
||||
|
||||
vec4 sampleSrcColor(){
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||
}
|
||||
|
||||
vec4 sampleDestColor(){
|
||||
|
|
|
@ -40,12 +40,13 @@ uniform vec2 uFramebufferSize;
|
|||
|
||||
in vec2 vColorTexCoord;
|
||||
in vec2 vMaskTexCoord;
|
||||
in float vOpacity;
|
||||
|
||||
|
||||
vec4 sampleSrcColor(){
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||
}
|
||||
|
||||
vec4 sampleDestColor(){
|
||||
|
|
|
@ -38,12 +38,13 @@ uniform vec2 uFramebufferSize;
|
|||
|
||||
in vec2 vColorTexCoord;
|
||||
in vec2 vMaskTexCoord;
|
||||
in float vOpacity;
|
||||
|
||||
|
||||
vec4 sampleSrcColor(){
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||
}
|
||||
|
||||
vec4 sampleDestColor(){
|
||||
|
|
|
@ -38,12 +38,13 @@ uniform vec2 uFramebufferSize;
|
|||
|
||||
in vec2 vColorTexCoord;
|
||||
in vec2 vMaskTexCoord;
|
||||
in float vOpacity;
|
||||
|
||||
|
||||
vec4 sampleSrcColor(){
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||
}
|
||||
|
||||
vec4 sampleDestColor(){
|
||||
|
|
|
@ -45,12 +45,13 @@ uniform vec2 uFramebufferSize;
|
|||
|
||||
in vec2 vColorTexCoord;
|
||||
in vec2 vMaskTexCoord;
|
||||
in float vOpacity;
|
||||
|
||||
|
||||
vec4 sampleSrcColor(){
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||
}
|
||||
|
||||
vec4 sampleDestColor(){
|
||||
|
|
|
@ -38,12 +38,13 @@ uniform vec2 uFramebufferSize;
|
|||
|
||||
in vec2 vColorTexCoord;
|
||||
in vec2 vMaskTexCoord;
|
||||
in float vOpacity;
|
||||
|
||||
|
||||
vec4 sampleSrcColor(){
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||
}
|
||||
|
||||
vec4 sampleDestColor(){
|
||||
|
|
|
@ -23,19 +23,20 @@ struct main0_in
|
|||
{
|
||||
float2 vColorTexCoord [[user(locn0)]];
|
||||
float2 vMaskTexCoord [[user(locn1)]];
|
||||
float vOpacity [[user(locn2)]];
|
||||
};
|
||||
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||
{
|
||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
||||
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||
}
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||
out.oFragColor = float4(srcRGBA.xyz * srcRGBA.w, srcRGBA.w);
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ struct main0_out
|
|||
{
|
||||
float2 vColorTexCoord [[user(locn0)]];
|
||||
float2 vMaskTexCoord [[user(locn1)]];
|
||||
float vOpacity [[user(locn2)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
|
@ -22,6 +23,7 @@ struct main0_in
|
|||
int2 aTilePosition [[attribute(0)]];
|
||||
float2 aColorTexCoord [[attribute(1)]];
|
||||
float2 aMaskTexCoord [[attribute(2)]];
|
||||
float aOpacity [[attribute(3)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||
|
@ -30,6 +32,7 @@ vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer
|
|||
float2 position = float2(in.aTilePosition) * (*spvDescriptorSet0.uTileSize);
|
||||
out.vMaskTexCoord = in.aMaskTexCoord;
|
||||
out.vColorTexCoord = in.aColorTexCoord;
|
||||
out.vOpacity = in.aOpacity;
|
||||
out.gl_Position = (*spvDescriptorSet0.uTransform) * float4(position, 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -26,13 +26,14 @@ struct main0_in
|
|||
{
|
||||
float2 vColorTexCoord [[user(locn0)]];
|
||||
float2 vMaskTexCoord [[user(locn1)]];
|
||||
float vOpacity [[user(locn2)]];
|
||||
};
|
||||
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||
{
|
||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
||||
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||
}
|
||||
|
||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||
|
@ -49,7 +50,7 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
|||
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 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||
float3 blended = abs(destRGBA.xyz - srcRGBA.xyz);
|
||||
float4 param = destRGBA;
|
||||
|
|
|
@ -27,13 +27,14 @@ struct main0_in
|
|||
{
|
||||
float2 vColorTexCoord [[user(locn0)]];
|
||||
float2 vMaskTexCoord [[user(locn1)]];
|
||||
float vOpacity [[user(locn2)]];
|
||||
};
|
||||
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||
{
|
||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
||||
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||
}
|
||||
|
||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||
|
@ -50,57 +51,57 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
|||
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 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||
float3 _118;
|
||||
float3 _122;
|
||||
if ((*spvDescriptorSet0.uBurn) == 0)
|
||||
{
|
||||
_118 = destRGBA.xyz;
|
||||
_122 = destRGBA.xyz;
|
||||
}
|
||||
else
|
||||
{
|
||||
_118 = float3(1.0) - destRGBA.xyz;
|
||||
_122 = float3(1.0) - destRGBA.xyz;
|
||||
}
|
||||
float3 dest = _118;
|
||||
float3 _132;
|
||||
float3 dest = _122;
|
||||
float3 _136;
|
||||
if ((*spvDescriptorSet0.uBurn) == 0)
|
||||
{
|
||||
_132 = float3(1.0) - srcRGBA.xyz;
|
||||
_136 = float3(1.0) - srcRGBA.xyz;
|
||||
}
|
||||
else
|
||||
{
|
||||
_132 = srcRGBA.xyz;
|
||||
_136 = srcRGBA.xyz;
|
||||
}
|
||||
float3 src = _132;
|
||||
float3 src = _136;
|
||||
bool3 srcNonzero = src != float3(0.0);
|
||||
float _153;
|
||||
float _157;
|
||||
if (srcNonzero.x)
|
||||
{
|
||||
_153 = dest.x / src.x;
|
||||
_157 = dest.x / src.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_153 = 1.0;
|
||||
_157 = 1.0;
|
||||
}
|
||||
float _166;
|
||||
float _170;
|
||||
if (srcNonzero.y)
|
||||
{
|
||||
_166 = dest.y / src.y;
|
||||
_170 = dest.y / src.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_166 = 1.0;
|
||||
_170 = 1.0;
|
||||
}
|
||||
float _179;
|
||||
float _183;
|
||||
if (srcNonzero.z)
|
||||
{
|
||||
_179 = dest.z / src.z;
|
||||
_183 = dest.z / src.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_179 = 1.0;
|
||||
_183 = 1.0;
|
||||
}
|
||||
float3 blended = fast::min(float3(_153, _166, _179), float3(1.0));
|
||||
float3 blended = fast::min(float3(_157, _170, _183), float3(1.0));
|
||||
if ((*spvDescriptorSet0.uBurn) != 0)
|
||||
{
|
||||
blended = float3(1.0) - blended;
|
||||
|
|
|
@ -26,13 +26,14 @@ struct main0_in
|
|||
{
|
||||
float2 vColorTexCoord [[user(locn0)]];
|
||||
float2 vMaskTexCoord [[user(locn1)]];
|
||||
float vOpacity [[user(locn2)]];
|
||||
};
|
||||
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||
{
|
||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
||||
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||
}
|
||||
|
||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||
|
@ -49,7 +50,7 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
|||
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 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||
float3 dest = destRGBA.xyz;
|
||||
float3 src = srcRGBA.xyz;
|
||||
|
|
|
@ -27,6 +27,7 @@ struct main0_in
|
|||
{
|
||||
float2 vColorTexCoord [[user(locn0)]];
|
||||
float2 vMaskTexCoord [[user(locn1)]];
|
||||
float vOpacity [[user(locn2)]];
|
||||
};
|
||||
|
||||
// Implementation of the GLSL mod() function, which is slightly different than Metal fmod()
|
||||
|
@ -36,11 +37,11 @@ Tx mod(Tx x, Ty y)
|
|||
return x - y * floor(x / y);
|
||||
}
|
||||
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||
{
|
||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
||||
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||
}
|
||||
|
||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||
|
@ -85,34 +86,34 @@ float3 convertRGBToHSL(thread const float3& rgb)
|
|||
|
||||
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
||||
{
|
||||
float _125;
|
||||
float _129;
|
||||
if (cond.x)
|
||||
{
|
||||
_125 = a.x;
|
||||
_129 = a.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_125 = b.x;
|
||||
_129 = b.x;
|
||||
}
|
||||
float _137;
|
||||
float _141;
|
||||
if (cond.y)
|
||||
{
|
||||
_137 = a.y;
|
||||
_141 = a.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_137 = b.y;
|
||||
_141 = b.y;
|
||||
}
|
||||
float _149;
|
||||
float _153;
|
||||
if (cond.z)
|
||||
{
|
||||
_149 = a.z;
|
||||
_153 = a.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_149 = b.z;
|
||||
_153 = b.z;
|
||||
}
|
||||
return float3(_125, _137, _149);
|
||||
return float3(_129, _141, _153);
|
||||
}
|
||||
|
||||
float3 convertHSLToRGB(thread const float3& hsl)
|
||||
|
@ -130,7 +131,7 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
|||
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 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||
float3 param = destRGBA.xyz;
|
||||
float3 destHSL = convertRGBToHSL(param);
|
||||
|
|
|
@ -27,13 +27,14 @@ struct main0_in
|
|||
{
|
||||
float2 vColorTexCoord [[user(locn0)]];
|
||||
float2 vMaskTexCoord [[user(locn1)]];
|
||||
float vOpacity [[user(locn2)]];
|
||||
};
|
||||
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||
{
|
||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
||||
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||
}
|
||||
|
||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||
|
@ -44,34 +45,34 @@ float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSi
|
|||
|
||||
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
||||
{
|
||||
float _118;
|
||||
float _122;
|
||||
if (cond.x)
|
||||
{
|
||||
_118 = a.x;
|
||||
_122 = a.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_118 = b.x;
|
||||
_122 = b.x;
|
||||
}
|
||||
float _130;
|
||||
float _134;
|
||||
if (cond.y)
|
||||
{
|
||||
_130 = a.y;
|
||||
_134 = a.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_130 = b.y;
|
||||
_134 = b.y;
|
||||
}
|
||||
float _142;
|
||||
float _146;
|
||||
if (cond.z)
|
||||
{
|
||||
_142 = a.z;
|
||||
_146 = a.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_142 = b.z;
|
||||
_146 = b.z;
|
||||
}
|
||||
return float3(_118, _130, _142);
|
||||
return float3(_122, _134, _146);
|
||||
}
|
||||
|
||||
float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA, thread const float3& blendedRGB)
|
||||
|
@ -82,29 +83,29 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
|||
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 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||
bool reversed = (*spvDescriptorSet0.uBlendMode) == 3;
|
||||
float3 _167;
|
||||
float3 _171;
|
||||
if (reversed)
|
||||
{
|
||||
_167 = srcRGBA.xyz;
|
||||
_171 = srcRGBA.xyz;
|
||||
}
|
||||
else
|
||||
{
|
||||
_167 = destRGBA.xyz;
|
||||
_171 = destRGBA.xyz;
|
||||
}
|
||||
float3 src = _167;
|
||||
float3 _178;
|
||||
float3 src = _171;
|
||||
float3 _182;
|
||||
if (reversed)
|
||||
{
|
||||
_178 = destRGBA.xyz;
|
||||
_182 = destRGBA.xyz;
|
||||
}
|
||||
else
|
||||
{
|
||||
_178 = srcRGBA.xyz;
|
||||
_182 = srcRGBA.xyz;
|
||||
}
|
||||
float3 dest = _178;
|
||||
float3 dest = _182;
|
||||
float3 multiply = src * dest;
|
||||
float3 blended;
|
||||
if ((*spvDescriptorSet0.uBlendMode) == 0)
|
||||
|
|
|
@ -26,13 +26,14 @@ struct main0_in
|
|||
{
|
||||
float2 vColorTexCoord [[user(locn0)]];
|
||||
float2 vMaskTexCoord [[user(locn1)]];
|
||||
float vOpacity [[user(locn2)]];
|
||||
};
|
||||
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||
{
|
||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
||||
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||
}
|
||||
|
||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||
|
@ -43,34 +44,34 @@ float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSi
|
|||
|
||||
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
||||
{
|
||||
float _118;
|
||||
float _122;
|
||||
if (cond.x)
|
||||
{
|
||||
_118 = a.x;
|
||||
_122 = a.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_118 = b.x;
|
||||
_122 = b.x;
|
||||
}
|
||||
float _130;
|
||||
float _134;
|
||||
if (cond.y)
|
||||
{
|
||||
_130 = a.y;
|
||||
_134 = a.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_130 = b.y;
|
||||
_134 = b.y;
|
||||
}
|
||||
float _142;
|
||||
float _146;
|
||||
if (cond.z)
|
||||
{
|
||||
_142 = a.z;
|
||||
_146 = a.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_142 = b.z;
|
||||
_146 = b.z;
|
||||
}
|
||||
return float3(_118, _130, _142);
|
||||
return float3(_122, _134, _146);
|
||||
}
|
||||
|
||||
float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA, thread const float3& blendedRGB)
|
||||
|
@ -81,7 +82,7 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
|||
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 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||
float3 dest = destRGBA.xyz;
|
||||
float3 src = srcRGBA.xyz;
|
||||
|
|
|
@ -18,14 +18,17 @@ uniform vec2 uTileSize;
|
|||
in ivec2 aTilePosition;
|
||||
in vec2 aColorTexCoord;
|
||||
in vec2 aMaskTexCoord;
|
||||
in float aOpacity;
|
||||
|
||||
out vec2 vColorTexCoord;
|
||||
out vec2 vMaskTexCoord;
|
||||
out float vOpacity;
|
||||
|
||||
void main() {
|
||||
vec2 position = aTilePosition * uTileSize;
|
||||
|
||||
vMaskTexCoord = aMaskTexCoord;
|
||||
vColorTexCoord = aColorTexCoord;
|
||||
vOpacity = aOpacity;
|
||||
gl_Position = uTransform * vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -15,12 +15,13 @@ uniform vec2 uFramebufferSize;
|
|||
|
||||
in vec2 vColorTexCoord;
|
||||
in vec2 vMaskTexCoord;
|
||||
in float vOpacity;
|
||||
|
||||
// NB: This does not premultiply.
|
||||
vec4 sampleSrcColor() {
|
||||
float coverage = texture(uStencilTexture, vMaskTexCoord).r;
|
||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||
return vec4(srcRGBA.rgb, srcRGBA.a * coverage);
|
||||
return vec4(srcRGBA.rgb, srcRGBA.a * coverage * vOpacity);
|
||||
}
|
||||
|
||||
vec4 sampleDestColor() {
|
||||
|
|
|
@ -15,7 +15,6 @@ extern crate bitflags;
|
|||
|
||||
use hashbrown::HashMap;
|
||||
use pathfinder_color::ColorU;
|
||||
use pathfinder_content::effects::BlendMode;
|
||||
use pathfinder_content::fill::FillRule;
|
||||
use pathfinder_content::outline::Outline;
|
||||
use pathfinder_content::segment::{Segment, SegmentFlags};
|
||||
|
@ -180,9 +179,9 @@ impl BuiltSVG {
|
|||
}
|
||||
|
||||
if let Some(clip_outline) = clip_outline {
|
||||
let name = format!("ClipPath({})", node.id());
|
||||
// FIXME(pcwalton): Is the winding fill rule correct to use?
|
||||
let clip_path = ClipPath::new(clip_outline, FillRule::Winding, name);
|
||||
let mut clip_path = ClipPath::new(clip_outline);
|
||||
clip_path.set_name(format!("ClipPath({})", node.id()));
|
||||
let clip_path_id = self.scene.push_clip_path(clip_path);
|
||||
self.clip_paths.insert(node.id().to_owned(), clip_path_id);
|
||||
}
|
||||
|
@ -232,16 +231,14 @@ impl BuiltSVG {
|
|||
paint: &UsvgPaint,
|
||||
opacity: Opacity,
|
||||
fill_rule: UsvgFillRule) {
|
||||
let style = self.scene.push_paint(&Paint::from_svg_paint(paint,
|
||||
opacity,
|
||||
&mut self.result_flags));
|
||||
let style = self.scene.push_paint(&Paint::from_svg_paint(paint, &mut self.result_flags));
|
||||
let fill_rule = FillRule::from_usvg_fill_rule(fill_rule);
|
||||
self.scene.push_path(DrawPath::new(outline,
|
||||
style,
|
||||
state.clip_path,
|
||||
fill_rule,
|
||||
BlendMode::SrcOver,
|
||||
name));
|
||||
let mut path = DrawPath::new(outline, style);
|
||||
path.set_clip_path(state.clip_path);
|
||||
path.set_fill_rule(fill_rule);
|
||||
path.set_name(name);
|
||||
path.set_opacity((opacity.value() * 255.0) as u8);
|
||||
self.scene.push_path(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,17 +285,15 @@ impl Display for BuildResultFlags {
|
|||
}
|
||||
|
||||
trait PaintExt {
|
||||
fn from_svg_paint(svg_paint: &UsvgPaint, opacity: Opacity, result_flags: &mut BuildResultFlags)
|
||||
-> Self;
|
||||
fn from_svg_paint(svg_paint: &UsvgPaint, result_flags: &mut BuildResultFlags) -> Self;
|
||||
}
|
||||
|
||||
impl PaintExt for Paint {
|
||||
#[inline]
|
||||
fn from_svg_paint(svg_paint: &UsvgPaint, opacity: Opacity, result_flags: &mut BuildResultFlags)
|
||||
-> Paint {
|
||||
fn from_svg_paint(svg_paint: &UsvgPaint, result_flags: &mut BuildResultFlags) -> Paint {
|
||||
// TODO(pcwalton): Support gradients.
|
||||
Paint::Color(match *svg_paint {
|
||||
UsvgPaint::Color(color) => ColorU::from_svg_color(color, opacity),
|
||||
UsvgPaint::Color(color) => ColorU::from_svg_color(color),
|
||||
UsvgPaint::Link(_) => {
|
||||
// TODO(pcwalton)
|
||||
result_flags.insert(BuildResultFlags::UNSUPPORTED_LINK_PAINT);
|
||||
|
@ -412,18 +407,13 @@ where
|
|||
}
|
||||
|
||||
trait ColorUExt {
|
||||
fn from_svg_color(svg_color: SvgColor, opacity: Opacity) -> Self;
|
||||
fn from_svg_color(svg_color: SvgColor) -> Self;
|
||||
}
|
||||
|
||||
impl ColorUExt for ColorU {
|
||||
#[inline]
|
||||
fn from_svg_color(svg_color: SvgColor, opacity: Opacity) -> ColorU {
|
||||
ColorU {
|
||||
r: svg_color.red,
|
||||
g: svg_color.green,
|
||||
b: svg_color.blue,
|
||||
a: (opacity.value() * 255.0).round() as u8,
|
||||
}
|
||||
fn from_svg_color(svg_color: SvgColor) -> ColorU {
|
||||
ColorU { r: svg_color.red, g: svg_color.green, b: svg_color.blue, a: !0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
use std::ops::Add;
|
||||
use pathfinder_color::{ColorF, ColorU};
|
||||
use pathfinder_content::effects::BlendMode;
|
||||
use pathfinder_content::fill::FillRule;
|
||||
use pathfinder_content::outline::{Outline, Contour};
|
||||
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
||||
|
@ -196,14 +195,9 @@ pub fn draw_paths_into_scene(library: &SymbolLibrary, scene: &mut Scene) {
|
|||
path = stroke_to_fill.into_outline();
|
||||
}
|
||||
|
||||
scene.push_path(DrawPath::new(
|
||||
path,
|
||||
paint_id,
|
||||
None,
|
||||
FillRule::EvenOdd,
|
||||
BlendMode::SrcOver,
|
||||
String::new()
|
||||
));
|
||||
let mut path = DrawPath::new(path, paint_id);
|
||||
path.set_fill_rule(FillRule::EvenOdd);
|
||||
scene.push_path(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ use font_kit::error::GlyphLoadingError;
|
|||
use font_kit::hinting::HintingOptions;
|
||||
use font_kit::loader::Loader;
|
||||
use lyon_path::builder::{FlatPathBuilder, PathBuilder, Build};
|
||||
use pathfinder_content::effects::BlendMode;
|
||||
use pathfinder_content::fill::FillRule;
|
||||
use pathfinder_content::outline::{Contour, Outline};
|
||||
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
||||
use pathfinder_geometry::transform2d::Transform2F;
|
||||
|
@ -78,13 +76,7 @@ impl SceneExt for Scene {
|
|||
outline = stroke_to_fill.into_outline();
|
||||
}
|
||||
|
||||
self.push_path(DrawPath::new(outline,
|
||||
paint_id,
|
||||
None,
|
||||
FillRule::Winding,
|
||||
BlendMode::SrcOver,
|
||||
String::new()));
|
||||
|
||||
self.push_path(DrawPath::new(outline, paint_id));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue