Skip to content

Commit

Permalink
feat(layer): add citybuildinglayer & add line add animate
Browse files Browse the repository at this point in the history
  • Loading branch information
lzxue committed Dec 24, 2019
1 parent f56327a commit d657286
Show file tree
Hide file tree
Showing 35 changed files with 769 additions and 145 deletions.
11 changes: 8 additions & 3 deletions packages/core/src/services/config/ConfigService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Ajv from 'ajv';
import { injectable, postConstruct } from 'inversify';
import { merge } from 'lodash';
import { ILayerConfig } from '../layer/ILayerService';
import { IGlobalConfigService, ISceneConfig } from './IConfigService';
import mapConfigSchema from './mapConfigSchema';
Expand Down Expand Up @@ -63,6 +64,12 @@ const defaultLayerConfig: Partial<ILayerConfig> = {
enableTAA: false,
jitterScale: 1,
enableLighting: false,
animateOption: {
enable: false,
interval: 0.2,
duration: 4,
trailLength: 0.15,
},
};

// @see https://github.com/epoberezkin/ajv#options
Expand Down Expand Up @@ -141,9 +148,7 @@ export default class GlobalConfigService implements IGlobalConfigService {
) {
// @ts-ignore
this.layerConfigCache[layerId] = {
...this.sceneConfigCache[sceneId],
...defaultLayerConfig,
...config,
...merge({}, this.sceneConfigCache[sceneId], defaultLayerConfig, config),
};
}

Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/services/layer/ILayerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export interface ILayer {
color(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
shape(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
label(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
animate(option: IAnimateOption): ILayer;
animate(option: Partial<IAnimateOption> | boolean): ILayer;
// pattern(field: string, value: StyleAttributeOption): ILayer;
filter(field: string, value: StyleAttributeOption): ILayer;
active(option: IActiveOption | boolean): ILayer;
Expand Down Expand Up @@ -172,6 +172,8 @@ export interface ILayer {
pick(query: { x: number; y: number }): void;

updateLayerConfig(configToUpdate: Partial<ILayerConfig | unknown>): void;
setAnimateStartTime(): void;
getLayerAnimateTime(): number;
}

/**
Expand Down Expand Up @@ -242,6 +244,7 @@ export interface ILayerConfig {
* 开启光照
*/
enableLighting: boolean;
animateOption: Partial<IAnimateOption>;
onHover(pickedFeature: IPickedFeature): void;
onClick(pickedFeature: IPickedFeature): void;
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/services/layer/IStyleAttributeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export interface IAnimateOption {
interval?: number;
duration?: number;
trailLength?: number;
repeat?: number;
}

export interface IEncodeFeature {
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/services/layer/LayerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,15 @@ export default class LayerService implements ILayerService {

public startAnimate() {
if (this.animateInstanceCount++ === 0) {
this.clock.start();
this.runRender();
}
}

public stopAnimate() {
if (--this.animateInstanceCount === 0) {
this.stopRender();
this.clock.stop();
}
}

Expand All @@ -102,7 +104,7 @@ export default class LayerService implements ILayerService {

private runRender() {
this.renderLayers();
this.layerRenderID = requestAnimationFrame(this.renderLayers.bind(this));
this.layerRenderID = requestAnimationFrame(this.runRender.bind(this));
}

private stopRender() {
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/shaders/project.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ vec2 ProjectFlat(vec2 lnglat){
float x=lnglat.x*d;
float y=lat*d;
y=log(tan((PI/4.)+(y/2.)));

float a=.5/PI,
b=.5,
c=-.5/PI;
Expand All @@ -32,3 +32,9 @@ vec2 unProjectFlat(vec2 px){
float lng=x/d;
return vec2(lng,lat);
}

float pixelDistance(vec2 from, vec2 to) {
vec2 a1 = ProjectFlat(from);
vec2 b1 = ProjectFlat(to);
return distance(a1, b1);
}
37 changes: 37 additions & 0 deletions packages/layers/src/citybuliding/building.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { IEncodeFeature } from '@antv/l7-core';
import BaseLayer from '../core/BaseLayer';
import CityBuildModel from './models/build';

export default class CityBuildingLayer extends BaseLayer {
public type: string = 'PolygonLayer';

protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}

protected renderModels() {
this.models.forEach((model) =>
model.draw({
uniforms: this.layerModel.getUninforms(),
}),
);
return this;
}

protected buildModels() {
this.layerModel = new CityBuildModel(this);
this.models = this.layerModel.buildModels();
}

protected getModelType(): string {
return 'citybuilding';
}
}
115 changes: 115 additions & 0 deletions packages/layers/src/citybuliding/models/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { AttributeType, gl, IEncodeFeature, IModel } from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { PolygonExtrudeTriangulation } from '../../core/triangulation';
import buildFrag from '../shaders/build_frag.glsl';
import buildVert from '../shaders/build_vert.glsl';
interface ICityBuildLayerStyleOptions {
opacity: number;
baseColor: string;
brightColor: string;
windowColor: string;
}
export default class CityBuildModel extends BaseModel {
public getUninforms() {
const {
opacity = 1,
baseColor = 'rgb(16,16,16)',
brightColor = 'rgb(255,176,38)',
windowColor = 'rgb(30,60,89)',
} = this.layer.getLayerConfig() as ICityBuildLayerStyleOptions;
return {
u_opacity: opacity,
u_baseColor: rgb2arr(baseColor),
u_brightColor: rgb2arr(brightColor),
u_windowColor: rgb2arr(windowColor),
u_time: this.layer.getLayerAnimateTime(),
};
}

public buildModels(): IModel[] {
this.startModelAnimate();
return [
this.layer.buildLayerModel({
moduleName: 'cityBuilding',
vertexShader: buildVert,
fragmentShader: buildFrag,
triangulation: PolygonExtrudeTriangulation,
}),
];
}

protected registerBuiltinAttributes() {
// point layer size;
this.styleAttributeService.registerStyleAttribute({
name: 'normal',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Normal',
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[],
) => {
return normal;
},
},
});

this.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
},
},
});
this.styleAttributeService.registerStyleAttribute({
name: 'uv',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Uv',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 2,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
return [vertex[3], vertex[4]];
},
},
});
}
}
104 changes: 104 additions & 0 deletions packages/layers/src/citybuliding/shaders/build_frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
uniform float u_opacity: 1.0;
uniform vec4 u_baseColor : [ 1.0, 0, 0, 1.0 ];
uniform vec4 u_brightColor : [ 1.0, 0, 0, 1.0 ];
uniform vec4 u_windowColor : [ 1.0, 0, 0, 1.0 ];
uniform float u_near : 0;
uniform float u_far : 1;
varying vec4 v_Color;
varying vec2 v_texCoord;
uniform float u_Zoom : 1;
uniform float u_time;

