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

Add coordinates expressions in WebGL tiles #15478

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
58 changes: 51 additions & 7 deletions examples/webgl-shaded-relief.js
Expand Up @@ -28,15 +28,58 @@ function elevation(xOffset, yOffset) {
];
}

// Edges conditions to avoid computations with pixels ouside the current tile.
const isLeftEdge = ['<=', ['tileCoordX'], 1];
const isRightEdge = ['>=', ['tileCoordX'], ['-', ['tileMaxCoordX'], 1]];
const isTopEdge = ['<=', ['tileCoordY'], 1];
const isBottomEdge = ['>=', ['tileCoordY'], ['-', ['tileMaxCoordY'], 1]];

// Computes the vertical and horizontal values for slope and aspect.
// Avoid computation with pixels outside the current tile.
const dpx = [
'case',
['any', isLeftEdge, isRightEdge],
['*', 1, ['resolution']],
['*', 2, ['resolution']],
];

const dpy = [
'case',
['any', isTopEdge, isBottomEdge],
['*', 1, ['resolution']],
['*', 2, ['resolution']],
];

const z0x = [
'case',
isLeftEdge,
['*', ['var', 'vert'], elevation(0, 0)],
['*', ['var', 'vert'], elevation(-1, 0)],
];
const z1x = [
'case',
isRightEdge,
['*', ['var', 'vert'], elevation(0, 0)],
['*', ['var', 'vert'], elevation(1, 0)],
];

const z0y = [
'case',
isTopEdge,
['*', ['var', 'vert'], elevation(0, 0)],
['*', ['var', 'vert'], elevation(0, -1)],
];
const z1y = [
'case',
isBottomEdge,
['*', ['var', 'vert'], elevation(0, 0)],
['*', ['var', 'vert'], elevation(0, 1)],
];

// Generates a shaded relief image given elevation data. Uses a 3x3
// neighborhood for determining slope and aspect.
const dp = ['*', 2, ['resolution']];
const z0x = ['*', ['var', 'vert'], elevation(-1, 0)];
const z1x = ['*', ['var', 'vert'], elevation(1, 0)];
const dzdx = ['/', ['-', z1x, z0x], dp];
const z0y = ['*', ['var', 'vert'], elevation(0, -1)];
const z1y = ['*', ['var', 'vert'], elevation(0, 1)];
const dzdy = ['/', ['-', z1y, z0y], dp];
const dzdx = ['/', ['-', z1x, z0x], dpx];
const dzdy = ['/', ['-', z1y, z0y], dpy];
const slope = ['atan', ['sqrt', ['+', ['^', dzdx, 2], ['^', dzdy, 2]]]];
const aspect = ['clamp', ['atan', ['-', 0, dzdx], dzdy], -Math.PI, Math.PI];
const sunEl = ['*', Math.PI / 180, ['var', 'sunEl']];
Expand All @@ -54,6 +97,7 @@ const shadedRelief = new TileLayer({
source: new XYZ({
url: 'https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png',
maxZoom: 15,
interpolate: false, // Enabling interpolation may create artifacts between tiles.
attributions:
'<a href="https://github.com/tilezen/joerd/blob/master/docs/attribution.md" target="_blank">Data sources and attribution</a>',
}),
Expand Down
8 changes: 8 additions & 0 deletions src/ol/expr/expression.js
Expand Up @@ -352,6 +352,10 @@ export const Ops = {
Resolution: 'resolution',
Zoom: 'zoom',
Time: 'time',
TileCoordX: 'tileCoordX',
TileCoordY: 'tileCoordY',
TileMaxCoordX: 'tileMaxCoordX',
TileMaxCoordY: 'tileMaxCoordY',
Equal: '==',
NotEqual: '!=',
GreaterThan: '>',
Expand Down Expand Up @@ -427,6 +431,10 @@ const parsers = {
[Ops.Resolution]: createParser(NumberType, withNoArgs),
[Ops.Zoom]: createParser(NumberType, withNoArgs),
[Ops.Time]: createParser(NumberType, withNoArgs),
[Ops.TileCoordX]: createParser(NumberType, withNoArgs),
[Ops.TileCoordY]: createParser(NumberType, withNoArgs),
[Ops.TileMaxCoordX]: createParser(NumberType, withNoArgs),
[Ops.TileMaxCoordY]: createParser(NumberType, withNoArgs),
[Ops.Any]: createParser(
BooleanType,
withArgsCount(2, Infinity),
Expand Down
4 changes: 4 additions & 0 deletions src/ol/expr/gpu.js
Expand Up @@ -273,6 +273,10 @@ const compilers = {
[Ops.Resolution]: () => 'u_resolution',
[Ops.Zoom]: () => 'u_zoom',
[Ops.Time]: () => 'u_time',
[Ops.TileCoordX]: () => 'v_textureCoord.x * u_texturePixelWidth',
[Ops.TileCoordY]: () => 'v_textureCoord.y * u_texturePixelHeight',
[Ops.TileMaxCoordX]: () => 'u_texturePixelWidth',
[Ops.TileMaxCoordY]: () => 'u_texturePixelHeight',
[Ops.Any]: createCompiler((compiledArgs) => `(${compiledArgs.join(` || `)})`),
[Ops.All]: createCompiler((compiledArgs) => `(${compiledArgs.join(` && `)})`),
[Ops.Not]: createCompiler(([value]) => `(!${value})`),
Expand Down