Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perspective interpolation fix for brush_blend #2991

Merged
merged 2 commits into from Aug 30, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -32,7 +32,10 @@ void brush_vs(
vec2 uv = snap_device_pos(vi) +
src_task.common_data.task_rect.p0 -
src_task.content_origin;
vUv = vec3(uv / texture_size, src_task.common_data.texture_layer_index);
vUv = vec3(
uv * gl_Position.w / texture_size, // multiply by W to compensate for perspective interpolation
src_task.common_data.texture_layer_index
);

vec2 uv0 = src_task.common_data.task_rect.p0;
vec2 uv1 = uv0 + src_task.common_data.task_rect.size;
@@ -124,7 +127,8 @@ vec3 Brightness(vec3 Cs, float amount) {
}

Fragment brush_fs() {
vec4 Cs = texture(sColor0, vUv);
vec2 base_uv = vUv.xy * gl_FragCoord.w;
vec4 Cs = texture(sColor0, vec3(base_uv, vUv.z));

if (Cs.a == 0.0) {
return Fragment(vec4(0.0)); // could also `discard`
@@ -155,7 +159,7 @@ Fragment brush_fs() {

// Fail-safe to ensure that we don't sample outside the rendered
// portion of a blend source.
alpha *= point_inside_rect(vUv.xy, vUvClipBounds.xy, vUvClipBounds.zw);
alpha *= point_inside_rect(base_uv, vUvClipBounds.xy, vUvClipBounds.zw);

// Pre-multiply the alpha into the output value.
return Fragment(alpha * vec4(color, 1.0));
@@ -829,6 +829,7 @@ impl AlphaBatchBuilder {
);

let filter_mode = match filter {
FilterOp::Identity => 1, // matches `Contrast(1)`
FilterOp::Blur(..) => 0,
FilterOp::Contrast(..) => 1,
FilterOp::Grayscale(..) => 2,
@@ -843,6 +844,7 @@ impl AlphaBatchBuilder {
};

let user_data = match filter {
FilterOp::Identity => 0x10000i32, // matches `Contrast(1)`
FilterOp::Contrast(amount) |
FilterOp::Grayscale(amount) |
FilterOp::Invert(amount) |
@@ -201,6 +201,7 @@ pub trait FilterOpHelpers {
impl FilterOpHelpers for FilterOp {
fn is_visible(&self) -> bool {
match *self {
FilterOp::Identity |
FilterOp::Blur(..) |
FilterOp::Brightness(..) |
FilterOp::Contrast(..) |
@@ -219,6 +220,7 @@ impl FilterOpHelpers for FilterOp {

fn is_noop(&self) -> bool {
match *self {
FilterOp::Identity => false, // this is intentional
FilterOp::Blur(length) => length == 0.0,
FilterOp::Brightness(amount) => amount == 1.0,
FilterOp::Contrast(amount) => amount == 1.0,
@@ -543,6 +543,9 @@ pub enum MixBlendMode {

#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
pub enum FilterOp {
/// Filter that does no transformation of the colors, needed for
/// debug purposes only.
Identity,
Blur(f32),
Brightness(f32),
Contrast(f32),
@@ -13,7 +13,8 @@ platform(linux,mac) == content-offset.yaml content-offset.png
platform(linux,mac) == coord-system.yaml coord-system.png
platform(linux,mac) zoom(4) == border-zoom.yaml border-zoom.png
platform(linux) fuzzy(1,520) == perspective-origin.yaml perspective-origin.png
platform(linux,mac) color_targets(1) alpha_targets(0) fuzzy(1,180) == screen-space-blit.yaml screen-space-blit.png
platform(linux,mac) color_targets(2) alpha_targets(0) fuzzy(1,180) == screen-space-blit.yaml screen-space-blit.png
platform(linux,mac) color_targets(1) alpha_targets(0) fuzzy(128,800) == screen-space-blit-trivial.yaml screen-space-blit.png
platform(linux) fuzzy(11,4592) == screen-space-blur.yaml screen-space-blur.png
platform(linux,mac) == nested-rotate-x.yaml nested-rotate-x.png
platform(linux,mac) == nested-preserve-3d.yaml nested-preserve-3d.png
@@ -0,0 +1,22 @@
# This test is similar to "screen-space-blit" but without filters,
# so the implementation doesn't attempt to bake the contents
# into a separate render target.
---
root:
items:
- type: "stacking-context"
perspective: 100
perspective-origin: 100 100
items:
- type: "stacking-context"
transform-origin: 235 235
transform: rotate-x(15)
items:
- image: checkerboard(2, 16, 16)
bounds: [100, 100, 260, 260]
- type: "stacking-context"
transform-origin: 635 235
transform: rotate-z(45)
items:
- image: checkerboard(2, 16, 16)
bounds: [500, 100, 260, 260]
Binary file not shown.
@@ -1,3 +1,6 @@
# This test uses `identity` filter on a preserve3D context to test how
# filters mix up with the SC's baking for preserve3d.
---
root:
items:
- type: "stacking-context"
@@ -7,14 +10,13 @@ root:
- type: "stacking-context"
transform-origin: 235 235
transform: rotate-x(15)
filters: opacity(0.5)
filters: identity
items:
- image: checkerboard(2, 16, 16)
bounds: [100, 100, 260, 260]
- type: "stacking-context"
transform-origin: 635 235
transform: rotate-z(45)
filters: opacity(0.5)
items:
- image: checkerboard(2, 16, 16)
bounds: [500, 100, 260, 260]
@@ -228,6 +228,7 @@ fn write_stacking_context(
let mut filters = vec![];
for filter in filter_iter {
match filter {
FilterOp::Identity => { filters.push(Yaml::String("identity".into())) }
FilterOp::Blur(x) => { filters.push(Yaml::String(format!("blur({})", x))) }
FilterOp::Brightness(x) => { filters.push(Yaml::String(format!("brightness({})", x))) }
FilterOp::Contrast(x) => { filters.push(Yaml::String(format!("contrast({})", x))) }
@@ -544,6 +544,9 @@ impl YamlHelper for Yaml {
fn as_filter_op(&self) -> Option<FilterOp> {
if let Some(s) = self.as_str() {
match parse_function(s) {
("identity", _, _) => {
Some(FilterOp::Identity)
}
("blur", ref args, _) if args.len() == 1 => {
Some(FilterOp::Blur(args[0].parse().unwrap()))
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.