#pragma include "picking"

vec3 getWindowColor(float n, float hot, vec3 brightColor, vec3 darkColor) {
float s = step(hot, n);
vec3 color = mix(brightColor,vec3(0.9,0.9,1.0),n);

return mix(darkColor, color, s);
}
float random (vec2 st) {
return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123);
}

float LinearizeDepth()
{
float z = gl_FragCoord.z * 2.0 - 1.0;
return (2.0 * u_near * u_far) / (u_far + u_near - z * (u_far - u_near));
}

vec3 fog(vec3 color, vec3 fogColor, float depth){
float fogFactor=clamp(depth,0.0,1.0);
vec3 output_color=mix(fogColor,color,fogFactor);
return output_color;
}

float sdRect(vec2 p, vec2 sz) {
vec2 d = abs(p) - sz;
float outside = length(max(d, 0.));
float inside = min(max(d.x, d.y), 0.);
return outside + inside;
}

void main() {
gl_FragColor = v_Color;
gl_FragColor.a *= u_opacity;

vec3 baseColor = u_baseColor.xyz;
vec3 brightColor = u_brightColor.xyz;
vec3 windowColor = u_windowColor.xyz;
float targetColId = 5.;
float depth = 1.0 - LinearizeDepth() / u_far * u_Zoom;
vec3 fogColor = vec3(23.0/255.0,31.0/255.0,51.0/255.0);
if(v_texCoord.x < 0.) { //顶部颜色
vec3 foggedColor = fog(baseColor.xyz + vec3(0.12*0.9,0.2*0.9,0.3*0.9),fogColor,depth);
gl_FragColor = vec4( foggedColor, v_Color.w);
}else { // 侧面颜色
vec2 st = v_texCoord;
vec2 UvScale = v_texCoord;
float tStep = min(0.08,max(0.05* (18.0-u_Zoom),0.02));
float tStart = 0.25 * tStep;
float tEnd = 0.75 * tStep;
float u = mod(UvScale.x, tStep);
float v = mod(UvScale.y, tStep);
float ux = floor(UvScale.x/tStep);
float uy = floor(UvScale.y/tStep);
float n = random(vec2(ux,uy));
float lightP = u_time;
float head = 1.0- step(0.005,st.y);
/*step3*/
// 将窗户颜色和墙面颜色区别开来
float sU = step(tStart, u) - step(tEnd, u);
float sV = step(tStart, v) - step(tEnd, v);
vec2 windowSize = vec2(abs(tEnd-tStart),abs(tEnd-tStart));
float dist = sdRect(vec2(u,v), windowSize);
float s = sU * sV;

float curColId = floor(UvScale.x / tStep);
float sCol = step(targetColId - 0.2, curColId) - step(targetColId + 0.2, curColId);

float mLightP = mod(lightP, 2.);
float sRow = step(mLightP - 0.2, st.y) - step(mLightP, st.y);
if(ux == targetColId){
n =0.;
}
float timeP = min(0.75, abs ( sin(u_time/6.0) ) );
float hot = smoothstep(1.0,0.0,timeP);
vec3 color = mix(baseColor, getWindowColor(n,hot,brightColor,windowColor), s);
//vec3 color = mix(baseColor, getWindowColor(n,hot,brightColor,windowColor), 1.0);
float sFinal = s * sCol * sRow;
color += mix(baseColor, brightColor, sFinal*n);
if (st.y<0.01){
color = baseColor;
}
if(head ==1.0) { // 顶部亮线
color = brightColor;
}
color = color * v_Color.rgb;

vec3 foggedColor = fog(color,fogColor,depth);

gl_FragColor = vec4(foggedColor,1.0);
}
gl_FragColor = filterColor(gl_FragColor);
}
Loading

0 comments on commit d657286

Please sign in to comment.