Skip to content

Commit

Permalink
fix: picking in WebGL2 w/ device api (#2125)
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoiver authored Dec 6, 2023
1 parent 06b3005 commit 98721e3
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 37 deletions.
1 change: 1 addition & 0 deletions packages/core/src/shaders/scene_uniforms.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ layout(std140) uniform SceneUniforms {
vec2 u_ViewportSize;
vec2 u_sceneCenterMercator;
float u_FocalDistance;
float u_SceneUniformsPadding;
};
76 changes: 47 additions & 29 deletions packages/layers/src/plugins/PixelPickingPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AttributeType,
gl,
IBuffer,
IEncodeFeature,
ILayer,
ILayerPlugin,
Expand All @@ -10,11 +11,13 @@ import {
import {
decodePickingColor,
encodePickingColor,
lodashUtil,
rgb2arr,
} from '@antv/l7-utils';
import { injectable } from 'inversify';
import 'reflect-metadata';
import { ShaderLocation } from '../core/CommonStyleAttribute';
const { isNumber } = lodashUtil;

const PickingStage = {
NONE: 0.0,
Expand All @@ -24,40 +27,41 @@ const PickingStage = {

@injectable()
export default class PixelPickingPlugin implements ILayerPlugin {
private PickOption: { [key: string]: number[] | number } = {
u_HighlightColor: [1, 0, 0, 1],
u_SelectColor: [1, 0, 0, 1],
u_PickingColor: [0, 0, 0],
u_PickingStage: 0,
u_CurrentSelectedId: [0, 0, 0],
u_PickingThreshold: 10,
u_PickingBuffer: 0, // TODO: 更新机制
u_shaderPick: 0,
u_EnableSelect: 0,
u_activeMix: 0,
};
/**
* Use map to keep order of insertion.
* @see https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order
*/
private pickingUniformMap: Map<string, number[] | number>;

private pickOption2Array() {
return Object.values(this.PickOption).flat();
const array: number[] = [];
this.pickingUniformMap.forEach((value, key) => {
if (isNumber(value)) {
array.push(value);
} else {
array.push(...value);
}
});
return array;
}

private updatePickOption(
option: { [key: string]: number[] | number },
rendererService: IRendererService,
options: { [key: string]: number[] | number },
uniformBuffer: IBuffer,
layer: ILayer,
) {
Object.keys(options).forEach((key) => {
this.pickingUniformMap.set(key, options[key]);
});

const u_PickingBuffer = layer.getLayerConfig().pickingBuffer || 0;
// Tip: 当前地图是否在拖动
const u_shaderPick = Number(layer.getShaderPickStat());
this.PickOption.u_PickingBuffer = u_PickingBuffer;
this.PickOption.u_shaderPick = u_shaderPick;

Object.keys(option).forEach((key: string) => {
this.PickOption[key] = option[key];
});
rendererService.uniformBuffers[1].subData({
this.pickingUniformMap.set('u_PickingBuffer', u_PickingBuffer);
this.pickingUniformMap.set('u_shaderPick', u_shaderPick);
uniformBuffer.subData({
offset: 0,
data: new Uint8Array(new Float32Array(this.pickOption2Array())),
data: this.pickOption2Array(),
});
}
public apply(
Expand All @@ -70,9 +74,23 @@ export default class PixelPickingPlugin implements ILayerPlugin {
styleAttributeService: IStyleAttributeService;
},
) {
let uniformBuffer: IBuffer;
this.pickingUniformMap = new Map<string, number[] | number>([
['u_HighlightColor', [1, 0, 0, 1]],
['u_SelectColor', [1, 0, 0, 1]],
['u_PickingColor', [0, 0, 0]],
['u_PickingStage', 0],
['u_CurrentSelectedId', [0, 0, 0]],
['u_PickingThreshold', 10],
['u_PickingBuffer', 0],
['u_shaderPick', 0],
['u_EnableSelect', 0],
['u_activeMix', 0],
]);

if (!rendererService.uniformBuffers[1]) {
// Create a Uniform Buffer Object(UBO).
const uniformBuffer = rendererService.createBuffer({
uniformBuffer = rendererService.createBuffer({
// vec4 u_HighlightColor;
// vec4 u_SelectColor;
// vec3 u_PickingColor;
Expand All @@ -87,7 +105,7 @@ export default class PixelPickingPlugin implements ILayerPlugin {
isUBO: true,
});
rendererService.uniformBuffers[1] = uniformBuffer;
this.updatePickOption({}, rendererService, layer);
this.updatePickOption({}, uniformBuffer, layer);
}

// TODO: 由于 Shader 目前无法根据是否开启拾取进行内容修改,因此即使不开启也需要生成 a_PickingColor
Expand Down Expand Up @@ -121,7 +139,7 @@ export default class PixelPickingPlugin implements ILayerPlugin {
{
u_PickingStage: PickingStage.ENCODE,
},
rendererService,
uniformBuffer,
layer,
);
layer.models.forEach((model) =>
Expand All @@ -140,7 +158,7 @@ export default class PixelPickingPlugin implements ILayerPlugin {
{
u_PickingStage: PickingStage.HIGHLIGHT,
},
rendererService,
uniformBuffer,
layer,
);
layer.models.forEach((model) =>
Expand Down Expand Up @@ -171,7 +189,7 @@ export default class PixelPickingPlugin implements ILayerPlugin {
u_HighlightColor: highlightColorInArray.map((c) => c * 255),
u_activeMix: activeMix,
};
this.updatePickOption(option, rendererService, layer);
this.updatePickOption(option, uniformBuffer, layer);
layer.models.forEach((model) => model.addUniforms(option));
},
);
Expand All @@ -197,7 +215,7 @@ export default class PixelPickingPlugin implements ILayerPlugin {
u_SelectColor: highlightColorInArray.map((c) => c * 255),
u_EnableSelect: 1,
};
this.updatePickOption(option, rendererService, layer);
this.updatePickOption(option, uniformBuffer, layer);
layer.models.forEach((model) => model.addUniforms(option));
},
);
Expand Down
3 changes: 2 additions & 1 deletion packages/layers/src/point/models/fill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ export default class FillModel extends BaseModel {
new Float32Array([
...commonIniform.u_blur_height_fixed,
commonIniform.u_stroke_width,
commonIniform.u_stroke_opacity,
commonIniform.u_additive,
commonIniform.u_stroke_opacity,
commonIniform.u_size_unit,
0,
]).buffer,
),
});
Expand Down
8 changes: 2 additions & 6 deletions packages/layers/src/point/models/normal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,9 @@ export default class NormalModel extends BaseModel {

this.uniformBuffers[1].subData({
offset: 0,
data: new Uint8Array(
new Float32Array([0.5
]).buffer,
)
data: new Uint8Array(new Float32Array([0.5]).buffer),
});


return {
u_size_scale: 0.5,
...attributes,
Expand All @@ -73,7 +69,7 @@ export default class NormalModel extends BaseModel {
isUBO: true,
});

this.uniformBuffers.push(uniformBuffer,commonBuffer);
this.uniformBuffers.push(uniformBuffer, commonBuffer);
const model = await this.layer.buildLayerModel({
moduleName: 'pointNormal',
vertexShader: normalVert,
Expand Down
1 change: 1 addition & 0 deletions packages/layers/src/point/shaders/fill_frag.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ layout(std140) uniform commonUniforms {
float u_additive;
float u_stroke_opacity;
float u_size_unit;
float u_common_uniforms_padding;
};

in vec4 v_color;
Expand Down
1 change: 1 addition & 0 deletions packages/layers/src/point/shaders/fill_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ layout(std140) uniform commonUniforms {
float u_additive;
float u_stroke_opacity;
float u_size_unit;
float u_common_uniforms_padding;
};

out vec4 v_color;
Expand Down
3 changes: 2 additions & 1 deletion packages/renderer/src/device/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,15 @@ export default class DeviceRendererService implements IRendererService {
const colorAttachment = this.currentFramebuffer
? this.currentFramebuffer['colorRenderTarget'] || null
: this.mainColorRT;
const colorResolveTo = this.currentFramebuffer ? null : onscreenTexture;
const depthStencilAttachment = this.currentFramebuffer
? this.currentFramebuffer['depthRenderTarget'] || null
: this.mainDepthRT;
const depthClearValue = depthStencilAttachment ? 1 : undefined;

this.renderPass = this.device.createRenderPass({
colorAttachment: [colorAttachment],
colorResolveTo: [this.currentFramebuffer ? null : onscreenTexture],
colorResolveTo: [colorResolveTo],
colorClearColor: [TransparentBlack],
depthStencilAttachment,
depthClearValue,
Expand Down

0 comments on commit 98721e3

Please sign in to comment.