From a37b33a9885ea20eb8904ddd033149e5118bc98b Mon Sep 17 00:00:00 2001 From: YiQianYao <42212176+2912401452@users.noreply.github.com> Date: Thu, 21 Apr 2022 13:58:42 +0800 Subject: [PATCH] Polygonside (#1069) * feat: polygon extrude mode support set linear color * style: lint style --- packages/layers/src/polygon/models/extrude.ts | 71 +++--- .../shaders/extrude/polygon_extrude_frag.glsl | 19 +- .../polygon_extrude_picklight_frag.glsl | 20 +- .../polygon_extrude_picklight_vert.glsl | 12 +- .../shaders/extrude/polygon_extrude_vert.glsl | 9 +- .../extrude/polygon_extrudetex_frag.glsl | 5 +- .../extrude/polygon_extrudetex_vert.glsl | 6 +- .../components/amap2demo_polygon_extrude.tsx | 235 +++++++++--------- stories/Map/components/polygon_extrudeTex.tsx | 11 +- 9 files changed, 207 insertions(+), 181 deletions(-) diff --git a/packages/layers/src/polygon/models/extrude.ts b/packages/layers/src/polygon/models/extrude.ts index 9c6fb1024f..8e06f73fd0 100644 --- a/packages/layers/src/polygon/models/extrude.ts +++ b/packages/layers/src/polygon/models/extrude.ts @@ -63,11 +63,13 @@ export default class ExtrudeModel extends BaseModel { } // 转化渐变色 + let useLinearColor = 0; // 默认不生效 let sourceColorArr = [1, 1, 1, 1]; let targetColorArr = [1, 1, 1, 1]; if (sourceColor && targetColor) { sourceColorArr = rgb2arr(sourceColor); targetColorArr = rgb2arr(targetColor); + useLinearColor = 1; } return { @@ -76,6 +78,9 @@ export default class ExtrudeModel extends BaseModel { u_cellTypeLayout: this.getCellTypeLayout(), u_raisingHeight: Number(raisingHeight), u_opacity: isNumber(opacity) ? opacity : 1.0, + + // 渐变色支持参数 + u_linearColor: useLinearColor, u_sourceColor: sourceColorArr, u_targetColor: targetColorArr, u_texture: this.texture, @@ -143,46 +148,36 @@ export default class ExtrudeModel extends BaseModel { } protected registerBuiltinAttributes() { - const { - mapTexture, - } = this.layer.getLayerConfig() as IPolygonLayerStyleOptions; + const bbox = this.layer.getSource().extent; + const [minLng, minLat, maxLng, maxLat] = bbox; + const lngLen = maxLng - minLng; + const latLen = maxLat - minLat; - if (mapTexture) { - const bbox = this.layer.getSource().extent; - const [minLng, minLat, maxLng, maxLat] = bbox; - const lngLen = maxLng - minLng; - const latLen = maxLat - minLat; - - this.styleAttributeService.registerStyleAttribute({ - name: 'uvs', - type: AttributeType.Attribute, - descriptor: { - name: 'a_uvs', - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.STATIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 3, - update: ( - feature: IEncodeFeature, - featureIdx: number, - vertex: number[], - attributeIdx: number, - normal: number[], - ) => { - const lng = vertex[0]; - const lat = vertex[1]; - return [ - (lng - minLng) / lngLen, - (lat - minLat) / latLen, - vertex[4], - ]; - }, + this.styleAttributeService.registerStyleAttribute({ + name: 'uvs', + type: AttributeType.Attribute, + descriptor: { + name: 'a_uvs', + buffer: { + // give the WebGL driver a hint that this buffer may change + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, }, - }); - } + size: 3, + update: ( + feature: IEncodeFeature, + featureIdx: number, + vertex: number[], + attributeIdx: number, + normal: number[], + ) => { + const lng = vertex[0]; + const lat = vertex[1]; + return [(lng - minLng) / lngLen, (lat - minLat) / latLen, vertex[4]]; + }, + }, + }); // point layer size; this.styleAttributeService.registerStyleAttribute({ name: 'normal', diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_frag.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_frag.glsl index 7e26959f40..7f137e3263 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_frag.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_frag.glsl @@ -1,12 +1,25 @@ uniform float u_opacity: 1.0; +uniform vec4 u_sourceColor; +uniform vec4 u_targetColor; +uniform float u_linearColor: 0; varying vec4 v_Color; varying mat4 styleMappingMat; // 传递从片元中传递的映射数据 #pragma include "picking" void main() { - float opacity = styleMappingMat[0][0]; - gl_FragColor = v_Color; - // gl_FragColor.a *= u_opacity; + float opacity = styleMappingMat[0][0]; + float isSide = styleMappingMat[0][3]; + float sidey = styleMappingMat[3][0]; + float lightWeight = styleMappingMat[3][1]; + + if(isSide < 1.0 && u_linearColor == 1.0) { + vec4 linearColor = mix(u_targetColor, u_sourceColor, sidey); + linearColor.rgb *= lightWeight; + gl_FragColor = linearColor; + } else { + gl_FragColor = v_Color; + } + gl_FragColor.a *= opacity; gl_FragColor = filterColor(gl_FragColor); } diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_frag.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_frag.glsl index b452c2be45..e61342dff1 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_frag.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_frag.glsl @@ -1,13 +1,25 @@ uniform float u_opacity: 1.0; +uniform vec4 u_sourceColor; +uniform vec4 u_targetColor; +uniform float u_linearColor: 0; varying vec4 v_Color; varying mat4 styleMappingMat; // 传递从片元中传递的映射数据 #pragma include "picking" -varying float v_lightWeight; void main() { float opacity = styleMappingMat[0][0]; - gl_FragColor = v_Color; - // gl_FragColor.a *= u_opacity; + float isSide = styleMappingMat[0][3]; + float sidey = styleMappingMat[3][0]; + float lightWeight = styleMappingMat[3][1]; + + if(isSide < 1.0 && u_linearColor == 1.0) { + vec4 linearColor = mix(u_targetColor, u_sourceColor, sidey); + linearColor.rgb *= lightWeight; + gl_FragColor = linearColor; + } else { + gl_FragColor = v_Color; + } + gl_FragColor.a *= opacity; - gl_FragColor = filterColorAlpha(gl_FragColor, v_lightWeight); + gl_FragColor = filterColorAlpha(gl_FragColor, lightWeight); } diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_vert.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_vert.glsl index 93979e7e37..819c9b868a 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_vert.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_vert.glsl @@ -8,6 +8,7 @@ attribute vec4 a_Color; attribute vec3 a_Position; attribute vec3 a_Normal; attribute float a_Size; +attribute vec3 a_uvs; uniform mat4 u_ModelMatrix; uniform mat4 u_Mvp; @@ -24,16 +25,16 @@ varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样 #pragma include "light" #pragma include "picking" -varying float v_lightWeight; - void main() { // cal style mapping - 数据纹理映射部分的计算 styleMappingMat = mat4( - 0.0, 0.0, 0.0, 0.0, // opacity - strokeOpacity - strokeWidth - empty + 0.0, 0.0, 0.0, 0.0, // opacity - strokeOpacity - strokeWidth - isSide 0.0, 0.0, 0.0, 0.0, // strokeR - strokeG - strokeB - strokeA 0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1] - 0.0, 0.0, 0.0, 0.0 + 0.0, 0.0, 0.0, 0.0 // sidey ); + styleMappingMat[0][3] = a_Position.z; + styleMappingMat[3][0] = a_uvs[2]; float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行 float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列 @@ -75,9 +76,10 @@ void main() { } float lightWeight = calc_lighting(pos); - v_lightWeight = lightWeight; // v_Color = a_Color; v_Color = vec4(a_Color.rgb * lightWeight, a_Color.w); + styleMappingMat[3][1] = lightWeight; + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_vert.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_vert.glsl index 4714e4a66c..82efbf734c 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_vert.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_vert.glsl @@ -8,6 +8,7 @@ attribute vec4 a_Color; attribute vec3 a_Position; attribute vec3 a_Normal; attribute float a_Size; +attribute vec3 a_uvs; uniform mat4 u_ModelMatrix; uniform mat4 u_Mvp; @@ -27,11 +28,13 @@ varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样 void main() { // cal style mapping - 数据纹理映射部分的计算 styleMappingMat = mat4( - 0.0, 0.0, 0.0, 0.0, // opacity - strokeOpacity - strokeWidth - empty + 0.0, 0.0, 0.0, 0.0, // opacity - strokeOpacity - strokeWidth - isSide 0.0, 0.0, 0.0, 0.0, // strokeR - strokeG - strokeB - strokeA 0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1] - 0.0, 0.0, 0.0, 0.0 + 0.0, 0.0, 0.0, 0.0 // sidey ); + styleMappingMat[0][3] = a_Position.z; + styleMappingMat[3][0] = a_uvs[2]; float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行 float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列 @@ -81,5 +84,7 @@ void main() { // v_Color = a_Color; v_Color = vec4(a_Color.rgb * lightWeight, a_Color.w); + styleMappingMat[3][1] = lightWeight; + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_frag.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_frag.glsl index 61bd9b63e0..63264d8ac3 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_frag.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_frag.glsl @@ -9,18 +9,17 @@ varying mat4 styleMappingMat; // 传递从片元中传递的映射数据 void main() { float opacity = styleMappingMat[0][0]; float isSide = styleMappingMat[0][3]; - + float lightWeight = styleMappingMat[3][1]; float topU = styleMappingMat[2][2]; float topV = styleMappingMat[2][3]; float sidey = styleMappingMat[3][0]; if(isSide < 1.0) { gl_FragColor = mix(u_targetColor, u_sourceColor, sidey); + gl_FragColor.rgb *= lightWeight; } else { gl_FragColor = texture2D(u_texture, vec2(topU, topV)); } - - // gl_FragColor = v_Color; gl_FragColor.a *= opacity; diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_vert.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_vert.glsl index 5074160dbc..9e10ae92e2 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_vert.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_vert.glsl @@ -4,7 +4,6 @@ precision highp float; #define diffuseRatio 0.3 #define specularRatio 0.2 -attribute vec4 a_Color; attribute vec3 a_Position; attribute vec3 a_Normal; attribute float a_Size; @@ -84,9 +83,8 @@ void main() { gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); } - // float lightWeight = calc_lighting(pos); - // v_Color = a_Color; - // v_Color = vec4(a_Color.rgb * lightWeight, a_Color.w); + float lightWeight = calc_lighting(pos); + styleMappingMat[3][1] = lightWeight; setPickingColor(a_PickingColor); } diff --git a/stories/Map/components/amap2demo_polygon_extrude.tsx b/stories/Map/components/amap2demo_polygon_extrude.tsx index aea7dcec19..1c0eea8a02 100644 --- a/stories/Map/components/amap2demo_polygon_extrude.tsx +++ b/stories/Map/components/amap2demo_polygon_extrude.tsx @@ -117,132 +117,133 @@ export default class Amap2demo_polygon_extrude extends React.Component { // .active(true); // scene.addLayer(layer); - // @ts-ignore - let lineDown, lineUp, textLayer; + scene.on('loaded', () => { + // @ts-ignore + let lineDown, lineUp, textLayer; - fetch('https://geo.datav.aliyun.com/areas_v3/bound/330000_full.json') - .then((res) => res.json()) - .then((data) => { - let texts: any[] = []; + fetch('https://geo.datav.aliyun.com/areas_v3/bound/330000_full.json') + .then((res) => res.json()) + .then((data) => { + let texts: any[] = []; - data.features.map((option: any) => { - const { name, center } = option.properties; - const [lng, lat] = center; - texts.push({ name, lng, lat }); + data.features.map((option: any) => { + const { name, center } = option.properties; + const [lng, lat] = center; + texts.push({ name, lng, lat }); + }); + + textLayer = new PointLayer({ zIndex: 2 }) + .source(texts, { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, + }) + .shape('name', 'text') + .size(14) + .color('#0ff') + .style({ + textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left + spacing: 2, // 字符间距 + padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近 + stroke: '#0ff', // 描边颜色 + strokeWidth: 0.2, // 描边宽度 + raisingHeight: 200000 + 150000 + 10000, + textAllowOverlap: true, + }); + scene.addLayer(textLayer); + + lineDown = new LineLayer() + .source(data) + .shape('line') + .color('#0DCCFF') + .size(1) + .style({ + raisingHeight: 200000, + }); + + lineUp = new LineLayer({ zIndex: 1 }) + .source(data) + .shape('line') + .color('#0DCCFF') + .size(1) + .style({ + raisingHeight: 200000 + 150000, + }); + + scene.addLayer(lineDown); + scene.addLayer(lineUp); }); - textLayer = new PointLayer({ zIndex: 2 }) - .source(texts, { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, - }) - .shape('name', 'text') - .size(14) - .color('#0ff') - .style({ - textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left - spacing: 2, // 字符间距 - padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近 - stroke: '#0ff', // 描边颜色 - strokeWidth: 0.2, // 描边宽度 - raisingHeight: 200000 + 150000 + 10000, - textAllowOverlap: true, - }); - scene.addLayer(textLayer); + fetch('https://geo.datav.aliyun.com/areas_v3/bound/330000.json') + .then((res) => res.json()) + .then((data) => { + const lineLayer = new LineLayer() + .source(data) + .shape('wall') + .size(150000) + .style({ + heightfixed: true, + opacity: 0.6, + sourceColor: '#0DCCFF', + targetColor: 'rbga(255,255,255, 0)', + }); + scene.addLayer(lineLayer); - lineDown = new LineLayer() - .source(data) - .shape('line') - .color('#0DCCFF') - .size(1) - .style({ - raisingHeight: 200000, + const provincelayer = new PolygonLayer({}) + .source(data) + .size(150000) + .shape('extrude') + .color('#0DCCFF') + .active({ + color: 'rgb(100,230,255)', + }) + .style({ + heightfixed: true, + pickLight: true, + raisingHeight: 200000, + opacity: 0.8, + }); + scene.addLayer(provincelayer); + + provincelayer.on('mousemove', () => { + provincelayer.style({ + raisingHeight: 200000 + 100000, + }); + // @ts-ignore + lineDown.style({ + raisingHeight: 200000 + 100000, + }); + // @ts-ignore + lineUp.style({ + raisingHeight: 200000 + 150000 + 100000, + }); + // @ts-ignore + textLayer.style({ + raisingHeight: 200000 + 150000 + 10000 + 100000, + }); }); - lineUp = new LineLayer({ zIndex: 1 }) - .source(data) - .shape('line') - .color('#0DCCFF') - .size(1) - .style({ - raisingHeight: 200000 + 150000, - }); - - scene.addLayer(lineDown); - scene.addLayer(lineUp); - }); - - fetch('https://geo.datav.aliyun.com/areas_v3/bound/330000.json') - .then((res) => res.json()) - .then((data) => { - const lineLayer = new LineLayer() - .source(data) - .shape('wall') - .size(150000) - .style({ - heightfixed: true, - opacity: 0.6, - sourceColor: '#0DCCFF', - targetColor: 'rbga(255,255,255, 0)', - }); - scene.addLayer(lineLayer); - - const provincelayer = new PolygonLayer({}) - .source(data) - .size(150000) - .shape('extrude') - .color('#0DCCFF') - .active({ - color: 'rgb(100,230,255)', - }) - .style({ - heightfixed: true, - pickLight: true, - raisingHeight: 200000, - opacity: 0.8, - }); - - scene.addLayer(provincelayer); - - provincelayer.on('mousemove', () => { - provincelayer.style({ - raisingHeight: 200000 + 100000, - }); - // @ts-ignore - lineDown.style({ - raisingHeight: 200000 + 100000, - }); - // @ts-ignore - lineUp.style({ - raisingHeight: 200000 + 150000 + 100000, - }); - // @ts-ignore - textLayer.style({ - raisingHeight: 200000 + 150000 + 10000 + 100000, + provincelayer.on('unmousemove', () => { + provincelayer.style({ + raisingHeight: 200000, + }); + // @ts-ignore + lineDown.style({ + raisingHeight: 200000, + }); + // @ts-ignore + lineUp.style({ + raisingHeight: 200000 + 150000, + }); + // @ts-ignore + textLayer.style({ + raisingHeight: 200000 + 150000 + 10000, + }); }); }); - - provincelayer.on('unmousemove', () => { - provincelayer.style({ - raisingHeight: 200000, - }); - // @ts-ignore - lineDown.style({ - raisingHeight: 200000, - }); - // @ts-ignore - lineUp.style({ - raisingHeight: 200000 + 150000, - }); - // @ts-ignore - textLayer.style({ - raisingHeight: 200000 + 150000 + 10000, - }); - }); - }); + }); } public render() { diff --git a/stories/Map/components/polygon_extrudeTex.tsx b/stories/Map/components/polygon_extrudeTex.tsx index 0204882af8..91b0fea0de 100644 --- a/stories/Map/components/polygon_extrudeTex.tsx +++ b/stories/Map/components/polygon_extrudeTex.tsx @@ -32,15 +32,16 @@ export default class Amap2demo_polygon_extrude extends React.Component { .size(150000) .shape('extrude') .color('#0DCCFF') - // .active({ - // color: 'rgb(100,230,255)', - // }) + .active({ + color: 'rgb(255,255,255)', + mix: 0.5, + }) .style({ heightfixed: true, pickLight: true, raisingHeight: 200000, - mapTexture: - 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*SOUKQJpw1FYAAAAAAAAAAAAAARQnAQ', + // mapTexture: + // 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*SOUKQJpw1FYAAAAAAAAAAAAAARQnAQ', // mapTexture: 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*EojwT4VzSiYAAAAAAAAAAAAAARQnAQ' // opacity: 0.8, sourceColor: '#f00',