feat(layers): add heatmap 3d layer

This commit is contained in:
thinkinggis 2019-11-02 00:42:30 +08:00
parent e04b3b268b
commit cd8409e4cb
6 changed files with 54 additions and 21 deletions

View File

@ -1,4 +1,5 @@
import { import {
ICameraService,
IEncodeFeature, IEncodeFeature,
IFontService, IFontService,
IGlobalConfigService, IGlobalConfigService,

View File

@ -1,6 +1,7 @@
import { import {
AttributeType, AttributeType,
gl, gl,
ICameraService,
IEncodeFeature, IEncodeFeature,
IFramebuffer, IFramebuffer,
ILayer, ILayer,
@ -12,6 +13,7 @@ import {
lazyInject, lazyInject,
TYPES, TYPES,
} from '@l7/core'; } from '@l7/core';
import { mat4 } from 'gl-matrix';
import BaseLayer from '../core/BaseLayer'; import BaseLayer from '../core/BaseLayer';
import { HeatmapTriangulation } from '../core/triangulation'; import { HeatmapTriangulation } from '../core/triangulation';
import { generateColorRamp, IColorRamp } from '../utils/color'; import { generateColorRamp, IColorRamp } from '../utils/color';
@ -34,6 +36,8 @@ export default class HeatMapLayer extends BaseLayer<IHeatMapLayerStyleOptions> {
public name: string = 'HeatMapLayer'; public name: string = 'HeatMapLayer';
protected texture: ITexture2D; protected texture: ITexture2D;
protected colorTexture: ITexture2D; protected colorTexture: ITexture2D;
@lazyInject(TYPES.ICameraService)
protected readonly camera: ICameraService;
protected heatmapFramerBuffer: IFramebuffer; protected heatmapFramerBuffer: IFramebuffer;
private intensityModel: IModel; private intensityModel: IModel;
private colorModel: IModel; private colorModel: IModel;
@ -72,7 +76,7 @@ export default class HeatMapLayer extends BaseLayer<IHeatMapLayerStyleOptions> {
this.intensityModel = this.buildHeatMapIntensity(); this.intensityModel = this.buildHeatMapIntensity();
this.models = [this.intensityModel]; this.models = [this.intensityModel];
// this.colorModel = this.buildHeatmapColor(); // this.colorModel = this.buildHeatmapColor();
this.colorModel = this.buildHeatmapColor(); this.colorModel = this.build3dHeatMap();
this.models.push(this.colorModel); this.models.push(this.colorModel);
const { rampColors } = this.getStyleOptions(); const { rampColors } = this.getStyleOptions();
const imageData = generateColorRamp(rampColors as IColorRamp); const imageData = generateColorRamp(rampColors as IColorRamp);
@ -251,12 +255,18 @@ export default class HeatMapLayer extends BaseLayer<IHeatMapLayerStyleOptions> {
private draw3DHeatMap() { private draw3DHeatMap() {
const { opacity } = this.getStyleOptions(); const { opacity } = this.getStyleOptions();
const mapbounds = this.map.getBounds(); const mapbounds = this.map.getBounds();
const invert = mat4.invert(
mat4.create(),
// @ts-ignore
mat4.fromValues(...this.camera.getViewProjectionMatrix()),
) as mat4;
this.colorModel.draw({ this.colorModel.draw({
uniforms: { uniforms: {
u_Opacity: opacity || 1.0, u_Opacity: opacity || 1.0,
u_colorTexture: this.colorTexture, u_colorTexture: this.colorTexture,
u_texture: this.heatmapFramerBuffer, u_texture: this.heatmapFramerBuffer,
u_extent: [-179.9476, -60.0959, 179.9778, 79.5651], u_extent: [-179.9476, -60.0959, 179.9778, 79.5651],
u_InverseViewProjectionMatrix: [...invert],
}, },
}); });
} }

View File

@ -11,6 +11,6 @@ void main(){
// vec4 color = texture2D(u_colorTexture,vec2(0.5,1.0-intensity)); // vec4 color = texture2D(u_colorTexture,vec2(0.5,1.0-intensity));
vec4 color = texture2D(u_colorTexture,ramp_pos); vec4 color = texture2D(u_colorTexture,ramp_pos);
gl_FragColor = color; gl_FragColor = color;
gl_FragColor.a = color.a * smoothstep(0.1,0.5,intensity) * u_Opacity; // gl_FragColor.a = color.a * smoothstep(0.0,0.12,intensity) * u_Opacity;
} }

View File

@ -5,19 +5,38 @@ uniform sampler2D u_texture;
uniform vec4 u_extent; uniform vec4 u_extent;
varying vec2 v_texCoord; varying vec2 v_texCoord;
uniform mat4 u_ModelMatrix; uniform mat4 u_ModelMatrix;
uniform mat4 u_InverseViewProjectionMatrix;
#pragma include "projection" #pragma include "projection"
void main() { void main() {
v_texCoord = a_Uv; v_texCoord = a_Uv;
vec2 minxy = project_position(vec4(u_extent.xy, 0, 1.0)).xy;
vec2 maxxy = project_position(vec4(u_extent.zw, 0, 1.0)).xy;
vec2 step = (maxxy - minxy); vec2 pos = a_Uv * vec2(2.0) - vec2(1.0);
vec2 pos = minxy + (vec2(a_Position.x, a_Position.y ) + vec2(1.0)) / vec2(2.0) * step; vec4 n_0 = vec4(pos, 0.0, 1.0) - u_ViewportCenterProjection;
vec4 n_1 = vec4(pos, 1.0, 1.0) - u_ViewportCenterProjection;
vec4 m_0 = u_InverseViewProjectionMatrix * n_0 ;
vec4 m_1 = u_InverseViewProjectionMatrix * n_1;
m_0 = m_0 / m_0.w;
m_1 = m_1 / m_1.w;
float zPos = (0.0 - m_0.z) / (m_1.z - m_0.z);
vec4 mapCoord = m_0 + zPos * (m_1 - m_0);
// vec4 p = u_InverseViewProjectionMatrix * (vec4(pos,0,1) - u_ViewportCenterProjection);
// p = p /p.w;
// pos.y = 1.0 -pos.y;
// vec2 minxy = project_position(vec4(u_extent.xy, 0, 1.0)).xy;
// vec2 maxxy = project_position(vec4(u_extent.zw, 0, 1.0)).xy;
// vec2 step = (maxxy - minxy);
// vec2 pos = minxy + (vec2(a_Position.x, a_Position.y ) + vec2(1.0)) / vec2(2.0) * step;
float intensity = texture2D(u_texture, v_texCoord).r; float intensity = texture2D(u_texture, v_texCoord).r;
gl_Position = project_common_position_to_clipspace(vec4(pos.xy, 0, 1.0)); gl_Position = project_common_position_to_clipspace(vec4(mapCoord.xy, intensity * 100., 1.0));
v_texCoord = (gl_Position.xy + vec2(1.0)) / vec2(2.0) * gl_Position.w; // gl_Position = vec4(pos,0.,1.0);
// v_texCoord = (gl_Position.xy + vec2(1.0)) / vec2(2.0) / gl_Position.w;
// v_texCoord.y = 1.0 - v_texCoord.y; // v_texCoord.y = 1.0 - v_texCoord.y;
} }

View File

@ -14,14 +14,14 @@ import RasterLayerDemo from './components/RasterLayer';
// @ts-ignore // @ts-ignore
storiesOf('图层', module) storiesOf('图层', module)
// .add('点图层', () => <PointDemo />) .add('点图层', () => <PointDemo />)
// .add('3D点', () => <Point3D />) .add('3D点', () => <Point3D />)
// .add('图片标注', () => <PointImage />) .add('图片标注', () => <PointImage />)
// .add('面3d图层', () => <Polygon3D />) .add('面3d图层', () => <Polygon3D />)
// .add('线图层', () => <LineLayer />) .add('线图层', () => <LineLayer />)
// .add('3D弧线', () => <ArcLineDemo />) .add('3D弧线', () => <ArcLineDemo />)
// .add('2D弧线', () => <Arc2DLineDemo />) .add('2D弧线', () => <Arc2DLineDemo />)
// .add('网格热力图', () => <GridHeatMap />) .add('网格热力图', () => <GridHeatMap />)
.add('热力图', () => <HeatMapDemo />) .add('热力图', () => <HeatMapDemo />)
// .add('栅格', () => <RasterLayerDemo />) .add('栅格', () => <RasterLayerDemo />)
.add('图片', () => <ImageLayerDemo />); .add('图片', () => <ImageLayerDemo />);

View File

@ -22,16 +22,19 @@ export default class HeatMapLayerDemo extends React.Component {
style: 'mapbox://styles/mapbox/dark-v10', style: 'mapbox://styles/mapbox/dark-v10',
zoom: 2, zoom: 2,
}); });
const layer = new HeatMapLayer({}); const layer = new HeatMapLayer({
enableTAA: true,
});
layer layer
.source(await response.json()) .source(await response.json())
.size('mag', [0, 1]) // weight映射通道 .size('mag', [0, 1]) // weight映射通道
.style({ .style({
intensity: 2, intensity: 2,
radius: 20, radius: 20,
opacity: 1, opacity: 0.5,
rampColors: { rampColors: {
colors: [ colors: [
'rgba(0,0,0,0)',
'#2E8AE6', '#2E8AE6',
'#69D1AB', '#69D1AB',
'#DAF291', '#DAF291',
@ -39,7 +42,7 @@ export default class HeatMapLayerDemo extends React.Component {
'#FF7A45', '#FF7A45',
'#CF1D49', '#CF1D49',
], ],
positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], positions: [0, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0],
}, },
}); });
scene.addLayer(layer); scene.addLayer(layer);