From 05bd44be1c2efd910d2fdae5f3c08365d286e2e8 Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Sat, 2 Nov 2019 00:42:30 +0800 Subject: [PATCH] feat(layers): add heatmap 3d layer --- packages/layers/src/core/BaseLayer.ts | 1 + packages/layers/src/heatmap/heatmap.ts | 12 ++++++- .../src/heatmap/shaders/heatmap_3d_frag.glsl | 2 +- .../src/heatmap/shaders/heatmap_3d_vert.glsl | 33 +++++++++++++++---- stories/Layers/Layers.stories.tsx | 18 +++++----- stories/Layers/components/heatMap.tsx | 9 +++-- 6 files changed, 54 insertions(+), 21 deletions(-) diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts index abd212c7df..750e43d302 100644 --- a/packages/layers/src/core/BaseLayer.ts +++ b/packages/layers/src/core/BaseLayer.ts @@ -1,4 +1,5 @@ import { + ICameraService, IEncodeFeature, IFontService, IGlobalConfigService, diff --git a/packages/layers/src/heatmap/heatmap.ts b/packages/layers/src/heatmap/heatmap.ts index 19d134b1b5..ddd039c596 100644 --- a/packages/layers/src/heatmap/heatmap.ts +++ b/packages/layers/src/heatmap/heatmap.ts @@ -1,6 +1,7 @@ import { AttributeType, gl, + ICameraService, IEncodeFeature, IFramebuffer, ILayer, @@ -12,6 +13,7 @@ import { lazyInject, TYPES, } from '@l7/core'; +import { mat4 } from 'gl-matrix'; import BaseLayer from '../core/BaseLayer'; import { HeatmapTriangulation } from '../core/triangulation'; import { generateColorRamp, IColorRamp } from '../utils/color'; @@ -34,6 +36,8 @@ export default class HeatMapLayer extends BaseLayer { public name: string = 'HeatMapLayer'; protected texture: ITexture2D; protected colorTexture: ITexture2D; + @lazyInject(TYPES.ICameraService) + protected readonly camera: ICameraService; protected heatmapFramerBuffer: IFramebuffer; private intensityModel: IModel; private colorModel: IModel; @@ -72,7 +76,7 @@ export default class HeatMapLayer extends BaseLayer { this.intensityModel = this.buildHeatMapIntensity(); this.models = [this.intensityModel]; // this.colorModel = this.buildHeatmapColor(); - this.colorModel = this.buildHeatmapColor(); + this.colorModel = this.build3dHeatMap(); this.models.push(this.colorModel); const { rampColors } = this.getStyleOptions(); const imageData = generateColorRamp(rampColors as IColorRamp); @@ -251,12 +255,18 @@ export default class HeatMapLayer extends BaseLayer { private draw3DHeatMap() { const { opacity } = this.getStyleOptions(); const mapbounds = this.map.getBounds(); + const invert = mat4.invert( + mat4.create(), + // @ts-ignore + mat4.fromValues(...this.camera.getViewProjectionMatrix()), + ) as mat4; this.colorModel.draw({ uniforms: { u_Opacity: opacity || 1.0, u_colorTexture: this.colorTexture, u_texture: this.heatmapFramerBuffer, u_extent: [-179.9476, -60.0959, 179.9778, 79.5651], + u_InverseViewProjectionMatrix: [...invert], }, }); } diff --git a/packages/layers/src/heatmap/shaders/heatmap_3d_frag.glsl b/packages/layers/src/heatmap/shaders/heatmap_3d_frag.glsl index f3f83b7c2a..f2c35866d3 100644 --- a/packages/layers/src/heatmap/shaders/heatmap_3d_frag.glsl +++ b/packages/layers/src/heatmap/shaders/heatmap_3d_frag.glsl @@ -11,6 +11,6 @@ void main(){ // vec4 color = texture2D(u_colorTexture,vec2(0.5,1.0-intensity)); vec4 color = texture2D(u_colorTexture,ramp_pos); 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; } diff --git a/packages/layers/src/heatmap/shaders/heatmap_3d_vert.glsl b/packages/layers/src/heatmap/shaders/heatmap_3d_vert.glsl index a7093f2215..087e4328bd 100644 --- a/packages/layers/src/heatmap/shaders/heatmap_3d_vert.glsl +++ b/packages/layers/src/heatmap/shaders/heatmap_3d_vert.glsl @@ -5,19 +5,38 @@ uniform sampler2D u_texture; uniform vec4 u_extent; varying vec2 v_texCoord; uniform mat4 u_ModelMatrix; +uniform mat4 u_InverseViewProjectionMatrix; #pragma include "projection" void main() { - 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; + v_texCoord = a_Uv; - 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; - gl_Position = project_common_position_to_clipspace(vec4(pos.xy, 0, 1.0)); - v_texCoord = (gl_Position.xy + vec2(1.0)) / vec2(2.0) * gl_Position.w; + gl_Position = project_common_position_to_clipspace(vec4(mapCoord.xy, intensity * 100., 1.0)); + // 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; } diff --git a/stories/Layers/Layers.stories.tsx b/stories/Layers/Layers.stories.tsx index e4d6f3ba92..1625fe47f2 100644 --- a/stories/Layers/Layers.stories.tsx +++ b/stories/Layers/Layers.stories.tsx @@ -14,14 +14,14 @@ import RasterLayerDemo from './components/RasterLayer'; // @ts-ignore storiesOf('图层', module) - // .add('点图层', () => ) - // .add('3D点', () => ) - // .add('图片标注', () => ) - // .add('面3d图层', () => ) - // .add('线图层', () => ) - // .add('3D弧线', () => ) - // .add('2D弧线', () => ) - // .add('网格热力图', () => ) + .add('点图层', () => ) + .add('3D点', () => ) + .add('图片标注', () => ) + .add('面3d图层', () => ) + .add('线图层', () => ) + .add('3D弧线', () => ) + .add('2D弧线', () => ) + .add('网格热力图', () => ) .add('热力图', () => ) - // .add('栅格', () => ) + .add('栅格', () => ) .add('图片', () => ); diff --git a/stories/Layers/components/heatMap.tsx b/stories/Layers/components/heatMap.tsx index 9ca24173d2..4dc2c55241 100644 --- a/stories/Layers/components/heatMap.tsx +++ b/stories/Layers/components/heatMap.tsx @@ -22,16 +22,19 @@ export default class HeatMapLayerDemo extends React.Component { style: 'mapbox://styles/mapbox/dark-v10', zoom: 2, }); - const layer = new HeatMapLayer({}); + const layer = new HeatMapLayer({ + enableTAA: true, + }); layer .source(await response.json()) .size('mag', [0, 1]) // weight映射通道 .style({ intensity: 2, radius: 20, - opacity: 1, + opacity: 0.5, rampColors: { colors: [ + 'rgba(0,0,0,0)', '#2E8AE6', '#69D1AB', '#DAF291', @@ -39,7 +42,7 @@ export default class HeatMapLayerDemo extends React.Component { '#FF7A45', '#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);