Skip to content

Commit

Permalink
Add background-pitch-alignment property (internal-1862)
Browse files Browse the repository at this point in the history
* Add background-pitch-alignment property

* Add support for rendering background-pattern with viewport pitch alignment

* Add test for viewport background with terrain
  • Loading branch information
endanke authored and mourner committed Sep 26, 2024
1 parent 19e548d commit c4d68ad
Show file tree
Hide file tree
Showing 21 changed files with 537 additions and 12 deletions.
10 changes: 10 additions & 0 deletions debug/walls.html
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,16 @@
}
});

map.addLayer({
"type": "background",
"id": "dimming-background",
"paint": {
"background-pitch-alignment": "viewport",
"background-color": "black",
"background-opacity": 0.5
}
});

map.addLayer({
"type": "fill",
"id": "floors",
Expand Down
23 changes: 21 additions & 2 deletions src/render/draw_background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {
backgroundUniformValues,
backgroundPatternUniformValues
} from './program/background_program';
import {OverscaledTileID} from '../source/tile_id';
import {mat4} from 'gl-matrix';

import type {OverscaledTileID} from '../source/tile_id';
import type Painter from './painter';
import type SourceCache from '../source/source_cache';
import type BackgroundStyleLayer from '../style/style_layer/background_style_layer';
Expand All @@ -19,6 +20,7 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg
const color = layer.paint.get('background-color');
const opacity = layer.paint.get('background-opacity');
const emissiveStrength = layer.paint.get('background-emissive-strength');
const isViewportPitch = layer.paint.get('background-pitch-alignment') === 'viewport';

if (opacity === 0) return;

Expand Down Expand Up @@ -60,6 +62,23 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg
painter.imageManager.bind(painter.context, layer.scope);
}

if (isViewportPitch) {
// Set overrideRtt to ignore 3D lights
const program = painter.getOrCreateProgram(programName, {overrideFog: false, overrideRtt: true});
const matrix = new Float32Array(mat4.identity([] as any));
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);

const uniformValues = image ?
backgroundPatternUniformValues(matrix, emissiveStrength, opacity, painter, image, layer.scope, patternPosition, isViewportPitch, {tileID, tileSize}) :
backgroundUniformValues(matrix, emissiveStrength, opacity, color.toRenderColor(layer.lut));

// @ts-expect-error - TS2554 - Expected 12-16 arguments, but got 11.
program.draw(painter, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
uniformValues, layer.id, painter.viewportBuffer,
painter.quadTriangleIndexBuffer, painter.viewportSegments);
return;
}

