Skip to content

Commit 64aefba

Browse files
authored
add terrain mask specs (#2621)
* add terrain mask specs * fixing specs * fixing specs
1 parent 06d0669 commit 64aefba

File tree

14 files changed

+205
-14
lines changed

14 files changed

+205
-14
lines changed

debug/gl/terrain-mask.html

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"zoom": 13,
3232
"pitch": 10,
3333
"bearing": 0,
34+
renderer: 'gl',
3435
queryTerrainInMapEvents: false
3536
});
3637

@@ -51,6 +52,7 @@
5152

5253
const terrain = {
5354
debug: true,
55+
shader: 'lit',
5456
type: "mapbox",
5557
urlTemplate: `https://{s}.tiles.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.pngraw?access_token=${token}`,
5658
subdomains: ["a", "b", "c", "d"]
@@ -65,11 +67,11 @@
6567
type: "Polygon",
6668
coordinates: [
6769
[
68-
[94.50812103, 29.45095163, 3000],
69-
[94.59012103, 29.45095163, 3000],
70-
[94.59012103, 29.40095163, 3000],
71-
[94.50812103, 29.40095163, 3000],
72-
[94.50812103, 29.45095163, 3000]
70+
[94.50812103, 29.45095163, 0],
71+
[94.59012103, 29.45095163, 0],
72+
[94.59012103, 29.40095163, 0],
73+
[94.50812103, 29.40095163, 0],
74+
[94.50812103, 29.45095163, 0]
7375
]
7476
]
7577
},
@@ -99,11 +101,10 @@
99101
renderPlugin: {
100102
dataConfig: {
101103
type: "fill",
104+
altitudeOffset: 3000
102105
},
103106
sceneConfig: {},
104107
type: "terrain-flat-mask",
105-
},
106-
symbol: {
107108
}
108109
}
109110
]

