Skip to content

Commit

Permalink
fix: 解决 GeometryLayer 在不同底图上的渲染不一致情况 (#2523)
Browse files Browse the repository at this point in the history
* fix: 解决 GeometryLayer 在不同底图上的渲染不一致情况

* chore: add changeset

* fix: 统一地形高度

* docs: 更新文档
  • Loading branch information
lvisei authored Jun 5, 2024
1 parent 958f5d1 commit 67647e9
Show file tree
Hide file tree
Showing 18 changed files with 275 additions and 119 deletions.
5 changes: 5 additions & 0 deletions .changeset/cyan-badgers-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@antv/l7-layers': patch
---

fix: 解决 GeometryLayer 在不同底图上的渲染不一致情况
4 changes: 4 additions & 0 deletions examples/demos/geometry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { plane } from './plane';
export { rain } from './rain';
export { snow } from './snow';
export { terrain } from './terrain';
28 changes: 28 additions & 0 deletions examples/demos/geometry/plane.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { GeometryLayer } from '@antv/l7';
import type { TestCase } from '../../types';
import { CaseScene } from '../../utils';

export const plane: TestCase = async (options) => {
const scene = await CaseScene({
...options,
mapConfig: {
center: [120.1025, 30.2594],
style: 'dark',
zoom: 10,
},
});

const layer = new GeometryLayer()
.shape('plane')
.style({
opacity: 0.8,
width: 0.074,
height: 0.061,
center: [120.1025, 30.2594],
})
.active(true)
.color('#ff0');
scene.addLayer(layer);

return scene;
};
33 changes: 33 additions & 0 deletions examples/demos/geometry/rain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GeometryLayer } from '@antv/l7';
import type { TestCase } from '../../types';
import { CaseScene } from '../../utils';

export const rain: TestCase = async (options) => {
const scene = await CaseScene({
...options,
mapConfig: {
pitch: 90,
style: 'dark',
center: [120, 30],
zoom: 6,
},
});

const layer = new GeometryLayer()
.shape('sprite')
.size(10)
.style({
opacity: 0.3,
mapTexture:
'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*w2SFSZJp4nIAAAAAAAAAAAAAARQnAQ', // rain
center: [120, 30],
spriteCount: 120,
spriteRadius: 10,
spriteTop: 300,
spriteUpdate: 10,
spriteScale: 0.8,
});
scene.addLayer(layer);

return scene;
};
31 changes: 31 additions & 0 deletions examples/demos/geometry/snow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { GeometryLayer } from '@antv/l7';
import type { TestCase } from '../../types';
import { CaseScene } from '../../utils';

export const snow: TestCase = async (options) => {
const scene = await CaseScene({
...options,
mapConfig: {
pitch: 40,
style: 'dark',
center: [120, 30],
zoom: 6,
},
});

const layer = new GeometryLayer()
.shape('sprite')
.size(10)
.style({
mapTexture:
'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*zLQwQKBSagYAAAAAAAAAAAAAARQnAQ', // snow
center: [120, 30],
spriteCount: 60,
spriteRadius: 10,
spriteTop: 300,
spriteUpdate: 5,
});
scene.addLayer(layer);

return scene;
};
84 changes: 84 additions & 0 deletions examples/demos/geometry/terrain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { GeometryLayer } from '@antv/l7';
import type { TestCase } from '../../types';
import { CaseScene } from '../../utils';

