feat: 清理渲染流程代码

This commit is contained in:
shihui 2022-12-02 20:19:58 +08:00
parent f519a6dce0
commit 8adec0eccd
14 changed files with 287 additions and 324 deletions

View File

@ -40,6 +40,7 @@ export default () => {
scene.on('loaded', () => {
scene.addLayer(pointLayer);
// scene.render();
})
}, [])
return (

View File

@ -66,9 +66,7 @@ export default class CoordinateSystemService
* TODO: 使用 memoize
*/
public refresh(offsetCenter?: [number, number]): void {
// if (!this.needRefresh) {
// return;
// }
const zoom = this.cameraService.getZoom();
const zoomScale = this.cameraService.getZoomScale();
const center = offsetCenter ? offsetCenter : this.cameraService.getCenter();

View File

@ -303,12 +303,7 @@ export default class PickingService implements IPickingService {
}
}
private async pickingAllLayer(target: IInteractionTarget) {
// 判断是否进行拾取操作
if (!this.layerService.needPick(target.type) ||!this.isPickingAllLayer()) return;
this.alreadyInPicking = true;
await this.pickingLayers(target);
this.layerService.renderLayers();
this.alreadyInPicking = false;
}
private isPickingAllLayer() {

View File

@ -40,12 +40,11 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
private readonly mapService: IMapService;
public reRender = throttle(() => {
this.updateLayerRenderList();
this.renderLayers();
}, 32);
public throttleRenderLayers = throttle(() => {
this.renderLayers();
}, 16);
public needPick(type:string): boolean {
@ -64,11 +63,7 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
}
public addMask(mask: ILayer) {
if (this.sceneInited) {
mask.init().then(() => {
this.renderLayers();
});
}
}
public async initLayers() {
@ -103,97 +98,39 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
}
public remove(layer: ILayer, parentLayer?: ILayer): void {
// Tip: layer.layerChildren 当 layer 存在子图层的情况
if (parentLayer) {
const layerIndex = parentLayer.layerChildren.indexOf(layer);
if (layerIndex > -1) {
parentLayer.layerChildren.splice(layerIndex, 1);
}
} else {
const layerIndex = this.layers.indexOf(layer);
if (layerIndex > -1) {
this.layers.splice(layerIndex, 1);
}
}
this.updateLayerRenderList();
layer.destroy();
this.renderLayers();
this.emit('layerChange', this.layers);
}
public removeAllLayers() {
this.destroy();
this.renderLayers();
}
public setEnableRender(flag: boolean) {
this.enableRender = flag;
}
public async renderLayers() {
if (this.alreadyInRendering || !this.enableRender) {
return;
}
this.alreadyInRendering = true;
public renderLayers() {
console.log('renderLayers');
this.clear();
for (const layer of this.layerList) {
if (layer.masks.filter((m)=>m.inited).length > 0) {
// 清除上一次的模版缓存
this.renderService.clear({
stencil: 0,
depth: 1,
framebuffer: null,
});
layer.masks.map(async (m: ILayer) => {
m.render();
})
}
if (layer.getLayerConfig().enableMultiPassRenderer) {
// multiPassRender 不是同步渲染完成的
await layer.renderMultiPass();
} else {
await layer.render();
}
layer.render();
}
this.alreadyInRendering = false;
}
public renderMask(masks:ILayer[]) {
masks.filter(m => m.inited)
.map(m =>{
m.render();
})
}
public async beforeRenderData(layer: ILayer) {
const flag = await layer.hooks.beforeRenderData.promise();
if(flag) {
this.renderLayers();
}
}
async renderLayer(layer: ILayer){
if (layer.masks.filter((m)=>m.inited).length > 0) {
layer.masks.map(mask =>{
this.renderService.clear({
stencil: 0,
depth: 1,
framebuffer: null,
});
mask.render();
})
}
if (layer.getLayerConfig().enableMultiPassRenderer) {
// multiPassRender 不是同步渲染完成的
await layer.renderMultiPass();
} else {
await layer.render();
}
layer.render();
}
@ -270,10 +207,6 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
}
private runRender() {
this.renderLayers();
this.layerRenderID = $window.requestAnimationFrame(
this.runRender.bind(this),
);
}
private stopRender() {

View File

@ -245,14 +245,14 @@ export default class PixelPickingPass<
// @ts-ignore
const [r, g, b] = pickedColors;
this.layer.hooks.beforeHighlight.call([r, g, b]);
this.layerService.renderLayers();
}
private selectFeature(pickedColors: Uint8Array | undefined) {
// @ts-ignore
const [r, g, b] = pickedColors;
this.layer.hooks.beforeSelect.call([r, g, b]);
this.layerService.renderLayers();
}
private selectFeatureHandle({ featureId }: Partial<IInteractionTarget>) {

View File

@ -295,10 +295,7 @@ export default class Scene extends EventEmitter implements ISceneService {
}
public async render() {
if (this.rendering || this.destroyed) {
return;
}
this.rendering = true;
// 首次初始化,或者地图的容器被强制销毁的需要重新初始化
if (!this.inited) {
// 还未初始化完成需要等待
@ -309,20 +306,18 @@ export default class Scene extends EventEmitter implements ISceneService {
}
// FIXME: 初始化 marker 容器,可以放到 map 初始化方法中?
await this.layerService.initLayers();
this.layerService.renderLayers();
this.controlService.addControls();
this.loaded = true;
this.emit('loaded');
this.inited = true;
} else {
// 尝试初始化未初始化的图层
await this.layerService.initLayers();
await this.layerService.renderLayers();
this.layerService.renderLayers();
}
// 组件需要等待layer 初始化完成之后添加
this.rendering = false;
}
/**
@ -460,6 +455,7 @@ export default class Scene extends EventEmitter implements ISceneService {
canvas.style.height = '100%';
}
// map move -> render
private handleMapCameraChanged = (viewport: IViewport) => {
this.cameraService.update(viewport);
this.render();

View File

@ -51,10 +51,12 @@ import {
StyleAttributeField,
StyleAttributeOption,
Triangulation,
CameraUniform,
CoordinateUniform,
TYPES,
} from '@antv/l7-core';
import Source from '@antv/l7-source';
import { encodePickingColor, WorkerSourceMap } from '@antv/l7-utils';
import { encodePickingColor } from '@antv/l7-utils';
import { EventEmitter } from 'eventemitter3';
import { Container } from 'inversify';
import { isFunction, isObject, isUndefined } from 'lodash';
@ -173,6 +175,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
protected coordinateService: ICoordinateSystemService;
protected coordinateSystemService: ICoordinateSystemService;
protected iconService: IIconService;
protected fontService: IFontService;
@ -340,13 +344,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
TYPES.IPickingService,
);
this.mapService = this.container.get<IMapService>(TYPES.IMapService);
const { enableMultiPassRenderer, passes } = this.getLayerConfig();
if (enableMultiPassRenderer && passes?.length && passes.length > 0) {
// Tip: 兼容 multiPassRender 在 amap1 时存在的图层不同步问题 zoom
this.mapService.on('mapAfterFrameChange', () => {
this.renderLayers();
});
}
const { enableMultiPassRenderer } = this.getLayerConfig();
this.cameraService = this.container.get<ICameraService>(
TYPES.ICameraService,
@ -354,6 +353,11 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
this.coordinateService = this.container.get<ICoordinateSystemService>(
TYPES.ICoordinateSystemService,
);
this.coordinateSystemService = this.container.get<ICoordinateSystemService>(
TYPES.ICoordinateSystemService,
);
this.shaderModuleService = this.container.get<IShaderModuleService>(
TYPES.IShaderModuleService,
);
@ -675,28 +679,53 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
*
*/
public renderLayers(): void {
this.rendering = true;
this.layerService.renderLayers();
this.rendering = false;
}
public render(): ILayer {
if (this.tileLayer) {
// 瓦片图层执行单独的 render 渲染队列
this.tileLayer.render();
return this;
}
this.layerService.beforeRenderData(this);
if (this.encodeDataLength <= 0 && !this.forceRender) {
return this;
}
this.updateUniform();
// Tip: this.getEncodedData().length !== 0 这个判断是为了解决在 2.5.x 引入数据纹理后产生的 空数据渲染导致 texture 超出上限问题
this.renderModels();
this.models.forEach((model) => {
model.draw({ uniforms: {} });
});
return this;
}
public updateUniform() {
// 重新计算坐标系参数
this.coordinateSystemService.refresh();
const { width, height } = this.rendererService.getViewportSize();
this.models.forEach((model) => {
model.addUniforms({
// 相机参数,包含 VP 矩阵、缩放等级
[CameraUniform.ProjectionMatrix]:
this.cameraService.getProjectionMatrix(),
[CameraUniform.ViewMatrix]: this.cameraService.getViewMatrix(),
[CameraUniform.ViewProjectionMatrix]:
this.cameraService.getViewProjectionMatrix(),
[CameraUniform.Zoom]: this.cameraService.getZoom(),
[CameraUniform.ZoomScale]: this.cameraService.getZoomScale(),
[CoordinateUniform.CoordinateSystem]:
this.coordinateSystemService.getCoordinateSystem(),
[CoordinateUniform.ViewportCenter]:
this.coordinateSystemService.getViewportCenter(),
[CoordinateUniform.ViewportCenterProjection]:
this.coordinateSystemService.getViewportCenterProjection(),
[CoordinateUniform.PixelsPerDegree]:
this.coordinateSystemService.getPixelsPerDegree(),
[CoordinateUniform.PixelsPerDegree2]:
this.coordinateSystemService.getPixelsPerDegree2(),
[CoordinateUniform.PixelsPerMeter]:
this.coordinateSystemService.getPixelsPerMeter(),
u_SceneCenterMKT: [0, 0],
u_ViewportSize: [width, height],
u_ModelMatrix: this.cameraService.getModelMatrix(),
});
});
}
/**
* renderMultiPass multipass layer
*/
@ -704,15 +733,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
if (this.encodeDataLength <= 0 && !this.forceRender) {
return;
}
if (this.multiPassRenderer && this.multiPassRenderer.getRenderFlag()) {
// multi render 开始执行 multiPassRender 的渲染流程
await this.multiPassRenderer.render();
} else if (this.multiPassRenderer) {
// renderPass 触发的渲染
this.renderModels();
} else {
this.renderModels();
}
}
public active(options: IActiveOption | boolean) {
@ -848,8 +869,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
}
public setIndex(index: number): ILayer {
this.zIndex = index;
this.layerService.updateLayerRenderList();
this.layerService.renderLayers();
return this;
}
@ -1301,18 +1321,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
await multiPassRenderer.render();
}
public renderModels(isPicking?: boolean) {
this.hooks.beforeRender.call();
this.models.forEach((model) => {
model.draw(
{
uniforms: {},
}
);
});
this.hooks.afterRender.call();
return this;
public renderModels() {
}
public updateStyleAttribute(

View File

@ -9,7 +9,6 @@ import {
IRendererService,
TYPES,
} from '@antv/l7-core';
import { $window } from '@antv/l7-utils';
import { inject, injectable } from 'inversify';
import 'reflect-metadata';
@ -31,84 +30,10 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
@inject(TYPES.IRendererService)
private readonly rendererService: IRendererService;
@inject(TYPES.IMapService)
private readonly mapService: IMapService;
public apply(layer: ILayer) {
const version = this.mapService.version;
let mvp = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; // default matrix (for gaode2.x)
let sceneCenterMKT = [0, 0];
layer.hooks.beforeRender.tap('ShaderUniformPlugin', () => {
// @ts-ignore
const offset = layer.getLayerConfig().tileOrigin;
// 重新计算坐标系参数
this.coordinateSystemService.refresh(offset);
if (version === 'GAODE2.x') {
this.setLayerCenter(layer);
// @ts-ignore
mvp = this.mapService.map.customCoords.getMVPMatrix();
// mvp = amapCustomCoords.getMVPMatrix()
// @ts-ignore
sceneCenterMKT = this.mapService.getCustomCoordCenter();
}
const { width, height } = this.rendererService.getViewportSize();
layer.models.forEach((model) => {
model.addUniforms({
// 相机参数,包含 VP 矩阵、缩放等级
[CameraUniform.ProjectionMatrix]:
this.cameraService.getProjectionMatrix(),
[CameraUniform.ViewMatrix]: this.cameraService.getViewMatrix(),
[CameraUniform.ViewProjectionMatrix]:
this.cameraService.getViewProjectionMatrix(),
[CameraUniform.Zoom]: this.cameraService.getZoom(),
[CameraUniform.ZoomScale]: this.cameraService.getZoomScale(),
[CameraUniform.FocalDistance]: this.cameraService.getFocalDistance(),
[CameraUniform.CameraPosition]:
this.cameraService.getCameraPosition(),
// 坐标系参数
[CoordinateUniform.CoordinateSystem]:
this.coordinateSystemService.getCoordinateSystem(),
[CoordinateUniform.ViewportCenter]:
this.coordinateSystemService.getViewportCenter(),
[CoordinateUniform.ViewportCenterProjection]:
this.coordinateSystemService.getViewportCenterProjection(),
[CoordinateUniform.PixelsPerDegree]:
this.coordinateSystemService.getPixelsPerDegree(),
[CoordinateUniform.PixelsPerDegree2]:
this.coordinateSystemService.getPixelsPerDegree2(),
[CoordinateUniform.PixelsPerMeter]:
this.coordinateSystemService.getPixelsPerMeter(),
// 坐标系是高德2.0的时候单独计算
[CoordinateUniform.Mvp]: mvp,
u_SceneCenterMKT: sceneCenterMKT,
// 其他参数例如视口大小、DPR 等
u_ViewportSize: [width, height],
u_ModelMatrix: this.cameraService.getModelMatrix(),
u_DevicePixelRatio: $window.devicePixelRatio,
// u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
u_PickingBuffer: layer.getLayerConfig().pickingBuffer || 0,
// Tip: 当前地图是否在拖动
u_shaderPick: Number(layer.getShaderPickStat()),
});
});
// TODO脏检查决定是否需要渲染
});
}
/**
* layer layer
* @param layer
*/
private setLayerCenter(layer: ILayer) {
if (layer.coordCenter === undefined) {
layer.coordCenter = layer.getSource().center;
}
if (this.mapService.setCoordCenter) {
this.mapService.setCoordCenter(layer.coordCenter);
}
}
}

View File

@ -4,50 +4,39 @@ import {
IEncodeFeature,
ILayer,
TYPES,
IShaderModuleService,
IRendererService,
IStyleAttributeService,
} from '@antv/l7-core';
import pointFillFrag from '../shaders/fill_frag.glsl';
import pointFillVert from '../shaders/fill_vert.glsl';
import StyleAttribute from '../../../../core/src/services/layer/StyleAttribute'
import { vert, frag } from './fillShader';
export default class FillModel {
protected layer: ILayer;
private attributes: any[] = [];
protected shaderModuleService: IShaderModuleService;
protected rendererService: IRendererService;
protected styleAttributeService: IStyleAttributeService;
constructor(layer: ILayer) {
this.layer = layer;
this.rendererService = layer
.getContainer()
.get<IRendererService>(TYPES.IRendererService);
this.shaderModuleService = layer
.getContainer()
.get<IShaderModuleService>(TYPES.IShaderModuleService);
this.styleAttributeService = layer
.getContainer()
.get<IStyleAttributeService>(TYPES.IStyleAttributeService);
this.registerBuiltinAttributes();
}
public createAttributesAndIndices(
features: IEncodeFeature[],
triangulation: Triangulation,
segmentNumber: number,
) {
function triangulation() {
const coordinates = [120, 30]
return {
vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
indices: [0, 1, 2, 2, 3, 0],
size: 2,
};
}
const descriptors = this.attributes.map((attr) => {
attr.resetDescriptor();
@ -70,7 +59,7 @@ export default class FillModel {
size: vertexSize,
indexes,
count,
} = triangulation(feature, segmentNumber);
} = triangulation(feature);
if (typeof count === 'number') {
vecticesCount += count;
@ -104,7 +93,7 @@ export default class FillModel {
vertexIndex = indexes[vertexIdx];
}
descriptors.forEach((descriptor, attributeIdx) => {
descriptors.forEach((descriptor) => {
if (descriptor && descriptor.update) {
(descriptor.buffer.data as number[]).push(
...descriptor.update(
@ -129,10 +118,8 @@ export default class FillModel {
const attributes = {};
descriptors.forEach((descriptor, attributeIdx) => {
descriptors.forEach((descriptor) => {
if (descriptor) {
// IAttribute 参数透传
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { buffer, update, name, ...rest } = descriptor;
const vertexAttribute = createAttribute({
@ -141,8 +128,6 @@ export default class FillModel {
...rest,
});
attributes[descriptor.name || ''] = vertexAttribute;
}
});
@ -159,44 +144,41 @@ export default class FillModel {
return attributesAndIndices;
}
public buildLayerModel( options: any ) {
const {
moduleName,
vertexShader,
fragmentShader,
triangulation,
segmentNumber,
...rest
} = options;
this.shaderModuleService.registerModule(moduleName, {
vs: vertexShader,
fs: fragmentShader,
});
const { vs, fs, uniforms } = this.shaderModuleService.getModule(moduleName);
public buildLayerModel() {
const uniforms = {
u_CameraPosition: [0, 0, 0],
u_CoordinateSystem: 0,
u_DevicePixelRatio: 0,
u_FocalDistance: 0,
u_ModelMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
u_Mvp: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
u_PixelsPerDegree: [0, 0, 0],
u_PixelsPerDegree2: [0, 0, 0],
u_PixelsPerMeter: [0, 0, 0],
u_ProjectionMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
u_ViewMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
u_ViewProjectionMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
u_ViewportCenter: [0, 0],
u_ViewportCenterProjection: [0, 0, 0, 0],
u_ViewportSize: [0, 0],
u_Zoom: 1,
u_ZoomScale: 1
}
const { createModel } = this.rendererService;
const { attributes, elements } =this.createAttributesAndIndices(
[{
color: [1, 0, 0, 1],
coordinates: [120, 30],
id: 0,
shape: 'circle',
size: 16
}],
triangulation,
segmentNumber,
);
const modelOptions = {
attributes,
uniforms,
fs,
vs,
fs: frag,
vs: vert,
elements,
...rest,
};
return createModel(modelOptions);
@ -204,23 +186,7 @@ export default class FillModel {
public buildModels() {
function PointFillTriangulation() {
const coordinates = [120, 30]
return {
vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
indices: [0, 1, 2, 2, 3, 0],
size: 2,
};
}
const model = this
.buildLayerModel({
moduleName: 'pointFill',
vertexShader: pointFillVert,
fragmentShader: pointFillFrag,
triangulation: PointFillTriangulation,
});
const model = this.buildLayerModel();
return [model];
}

View File

@ -1,18 +1,23 @@
export const vert = `
attribute vec3 a_Position;
attribute vec3 a_Extrude;
uniform mat4 u_ModelMatrix;
#define TILE_SIZE 512.0
#define PI 3.1415926536
#define WORLD_SCALE TILE_SIZE / (PI * 2.0)
#define COORDINATE_SYSTEM_LNGLAT 1.0 // mapbox
#define COORDINATE_SYSTEM_LNGLAT_OFFSET 2.0 // mapbox offset
#define COORDINATE_SYSTEM_VECTOR_TILE 3.0
#define COORDINATE_SYSTEM_IDENTITY 4.0
#define COORDINATE_SYSTEM_P20 5.0 // amap
#define COORDINATE_SYSTEM_P20_OFFSET 6.0 // amap offset
#define COORDINATE_SYSTEM_METER_OFFSET 7.0
attribute vec3 a_Position;
attribute vec3 a_Extrude;
uniform mat4 u_ModelMatrix;
#define COORDINATE_SYSTEM_P20_2 8.0 // amap2.0
uniform mat4 u_ViewProjectionMatrix;
@ -32,6 +37,8 @@ uniform vec3 u_PixelsPerDegree2;
uniform vec3 u_PixelsPerMeter;
vec2 project_mercator(vec2 lnglat) {
float x = lnglat.x;
return vec2(
@ -45,6 +52,7 @@ float project_scale(float meters) {
}
// offset coords -> world coords
vec4 project_offset(vec4 offset) {
float dy = offset.y;
dy = clamp(dy, -1., 1.);
@ -52,8 +60,24 @@ vec4 project_offset(vec4 offset) {
return vec4(offset.xyz * pixels_per_unit, offset.w);
}
vec4 project_position(vec4 position) {
float a = COORDINATE_SYSTEM_LNGLAT_OFFSET;
float b = COORDINATE_SYSTEM_P20_OFFSET;
float c = COORDINATE_SYSTEM_LNGLAT;
if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET
|| u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
float X = position.x - u_ViewportCenter.x;
float Y = position.y - u_ViewportCenter.y;
return project_offset(vec4(X, Y, position.z, position.w));
}
if (u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && u_CoordinateSystem >COORDINATE_SYSTEM_LNGLAT - 0.01) {
return vec4(
project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale,
project_scale(position.z),
position.w
);
}
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) {
return vec4(
(project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale - vec2(215440491., 106744817.)) * vec2(1., -1.),
@ -61,23 +85,33 @@ vec4 project_position(vec4 position) {
position.w
);
}
return position;
}
vec2 project_pixel(vec2 pixel) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
// P20 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减1
return pixel * pow(2.0, (19.0 - u_Zoom));
}
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
// P20_2 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减3
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
}
return pixel * -1.;
}
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET ||
u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
// Needs to be divided with project_uCommonUnitsPerMeter
position.w *= u_PixelsPerMeter.z;
}
return viewProjectionMatrix * position + center;
}
// Projects from common space coordinates to clip space
vec4 project_common_position_to_clipspace(vec4 position) {
return project_common_position_to_clipspace(
position,
@ -86,18 +120,13 @@ vec4 project_common_position_to_clipspace(vec4 position) {
);
}
vec4 unproject_clipspace_to_position(vec4 clipspacePos, mat4 u_InverseViewProjectionMatrix) {
vec4 pos = u_InverseViewProjectionMatrix * (clipspacePos - u_ViewportCenterProjection);
return pos;
}
void main() {
vec2 offset = a_Extrude.xy * 10.0;
offset = project_pixel(offset);
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
}
`;

View File

@ -1,6 +1,11 @@
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
}

View File

@ -2,9 +2,122 @@ attribute vec3 a_Position;
attribute vec3 a_Extrude;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
#pragma include "projection"
#define TILE_SIZE 512.0
#define PI 3.1415926536
#define WORLD_SCALE TILE_SIZE / (PI * 2.0)
#define COORDINATE_SYSTEM_LNGLAT 1.0 // mapbox
#define COORDINATE_SYSTEM_LNGLAT_OFFSET 2.0 // mapbox offset
#define COORDINATE_SYSTEM_VECTOR_TILE 3.0
#define COORDINATE_SYSTEM_IDENTITY 4.0
#define COORDINATE_SYSTEM_P20 5.0 // amap
#define COORDINATE_SYSTEM_P20_OFFSET 6.0 // amap offset
#define COORDINATE_SYSTEM_METER_OFFSET 7.0
#define COORDINATE_SYSTEM_P20_2 8.0 // amap2.0
uniform mat4 u_ViewProjectionMatrix;
uniform float u_Zoom;
uniform float u_ZoomScale;
uniform float u_CoordinateSystem;
uniform vec2 u_ViewportCenter;
uniform vec4 u_ViewportCenterProjection;
uniform vec3 u_PixelsPerDegree;
uniform vec3 u_PixelsPerDegree2;
uniform vec3 u_PixelsPerMeter;
vec2 project_mercator(vec2 lnglat) {
float x = lnglat.x;
return vec2(
radians(x) + PI,
PI - log(tan(PI * 0.25 + radians(lnglat.y) * 0.5))
);
}
float project_scale(float meters) {
return meters * u_PixelsPerMeter.z;
}
// offset coords -> world coords
vec4 project_offset(vec4 offset) {
float dy = offset.y;
dy = clamp(dy, -1., 1.);
vec3 pixels_per_unit = u_PixelsPerDegree + u_PixelsPerDegree2 * dy;
return vec4(offset.xyz * pixels_per_unit, offset.w);
}
vec4 project_position(vec4 position) {
float a = COORDINATE_SYSTEM_LNGLAT_OFFSET;
float b = COORDINATE_SYSTEM_P20_OFFSET;
float c = COORDINATE_SYSTEM_LNGLAT;
if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET
|| u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
float X = position.x - u_ViewportCenter.x;
float Y = position.y - u_ViewportCenter.y;
return project_offset(vec4(X, Y, position.z, position.w));
}
if (u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && u_CoordinateSystem >COORDINATE_SYSTEM_LNGLAT - 0.01) {
return vec4(
project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale,
project_scale(position.z),
position.w
);
}
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) {
return vec4(
(project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale - vec2(215440491., 106744817.)) * vec2(1., -1.),
project_scale(position.z),
position.w
);
}
return position;
}
vec2 project_pixel(vec2 pixel) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
// P20 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减1
return pixel * pow(2.0, (19.0 - u_Zoom));
}
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
// P20_2 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减3
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
}
return pixel * -1.;
}
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET ||
u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
// Needs to be divided with project_uCommonUnitsPerMeter
position.w *= u_PixelsPerMeter.z;
}
return viewProjectionMatrix * position + center;
}
// Projects from common space coordinates to clip space
vec4 project_common_position_to_clipspace(vec4 position) {
return project_common_position_to_clipspace(
position,
u_ViewProjectionMatrix,
u_ViewportCenterProjection
);
}
void main() {
vec2 offset = a_Extrude.xy * 10.0;
@ -13,10 +126,5 @@ void main() {
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
gl_Position = u_Mvp * vec4(project_pos.xy + offset, 0.0, 1.0);
} else {
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
}
}
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
}

View File

@ -35,7 +35,7 @@ export class Base {
}
public render() {
this.parent.renderLayers();
}
public hasTile(tile: SourceTile) {

View File

@ -76,9 +76,6 @@ export default class ReglModel implements IModel {
}
public draw(options: IModelDrawOptions) {
this.drawCommand(this.uniforms);
}