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

Port asymmetric viewport rendering to gl-js #8638

Merged
merged 33 commits into from
Feb 13, 2020
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a9cc2f9
add edge insets class
Aug 9, 2019
537562c
add unit tests for EdgeInsets
Aug 10, 2019
1ce9ea1
add EdgeInsets docs comments
Aug 10, 2019
e79edaf
WIP tests for rendering padding
Aug 13, 2019
03ac661
working padding visualization
Aug 13, 2019
e01bafa
working initial transition
Aug 14, 2019
c8bb865
working centerPoint refactor
Aug 15, 2019
8bb8460
fix bugs with camera transition functions and padding logic
Aug 15, 2019
649e1d4
account for pixelRatio in showPadding
Aug 15, 2019
aa7fd47
Add synchrounous getPadding and setPadding methods to Map
Aug 17, 2019
7a479e3
fix broken import
Aug 19, 2019
bbba3ee
add render tests for visualizing padding and fix camera unit test
Aug 20, 2019
1cdf37f
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into feat/asy…
Aug 20, 2019
64522f5
add unit test that ensures padding doesnt change if no new values are…
Aug 21, 2019
d0080a4
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into feat/asy…
Sep 9, 2019
3833d3e
fix linter issues
Sep 9, 2019
d10d082
fix more linter issues
Sep 9, 2019
29bd59e
Fix edgeInset interpolation issue
Sep 10, 2019
21ff1b6
Merge <master> into <feat/asymmetric-viewport>
Feb 3, 2020
220673b
Fix integration with LOD based covering tiles
Feb 3, 2020
3420f3f
switch to simpler getCenter implementation
Feb 4, 2020
e39f561
Fix linting
Feb 4, 2020
d45f48f
Remove all user-facing `EdgeInset` types and fix flow errors
Feb 5, 2020
b98ffea
Account for off-axis padding in fitBounds and related functions
Feb 5, 2020
39f4288
Use glClear for drawing debug padding
Feb 5, 2020
44a2654
Delete unused ss_rect shader
Feb 5, 2020
00de0c6
Fix missing imports
Feb 6, 2020
372099a
Remove duplicated centerPoint code
Feb 12, 2020
e0871f7
Remove padding events from camera
Feb 12, 2020
354a555
Remove unused SerializedPadding type
Feb 12, 2020
fbb26fa
Update render tests to represent distortion caused by asymmetric view…
Feb 12, 2020
b7e8e6c
Fix lint error caused by unused variables
Feb 12, 2020
2d0e390
Update render tests to fix precision errors with 0 padding line rende…
Feb 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions src/geo/edge_insets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// @flow
import { number } from "../style-spec/util/interpolate";
import Point from "@mapbox/point-geometry";

/**
* An `EdgeInset` object represents screen space padding applied to the edges of the viewport.
* This shifts the apprent center or the vanishing point of the map. This is useful for adding floating UI elements
* on top of the map and having the vanishing point shift as UI elements resize.
*
* @param {number} [top=0]
* @param {number} [bottom=0]
* @param {number} [left=0]
* @param {number} [right=0]
*/
class EdgeInsets {
top: number;
bottom: number;
left: number;
right: number;

constructor(top: number = 0, bottom: number = 0, left: number = 0, right: number = 0) {
if (isNaN(top) || top < 0 ||
isNaN(bottom) || bottom < 0 ||
isNaN(left) || left < 0 ||
isNaN(right) || right < 0
) {
throw new Error('Invalid value for edge-insets, top, bottom, left and right must all be numbers');
}

this.top = top;
this.bottom = bottom;
this.left = left;
this.right = right;
}

/**
* Interpolates the inset in-place.
* This maintains the current inset value for any inset not present in `target`.
*
* @param {EdgeInsetLike} target
* @param {number} t
* @returns {EdgeInsets}
* @memberof EdgeInsets
*/
interpolate(target: EdgeInsetLike, t: number): EdgeInsets {
if (target.top != null) this.top = number(this.top, target.top, t);
if (target.bottom != null) this.bottom = number(this.bottom, target.bottom, t);
if (target.left != null) this.left = number(this.left, target.left, t);
if (target.right != null) this.right = number(this.right, target.right, t);

return this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interpolates the padding between the previous frame's value and the target instead of from the starting value to the target. Switching to the more functional approach used for other interpolation could be a good idea.

}

/**
* Utility method that computes the new apprent center or vanishing point after applying insets.
* This is in pixels and with the top left being (0.0) and +y being downwards.
*
* @param {number} width
* @param {number} height
* @returns {Point}
* @memberof EdgeInsets
*/
getCenter(width: number, height: number): Point {
// Clamp insets so they never overflow width/height and always calculate a valid center
const totalXInset = Math.min(this.left + this.right, width);
astojilj marked this conversation as resolved.
Show resolved Hide resolved
const totalYInset = Math.min(this.top + this.bottom, height);

const x = Math.min(this.left, width) + 0.5 * (width - totalXInset);
const y = Math.min(this.top, height) + 0.5 * (height - totalYInset);

return new Point(x, y);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be simpler as this?

const x  = (width + this.left - this.right) / 2;
const y = (height + this.top - this.bottom) / 2; 

The main difference would be that in the case where left + right > width it would take equal amounts off of both sides rather than only compromising on the right side. Not sure which is preferable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the simpler one you suggested is better!
Do you think we should throw an error/warning when the overflow happens?

}

equals(other: EdgeInsetLike): boolean {
return this.top === other.top &&
this.bottom === other.bottom &&
this.left === other.left &&
this.right === other.right;
}

clone(): EdgeInsets {
return new EdgeInsets(this.top, this.bottom, this.left, this.right);
}

/**
* Returns the current sdtate as json, useful when you want to have a
* read-only representation of the inset.
*
* @returns {EdgeInsetJSON}
* @memberof EdgeInsets
*/
toJSON(): EdgeInsetJSON {
return {
top: this.top,
bottom: this.bottom,
left: this.left,
right: this.right
};
}
}