for (const tileID of tileIDs) {
const affectedByFog = painter.isTileAffectedByFog(tileID);
const program = painter.getOrCreateProgram(programName, {overrideFog: affectedByFog});
Expand All @@ -72,7 +91,7 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg

const uniformValues = image ?

backgroundPatternUniformValues(matrix, emissiveStrength, opacity, painter, image, layer.scope, patternPosition, {tileID, tileSize}) :
backgroundPatternUniformValues(matrix, emissiveStrength, opacity, painter, image, layer.scope, patternPosition, isViewportPitch, {tileID, tileSize}) :

backgroundUniformValues(matrix, emissiveStrength, opacity, color.toRenderColor(layer.lut));

Expand Down
7 changes: 4 additions & 3 deletions src/render/program/background_program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export type BackgroundPatternUniformsType = {
['u_pattern_size']: Uniform2f;
['u_pixel_coord_upper']: Uniform2f;
['u_pixel_coord_lower']: Uniform2f;
['u_tile_units_to_pixels']: Uniform1f;
['u_pattern_units_to_pixels']: Uniform2f;
};

const backgroundUniforms = (context: Context): BackgroundUniformsType => ({
Expand All @@ -56,7 +56,7 @@ const backgroundPatternUniforms = (context: Context): BackgroundPatternUniformsT
'u_pattern_size': new Uniform2f(context),
'u_pixel_coord_upper': new Uniform2f(context),
'u_pixel_coord_lower': new Uniform2f(context),
'u_tile_units_to_pixels': new Uniform1f(context)
'u_pattern_units_to_pixels': new Uniform2f(context)
});

const backgroundUniformValues = (
Expand All @@ -79,12 +79,13 @@ const backgroundPatternUniformValues = (
image: ResolvedImage,
scope: string,
patternPosition: ImagePosition | null | undefined,
isViewport: boolean,
tile: {
tileID: OverscaledTileID;
tileSize: number;
},
): UniformValues<BackgroundPatternUniformsType> => extend(
bgPatternUniformValues(image, scope, patternPosition, painter, tile),
bgPatternUniformValues(image, scope, patternPosition, painter, isViewport, tile),
{
'u_matrix': matrix,
'u_emissive_strength': emissiveStrength,
Expand Down
5 changes: 3 additions & 2 deletions src/render/program/pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type BackgroundPatternUniformsType = {
['u_pattern_size']: Uniform2f;
['u_pixel_coord_upper']: Uniform2f;
['u_pixel_coord_lower']: Uniform2f;
['u_tile_units_to_pixels']: Uniform1f;
['u_pattern_units_to_pixels']: Uniform2f;
};

export type PatternUniformsType = {
Expand Down Expand Up @@ -54,6 +54,7 @@ function bgPatternUniformValues(
scope: string,
patternPosition: ImagePosition | null | undefined,
painter: Painter,
isViewport: boolean,
tile: {
tileID: OverscaledTileID;
tileSize: number;
Expand All @@ -74,7 +75,7 @@ function bgPatternUniformValues(
'u_pattern_br': (patternPosition as any).br,
'u_texsize': [width, height],
'u_pattern_size': (patternPosition as any).displaySize,
'u_tile_units_to_pixels': 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom),
'u_pattern_units_to_pixels': isViewport ? [painter.transform.width, -1.0 * painter.transform.height] : [1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom), 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom)],
// split the pixel coord into two pairs of 16 bit numbers. The glsl spec only guarantees 16 bits of precision.
'u_pixel_coord_upper': [pixelX >> 16, pixelY >> 16],
'u_pixel_coord_lower': [pixelX & 0xFFFF, pixelY & 0xFFFF]
Expand Down
9 changes: 7 additions & 2 deletions src/shaders/_prelude.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,15 @@ vec4 unpack_mix_color(const vec4 packedColors, const float t) {
//
// The offset is calculated in a series of steps that should preserve this precision:
vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower,
const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) {
const vec2 pattern_size, const vec2 units_to_pixels, const vec2 pos) {

vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size);
return (tile_units_to_pixels * pos + offset) / pattern_size;
return (units_to_pixels * pos + offset) / pattern_size;
}

vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower,
const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) {
return get_pattern_pos(pixel_coord_upper, pixel_coord_lower, pattern_size, vec2(tile_units_to_pixels), pos);
}

float mercatorXfromLng(float lng) {
Expand Down
4 changes: 2 additions & 2 deletions src/shaders/background_pattern.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ uniform mat4 u_matrix;
uniform vec2 u_pattern_size;
uniform vec2 u_pixel_coord_upper;
uniform vec2 u_pixel_coord_lower;
uniform float u_tile_units_to_pixels;
uniform vec2 u_pattern_units_to_pixels;

in vec2 a_pos;

Expand All @@ -13,7 +13,7 @@ out highp vec2 v_pos;
void main() {
gl_Position = u_matrix * vec4(a_pos, 0, 1);

v_pos = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_pattern_size, u_tile_units_to_pixels, a_pos);
v_pos = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_pattern_size, u_pattern_units_to_pixels, a_pos);

#ifdef FOG
v_fog_pos = fog_position(a_pos);
Expand Down
25 changes: 25 additions & 0 deletions src/style-spec/reference/v8.json
Original file line number Diff line number Diff line change
Expand Up @@ -8532,6 +8532,31 @@
}
},
"paint_background": {
"background-pitch-alignment": {
"type": "enum",
"values": {
"map": {
"doc": "The background is aligned to the plane of the map."
},
"viewport": {
"doc": "The background is aligned to the plane of the viewport, covering the whole screen."
}
},
"default": "map",
"doc": "Orientation of background layer.",
"sdk-support": {
"basic functionality": {
"js": "3.8.0",
"android": "11.8.0",
"ios": "11.8.0"
}
},
"expression": {
"interpolated": false,
"parameters": []
},
"property-type": "data-constant"
},
"background-color": {
"type": "color",
"default": "#000000",
Expand Down
1 change: 1 addition & 0 deletions src/style-spec/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,7 @@ export type BackgroundLayerSpecification = {
"visibility"?: "visible" | "none" | ExpressionSpecification
},
"paint"?: {
"background-pitch-alignment"?: "map" | "viewport" | ExpressionSpecification,
"background-color"?: PropertyValueSpecification<ColorSpecification>,
"background-color-transition"?: TransitionSpecification,
"background-pattern"?: PropertyValueSpecification<ResolvedImageSpecification>,
Expand Down
2 changes: 1 addition & 1 deletion src/style/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2662,7 +2662,7 @@ class Style extends Evented<MapEvents> {
// This means that that the line_layer feature is above the extrusion_layer_b feature despite
// it being in an earlier layer.

const isLayer3D = (layerId: string) => this._mergedLayers[layerId].type === 'fill-extrusion' || this._mergedLayers[layerId].type === 'model';
const isLayer3D = (layerId: string) => this._mergedLayers[layerId].is3D();

const order = this.order;

Expand Down
4 changes: 4 additions & 0 deletions src/style/style_layer/background_style_layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class BackgroundStyleLayer extends StyleLayer {
overrideFog: false
};
}

is3D(): boolean {
return this.paint.get('background-pitch-alignment') === 'viewport';
}
}

export default BackgroundStyleLayer;
2 changes: 2 additions & 0 deletions src/style/style_layer/background_style_layer_properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const getLayoutProperties = (): Properties<LayoutProps> => layout || (lay
}));

export type PaintProps = {
"background-pitch-alignment": DataConstantProperty<"map" | "viewport">;
"background-color": DataConstantProperty<Color>;
"background-pattern": DataConstantProperty<ResolvedImage | null | undefined>;
"background-opacity": DataConstantProperty<number>;
Expand All @@ -33,6 +34,7 @@ export type PaintProps = {

let paint: Properties<PaintProps>;
export const getPaintProperties = (): Properties<PaintProps> => paint || (paint = new Properties({
"background-pitch-alignment": new DataConstantProperty(styleSpec["paint_background"]["background-pitch-alignment"]),
"background-color": new DataConstantProperty(styleSpec["paint_background"]["background-color"]),
"background-pattern": new DataConstantProperty(styleSpec["paint_background"]["background-pattern"]),
"background-opacity": new DataConstantProperty(styleSpec["paint_background"]["background-opacity"]),
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"version": 8,
"metadata": {
"test": {
"width": 512,
"height": 256,
"allowed": 0.0006,
"operations": [
["setProjection", "globe"],
["wait"]
]
}
},
"sprite": "local://sprites/emerald",
"sources": {
"satellite": {
"type": "raster",
"tiles": [
"local://tiles/{z}-{x}-{y}.satellite.png"
],
"tileSize": 256
}
},
"fog": {},
"layers": [
{
"id": "satellite",
"type": "raster",
"source": "satellite",
"paint": {
"raster-fade-duration": 0
}
},
{
"id": "background",
"type": "background",
"paint": {
"background-pitch-alignment": "viewport",
"background-pattern": "cemetery_icon"
}
}
]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"version": 8,
"metadata": {
"test": {
"width": 512,
"height": 512,
"allowed": 0.0006,
"operations": [
["setProjection", "globe"],
["wait"]
]
}
},
"sources": {
"satellite": {
"type": "raster",
"tiles": [
"local://tiles/{z}-{x}-{y}.satellite.png"
],
"tileSize": 256
}
},
"fog": {},
"layers": [
{
"id": "satellite",
"type": "raster",
"source": "satellite",
"paint": {
"raster-fade-duration": 0
}
},
{
"id": "background",
"type": "background",
"paint": {
"background-color": "yellow",
"background-opacity": 0.5,
"background-pitch-alignment": "viewport"
}
}
]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"version": 8,
"metadata": {
"test": {
"width": 512,
"height": 512,
"allowed": 0.0006,
"operations": [
["wait"]
]
}
},
"sources": {
"satellite": {
"type": "raster",
"tiles": [
"local://tiles/{z}-{x}-{y}.satellite.png"
],
"tileSize": 256
}
},
"fog": {},
"layers": [
{
"id": "satellite",
"type": "raster",
"source": "satellite",
"paint": {
"raster-fade-duration": 0
}
},
{
"id": "background",
"type": "background",
"paint": {
"background-color": "yellow",
"background-opacity": 0.5,
"background-pitch-alignment": "viewport"
}
}
]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit c4d68ad

Please sign in to comment.