export const terrain: TestCase = async (options) => {
const scene = await CaseScene({
...options,
mapConfig: {
center: [120.1025, 30.2594],
style: 'dark',
pitch: 65,
rotation: 180,
zoom: 14,
},
});

let currentZoom = 14,
currentModelData = '100x100';

const layer = new GeometryLayer().shape('plane').style({
width: 0.074,
height: 0.061,
center: [120.1025, 30.2594],
widthSegments: 100,
heightSegments: 100,
terrainClipHeight: 1,
mapTexture:
'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*gA0NRbuOF5cAAAAAAAAAAAAAARQnAQ',
terrainTexture:
'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*eYFaRYlnnOUAAAAAAAAAAAAAARQnAQ',
rgb2height: (r, g, b) => {
let h = (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1;
h = h / 200 - 12750;
h = Math.max(0, h);
return h;
},
});

let modelData10: any, modelData20: any, modelData100: any;

layer.on('terrainImageLoaded', () => {
modelData10 = layer.layerModel.createModelData({
widthSegments: 10,
heightSegments: 10,
});

modelData20 = layer.layerModel.createModelData({
widthSegments: 20,
heightSegments: 20,
});

modelData100 = layer.layerModel.createModelData({
widthSegments: 100,
heightSegments: 100,
});
});

scene.on('zoom', () => {
const zoom = Math.floor(scene.getZoom());
if (currentZoom !== zoom) {
if (zoom > 13) {
if (currentModelData !== '100x100') {
layer.updateModelData(modelData100);
currentModelData = '100x100';
}
} else if (zoom > 12) {
if (currentModelData !== '20x20') {
layer.updateModelData(modelData20);
currentModelData = '20x20';
}
} else {
if (currentModelData !== '10x10') {
layer.updateModelData(modelData10);
currentModelData = '10x10';
}
}
currentZoom = zoom;
}
});

scene.addLayer(layer);

return scene;
};
29 changes: 17 additions & 12 deletions examples/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as CanvasTestCases from './canvas';
import * as ComponentsTestCases from './components';
import * as ExtendTestCases from './extend';
import * as GalleryTestCases from './gallery';
import * as GeometryTestCases from './geometry';
import * as HeatmapTestCases from './heatmap';
import * as LineTestCases from './line';
import * as MaskTestCases from './mask';
Expand All @@ -26,20 +27,24 @@ export const TestCases = new Map<string, [string, TestCase][]>([
['canvas', Object.entries(CanvasTestCases)],
['basemap', Object.entries(BasemapTestCases)],
['components', Object.entries(ComponentsTestCases)],
['geometry', Object.entries(GeometryTestCases)],
['gallery', Object.entries(GalleryTestCases)],
['webgpu', Object.entries(WebgpuTestCases)],
['extend', Object.entries(ExtendTestCases)],
]);

export function geSnapshotTestsFromNamespace(namespace: string) {
const testcases = TestCases.get(namespace);
if (!testcases) return [];
const demo = testcases
.filter(([, demo]) => Boolean(demo.snapshot))
.map(([name, demo]) => ({
name,
snapshot: Boolean(demo.snapshot),
sleepTime: typeof demo?.snapshot === 'object' ? demo.snapshot?.sleepTime : undefined,
}));
return demo;
}
/**
* ge SnapshotTests from namespace
*/
// export function geSnapshotTestsFromNamespace(namespace: string) {
// const testcases = TestCases.get(namespace);
// if (!testcases) return [];
// const demo = testcases
// .filter(([, demo]) => Boolean(demo.snapshot))
// .map(([name, demo]) => ({
// name,
// snapshot: Boolean(demo.snapshot),
// sleepTime: typeof demo?.snapshot === 'object' ? demo.snapshot?.sleepTime : undefined,
// }));
// return demo;
// }
100 changes: 37 additions & 63 deletions packages/layers/src/geometry/models/plane.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import type {
IAttributeAndElements,
IEncodeFeature,
IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import type { IEncodeFeature, IModel, IModelUniform, ITexture2D } from '@antv/l7-core';
import { AttributeType, gl } from '@antv/l7-core';
// import { mat4, vec3 } from 'gl-matrix';
import BaseModel from '../../core/BaseModel';
import type { IGeometryLayerStyleOptions } from '../../core/interface';
import planeFrag from '../shaders/plane_frag.glsl';
Expand Down Expand Up @@ -83,6 +76,7 @@ export default class PlaneModel extends BaseModel {
heightSegments = 1,
center = [120, 30],
terrainTexture,
rgb2height = (r: number, g: number, b: number) => r + g + b,
} = this.layer.getLayerConfig() as IGeometryLayerStyleOptions;
const { indices, positions } = this.initPlane(
width,
Expand All @@ -93,7 +87,14 @@ export default class PlaneModel extends BaseModel {
);
if (terrainTexture) {
// 存在地形贴图的时候会根据地形贴图对顶点进行偏移
this.loadTerrainTexture(positions, indices);
return this.translateVertex(
positions,
indices,
this.terrainImage,
widthSegments,
heightSegments,
rgb2height,
);
}

return {
Expand Down Expand Up @@ -147,7 +148,8 @@ export default class PlaneModel extends BaseModel {
}

public async initModels(): Promise<IModel[]> {
const { mapTexture } = this.layer.getLayerConfig() as IGeometryLayerStyleOptions;
const { mapTexture, terrainTexture } =
this.layer.getLayerConfig() as IGeometryLayerStyleOptions;
this.mapTexture = mapTexture;

const { createTexture2D } = this.rendererService;
Expand All @@ -159,6 +161,10 @@ export default class PlaneModel extends BaseModel {
this.updateTexture(mapTexture);
this.initUniformsBuffer();

if (terrainTexture) {
this.terrainImage = await this.loadTerrainImage(terrainTexture);
}

const model = await this.layer.buildLayerModel({
moduleName: 'geometryPlane',
vertexShader: planeVert,
Expand Down Expand Up @@ -282,70 +288,38 @@ export default class PlaneModel extends BaseModel {
}
}

const oldFeatures = this.layer.getEncodedData();
const modelData = this.styleAttributeService.createAttributesAndIndices(oldFeatures, () => {
return {
vertices: positions,
indices,
size: 5,
};
});
this.layer.updateModelData(modelData as IAttributeAndElements);
this.layerService.throttleRenderLayers();
return {
vertices: positions,
indices,
size: 5,
};
}

/**
* load terrain texture & offset attribute z
*/
protected loadTerrainTexture(positions: number[], indices: number[]) {
const {
widthSegments = 1,
heightSegments = 1,
terrainTexture,
rgb2height = (r: number, g: number, b: number) => r + g + b,
} = this.layer.getLayerConfig() as IGeometryLayerStyleOptions;
private async loadTerrainImage(terrainTexture: string) {
if (this.terrainImage) {
// 若当前已经存在 image,直接进行偏移计算(LOD)
if (this.terrainImageLoaded) {
this.translateVertex(
positions,
indices,
this.terrainImage,
widthSegments,
heightSegments,
rgb2height,
);
return this.terrainImage;
} else {
this.terrainImage.onload = () => {
this.translateVertex(
positions,
indices,
this.terrainImage,
widthSegments,
heightSegments,
rgb2height,
);
};
return new Promise<HTMLImageElement>((resolve) => {
this.terrainImage.onload = () => {
resolve(this.terrainImage);
};
});
}
} else {
// 加载地形贴图、根据地形贴图对 planeGeometry 进行偏移
const terrainImage = new Image();
this.terrainImage = terrainImage;
terrainImage.crossOrigin = 'anonymous';
terrainImage.onload = () => {
this.terrainImageLoaded = true;
// 图片加载完,触发事件,可以进行地形图的顶点计算存储
setTimeout(() => this.layer.emit('terrainImageLoaded', null));
this.translateVertex(
positions,
indices,
terrainImage,
widthSegments,
heightSegments,
rgb2height,
);
};
terrainImage.src = terrainTexture as string;
return new Promise<HTMLImageElement>((resolve) => {
terrainImage.onload = () => {
this.terrainImageLoaded = true;
resolve(terrainImage);
// 图片加载完,触发事件,可以进行地形图的顶点计算存储
setTimeout(() => this.layer.emit('terrainImageLoaded', null));
};
terrainImage.src = terrainTexture as string;
});
}
}

Expand Down
Loading

0 comments on commit 67647e9

Please sign in to comment.