@deck.gl/geo-layers
Version:
deck.gl layers supporting geospatial use cases and GIS formats
164 lines (146 loc) • 3.96 kB
JavaScript
import { GLTFMaterialParser } from '@luma.gl/experimental';
import { Model, pbr } from '@luma.gl/core';
import { SimpleMeshLayer } from '@deck.gl/mesh-layers';
import vs from './mesh-layer-vertex.glsl';
import fs from './mesh-layer-fragment.glsl';
function validateGeometryAttributes(attributes) {
const hasColorAttribute = attributes.COLOR_0 || attributes.colors;
if (!hasColorAttribute) {
attributes.colors = {
constant: true,
value: new Float32Array([1, 1, 1])
};
}
}
const defaultProps = {
pbrMaterial: {
type: 'object',
value: null
},
featureIds: {
type: 'array',
value: null,
optional: true
}
};
export default class _MeshLayer extends SimpleMeshLayer {
getShaders() {
const shaders = super.getShaders();
const modules = shaders.modules;
modules.push(pbr);
return { ...shaders,
vs,
fs
};
}
initializeState() {
const {
featureIds
} = this.props;
super.initializeState();
if (featureIds) {
this.state.attributeManager.add({
featureIdsPickingColors: {
type: 5121,
size: 3,
noAlloc: true,
update: this.calculateFeatureIdsPickingColors
}
});
}
}
updateState({
props,
oldProps,
changeFlags
}) {
super.updateState({
props,
oldProps,
changeFlags
});
if (props.pbrMaterial !== oldProps.pbrMaterial) {
this.updatePbrMaterialUniforms(props.pbrMaterial);
}
}
draw(opts) {
const {
featureIds
} = this.props;
if (!this.state.model) {
return;
}
this.state.model.setUniforms({
u_Camera: this.state.model.getUniforms().project_uCameraPosition,
u_pickFeatureIds: Boolean(featureIds)
});
super.draw(opts);
}
getModel(mesh) {
const {
id,
pbrMaterial
} = this.props;
const materialParser = this.parseMaterial(pbrMaterial, mesh);
const shaders = this.getShaders();
validateGeometryAttributes(mesh.attributes);
const model = new Model(this.context.gl, { ...this.getShaders(),
id,
geometry: mesh,
defines: { ...shaders.defines,
...(materialParser === null || materialParser === void 0 ? void 0 : materialParser.defines),
HAS_UV_REGIONS: mesh.attributes.uvRegions
},
parameters: materialParser === null || materialParser === void 0 ? void 0 : materialParser.parameters,
isInstanced: true
});
return model;
}
updatePbrMaterialUniforms(pbrMaterial) {
const {
model
} = this.state;
if (model) {
const {
mesh
} = this.props;
const materialParser = this.parseMaterial(pbrMaterial, mesh);
model.setUniforms(materialParser.uniforms);
}
}
parseMaterial(pbrMaterial, mesh) {
const unlit = Boolean(pbrMaterial.pbrMetallicRoughness && pbrMaterial.pbrMetallicRoughness.baseColorTexture);
const materialParser = new GLTFMaterialParser(this.context.gl, {
attributes: {
NORMAL: mesh.attributes.normals,
TEXCOORD_0: mesh.attributes.texCoords
},
material: {
unlit,
...pbrMaterial
},
pbrDebug: false,
imageBasedLightingEnvironment: null,
lights: true,
useTangents: false
});
return materialParser;
}
calculateFeatureIdsPickingColors(attribute) {
const {
featureIds
} = this.props;
const value = new Uint8ClampedArray(featureIds.length * attribute.size);
const pickingColor = [];
for (let index = 0; index < featureIds.length; index++) {
this.encodePickingColor(featureIds[index], pickingColor);
value[index * 3] = pickingColor[0];
value[index * 3 + 1] = pickingColor[1];
value[index * 3 + 2] = pickingColor[2];
}
attribute.value = value;
}
}
_MeshLayer.layerName = '_MeshLayer';
_MeshLayer.defaultProps = defaultProps;
//# sourceMappingURL=mesh-layer.js.map