This commit is contained in:
2912401452 2022-02-15 16:59:22 +08:00
commit b56e75ccfb
22 changed files with 793 additions and 139 deletions

View File

@ -118,4 +118,24 @@ layer.style({
[光标柱图](../../../examples/point/column#column_light)
[渐变柱图](../../../examples/point/column#column_linear)
- heightFixed 设置 3D 柱体的高度固定(保持固定的笛卡尔高度而不是等像素高度)
🌟 3D 柱图在设置 heightFixed 为 true 后柱子的半径也会固定,从 v2.7.12 版本开始支持
```javascript
style({
heightfixed: true, // 默认为 false
});
```
- pickLight 设置 3D 柱体拾取高亮颜色是否支持光照计算
🌟 3D 柱图支持通过设置 pickLight 来控制拾取高亮颜色的光照计算,从 v2.7.12 版本开始支持
```javascript
style({
pickLight: true, // 默认为 false
});
```
`markdown:docs/common/layer/base.md`

View File

@ -16,47 +16,47 @@ layer.style({
});
```
- 样式数据映射
在大多数情况下,用户需要将 source 中传入的数据映射到图层的元素中,以此来达到需要的可视化的效果,比如想要用柱形图表示各地的人口数据,代码可能是这个样子的:
- 样式数据映射🌟
在正常情况下style 的参数会作用到一个图层上的所有图形,如一个 PointLayer 中有十个点,我们设置 opacity = 0.5 这样十个点的透明度都是 0.5。
而在特殊情况下,我们可能需要为每个点分别设置一个透明度,这时候按照原来的方式直接设置 style 方法的 opacity 的值就无法满足需求了,为此我们需要提供特殊的赋值方式。
通常我们会根据传入图层的数据为图层的每个图形设置单独的值,因此我们称之为“样式数据映射”。
我们支持几种设置 style 中的参数从 source 数据中动态取值的写法。
```javascript
const population = await getPopulation();
// 根据数据中的 v 字段的值设置点图层各个点的透明度
const data = [
{
lng: 120,
lat: 30,
v: 0.5
},
...
]
const layer = new PointLayer()
.source(population)
.shape('cylinder')
.color('#f00')
.size('population'); // population 字段表示数据中的人口值
scene.addLayer(layer);
```
而在一些特殊的业务场景下,我们可能需要将除了 size、color、以外的属性根据数据动态设置如我们在绘制文本标注的时候需要根据文本的长短来设置偏移量以保证文本位置的相对固定。在这种情况下我们就需要使用图层样式数据纹理来完成这一项工作。
<img width="60%" style="display: block;margin: 0 auto;" alt="案例" src='https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*wZOKSb0YdjwAAAAAAAAAAAAAARQnAQ'>
```javascript
const pointLayer = new PointLayer({})
.source(data, {
parser: {
type: 'json',
x: 'j',
y: 'w',
},
x: 'lng',
y: 'lat'
}
})
.shape('m', 'text')
.size(12)
.color('w', ['#0e0030', '#0e0030', '#0e0030'])
.style({
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
textOffset: 'textOffset', // 文本相对锚点的偏移量 [水平, 垂直]
fontFamily,
iconfont: true,
textAllowOverlap: true,
});
.shape('circle')
.color('#f00')
.size({
// 第一种写法 根据字段从 data 中直接取值
opacity: 'v'// opacity = 0.5
// 第二种写法 根据字段从 data 中取值,同时通过回调函数赋值(通常会在回调函数中写业务逻辑)
opacity: ['v', (v: number) => v] // opacity = 0.5
// 第三种写法 根据字段取值,然后映射到设置的值区间
opaicty: ['v', [0.1, 0.5]] // opacity 的值字啊 0.1 0.5 之间
});
scene.addLayer(layer);
```
[在线案例](../../examples/point/text#styleMap)
从 L7 2.5 开始,各图层样式将逐步支持样式数据映射
从 L7 2.5 开始,各图层样式将逐步支持样式数据映射,目前支持样式数据映射的 style 参数如下:
| layer 类型/shape | 支持的样式字段 | 备注 |
| ---------------------- | ---------------------------------------------------- | --------------------------------- |

View File

@ -92,4 +92,6 @@ layer 初始化完成之后,地图是否自动缩放到图层范围
是否在 maskLayer 显示
- true 在内部显示
- false 在外部显示
-

View File

@ -14,8 +14,15 @@ import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
import { LineArcTriangulation } from '../../core/triangulation';
import line_arc_frag from '../shaders/line_arc_frag.glsl';
import line_arc2d_vert from '../shaders/line_arc_vert.glsl';
// arc dash line
import arc_dash_frag from '../shaders/dash/arc_dash_frag.glsl';
import arc_dash_vert from '../shaders/dash/arc_dash_vert.glsl';
// arc normal line
import arc_line_frag from '../shaders/line_arc_frag.glsl';
import arc_line_vert from '../shaders/line_arc_vert.glsl';
// arc linear line
import arc_linear_frag from '../shaders/linear/arc_linear_frag.glsl';
import arc_linear_vert from '../shaders/linear/arc_linear_vert.glsl';
const lineStyleObj: { [key: string]: number } = {
solid: 0.0,
dash: 1.0,
@ -116,7 +123,6 @@ export default class ArcModel extends BaseModel {
public getAnimateUniforms(): IModelUniform {
const { animateOption } = this.layer.getLayerConfig() as ILayerConfig;
// console.log('animateOption', animateOption)
return {
u_aimate: this.animateOption2Array(animateOption as IAnimateOption),
u_time: this.layer.getLayerAnimateTime(),
@ -136,18 +142,48 @@ export default class ArcModel extends BaseModel {
this.iconService.off('imageUpdate', this.updateTexture);
}
public getShaders(): { frag: string; vert: string; type: string } {
const {
sourceColor,
targetColor,
lineType,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
if (lineType === 'dash') {
return {
frag: arc_dash_frag,
vert: arc_dash_vert,
type: 'dash',
};
}
if (sourceColor && targetColor) {
// 分离 linear 功能
return {
frag: arc_linear_frag,
vert: arc_linear_vert,
type: 'linear',
};
} else {
return {
frag: arc_line_frag,
vert: arc_line_vert,
type: 'normal',
};
}
}
public buildModels(): IModel[] {
const {
segmentNumber = 30,
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
return [
this.layer.buildLayerModel({
moduleName: 'arc2dline',
vertexShader: line_arc2d_vert,
fragmentShader: line_arc_frag,
moduleName: 'arc2dline' + type,
vertexShader: vert,
fragmentShader: frag,
triangulation: LineArcTriangulation,
depth: { enable: false },
blend: this.getBlend(),

View File

@ -14,8 +14,13 @@ import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
import { LineArcTriangulation } from '../../core/triangulation';
import { EARTH_RADIUS } from '../../earth/utils';
import line_arc_frag from '../shaders/line_arc_3d_frag.glsl';
import line_arc_vert from '../shaders/line_arc_3d_vert.glsl';
// arc3d line layer
import arc3d_line_frag from '../shaders/line_arc_3d_frag.glsl';
import arc3d_line_vert from '../shaders/line_arc_3d_vert.glsl';
// arc3d linear layer
import arc3d_linear_frag from '../shaders/linear/arc3d_linear_frag.glsl';
import arc3d_linear_vert from '../shaders/linear/arc3d_linear_vert.glsl';
const lineStyleObj: { [key: string]: number } = {
solid: 0.0,
dash: 1.0,
@ -132,17 +137,41 @@ export default class Arc3DModel extends BaseModel {
this.iconService.off('imageUpdate', this.updateTexture);
}
public getShaders(): { frag: string; vert: string; type: string } {
const {
sourceColor,
targetColor,
lineType,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
if (sourceColor && targetColor) {
// 分离 linear 功能
return {
frag: arc3d_linear_frag,
vert: arc3d_linear_vert,
type: 'linear',
};
} else {
return {
frag: arc3d_line_frag,
vert: arc3d_line_vert,
type: 'normal',
};
}
}
public buildModels(): IModel[] {
const {
segmentNumber = 30,
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
return [
this.layer.buildLayerModel({
moduleName: 'arc3Dline',
vertexShader: line_arc_vert,
fragmentShader: line_arc_frag,
moduleName: 'arc3Dline' + type,
vertexShader: vert,
fragmentShader: frag,
triangulation: LineArcTriangulation,
blend: this.getBlend(),
segmentNumber,

View File

@ -18,11 +18,11 @@ import { LineTriangulation } from '../../core/triangulation';
// dash line shader
import line_dash_frag from '../shaders/dash/line_dash_frag.glsl';
import line_dash_vert from '../shaders/dash/line_dash_vert.glsl';
// other function shaders
import linear_line_frag from '../shaders/frag/linear_frag.glsl';
// basic line shader
import line_frag from '../shaders/line_frag.glsl';
import line_vert from '../shaders/line_vert.glsl';
// other function shaders
import linear_line_frag from '../shaders/linear/line_linear_frag.glsl';
const lineStyleObj: { [key: string]: number } = {
solid: 0.0,
@ -170,10 +170,9 @@ export default class LineModel extends BaseModel {
sourceColor,
targetColor,
lineType,
dashArray,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
if (lineType === 'dash' && dashArray) {
if (lineType === 'dash') {
return {
frag: line_dash_frag,
vert: line_dash_vert,

View File

@ -13,8 +13,10 @@ import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions } from '../../core/interface';
import { SimpleLineTriangulation } from '../../core/triangulation';
import line_frag from '../shaders/simpleline_frag.glsl';
import line_vert from '../shaders/simpleline_vert.glsl';
// linear simple line shader
import simle_linear_frag from '../shaders/linear/simpleline_linear_frag.glsl';
import simple_line_frag from '../shaders/simpleline_frag.glsl';
import simple_line_vert from '../shaders/simpleline_vert.glsl';
export default class SimpleLineModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
@ -94,17 +96,39 @@ export default class SimpleLineModel extends BaseModel {
this.dataTexture?.destroy();
}
public getShaders(): { frag: string; vert: string; type: string } {
const {
sourceColor,
targetColor,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
if (sourceColor && targetColor) {
// 分离 linear 功能
return {
frag: simle_linear_frag,
vert: simple_line_vert,
type: 'linear',
};
} else {
return {
frag: simple_line_frag,
vert: simple_line_vert,
type: 'normal',
};
}
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
return [
this.layer.buildLayerModel({
moduleName: 'simpleline',
vertexShader: line_vert,
fragmentShader: line_frag,
moduleName: 'simpleline' + type,
vertexShader: vert,
fragmentShader: frag,
triangulation: SimpleLineTriangulation,
primitive: gl.LINES, // gl.LINES gl.TRIANGLES
blend: this.getBlend(),

View File

@ -0,0 +1,28 @@
uniform float u_opacity;
varying vec4 v_dash_array;
varying vec4 v_color;
uniform float segmentNumber;
varying mat4 styleMappingMat; // 传递从片元中传递的映射数据
#pragma include "picking"
void main() {
float opacity = styleMappingMat[0][0];
float d_distance_ratio = styleMappingMat[3].b; // 当前顶点在弧线中所处的分段比例
gl_FragColor = v_color;
gl_FragColor.a *= opacity;
float flag = 0.;
float dashLength = mod(d_distance_ratio, v_dash_array.x + v_dash_array.y + v_dash_array.z + v_dash_array.w);
if(dashLength < v_dash_array.x || (dashLength > (v_dash_array.x + v_dash_array.y) && dashLength < v_dash_array.x + v_dash_array.y + v_dash_array.z)) {
flag = 1.;
}
gl_FragColor.a *=flag;
gl_FragColor = filterColor(gl_FragColor);
}

View File

@ -0,0 +1,149 @@
attribute vec4 a_Color;
attribute vec3 a_Position;
attribute vec4 a_Instance;
attribute float a_Size;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float segmentNumber;
varying vec4 v_color;
uniform vec4 u_dash_array: [10.0, 5., 0, 0];
uniform float u_lineDir: 1.0;
varying vec4 v_dash_array;
uniform float u_thetaOffset: 0.314;
uniform float u_opacity: 1.0;
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
#pragma include "styleMapping"
#pragma include "styleMappingCalOpacity"
#pragma include "styleMappingCalThetaOffset"
#pragma include "projection"
#pragma include "project"
#pragma include "picking"
float bezier3(vec3 arr, float t) {
float ut = 1. - t;
return (arr.x * ut + arr.y * t) * ut + (arr.y * ut + arr.z * t) * t;
}
vec2 midPoint(vec2 source, vec2 target, float arcThetaOffset) {
vec2 center = target - source;
float r = length(center);
float theta = atan(center.y, center.x);
float thetaOffset = arcThetaOffset;
float r2 = r / 2.0 / cos(thetaOffset);
float theta2 = theta + thetaOffset;
vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y);
if(u_lineDir == 1.0) { // 正向
return mid;
} else { // 逆向
// (mid + vmin)/2 = (s + t)/2
vec2 vmid = source + target - mid;
return vmid;
}
// return mid;
}
float getSegmentRatio(float index) {
return smoothstep(0.0, 1.0, index / (segmentNumber - 1.));
}
vec2 interpolate (vec2 source, vec2 target, float t, float arcThetaOffset) {
// if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation
vec2 mid = midPoint(source, target, arcThetaOffset);
vec3 x = vec3(source.x, mid.x, target.x);
vec3 y = vec3(source.y, mid.y, target.y);
return vec2(bezier3(x ,t), bezier3(y,t));
}
vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0;
return offset;
}
vec2 getNormal(vec2 line_clipspace, float offset_direction) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
return reverse_offset_normal(vec3(dir_screenspace,1.0)).xy * sign(offset_direction);
}
void main() {
v_color = a_Color;
// 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, // strokeR - strokeG - strokeB - strokeA
0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1]
0.0, 0.0, 0.0, 0.0 // dataset 数据集
);
float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行
float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列
float columnWidth = 1.0/columnCount; // 列宽
float rowHeight = 1.0/rowCount; // 行高
float cellCount = calCellCount(); // opacity - strokeOpacity - strokeWidth - stroke - offsets
float id = a_vertexId; // 第n个顶点
float cellCurrentRow = floor(id * cellCount / columnCount) + 1.0; // 起始点在第几行
float cellCurrentColumn = mod(id * cellCount, columnCount) + 1.0; // 起始点在第几列
// cell 固定顺序 opacity -> strokeOpacity -> strokeWidth -> stroke -> thetaOffset...
// 按顺序从 cell 中取值、若没有则自动往下取值
float textureOffset = 0.0; // 在 cell 中取值的偏移量
vec2 opacityAndOffset = calOpacityAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight);
styleMappingMat[0][0] = opacityAndOffset.r;
textureOffset = opacityAndOffset.g;
vec2 thetaOffsetAndOffset = calThetaOffsetAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight);
styleMappingMat[0][1] = thetaOffsetAndOffset.r;
textureOffset = thetaOffsetAndOffset.g;
// cal style mapping - 数据纹理映射部分的计算
vec2 source = a_Instance.rg; // 起始点
vec2 target = a_Instance.ba; // 终点
float segmentIndex = a_Position.x;
float segmentRatio = getSegmentRatio(segmentIndex);
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);
vec2 s = source;
vec2 t = target;
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
s = unProjCustomCoord(source);
t = unProjCustomCoord(target);
}
float total_Distance = pixelDistance(s, t) / 2.0 * PI;
v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / (total_Distance / segmentNumber * segmentIndex);
styleMappingMat[3].b = segmentIndex / segmentNumber;
// styleMappingMat[0][1] - arcThetaOffset
vec4 curr = project_position(vec4(interpolate(source, target, segmentRatio, styleMappingMat[0][1]), 0.0, 1.0));
vec4 next = project_position(vec4(interpolate(source, target, nextSegmentRatio, styleMappingMat[0][1]), 0.0, 1.0));
// v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
//unProjCustomCoord
vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y));
// gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0));
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
// gl_Position = u_Mvp * (vec4(curr.xy + offset, 0, 1.0));
gl_Position = u_Mvp * (vec4(curr.xy + offset, 0, 1.0));
} else {
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0));
}
setPickingColor(a_PickingColor);
}

View File

@ -22,10 +22,6 @@ varying vec2 v_iconMapUV;
uniform float u_time;
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
varying mat4 styleMappingMat;
#pragma include "picking"
@ -34,18 +30,11 @@ void main() {
float opacity = styleMappingMat[0][0];
float animateSpeed = 0.0; // 运动速度
float d_distance_ratio = styleMappingMat[3].g; // 当前点位距离占线总长的比例
gl_FragColor = v_color;
if(u_linearColor == 1.0) { // 使用渐变颜色
gl_FragColor = mix(u_sourceColor, u_targetColor, v_segmentIndex/segmentNumber);
} else { // 使用 color 方法传入的颜色
gl_FragColor = v_color;
}
// float blur = 1.- smoothstep(u_blur, 1., length(v_normal.xy));
// float blur = smoothstep(1.0, u_blur, length(v_normal.xy));
gl_FragColor.a *= opacity;
if(u_line_type == LineTypeDash) {
float flag = 0.;
float flag = 0.;
float dashLength = mod(d_distance_ratio, v_dash_array.x + v_dash_array.y + v_dash_array.z + v_dash_array.w);
if(dashLength < v_dash_array.x || (dashLength > (v_dash_array.x + v_dash_array.y) && dashLength < v_dash_array.x + v_dash_array.y + v_dash_array.z)) {
flag = 1.;

View File

@ -1,5 +1,4 @@
#define LineTypeSolid 0.0
#define LineTypeDash 1.0
#define Animate 0.0
#define LineTexture 1.0
@ -23,10 +22,6 @@ varying vec2 v_iconMapUV;
varying mat4 styleMappingMat; // 传递从片元中传递的映射数据
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
#pragma include "picking"
void main() {
@ -35,24 +30,9 @@ void main() {
float d_segmentIndex = styleMappingMat[3].r; // 当前顶点在弧线中所处的分段位置
float d_distance_ratio = styleMappingMat[3].b; // 当前顶点在弧线中所处的分段比例
// 设置弧线的底色
if(u_linearColor == 1.0) { // 使用渐变颜色
gl_FragColor = mix(u_sourceColor, u_targetColor, d_segmentIndex/segmentNumber);
} else { // 使用 color 方法传入的颜色
gl_FragColor = v_color;
}
gl_FragColor = v_color;
// float blur = 1.- smoothstep(u_blur, 1., length(v_normal.xy));
// float blur = smoothstep(1.0, u_blur, length(v_normal.xy));
gl_FragColor.a *= opacity;
if(u_line_type == LineTypeDash) {
float flag = 0.;
float dashLength = mod(d_distance_ratio, v_dash_array.x + v_dash_array.y + v_dash_array.z + v_dash_array.w);
if(dashLength < v_dash_array.x || (dashLength > (v_dash_array.x + v_dash_array.y) && dashLength < v_dash_array.x + v_dash_array.y + v_dash_array.z)) {
flag = 1.;
}
gl_FragColor.a *=flag;
}
if(u_aimate.x == Animate && u_line_texture != LineTexture) {
animateSpeed = u_time / u_aimate.y;
@ -64,7 +44,7 @@ void main() {
}
// 当存在贴图时在底色上贴上贴图
if(u_line_texture == LineTexture && u_line_type != LineTypeDash) { // while load texture
if(u_line_texture == LineTexture) { // while load texture
float arcRadio = smoothstep( 0.0, 1.0, (d_segmentIndex / segmentNumber));
// float arcRadio = smoothstep( 0.0, 1.0, d_distance_ratio);

View File

@ -1,5 +1,3 @@
#define LineTypeSolid 0.0
#define LineTypeDash 1.0
#define Animate 0.0
#define LineTexture 1.0
@ -12,12 +10,8 @@ uniform mat4 u_Mvp;
uniform float segmentNumber;
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
varying vec4 v_color;
// varying vec2 v_normal;
uniform float u_line_type: 0.0;
uniform vec4 u_dash_array: [10.0, 5., 0, 0];
uniform float u_lineDir: 1.0;
varying vec4 v_dash_array;
uniform float u_thetaOffset: 0.314;
uniform float u_icon_step: 100;
@ -125,20 +119,6 @@ void main() {
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);
float d_distance_ratio;
if(u_line_type == LineTypeDash) {
d_distance_ratio = segmentIndex / segmentNumber;
vec2 s = source;
vec2 t = target;
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
s = unProjCustomCoord(source);
t = unProjCustomCoord(target);
}
float total_Distance = pixelDistance(s, t) / 2.0 * PI;
// float total_Distance = pixelDistance(a_Instance.rg, a_Instance.ba) / 2.0 * PI;
v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / (total_Distance / segmentNumber * segmentIndex);
}
if(u_aimate.x == Animate) {
d_distance_ratio = segmentIndex / segmentNumber;

View File

@ -0,0 +1,47 @@
#define Animate 0.0
uniform float u_opacity;
uniform float u_blur : 0.9;
varying float v_segmentIndex;
uniform float segmentNumber;
uniform float u_time;
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
varying mat4 styleMappingMat;
#pragma include "picking"
void main() {
float opacity = styleMappingMat[0][0];
float animateSpeed = 0.0; // 运动速度
float d_distance_ratio = styleMappingMat[3].g; // 当前点位距离占线总长的比例
gl_FragColor = mix(u_sourceColor, u_targetColor, v_segmentIndex/segmentNumber);
gl_FragColor.a *= opacity;
if(u_aimate.x == Animate) {
animateSpeed = u_time / u_aimate.y;
float alpha =1.0 - fract( mod(1.0- d_distance_ratio, u_aimate.z)* (1.0/ u_aimate.z) + u_time / u_aimate.y);
alpha = (alpha + u_aimate.w -1.0) / u_aimate.w;
// alpha = smoothstep(0., 1., alpha);
alpha = clamp(alpha, 0.0, 1.0);
gl_FragColor.a *= alpha;
// u_aimate
// x enable
// y duration
// z interval
// w trailLength
}
gl_FragColor = filterColor(gl_FragColor);
}

View File

@ -0,0 +1,207 @@
#define LineTypeSolid 0.0
#define LineTypeDash 1.0
#define Animate 0.0
#define LineTexture 1.0
attribute vec3 a_Position;
attribute vec4 a_Instance;
attribute vec4 a_Color;
attribute float a_Size;
uniform float u_globel;
uniform float u_globel_radius;
uniform float u_global_height: 10;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float segmentNumber;
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
varying vec4 v_color;
// varying vec2 v_normal;
uniform float u_line_type: 0.0;
uniform vec4 u_dash_array: [10.0, 5., 0, 0];
varying vec4 v_dash_array;
uniform float u_icon_step: 100;
uniform float u_line_texture: 0.0;
varying float v_segmentIndex;
attribute vec2 a_iconMapUV;
varying vec2 v_iconMapUV;
uniform float u_opacity: 1.0;
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
#pragma include "styleMapping"
#pragma include "styleMappingCalOpacity"
#pragma include "projection"
#pragma include "project"
#pragma include "picking"
float maps (float value, float start1, float stop1, float start2, float stop2) {
return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
}
float getSegmentRatio(float index) {
return smoothstep(0.0, 1.0, index / (segmentNumber - 1.0));
}
float paraboloid(vec2 source, vec2 target, float ratio) {
vec2 x = mix(source, target, ratio);
vec2 center = mix(source, target, 0.5);
float dSourceCenter = distance(source, center);
float dXCenter = distance(x, center);
return (dSourceCenter + dXCenter) * (dSourceCenter - dXCenter);
}
vec3 getPos(vec2 source, vec2 target, float segmentRatio) {
float vertex_height = paraboloid(source, target, segmentRatio);
return vec3(
mix(source, target, segmentRatio),
sqrt(max(0.0, vertex_height))
);
}
vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0;
return offset;
}
vec2 getNormal(vec2 line_clipspace, float offset_direction) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
return reverse_offset_normal(vec3(dir_screenspace,1.0)).xy * sign(offset_direction);
}
float torad(float deg) {
return (deg / 180.0) * acos(-1.0);
}
vec3 lglt2xyz(vec2 lnglat) {
float pi = 3.1415926;
// TODO: + Math.PI/2 是为了对齐坐标
float lng = torad(lnglat.x) + pi / 2.0;
float lat = torad(lnglat.y);
// TODO: 手动增加一些偏移,减轻面的冲突
float radius = u_globel_radius;
float z = radius * cos(lat) * cos(lng);
float x = radius * cos(lat) * sin(lng);
float y = radius * sin(lat);
return vec3(x, y, z);
}
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, // strokeR - strokeG - strokeB - strokeA
0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1]
0.0, 0.0, 0.0, 0.0 // dataset 数据集
);
float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行
float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列
float columnWidth = 1.0/columnCount; // 列宽
float rowHeight = 1.0/rowCount; // 行高
float cellCount = calCellCount(); // opacity - strokeOpacity - strokeWidth - stroke - offsets
float id = a_vertexId; // 第n个顶点
float cellCurrentRow = floor(id * cellCount / columnCount) + 1.0; // 起始点在第几行
float cellCurrentColumn = mod(id * cellCount, columnCount) + 1.0; // 起始点在第几列
// cell 固定顺序 opacity -> strokeOpacity -> strokeWidth -> stroke ...
// 按顺序从 cell 中取值、若没有则自动往下取值
float textureOffset = 0.0; // 在 cell 中取值的偏移量
vec2 opacityAndOffset = calOpacityAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight);
styleMappingMat[0][0] = opacityAndOffset.r;
textureOffset = opacityAndOffset.g;
// cal style mapping - 数据纹理映射部分的计算
v_color = a_Color;
vec2 source = project_position(vec4(a_Instance.rg, 0, 0)).xy;
vec2 target = project_position(vec4(a_Instance.ba, 0, 0)).xy;
float segmentIndex = a_Position.x;
float segmentRatio = getSegmentRatio(segmentIndex);
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
float d_distance_ratio;
if(u_line_type == LineTypeDash) {
d_distance_ratio = segmentIndex / segmentNumber;
// float total_Distance = pixelDistance(a_Instance.rg, a_Instance.ba) / 2.0 * PI;
vec2 s = source;
vec2 t = target;
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
s = unProjCustomCoord(source);
t = unProjCustomCoord(target);
}
float total_Distance = pixelDistance(s, t) / 2.0 * PI;
v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / (total_Distance / segmentNumber * segmentIndex);
}
if(u_aimate.x == Animate) {
d_distance_ratio = segmentIndex / segmentNumber;
}
styleMappingMat[3].g = d_distance_ratio; // 当前点位距离占线总长的比例
float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);
vec3 curr = getPos(source, target, segmentRatio);
vec3 next = getPos(source, target, nextSegmentRatio);
vec2 offset = getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y);
// v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
v_segmentIndex = a_Position.x;
if(LineTexture == u_line_texture && u_line_type != LineTypeDash) { // 开启贴图模式
float arcDistrance = length(source - target);
float pixelLen = project_pixel_texture(u_icon_step);
styleMappingMat[3].b = floor(arcDistrance/pixelLen); // 贴图在弧线上重复的数量
vec2 projectOffset = project_pixel(offset);
float lineOffsetWidth = length(projectOffset + projectOffset * sign(a_Position.y)); // 线横向偏移的距离
float linePixelSize = project_pixel(a_Size); // 定点位置偏移,按地图等级缩放后的距离
styleMappingMat[3].a = lineOffsetWidth/linePixelSize; // 线图层贴图部分的 v 坐标值
v_iconMapUV = a_iconMapUV;
}
// gl_Position = project_common_position_to_clipspace(vec4(curr.xy + project_pixel(offset), curr.z, 1.0));
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
gl_Position = u_Mvp * (vec4(curr.xy + project_pixel(offset), curr.z, 1.0));
} else {
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + project_pixel(offset), curr.z, 1.0));
}
// 地球模式
if(u_globel > 0.0) {
vec3 startLngLat = lglt2xyz(a_Instance.rg);
vec3 endLngLat = lglt2xyz(a_Instance.ba);
float globalRadius = length(startLngLat);
vec3 lineDir = normalize(endLngLat - startLngLat);
vec3 midPointDir = normalize((startLngLat + endLngLat)/2.0);
// 线的偏移
vec3 lnglatOffset = cross(lineDir, midPointDir) * a_Position.y;
// 计算起始点和终止点的距离
float lnglatLength = length(a_Instance.rg - a_Instance.ba)/50.0;
// 计算飞线各个节点相应的高度
float lineHeight = u_global_height * (-4.0*segmentRatio*segmentRatio + 4.0 * segmentRatio) * lnglatLength;
// 地球点位
vec3 globalPoint = normalize(mix(startLngLat, endLngLat, segmentRatio)) * (globalRadius + lineHeight) + lnglatOffset * a_Size;
gl_Position = u_ViewProjectionMatrix * vec4(globalPoint, 1.0);
}
setPickingColor(a_PickingColor);
}

View File

@ -0,0 +1,38 @@
#define Animate 0.0
#define LineTexture 1.0
uniform float u_opacity;
uniform float u_textureBlend;
uniform float u_blur : 0.9;
uniform float u_line_type: 0.0;
// varying vec2 v_normal;
varying vec4 v_dash_array;
varying vec4 v_color;
uniform float u_time;
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
uniform float u_line_texture;
uniform sampler2D u_texture;
uniform vec2 u_textSize;
uniform float segmentNumber;
varying vec2 v_iconMapUV;
varying mat4 styleMappingMat; // 传递从片元中传递的映射数据
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
#pragma include "picking"
void main() {
float opacity = styleMappingMat[0][0];
float d_segmentIndex = styleMappingMat[3].r; // 当前顶点在弧线中所处的分段位置
// 设置弧线的底色
gl_FragColor = mix(u_sourceColor, u_targetColor, d_segmentIndex/segmentNumber);
gl_FragColor.a *= opacity;
gl_FragColor = filterColor(gl_FragColor);
}

View File

@ -0,0 +1,138 @@
attribute vec4 a_Color;
attribute vec3 a_Position;
attribute vec4 a_Instance;
attribute float a_Size;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float segmentNumber;
varying vec4 v_color;
uniform float u_lineDir: 1.0;
uniform float u_thetaOffset: 0.314;
uniform float u_opacity: 1.0;
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
#pragma include "styleMapping"
#pragma include "styleMappingCalOpacity"
#pragma include "styleMappingCalThetaOffset"
#pragma include "projection"
#pragma include "project"
#pragma include "picking"
float bezier3(vec3 arr, float t) {
float ut = 1. - t;
return (arr.x * ut + arr.y * t) * ut + (arr.y * ut + arr.z * t) * t;
}
vec2 midPoint(vec2 source, vec2 target, float arcThetaOffset) {
vec2 center = target - source;
float r = length(center);
float theta = atan(center.y, center.x);
float thetaOffset = arcThetaOffset;
float r2 = r / 2.0 / cos(thetaOffset);
float theta2 = theta + thetaOffset;
vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y);
if(u_lineDir == 1.0) { // 正向
return mid;
} else { // 逆向
// (mid + vmin)/2 = (s + t)/2
vec2 vmid = source + target - mid;
return vmid;
}
// return mid;
}
float getSegmentRatio(float index) {
return smoothstep(0.0, 1.0, index / (segmentNumber - 1.));
}
vec2 interpolate (vec2 source, vec2 target, float t, float arcThetaOffset) {
// if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation
vec2 mid = midPoint(source, target, arcThetaOffset);
vec3 x = vec3(source.x, mid.x, target.x);
vec3 y = vec3(source.y, mid.y, target.y);
return vec2(bezier3(x ,t), bezier3(y,t));
}
vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0;
return offset;
}
vec2 getNormal(vec2 line_clipspace, float offset_direction) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
return reverse_offset_normal(vec3(dir_screenspace,1.0)).xy * sign(offset_direction);
}
void main() {
v_color = a_Color;
// 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, // strokeR - strokeG - strokeB - strokeA
0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1]
0.0, 0.0, 0.0, 0.0 // dataset 数据集
);
float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行
float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列
float columnWidth = 1.0/columnCount; // 列宽
float rowHeight = 1.0/rowCount; // 行高
float cellCount = calCellCount(); // opacity - strokeOpacity - strokeWidth - stroke - offsets
float id = a_vertexId; // 第n个顶点
float cellCurrentRow = floor(id * cellCount / columnCount) + 1.0; // 起始点在第几行
float cellCurrentColumn = mod(id * cellCount, columnCount) + 1.0; // 起始点在第几列
// cell 固定顺序 opacity -> strokeOpacity -> strokeWidth -> stroke -> thetaOffset...
// 按顺序从 cell 中取值、若没有则自动往下取值
float textureOffset = 0.0; // 在 cell 中取值的偏移量
vec2 opacityAndOffset = calOpacityAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight);
styleMappingMat[0][0] = opacityAndOffset.r;
textureOffset = opacityAndOffset.g;
vec2 thetaOffsetAndOffset = calThetaOffsetAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight);
styleMappingMat[0][1] = thetaOffsetAndOffset.r;
textureOffset = thetaOffsetAndOffset.g;
// cal style mapping - 数据纹理映射部分的计算
vec2 source = a_Instance.rg; // 起始点
vec2 target = a_Instance.ba; // 终点
float segmentIndex = a_Position.x;
float segmentRatio = getSegmentRatio(segmentIndex);
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);
float d_distance_ratio;
styleMappingMat[3].b = d_distance_ratio;
// styleMappingMat[0][1] - arcThetaOffset
vec4 curr = project_position(vec4(interpolate(source, target, segmentRatio, styleMappingMat[0][1]), 0.0, 1.0));
vec4 next = project_position(vec4(interpolate(source, target, nextSegmentRatio, styleMappingMat[0][1]), 0.0, 1.0));
// v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
//unProjCustomCoord
vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y));
float d_segmentIndex = a_Position.x + 1.0; // 当前顶点在弧线中所处的分段位置
styleMappingMat[3].r = d_segmentIndex;
// gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0));
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
// gl_Position = u_Mvp * (vec4(curr.xy + offset, 0, 1.0));
gl_Position = u_Mvp * (vec4(curr.xy + offset, 0, 1.0));
} else {
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0));
}
setPickingColor(a_PickingColor);
}

View File

@ -0,0 +1,13 @@
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
varying mat4 styleMappingMat;
void main() {
float opacity = styleMappingMat[0][0];
float d_distance_ratio = styleMappingMat[3].r; // 当前点位距离占线总长的比例
gl_FragColor = mix(u_sourceColor, u_targetColor, d_distance_ratio);
gl_FragColor.a *= opacity; // 全局透明度
}

View File

@ -1,31 +1,10 @@
uniform float u_blur : 0.99;
uniform float u_line_type: 0.0;
uniform float u_opacity : 1.0;
uniform float u_borderWidth: 0.0;
uniform vec4 u_borderColor;
varying vec4 v_color;
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
uniform float u_time;
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ]; // 控制运动
varying mat4 styleMappingMat;
void main() {
float opacity = styleMappingMat[0][0];
float d_distance_ratio = styleMappingMat[3].r; // 当前点位距离占线总长的比例
if(u_linearColor == 1.0) { // 使用渐变颜色
gl_FragColor = mix(u_sourceColor, u_targetColor, d_distance_ratio);
} else { // 使用 color 方法传入的颜色
gl_FragColor = v_color;
}
// anti-alias
// float blur = 1.0 - smoothstep(u_blur, 1., length(v_normal.xy));
gl_FragColor = v_color;
gl_FragColor.a *= opacity; // 全局透明度
}

View File

@ -11,13 +11,13 @@ attribute float a_Distance;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float u_opacity: 1.0;
uniform float u_vertexScale: 1.0;
#pragma include "projection"
varying vec4 v_color;
uniform float u_opacity: 1.0;
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
#pragma include "styleMapping"
@ -51,11 +51,7 @@ void main() {
// cal style mapping - 数据纹理映射部分的计算
float d_distance_ratio; // 当前点位距离占线总长的比例
v_color = a_Color;
// 设置数据集的参数
styleMappingMat[3][0] = a_Distance / a_Total_Distance; // 当前点位距离占线总长的比例
v_color = a_Color;
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));

View File

@ -45,7 +45,7 @@ export default class Amap2demo_arcLine extends React.Component {
opacity: 0.8,
blur: 0.99,
// segmentNumber: 3,
// lineType: 'dash',
lineType: 'dash',
// dashArray: [5, 5],
});
// .forward(false)

View File

@ -177,7 +177,7 @@ export default class GridTile2 extends React.Component {
.style({
vertexHeightScale: 2000,
sourceColor: '#f00',
targetColor: '#0f0',
// targetColor: '#0f0',
});
scene.addLayer(layer);
};