-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GPU Aggregation (6/8): HexagonLayer (#9098)
- Loading branch information
1 parent
fdbb88a
commit 427a95b
Showing
12 changed files
with
967 additions
and
1,283 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 0 additions & 127 deletions
127
modules/aggregation-layers/src/hexagon-layer/hexagon-aggregator.ts
This file was deleted.
Oops, something went wrong.
77 changes: 77 additions & 0 deletions
77
modules/aggregation-layers/src/hexagon-layer/hexagon-cell-layer-vertex.glsl.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// deck.gl | ||
// SPDX-License-Identifier: MIT | ||
// Copyright (c) vis.gl contributors | ||
|
||
import {getHexbinCentroidGLSL} from './hexbin'; | ||
|
||
export default /* glsl */ `\ | ||
#version 300 es | ||
#define SHADER_NAME hexagon-cell-layer-vertex-shader | ||
in vec3 positions; | ||
in vec3 normals; | ||
in vec2 instancePositions; | ||
in float instanceElevationValues; | ||
in float instanceColorValues; | ||
in vec3 instancePickingColors; | ||
// Custom uniforms | ||
uniform float opacity; | ||
uniform bool extruded; | ||
uniform float coverage; | ||
uniform float radius; | ||
uniform vec2 hexOriginCommon; | ||
uniform vec2 colorDomain; | ||
uniform sampler2D colorRange; | ||
uniform vec2 elevationDomain; | ||
uniform vec2 elevationRange; | ||
// Result | ||
out vec4 vColor; | ||
${getHexbinCentroidGLSL} | ||
float interp(float value, vec2 domain, vec2 range) { | ||
float r = min(max((value - domain.x) / (domain.y - domain.x), 0.), 1.); | ||
return mix(range.x, range.y, r); | ||
} | ||
vec4 interp(float value, vec2 domain, sampler2D range) { | ||
float r = min(max((value - domain.x) / (domain.y - domain.x), 0.), 1.); | ||
return texture(range, vec2(r, 0.5)); | ||
} | ||
void main(void) { | ||
geometry.pickingColor = instancePickingColors; | ||
if (isnan(instanceColorValues)) { | ||
gl_Position = vec4(0.); | ||
return; | ||
} | ||
vec2 commonPosition = hexbinCentroid(instancePositions, radius) + (hexOriginCommon - project.commonOrigin.xy); | ||
commonPosition += positions.xy * radius * coverage; | ||
geometry.position = vec4(commonPosition, 0.0, 1.0); | ||
geometry.normal = project_normal(normals); | ||
// calculate z, if 3d not enabled set to 0 | ||
float elevation = 0.0; | ||
if (extruded) { | ||
elevation = interp(instanceElevationValues, elevationDomain, elevationRange); | ||
elevation = project_size(elevation); | ||
// cylindar gemoetry height are between -1.0 to 1.0, transform it to between 0, 1 | ||
geometry.position.z = (positions.z + 1.0) / 2.0 * elevation; | ||
} | ||
gl_Position = project_common_position_to_clipspace(geometry.position); | ||
DECKGL_FILTER_GL_POSITION(gl_Position, geometry); | ||
vColor = interp(instanceColorValues, colorDomain, colorRange); | ||
vColor.a *= opacity; | ||
if (extruded) { | ||
vColor.rgb = lighting_getLightColor(vColor.rgb, project.cameraPosition, geometry.position.xyz, geometry.normal); | ||
} | ||
DECKGL_FILTER_COLOR(vColor, geometry); | ||
} | ||
`; |
111 changes: 111 additions & 0 deletions
111
modules/aggregation-layers/src/hexagon-layer/hexagon-cell-layer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// deck.gl | ||
// SPDX-License-Identifier: MIT | ||
// Copyright (c) vis.gl contributors | ||
|
||
import {Texture} from '@luma.gl/core'; | ||
import {UpdateParameters, Color} from '@deck.gl/core'; | ||
import {ColumnLayer} from '@deck.gl/layers'; | ||
import {colorRangeToTexture} from '../utils/color-utils'; | ||
import vs from './hexagon-cell-layer-vertex.glsl'; | ||
|
||
/** Proprties added by HexagonCellLayer. */ | ||
export type _HexagonCellLayerProps = { | ||
hexOriginCommon: [number, number]; | ||
colorDomain: () => [number, number]; | ||
colorRange?: Color[]; | ||
elevationDomain: () => [number, number]; | ||
elevationRange: [number, number]; | ||
}; | ||
|
||
export default class HexagonCellLayer<ExtraPropsT extends {} = {}> extends ColumnLayer< | ||
null, | ||
ExtraPropsT & Required<_HexagonCellLayerProps> | ||
> { | ||
static layerName = 'HexagonCellLayer'; | ||
|
||
state!: ColumnLayer['state'] & { | ||
colorTexture: Texture; | ||
}; | ||
|
||
getShaders() { | ||
return { | ||
...super.getShaders(), | ||
vs | ||
}; | ||
} | ||
|
||
initializeState() { | ||
super.initializeState(); | ||
|
||
const attributeManager = this.getAttributeManager()!; | ||
attributeManager.remove([ | ||
'instanceElevations', | ||
'instanceFillColors', | ||
'instanceLineColors', | ||
'instanceStrokeWidths' | ||
]); | ||
attributeManager.addInstanced({ | ||
instancePositions: { | ||
size: 2, | ||
type: 'float32', | ||
accessor: 'getBin' | ||
}, | ||
instanceColorValues: { | ||
size: 1, | ||
type: 'float32', | ||
accessor: 'getColorValue' | ||
}, | ||
instanceElevationValues: { | ||
size: 1, | ||
type: 'float32', | ||
accessor: 'getElevationValue' | ||
} | ||
}); | ||
} | ||
|
||
updateState(params: UpdateParameters<this>) { | ||
super.updateState(params); | ||
|
||
const {props, oldProps} = params; | ||
const model = this.state.fillModel!; | ||
|
||
if (oldProps.colorRange !== props.colorRange) { | ||
this.state.colorTexture?.destroy(); | ||
this.state.colorTexture = colorRangeToTexture(this.context.device, props.colorRange); | ||
model.setBindings({colorRange: this.state.colorTexture}); | ||
} | ||
} | ||
|
||
finalizeState(context) { | ||
super.finalizeState(context); | ||
|
||
this.state.colorTexture?.destroy(); | ||
} | ||
|
||
draw({uniforms}) { | ||
// Use dynamic domain from the aggregator | ||
const colorDomain = this.props.colorDomain(); | ||
const elevationDomain = this.props.elevationDomain(); | ||
const {radius, hexOriginCommon, elevationRange, elevationScale, extruded, coverage} = | ||
this.props; | ||
const fillModel = this.state.fillModel!; | ||
|
||
if (fillModel.vertexArray.indexBuffer) { | ||
// indices are for drawing wireframe, disable them | ||
// TODO - this should be handled in ColumnLayer? | ||
fillModel.setIndexBuffer(null); | ||
} | ||
fillModel.setVertexCount(this.state.fillVertexCount); | ||
fillModel.setUniforms(uniforms); | ||
fillModel.setUniforms({ | ||
extruded, | ||
coverage, | ||
colorDomain, | ||
elevationDomain, | ||
radius, | ||
hexOriginCommon, | ||
elevationRange: [elevationRange[0] * elevationScale, elevationRange[1] * elevationScale] | ||
}); | ||
fillModel.draw(this.context.renderPass); | ||
} | ||
} |
Oops, something went wrong.