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

Full rectangular pixel snapping #1292

Merged
merged 3 commits into from May 26, 2017
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Full rectangular pixel snapping

  • Loading branch information
kvark committed May 26, 2017
commit 0a6626bcf3760056c4b2294c0b6c1911f751c042
@@ -84,23 +84,16 @@ vec2 clamp_rect(vec2 point, RectWithEndpoint rect) {
return clamp(point, rect.p0, rect.p1);
}

// Clamp 2 points at once.
vec4 clamp_rect(vec4 points, RectWithSize rect) {
return clamp(points, rect.p0.xyxy, rect.p0.xyxy + rect.size.xyxy);
}

vec4 clamp_rect(vec4 points, RectWithEndpoint rect) {
return clamp(points, rect.p0.xyxy, rect.p1.xyxy);
RectWithEndpoint intersect_rect(RectWithEndpoint a, RectWithEndpoint b) {
vec2 p0 = clamp_rect(a.p0, b);
vec2 p1 = clamp_rect(a.p1, b);
return RectWithEndpoint(p0, max(p0, p1));
}

RectWithSize intersect_rect(RectWithSize a, RectWithSize b) {
vec4 p = clamp_rect(vec4(a.p0, a.p0 + a.size), b);
return RectWithSize(p.xy, max(vec2(0.0), p.zw - p.xy));
}

RectWithEndpoint intersect_rect(RectWithEndpoint a, RectWithEndpoint b) {
vec4 p = clamp_rect(vec4(a.p0, a.p1), b);
return RectWithEndpoint(p.xy, max(p.xy, p.zw));
RectWithEndpoint r = intersect_rect(to_rect_with_endpoint(a),
to_rect_with_endpoint(b));
return to_rect_with_size(r);
}

float distance_to_line(vec2 p0, vec2 perp_dir, vec2 p) {
@@ -573,38 +566,46 @@ VertexInfo write_vertex(RectWithSize instance_rect,
float z,
Layer layer,
AlphaBatchTask task,
vec2 snap_ref) {
RectWithSize snap_rect) {

// Select the corner of the local rect that we are processing.
vec2 local_pos = instance_rect.p0 + instance_rect.size * aPosition.xy;

// xy = top left corner of the local rect, zw = position of current vertex.
vec4 local_p0_pos = vec4(snap_ref, local_pos);

// Clamp to the two local clip rects.
local_p0_pos = clamp_rect(local_p0_pos, local_clip_rect);
local_p0_pos = clamp_rect(local_p0_pos, layer.local_clip_rect);

// Transform the top corner and current vertex to world space.
vec4 world_p0 = layer.transform * vec4(local_p0_pos.xy, 0.0, 1.0);
world_p0.xyz /= world_p0.w;
vec4 world_pos = layer.transform * vec4(local_p0_pos.zw, 0.0, 1.0);
world_pos.xyz /= world_pos.w;

// Convert the world positions to device pixel space. xy=top left corner. zw=current vertex.
vec4 device_p0_pos = vec4(world_p0.xy, world_pos.xy) * uDevicePixelRatio;

// Calculate the distance to snap the vertex by (snap top left corner).
vec2 snap_delta = device_p0_pos.xy - floor(device_p0_pos.xy + 0.5);
vec2 clamped_local_pos = clamp_rect(clamp_rect(local_pos, local_clip_rect),
layer.local_clip_rect);

// Adjust the snap rectangle.
RectWithSize clamped_snap_rect = intersect_rect(intersect_rect(snap_rect, local_clip_rect),
layer.local_clip_rect);
// Transform the snap corners to the world space.
vec4 world_snap_p0 = layer.transform * vec4(clamped_snap_rect.p0, 0.0, 1.0);
vec4 world_snap_p1 = layer.transform * vec4(clamped_snap_rect.p0 + clamped_snap_rect.size, 0.0, 1.0);
// Snap bounds in world coordinates, adjusted for pixel ratio. XY = top left, ZW = bottom right
vec4 world_snap = uDevicePixelRatio * vec4(world_snap_p0.xy, world_snap_p1.xy) /
vec4(world_snap_p0.ww, world_snap_p1.ww);
/// World offsets applied to the corners of the snap rectangle.
vec4 snap_offsets = floor(world_snap + 0.5) - world_snap;

/// Compute the position of this vertex inside the snap rectangle.
vec2 normalized_snap_pos = (clamped_local_pos - clamped_snap_rect.p0) / clamped_snap_rect.size;
/// Compute the actual world offset for this vertex needed to make it snap.
vec2 snap_offset = mix(snap_offsets.xy, snap_offsets.zw, normalized_snap_pos);

// Transform the current vertex to the world cpace.
vec4 world_pos = layer.transform * vec4(clamped_local_pos, 0.0, 1.0);

// Convert the world positions to device pixel space.
vec2 device_pos = world_pos.xy / world_pos.w * uDevicePixelRatio;

// Apply offsets for the render task to get correct screen location.
vec2 final_pos = device_p0_pos.zw -
snap_delta -
vec2 final_pos = device_pos + snap_offset -
task.screen_space_origin +
task.render_target_origin;

gl_Position = uTransform * vec4(final_pos, z, 1.0);

VertexInfo vi = VertexInfo(local_p0_pos.zw, device_p0_pos.zw);
VertexInfo vi = VertexInfo(clamped_local_pos, device_pos);
return vi;
}

@@ -639,7 +640,7 @@ TransformVertexInfo write_transform_vertex(RectWithSize instance_rect,
float z,
Layer layer,
AlphaBatchTask task,
vec2 snap_ref) {
RectWithSize snap_rect) {
RectWithEndpoint local_rect = to_rect_with_endpoint(instance_rect);

vec2 current_local_pos, prev_local_pos, next_local_pos;
@@ -699,7 +700,8 @@ TransformVertexInfo write_transform_vertex(RectWithSize instance_rect,
adjusted_next_p1);

// Calculate the snap amount based on the first vertex as a reference point.
vec4 world_p0 = layer.transform * vec4(snap_ref, 0.0, 1.0);
//TODO: full rectangle snapping, similar to `write_vertex`
vec4 world_p0 = layer.transform * vec4(snap_rect.p0, 0.0, 1.0);
vec2 device_p0 = uDevicePixelRatio * world_p0.xy / world_p0.w;
vec2 snap_delta = device_p0 - floor(device_p0 + 0.5);

@@ -12,7 +12,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

vPos = vi.local_pos - prim.local_rect.p0;

@@ -271,14 +271,14 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#else
VertexInfo vi = write_vertex(segment_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#endif

vLocalPos = vi.local_pos;
@@ -184,14 +184,14 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#else
VertexInfo vi = write_vertex(segment_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#endif

vLocalPos = vi.local_pos;
@@ -13,7 +13,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

RenderTaskData child_task = fetch_render_task(prim.user_data1);
vUv.z = child_task.data1.x;
@@ -14,7 +14,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

RenderTaskData child_task = fetch_render_task(prim.user_data1);
vUv.z = child_task.data1.x;
@@ -62,7 +62,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos;
vec2 f = (vi.local_pos.xy - prim.local_rect.p0) / prim.local_rect.size;
#else
@@ -71,7 +71,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

vec2 f = (vi.local_pos - segment_rect.p0) / segment_rect.size;
vPos = vi.local_pos;
@@ -14,15 +14,15 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos;
#else
VertexInfo vi = write_vertex(prim.local_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos - prim.local_rect.p0;
#endif

@@ -12,7 +12,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);

vPos = vi.local_pos - prim.local_rect.p0;

@@ -13,15 +13,15 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos;
#else
VertexInfo vi = write_vertex(prim.local_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
#endif

#ifdef WR_FEATURE_CLIP
@@ -18,7 +18,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
local_rect.p0);
local_rect);
vLocalPos = vi.local_pos;
vec2 f = (vi.local_pos.xy / vi.local_pos.z - local_rect.p0) / local_rect.size;
#else
@@ -27,7 +27,7 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
local_rect.p0);
local_rect);
vec2 f = (vi.local_pos - local_rect.p0) / local_rect.size;
#endif

@@ -11,15 +11,15 @@ void main(void) {
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos;
#else
VertexInfo vi = write_vertex(prim.local_rect,
prim.local_clip_rect,
prim.z,
prim.layer,
prim.task,
prim.local_rect.p0);
prim.local_rect);
vLocalPos = vi.local_pos - prim.local_rect.p0;
#endif

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.