export type EdgeInsetLike = EdgeInsets | {top?: number, bottom?: number, right?: number, left?: number} | EdgeInsetJSON;
export type EdgeInsetJSON = {top: number, bottom: number, right: number, left: number}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not using PaddingOptions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that padding might be a better name here since that is what is exposed.


export default EdgeInsets;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we simplify this class somewhat, could it be small enough to the point it's simpler to have this state as a part of transform rather than a separate class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be, but this seems easier to write unit tests for, and handles a lot of the validation and updating logic without adding additional private methods to the transform class.

71 changes: 64 additions & 7 deletions src/geo/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import tileCover from '../util/tile_cover';
import { UnwrappedTileID } from '../source/tile_id';
import EXTENT from '../data/extent';
import { vec4, mat4, mat2 } from 'gl-matrix';
import EdgeInsets from './edge_insets';

import type { OverscaledTileID, CanonicalTileID } from '../source/tile_id';
import type { EdgeInsetLike, EdgeInsetJSON } from './edge_insets';

/**
* A single transform, generally used for a single tile to be
Expand Down Expand Up @@ -47,6 +49,7 @@ class Transform {
_minZoom: number;
_maxZoom: number;
_center: LngLat;
_edgeInsets: EdgeInsets;
_constraining: boolean;
_posMatrixCache: {[number]: Float32Array};
_alignedPosMatrixCache: {[number]: Float32Array};
Expand All @@ -69,6 +72,7 @@ class Transform {
this._fov = 0.6435011087932844;
this._pitch = 0;
this._unmodified = true;
this._edgeInsets = new EdgeInsets();
this._posMatrixCache = {};
this._alignedPosMatrixCache = {};
}
Expand All @@ -85,6 +89,7 @@ class Transform {
clone._fov = this._fov;
clone._pitch = this._pitch;
clone._unmodified = this._unmodified;
clone._edgeInsets = this._edgeInsets.clone();
clone._calcMatrices();
return clone;
}
Expand Down Expand Up @@ -118,8 +123,8 @@ class Transform {
return this.tileSize * this.scale;
}

get centerPoint(): Point {
return this.size._div(2);
get centerOffset(): Point {
return this._edgeInsets.getCenter(this.width, this.height).sub(this.size._div(2));
arindam1993 marked this conversation as resolved.
Show resolved Hide resolved
}

get size(): Point {
Expand Down Expand Up @@ -185,6 +190,52 @@ class Transform {
this._calcMatrices();
}

get padding(): EdgeInsetJSON { return this._edgeInsets.toJSON(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Serving the existing API in native, i didn't like that in Android we use "padding" and in iOS "edgeInsets". is padding here added to keep it close to native implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just did it so the public facing term for is it simpler, but happy to change it to whatever.
Maybe @chloekraw , do you have any thoughts?

Copy link
Contributor

@chloekraw chloekraw Aug 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this feature, I think padding is the term that's going to be closest to what web developers who use CSS would expect. inset is most commonly used as a type of border style:

I did find this https://developer.mozilla.org/en-US/docs/Web/CSS/inset "experimental technology" but it sounds like this inset is more about defining margins around blocks of text and is less analogous to a viewport. (related: https://developer.mozilla.org/en-US/docs/Web/CSS/inset-block, https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline)

@arindam1993 are there other parts of the GL-JS code base that also use this idea of padding?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arindam1993 , related to this - what's your opinion about propagating CSS style padding specified to Map's parent HTML container to transform?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chloekraw I don't think so.

@astojilj I don't think we should, I think devs waning to create floating UI elements, which this feature is designed for would want to set a padding on the container, since it'd offset all their UI elements which I assume would be appended as children fo the map container.

However I think it might be useful to push the current state of padding to our own CSS classes and DOM elements which we use for nesting NavigationControl and AttributionControl
Screen Shot 2019-08-20 at 3 21 37 PM
top,left, right and bottom attributes are always 0, i think we can update them from within Map.

Having Map be the only API entrypoint seems more intuitive to me, with plugins automatically respecting it as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a demo of what I mean.

2019-08-20 19 33 01

set padding(padding: EdgeInsetLike) {
if (this._edgeInsets.equals(padding)) return;
this._unmodified = false;
//Update edge-insets inplace
this._edgeInsets.interpolate(padding, 1);
this._calcMatrices();
}

/**
* The center of the screen in pixels with the top-left corner being (0,0)
* and +y axis pointing downwards. This accounts for padding.
*
* @readonly
* @type {Point}
* @memberof Transform
*/
get centerPoint(): Point {
return this._edgeInsets.getCenter(this.width, this.height);
}