packages/gl/src/layer/terrain/TerrainLitPainter.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,16 @@ class TerrainLitPainter extends TerrainPainter {
105105
const material = new reshader.pbr.StandardMaterial(matInfo);
106106
const mesh = new reshader.Mesh(geo, material);
107107
mesh.properties.matVer = this._matVer;
108+
if (!mesh.uniforms.flatMask) {
109+
const emptyTexture = this.getEmptyTexture();
110+
mesh.setUniform('flatMask', emptyTexture);
111+
}
108112
const defines = mesh.defines;
109113
defines['HAS_UV_FLIP'] = 1;
110114
defines['HAS_TERRAIN_NORMAL'] = 1;
111115
defines['HAS_MAP'] = 1;
112116
defines['HAS_LAYER_OPACITY'] = 1;
117+
defines['HAS_TERRAIN_FLAT_MASK'] = 1;
113118
mesh.defines = defines;
114119
// mesh.setUniform('terrainTileResolution', tileInfo.res);
115120
this.prepareMesh(mesh, tileInfo, terrainImage);
@@ -126,7 +131,10 @@ class TerrainLitPainter extends TerrainPainter {
126131
mesh.properties.matVer = this._matVer;
127132
}
128133
if (tileImage.skin) {
129-
mesh.material.set('skinTexture', tileImage.skin);
134+
mesh.material.set('skinTexture', tileImage.skin.color[0]);
135+
}
136+
if (tileImage.mask) {
137+
mesh.setUniform('flatMask', tileImage.mask.color[0]);
130138
}
131139
mesh.setUniform('polygonOpacity', 1.0);
132140
// const { skirtOffset, skirtCount } = mesh.properties;

packages/reshader.gl/src/pbr/glsl/standard.vert

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ precision highp float;
44

55
attribute vec3 aPosition;
66

7-
#if defined(HAS_MAP)
7+
#if defined(HAS_MAP) || defined(HAS_TERRAIN_FLAT_MASK)
88
attribute vec2 aTexCoord;
9+
#include <common_pack_float>
10+
#endif
11+
12+
#if defined(HAS_MAP)
13+
914
uniform vec2 uvOrigin;
1015
uniform vec2 uvScale;
1116
uniform vec2 uvOffset;

packages/reshader.gl/src/pbr/wgsl/standard_vert.wgsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <fbo_picking_vert>
99
#endif
1010
#include <excavate_vert>
11+
#include <common_pack_float>
1112

1213
struct VertexInput {
1314
#ifdef POSITION_IS_INT
@@ -16,8 +17,11 @@ struct VertexInput {
1617
@location($i) aPosition: vec3f,
1718
#endif
1819

19-
#if HAS_MAP
20+
#if HAS_MAP || HAS_TERRAIN_FLAT_MASK
2021
@location($i) aTexCoord: vec2f,
22+
#endif
23+
#if HAS_MAP
24+
2125
#ifdef HAS_I3S_UVREGION
2226
@location($i) uvRegion: vec4f,
2327
#endif

packages/reshader.gl/src/shaderlib/glsl/output.vert

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ mat4 getPositionMatrix() {
6969
}
7070

7171
#ifdef HAS_MIN_ALTITUDE
72-
uniform float minAltitude;
72+
uniform float minAltitude;
73+
#endif
74+
75+
#ifdef HAS_TERRAIN_FLAT_MASK
76+
uniform sampler2D flatMask;
7377
#endif
7478

7579
vec4 getPosition(vec3 aPosition) {
@@ -84,6 +88,15 @@ vec4 getPosition(vec3 aPosition) {
8488
#ifdef HAS_TERRAIN_ALTITUDE
8589
POSITION.z += aTerrainAltitude * 100.0;
8690
#endif
91+
#ifdef HAS_TERRAIN_FLAT_MASK
92+
vec2 uv = aTexCoord;
93+
uv.y = 1.0 - uv.y;
94+
vec4 encodedHeight = texture2D(flatMask, uv);
95+
if (length(encodedHeight) < 2.0) {
96+
float maskHeight = decodeFloat32(encodedHeight);
97+
POSITION.z = min(POSITION.z, maskHeight);
98+
}
99+
#endif
87100
#ifdef HAS_MIN_ALTITUDE
88101
POSITION.z += minAltitude * 100.0;
89102
#endif

packages/reshader.gl/src/shaderlib/wgsl/common_pack_float.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,34 @@ fn common_encodeDepth(depth: f32) -> vec4f {
6767
fn common_decodeDepth(pack: vec4f) -> f32 {
6868
return pack.r + pack.g / 255.0;
6969
}
70+
71+
// https://cloud.tencent.com/developer/ask/sof/103481834
72+
fn encodeFloat32(f: f32) -> vec4f {
73+
var e = 5.0;
74+
75+
var F = abs(f);
76+
var Sign = step(0.0, -f);
77+
var Exponent = floor(log2(F));
78+
var Mantissa = (exp2(- Exponent) * F);
79+
Exponent = floor(log2(F) + 127.0) + floor(log2(Mantissa));
80+
var rgba = vec4(0.0);
81+
rgba[0] = 128.0 * Sign + floor(Exponent*exp2(-1.0));
82+
rgba[1] = 128.0 * mod(Exponent,2.0) + mod(floor(Mantissa*128.0),128.0);
83+
rgba[2] = floor(mod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0)));
84+
rgba[3] = floor(exp2(23.0)*mod(Mantissa,exp2(-15.0)));
85+
return rgba / 255.0;
86+
}
87+
88+
fn decodeFloat32(rgba: vec4f) -> f32 {
89+
rgba *= 255.0;
90+
var Sign = 1.0 - step(128.0,rgba[0])*2.0;
91+
var Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
92+
var Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
93+
var Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
94+
return Result;
95+
}
96+
97+
7098
`;
7199

72100
const frag = vert;

packages/reshader.gl/src/shaderlib/wgsl/output.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ const vert = /* wgsl */`
3131
@group(0) @binding($b) var<uniform> altitudeUniforms: AltitudeUniforms;
3232
#endif
3333
34+
#ifdef HAS_TERRAIN_FLAT_MASK
35+
@group(0) @binding($b) var flatMask: texture_2d<f32>;
36+
@group(0) @binding($b) var flatMaskSampler: sampler;
37+
#endif
38+
3439
fn getPositionMatrix(input: VertexInput, vertexOutput: ptr<function, VertexOutput>, positionMatrix: mat4x4f) -> mat4x4f {
3540
var worldMatrix: mat4x4f;
3641
#ifdef HAS_INSTANCE
@@ -79,6 +84,15 @@ fn getPosition(inputPosition: vec3f, vertexInput: VertexInput) -> vec4f {
7984
#ifdef HAS_TERRAIN_ALTITUDE
8085
outputPosition.z += vertexInput.aTerrainAltitude * 100.0;
8186
#endif
87+
#ifdef HAS_TERRAIN_FLAT_MASK
88+
var uv = aTexCoord;
89+
uv.y = 1.0 - uv.y;
90+
let encodedHeight = textureSample(flatMask, flatMaskSampler, uv);
91+
if (length(encodedHeight) < 2.0) {
92+
float maskHeight = decodeFloat32(encodedHeight);
93+
outputPosition.z = min(outputPosition.z, maskHeight);
94+
}
95+
#endif
8296
#ifdef HAS_MIN_ALTITUDE
8397
outputPosition.z += altitudeUniforms.minAltitude * 100.0;
8498
#endif

packages/vt/src/layer/layer/VectorTileLayer.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,9 @@ class VectorTileLayer extends maptalks.TileLayer {
12911291
) {
12921292
throw new Error(`Invalid filter at ${i} : ${JSON.stringify(filter)}`);
12931293
}
1294+
if (!styles[i].symbol) {
1295+
styles[i].symbol = {};
1296+
}
12941297
//TODO 如果定义了renderPlugin就必须定义symbol
12951298
}
12961299
}
9.25 KB
Loading
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const data = {
2+
type: 'FeatureCollection',
3+
features: [
4+
{ type: 'Feature', geometry: { type: 'Polygon', coordinates: [
5+
[[91.14478,29.696272], [91.14778,29.696272], [91.14778,29.690272], [91.14478,29.690272], [91.14478,29.696272]]]
6+
}, properties: { type: 1 } }
7+
]
8+
9+
};
10+
11+
const style = [
12+
{
13+
filter: true,
14+
renderPlugin: {
15+
type: 'fill',
16+
dataConfig: {
17+
type: 'fill'
18+
}
19+
},
20+
symbol: {
21+
polygonFill: '#f00',
22+
polygonOpacity: 0.5
23+
}
24+
},
25+
{
26+
filter: true,
27+
renderPlugin: {
28+
type: 'terrain-flat-mask',
29+
dataConfig: {
30+
type: 'fill',
31+
altitudeOffset: 3500
32+
}
33+
},
34+
symbol: {}
35+
}
36+
];
37+
38+
module.exports = {
39+
style,
40+
data,
41+
lit: true,
42+
renderingCount: 10,
43+
view: {
44+
center: [91.14478,29.708272],
45+
zoom: 12,
46+
pitch: 20,
47+
bearing: 0,
48+
}
49+
};

0 commit comments

Comments
 (0)