Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions packages/core/src/services/coordinate/CoordinateSystemService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@ export default class CoordinateSystemService implements ICoordinateSystemService
private viewportCenter: [number, number];

/**
* 屏幕中心点的最终投影结果,在 CPU 侧计算后传入 Shader
* @see https://zhuanlan.zhihu.com/p/57469121
* 屏幕中心点的 fp64 低精度部分,用于高精度坐标偏移计算
* fp64LowPart(x) = x - Math.fround(x)
*/
private viewportCenterProjection: [number, number, number, number];
private viewportCenterLow: [number, number] = [0, 0];

/**
* 像素单位 -> 经纬度 [x, y, z]
* 屏幕中心点的最终投影结果,在 CPU 侧计算后传入 Shader
* @see https://zhuanlan.zhihu.com/p/57469121
*/
private pixelsPerDegree: [number, number, number];
private viewportCenterProjection: [number, number, number, number];

/**
* 像素单位 -> 经纬度 [lng, lat] 使用泰勒级数展开
Expand All @@ -48,6 +49,11 @@ export default class CoordinateSystemService implements ICoordinateSystemService
*/
private pixelsPerMeter: [number, number, number];

/**
* 像素单位 -> 经纬度 [x, y, z]
*/
private pixelsPerDegree: [number, number, number];

/**
* 重新计算当前坐标系参数
* TODO: 使用 memoize 缓存参数以及计算结果
Expand All @@ -66,6 +72,11 @@ export default class CoordinateSystemService implements ICoordinateSystemService
zoom,
});
this.viewportCenter = center;
// 计算 fp64 低精度部分,用于高精度坐标偏移:fp64LowPart(x) = x - Math.fround(x)
this.viewportCenterLow = [
center[0] - Math.fround(center[0]),
center[1] - Math.fround(center[1]),
];
this.viewportCenterProjection = [0, 0, 0, 0];
this.pixelsPerMeter = pixelsPerMeter;
this.pixelsPerDegree = pixelsPerDegree;
Expand Down Expand Up @@ -102,6 +113,10 @@ export default class CoordinateSystemService implements ICoordinateSystemService
return this.viewportCenterProjection;
}

public getViewportCenterLow(): [number, number] {
return this.viewportCenterLow;
}

public getPixelsPerDegree(): [number, number, number] {
return this.pixelsPerDegree;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const CoordinateUniform = {
CoordinateSystem: 'u_CoordinateSystem',
ViewportCenter: 'u_ViewportCenter',
ViewportCenterProjection: 'u_ViewportCenterProjection',
ViewportCenterLow: 'u_ViewportCenterLow',
PixelsPerDegree: 'u_PixelsPerDegree',
PixelsPerDegree2: 'u_PixelsPerDegree2',
PixelsPerMeter: 'u_PixelsPerMeter',
Expand All @@ -35,6 +36,7 @@ export interface ICoordinateSystemService {
getViewportCenter(): [number, number];
setViewportCenter(center: [number, number]): void;
getViewportCenterProjection(): [number, number, number, number];
getViewportCenterLow(): [number, number];
getPixelsPerDegree(): [number, number, number];
getPixelsPerDegree2(): [number, number, number];
getPixelsPerMeter(): [number, number, number];
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/shaders/projection.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ vec4 project_position(vec4 position, vec2 position64xyLow) {
vec2 center = u_ViewportCenter;
float X = absolutePosition.x - center.x;
float Y = absolutePosition.y - center.y;
// 减去中心点的低精度部分,实现全双精度坐标计算,解决高缩放级别下坐标偏移问题
return project_offset(
vec4(
X + absolutePosition64xyLow.x,
Y + absolutePosition64xyLow.y,
X + absolutePosition64xyLow.x - u_ViewportCenterLow.x,
Y + absolutePosition64xyLow.y - u_ViewportCenterLow.y,
absolutePosition.z,
absolutePosition.w
)
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/shaders/scene_uniforms.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ layout(std140) uniform SceneUniforms {
float u_FocalDistance;
vec2 u_RelativeOrigin;
float u_Reserved3;
vec2 u_ViewportCenterLow;
};
5 changes: 4 additions & 1 deletion packages/layers/src/plugins/ShaderUniformPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
const u_ViewportSize = [width, height];
const u_FocalDistance = this.cameraService.getFocalDistance();
const u_RelativeOrigin = offset && offset.length >= 2 ? [offset[0], offset[1]] : [0, 0];
const u_ViewportCenterLow = this.coordinateSystemService.getViewportCenterLow();

const data: number[] = [
...u_ViewMatrix, // 16
Expand All @@ -137,7 +138,8 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
...u_ViewportSize, // 4
u_FocalDistance, // 1
...u_RelativeOrigin, // 2
0, // padding
0, // padding (u_Reserved3)
...u_ViewportCenterLow, // 2
];

return {
Expand All @@ -155,6 +157,7 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
[CoordinateUniform.CoordinateSystem]: u_CoordinateSystem,
[CoordinateUniform.ViewportCenter]: u_ViewportCenter,
[CoordinateUniform.ViewportCenterProjection]: u_ViewportCenterProjection,
[CoordinateUniform.ViewportCenterLow]: u_ViewportCenterLow,
[CoordinateUniform.PixelsPerDegree]: u_PixelsPerDegree,
[CoordinateUniform.PixelsPerDegree2]: u_PixelsPerDegree2,
[CoordinateUniform.PixelsPerMeter]: u_PixelsPerMeter,
Expand Down
Loading