improvement: 修复提高拾取性能10倍+

This commit is contained in:
thinkinggis 2020-02-20 00:03:00 +08:00
parent 19ca0750dc
commit ef7b3608b0
4 changed files with 46 additions and 18 deletions

View File

@ -18,6 +18,7 @@ import { gl } from '../renderer/gl';
import { IFramebuffer } from '../renderer/IFramebuffer';
import { IPickingService } from './IPickingService';
const PICKSCALE = 10.0;
@injectable()
export default class PickingService implements IPickingService {
@inject(TYPES.IRendererService)
@ -64,23 +65,52 @@ export default class PickingService implements IPickingService {
return;
}
this.alreadyInPicking = true;
const layers = this.layerService.getLayers();
layers
.filter((layer) => layer.needPick())
.reverse()
.forEach(async (layer) => {
await this.pickingLayer(layer, target); // 可以实现是否向下触发
});
await this.pickingLayers(target);
this.layerService.renderLayers();
this.alreadyInPicking = false;
}
private async pickingLayers(target: IInteractionTarget) {
const { getViewportSize, useFramebuffer, clear } = this.rendererService;
const { width, height } = getViewportSize();
if (this.width !== width || this.height !== height) {
this.pickingFBO.resize({
width: Math.round(width / PICKSCALE),
height: Math.round(height / PICKSCALE),
});
this.width = width;
this.height = height;
}
useFramebuffer(this.pickingFBO, () => {
const layers = this.layerService.getLayers();
layers
.filter((layer) => layer.needPick())
.reverse()
.forEach((layer) => {
clear({
framebuffer: this.pickingFBO,
color: [0, 0, 0, 0],
stencil: 0,
depth: 1,
});
layer.hooks.beforePickingEncode.call();
layer.renderModels();
layer.hooks.afterPickingEncode.call();
this.pickFromPickingFBO(layer, target);
});
});
}
private async pickingLayer(layer: ILayer, target: IInteractionTarget) {
const { getViewportSize, useFramebuffer, clear } = this.rendererService;
const { width, height } = getViewportSize();
if (this.width !== width || this.height !== height) {
this.pickingFBO.resize({ width, height });
this.pickingFBO.resize({
width: Math.round(width / PICKSCALE),
height: Math.round(height / PICKSCALE),
});
this.width = width;
this.height = height;
}
@ -124,17 +154,15 @@ export default class PickingService implements IPickingService {
return;
}
let pickedColors: Uint8Array | undefined;
pickedColors = readPixels({
x: Math.round(xInDevicePixel),
x: Math.round(xInDevicePixel / PICKSCALE),
// 视口坐标系原点在左上,而 WebGL 在左下,需要翻转 Y 轴
y: Math.round(height - (y + 1) * window.devicePixelRatio),
y: Math.round((height - (y + 1) * window.devicePixelRatio) / PICKSCALE),
width: 1,
height: 1,
data: new Uint8Array(1 * 1 * 4),
framebuffer: this.pickingFBO,
});
if (
pickedColors[0] !== 0 ||
pickedColors[1] !== 0 ||
@ -220,13 +248,13 @@ export default class PickingService implements IPickingService {
) {
const [r, g, b] = pickedColors;
layer.hooks.beforeHighlight.call([r, g, b]);
this.layerService.renderLayers();
// this.layerService.renderLayers();
}
private selectFeature(layer: ILayer, pickedColors: Uint8Array | undefined) {
const [r, g, b] = pickedColors;
layer.hooks.beforeSelect.call([r, g, b]);
this.layerService.renderLayers();
// this.layerService.renderLayers();
}
private selectFeatureHandle(

View File

@ -87,7 +87,7 @@ export default class FillModel extends BaseModel {
vertex: number[],
attributeIdx: number,
) => {
const extrude = [-1, -1, 1, -1, 1, 1, -1, 1];
const extrude = [1, 1, -1, 1, -1, -1, 1, -1];
const extrudeIndex = (attributeIdx % 4) * 2;
return [extrude[extrudeIndex], extrude[extrudeIndex + 1]];
},

View File

@ -24,7 +24,7 @@ void main() {
// radius(16-bit)
v_radius = a_Size;
vec2 offset = project_pixel(extrude * (a_Size + u_stroke_width));
vec2 offset = project_pixel(extrude * (a_Size + u_stroke_width)) * -1.;
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));

View File

@ -46,9 +46,9 @@ export default class PointImage extends React.Component {
y: 'latitude',
},
})
.shape('circle')
.shape('triangle')
.color('red')
.active(false)
.active(true)
.size(20);
scene.addLayer(imageLayer);
i++;