Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve shader projection in auto offset mode #6161

Merged
merged 2 commits into from
Sep 9, 2021
Merged
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
21 changes: 16 additions & 5 deletions modules/core/src/shaderlib/project/project.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ uniform float project_uDevicePixelRatio;
uniform float project_uFocalDistance;
uniform vec3 project_uCameraPosition;
uniform vec3 project_uCoordinateOrigin;
uniform vec3 project_uCommonOrigin;

const float TILE_SIZE = 512.0;
const float PI = 3.1415926536;
Expand Down Expand Up @@ -87,9 +88,6 @@ vec3 project_normal(vec3 vector) {

vec4 project_offset_(vec4 offset) {
float dy = offset.y;
if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
dy = clamp(dy, -1., 1.);
}
vec3 commonUnitsPerWorldUnit = project_uCommonUnitsPerWorldUnit + project_uCommonUnitsPerWorldUnit2 * dy;
return vec4(offset.xyz * commonUnitsPerWorldUnit, offset.w);
}
Expand All @@ -106,7 +104,7 @@ vec2 project_mercator_(vec2 lnglat) {
return vec2(
radians(x) + PI,
PI + log(tan_fp32(PI * 0.25 + radians(y) * 0.5))
);
) * WORLD_SCALE;
}

vec3 project_globe_(vec3 lnglatz) {
Expand All @@ -132,7 +130,7 @@ vec4 project_position(vec4 position, vec3 position64Low) {
if (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR) {
if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
return vec4(
project_mercator_(position_world.xy) * WORLD_SCALE,
project_mercator_(position_world.xy),
project_size(position_world.z),
position_world.w
);
Expand All @@ -149,6 +147,19 @@ vec4 project_position(vec4 position, vec3 position64Low) {
);
}
}
if (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
if (abs(position_world.y - project_uCoordinateOrigin.y) > 0.25) {
// Too far from the projection center for offset mode to be accurate
// Only use high parts
return vec4(
project_mercator_(position_world.xy) - project_uCommonOrigin.xy,
project_size(position_world.z),
position_world.w
);
}
}
}
if (project_uProjectionMode == PROJECTION_MODE_IDENTITY ||
(project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET &&
(project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT ||
Expand Down
18 changes: 10 additions & 8 deletions modules/core/src/shaderlib/project/viewport-uniforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ function calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin)
let {viewMatrix, viewProjectionMatrix} = viewport;

let projectionCenter = ZERO_VECTOR;
let originCommon = ZERO_VECTOR;
let cameraPosCommon = viewport.cameraPosition;
const {geospatialOrigin, shaderCoordinateOrigin, offsetMode} = getOffsetOrigin(
viewport,
Expand All @@ -122,21 +123,19 @@ function calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin)
// Calculate transformed projectionCenter (using 64 bit precision JS)
// This is the key to offset mode precision
// (avoids doing this addition in 32 bit precision in GLSL)
const positionCommonSpace = viewport.projectPosition(
geospatialOrigin || shaderCoordinateOrigin
);
originCommon = viewport.projectPosition(geospatialOrigin || shaderCoordinateOrigin);

cameraPosCommon = [
cameraPosCommon[0] - positionCommonSpace[0],
cameraPosCommon[1] - positionCommonSpace[1],
cameraPosCommon[2] - positionCommonSpace[2]
cameraPosCommon[0] - originCommon[0],
cameraPosCommon[1] - originCommon[1],
cameraPosCommon[2] - originCommon[2]
];

positionCommonSpace[3] = 1;
originCommon[3] = 1;

// projectionCenter = new Matrix4(viewProjectionMatrix)
// .transformVector([positionPixels[0], positionPixels[1], 0.0, 1.0]);
projectionCenter = vec4.transformMat4([], positionCommonSpace, viewProjectionMatrix);
projectionCenter = vec4.transformMat4([], originCommon, viewProjectionMatrix);

// Always apply uncentered projection matrix if available (shader adds center)
viewMatrix = viewMatrixUncentered || viewMatrix;
Expand All @@ -152,6 +151,7 @@ function calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin)
viewMatrix,
viewProjectionMatrix,
projectionCenter,
originCommon,
cameraPosCommon,
shaderCoordinateOrigin,
geospatialOrigin
Expand Down Expand Up @@ -204,6 +204,7 @@ function calculateViewportUniforms({
const {
projectionCenter,
viewProjectionMatrix,
originCommon,
cameraPosCommon,
shaderCoordinateOrigin,
geospatialOrigin
Expand All @@ -226,6 +227,7 @@ function calculateViewportUniforms({
project_uCoordinateSystem: coordinateSystem,
project_uProjectionMode: viewport.projectionMode,
project_uCoordinateOrigin: shaderCoordinateOrigin,
project_uCommonOrigin: originCommon.slice(0, 3),
project_uCenter: projectionCenter,

// Screen size
Expand Down