* feat: 增加 bloomPass1.0、修改渲染流程,让 multiPass 有正确的渲染顺序

* style: lint style

* feat: 取消 bloom 在 postprocessor 中的多次渲染(没有明显优化)

* feat: polygon extrude 模式支持配置固定高度

* style: lint style

* feat: 优化后处理 bloom 的效果

* feat: 修改交替绘制 bloom 的写法

* style: lint style

* feat: 完善 iconService 加载渲染和销毁

* style: lint style

* feat: 补全 mapbox 模式下等面积点

* style: lint style

* fix: 修复 pointLayer animate 模式 opacity 失效

* style: lint style

* feat: 拆分 pointLayer 的 shader

* style: lint sytle

* feat: 拆分 lineLayer 的 linear 模式

* style: lint style

* feat: 优化点击的拾取判断

* style: lint style

* feat: 取消圆柱 shader 中的三元表达式、增强健壮性

* feat: 点图层圆柱体支持固定高度配置 heightfixed

* feat: 点图层圆柱体支持拾取高亮颜色的光照计算

* style: lint style

* style: lint style

* feat: 拆分 lintLayer line 模式下的 dash line

* style: lint style

* feat: lineLayer simpleline 的 linear shader 代码拆分

* style: lint style

* feat: 拆分 lineLayer arcLine linear shader  代码

* style: line style

* feat: lineLayer arc line 在 shader 中移除 linear 部分计算

* feat: 拆分 lineLayer arc dash 虚线的 shader 代码

* style: lint style

* feat: 拆分 lineLayer arc3d linear 部分的 shader 代码
This commit is contained in:
YiQianYao 2022-02-15 16:58:57 +08:00 committed by GitHub
parent 1efbe605e5
commit 7b91e55ce5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 739 additions and 107 deletions

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);
};