/**
* Returns if the padding params match
*
* @param {EdgeInsetLike} padding
* @returns {boolean}
* @memberof Transform
*/
isPaddingEqual(padding: EdgeInsetLike): boolean {
return this._edgeInsets.equals(padding);
}

/**
* Helper method to upadte edge-insets inplace
*
* @param {EdgeInsetLike} target
* @param {number} t
* @memberof Transform
*/
interpolatePadding(target: EdgeInsetLike, t: number) {
this._unmodified = false;
this._edgeInsets.interpolate(target, t);
this._constrain();
this._calcMatrices();
}

/**
* Return a zoom level that will cover all tiles the transform
* @param {Object} options
Expand Down Expand Up @@ -520,15 +571,17 @@ class Transform {
_calcMatrices() {
if (!this.height) return;

this.cameraToCenterDistance = 0.5 / Math.tan(this._fov / 2) * this.height;
const halfFov = this._fov / 2;
const offset = this.centerOffset;
this.cameraToCenterDistance = 0.5 / Math.tan(halfFov) * this.height;

// Find the distance from the center point [width/2, height/2] to the
// center top point [width/2, 0] in Z units, using the law of sines.
// Find the distance from the center point [width/2 + offset.x, height/2 + offset.y] to the
// center top point [width/2 + offset.x, 0] in Z units, using the law of sines.
// 1 Z unit is equivalent to 1 horizontal px at the center of the map
// (the distance between[width/2, height/2] and [width/2 + 1, height/2])
const halfFov = this._fov / 2;
const groundAngle = Math.PI / 2 + this._pitch;
const topHalfSurfaceDistance = Math.sin(halfFov) * this.cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov);
const fovAboveCenter = this._fov * (0.5 + offset.y / this.height);
const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * this.cameraToCenterDistance / Math.sin(Math.PI - groundAngle - fovAboveCenter);
const point = this.point;
const x = point.x, y = point.y;

Expand All @@ -541,6 +594,10 @@ class Transform {
let m = new Float64Array(16);
mat4.perspective(m, this._fov, this.width / this.height, 1, farZ);

//Apply center of perspective offset
m[8] = -offset.x * 2 / this.width;
m[9] = offset.y * 2 / this.height;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be done using the methods provided by mat4 (translate, multiply, etc) rather than directly editing the matrix directly? It took me a while to understand the math here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only api method that allows that I think can work is the asymmetric view frustum method but that takes 4 different fov's as input, and back calculating that seemed more janky to me.

mat4.scale(m, m, [1, -1, 1]);
mat4.translate(m, m, [0, 0, -this.cameraToCenterDistance]);
mat4.rotateX(m, m, this._pitch);
Expand Down
47 changes: 46 additions & 1 deletion src/render/draw_debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,60 @@ import SegmentVector from '../data/segment';
import DepthMode from '../gl/depth_mode';
import StencilMode from '../gl/stencil_mode';
import CullFaceMode from '../gl/cull_face_mode';
import { debugUniformValues } from './program/debug_program';
import ColorMode from '../gl/color_mode';
import { debugUniformValues, debugSSRectUniformValues } from './program/debug_program';
import Color from '../style-spec/util/color';
import browser from '../util/browser';

import type Painter from './painter';
import type SourceCache from '../source/source_cache';
import type {OverscaledTileID} from '../source/tile_id';

export default drawDebug;

const topColor = new Color(1, 0, 0, 0.4);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does draw_debug.js go to production code?
I'm not sure how useful is to including additional shader and this code for rendering different colors or padding values.
For manual debugging, propose to add additional debug/***.html page (doesn't go to production code AFAIK) with overlays (in the way the customers are supposed to use it)...

  • manually test the debug page

and in that that page would be used for this step.

Please doublecheck my opinion with other reviewers - I might be missing something...

Copy link
Contributor Author

@arindam1993 arindam1993 Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

draw_debug does go into the final bundle, and we do publish docs for showTileBoundaries and showCollisionBoxes. My idea was to make a similar thing for padding as well.
https://docs.mapbox.com/mapbox-gl-js/api/#map#showtileboundaries
I'm also using the in-gl rendering of the padding as a render-test, similar to tile boundaries and collision box debugging.

And regarding the debug page, I agree, I can add one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does draw_debug.js go to production code?

Having this as part of the built-in debug shaders allows easily debugging issues when building/updating work in this area. I can see it being very useful for debugging flyTo animations for example.

That said, this PR adds a total of +4.13 kB to the gl-js bundle. Is there a simpler debug option that can be built?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding a debug view. They can be pretty useful for understanding things. If the size and complexity of the shader another approach could be to use a gl scissor and clear to draw a line at each edge.

    gl.enable(gl.SCISSOR_TEST);
    gl.scissor(x, y, width, height);
    context.clear({ color });
    gl.disable(gl.SCISSOR_TEST);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^ I did this, it is much simpler though it only saved half a kb of bundle size.

const btmColor = new Color(0, 1, 0, 0.4);
const leftColor = new Color(0, 0, 1, 0.4);
const rightColor = new Color(1, 0, 1, 0.4);
const centerColor = new Color(0, 1, 1, 0.4);

export function drawDebugPadding(painter: Painter) {
const padding = painter.transform.padding;
// Top
drawDebugSSRect(painter, 0, 0, painter.transform.width, padding.top, topColor);
// Bottom
drawDebugSSRect(painter, 0, painter.transform.height - padding.bottom, painter.transform.width, padding.bottom, btmColor);
// Left
drawDebugSSRect(painter, 0, 0, padding.left, painter.transform.height, leftColor);
// Right
drawDebugSSRect(painter, painter.transform.width - padding.right, 0, padding.right, painter.transform.height, rightColor);
// Center
const center = painter.transform.centerPoint;
const centerSize = 10;
drawDebugSSRect(painter, center.x - centerSize / 2, center.y - centerSize / 2, centerSize, centerSize, centerColor);
}

function drawDebugSSRect(painter: Painter, x: number, y: number, width: number, height: number, color: Color) {
const context = painter.context;
const gl = context.gl;

const program = painter.useProgram('debugSSRect');

const depthMode = DepthMode.disabled;
const stencilMode = StencilMode.disabled;
const colorMode = ColorMode.alphaBlended;
const id = '$debug_ss_rect';
// convert pixel-space coordinates to gl coordinates
const glWidth = 2 * browser.devicePixelRatio * width / painter.width;
const glHeight = 2 * browser.devicePixelRatio * -height / painter.height;
const glX = (2 * browser.devicePixelRatio * x / painter.width - 1);
const glY = -1 * (2 * browser.devicePixelRatio * y / painter.height - 1);

program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
debugSSRectUniformValues(color, [glX, glY], [glWidth, glHeight]), id,
painter.viewportBuffer, painter.quadTriangleIndexBuffer, painter.viewportSegments);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you anticipate this debug code being used often, or did it already serve its purpose since the asymmetric viewport implementation is complete? Just noting an opportunity to potentially cut this for smaller bundle size impact.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not super often, no actually, but it seems like an useful tool to have for render tests, examples and debug pages. I could make it so it is only available in the dev build, but it will break our usual convention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've also added some new render tests in the newest commit that represents the distortion caused by asymmetric viewport much better.
https://github.com/mapbox/mapbox-gl-js/pull/8638/files#diff-633f8e084d5e1ba0bb38d2c145e1b771

function drawDebug(painter: Painter, sourceCache: SourceCache, coords: Array<OverscaledTileID>) {
for (let i = 0; i < coords.length; i++) {
drawDebugTile(painter, sourceCache, coords[i]);
Expand Down
7 changes: 6 additions & 1 deletion src/render/painter.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import fillExtrusion from './draw_fill_extrusion';
import hillshade from './draw_hillshade';
import raster from './draw_raster';
import background from './draw_background';
import debug from './draw_debug';
import debug, { drawDebugPadding } from './draw_debug';
import custom from './draw_custom';

const draw = {
Expand Down Expand Up @@ -68,6 +68,7 @@ export type RenderPass = 'offscreen' | 'opaque' | 'translucent';
type PainterOptions = {
showOverdrawInspector: boolean,
showTileBoundaries: boolean,
showPadding: boolean,
rotating: boolean,
zooming: boolean,
moving: boolean,
Expand Down Expand Up @@ -434,6 +435,10 @@ class Painter {
}
}

if (this.options.showPadding) {
drawDebugPadding(this);
}

// Set defaults for most GL values so that anyone using the state after the render
// encounters more expected values.
this.context.setDefault();
Expand Down
23 changes: 21 additions & 2 deletions src/render/program/debug_program.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import {
UniformColor,
UniformMatrix4f
UniformMatrix4f,
Uniform2f
} from '../uniform_binding';

import type Context from '../../gl/context';
Expand All @@ -14,14 +15,32 @@ export type DebugUniformsType = {|
'u_matrix': UniformMatrix4f
|};

export type DebugSSRectUniformsType = {|
'u_color': UniformColor,
'u_offset': Uniform2f,
'u_dim': Uniform2f
|};

const debugUniforms = (context: Context, locations: UniformLocations): DebugUniformsType => ({
'u_color': new UniformColor(context, locations.u_color),
'u_matrix': new UniformMatrix4f(context, locations.u_matrix)
});

const debugSSRectUniforms = (context: Context, locations: UniformLocations): DebugSSRectUniformsType => ({
'u_color': new UniformColor(context, locations.u_color),
'u_offset': new Uniform2f(context, locations.u_offset),
'u_dim': new Uniform2f(context, locations.u_dim)
});

const debugSSRectUniformValues = (color: Color, offset: [number, number], dim: [number, number]): UniformValues<DebugSSRectUniformsType> => ({
'u_color': color,
'u_offset': offset,
'u_dim': dim,
});

const debugUniformValues = (matrix: Float32Array, color: Color): UniformValues<DebugUniformsType> => ({
'u_matrix': matrix,
'u_color': color
});

export { debugUniforms, debugUniformValues };
export { debugUniforms, debugUniformValues, debugSSRectUniforms, debugSSRectUniformValues };
3 changes: 2 additions & 1 deletion src/render/program/program_uniforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { fillExtrusionUniforms, fillExtrusionPatternUniforms } from './fill_extr
import { fillUniforms, fillPatternUniforms, fillOutlineUniforms, fillOutlinePatternUniforms } from './fill_program';
import { circleUniforms } from './circle_program';
import { collisionUniforms } from './collision_program';
import { debugUniforms } from './debug_program';
import { debugUniforms, debugSSRectUniforms } from './debug_program';
import { clippingMaskUniforms } from './clipping_mask_program';
import { heatmapUniforms, heatmapTextureUniforms } from './heatmap_program';
import { hillshadeUniforms, hillshadePrepareUniforms } from './hillshade_program';
Expand All @@ -24,6 +24,7 @@ export const programUniforms = {
collisionBox: collisionUniforms,
collisionCircle: collisionUniforms,
debug: debugUniforms,
debugSSRect: debugSSRectUniforms,
clippingMask: clippingMaskUniforms,
heatmap: heatmapUniforms,
heatmapTexture: heatmapTextureUniforms,
Expand Down
8 changes: 8 additions & 0 deletions src/shaders/debug_ss_rect.vertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
attribute vec2 a_pos;

uniform vec2 u_offset;
uniform vec2 u_dim;

void main() {
gl_Position = vec4((a_pos*u_dim)+u_offset, 0, 1);
}
Loading