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

Use UBOs in project module #8782

Merged
merged 44 commits into from May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
167d6c3
WIP
felixpalmer Apr 10, 2024
3b337da
Hook up getUniforms
felixpalmer Apr 11, 2024
18e2603
Tidy
felixpalmer Apr 11, 2024
ca48f7f
uCoordinateSystem
felixpalmer Apr 11, 2024
44f55be
projectionMode
felixpalmer Apr 11, 2024
19d53b2
project_uScale
felixpalmer Apr 11, 2024
af45e52
commonUnitsperWorldUnit
felixpalmer Apr 11, 2024
dfcabe8
project.center
felixpalmer Apr 11, 2024
7b3b511
modelMatrix
felixpalmer Apr 11, 2024
2d426cb
viewProjectionMatrix
felixpalmer Apr 11, 2024
837fa16
viewportSize
felixpalmer Apr 11, 2024
ab8bdf7
devicePixelRatio
felixpalmer Apr 11, 2024
3ab15bc
focalDistance
felixpalmer Apr 11, 2024
607718a
coordinateOrigin
felixpalmer Apr 11, 2024
1194ed1
commonOrigin
felixpalmer Apr 11, 2024
3046ac5
Update layer shaders
felixpalmer Apr 11, 2024
a01ad11
Update layers
felixpalmer Apr 11, 2024
5f0cb39
Migrate shader modules
felixpalmer Apr 11, 2024
ca64fcc
Shadow spec
felixpalmer Apr 11, 2024
4557364
Lint
felixpalmer Apr 11, 2024
dd57f79
Fix ScreenGridLayer binding
felixpalmer Apr 11, 2024
650b238
Merge branch 'master' into felix/project-ubo
felixpalmer Apr 11, 2024
f3565d3
Remove project32 hacks
felixpalmer Apr 16, 2024
fecbe18
Use varying to pass cameraPosition column fragment
felixpalmer Apr 19, 2024
6706560
Fix project tests
felixpalmer Apr 19, 2024
233e1cf
Fix transitions
felixpalmer Apr 19, 2024
c0387cd
Fix project-functions.spec
felixpalmer Apr 19, 2024
6822522
UBO for project64
felixpalmer Apr 19, 2024
a9a64ae
Rename
felixpalmer Apr 19, 2024
0d90fc3
Fix test
felixpalmer Apr 19, 2024
ddb80ad
Reinstate scale64
felixpalmer Apr 19, 2024
361bfed
Better imports
felixpalmer Apr 19, 2024
7f738a8
Merge branch 'master' into felix/project-ubo
felixpalmer Apr 19, 2024
7380682
autoWrap rename
felixpalmer Apr 19, 2024
44e7464
Bump to luma 9.0.12
felixpalmer Apr 30, 2024
cc4b460
Merge branch 'master' into felix/project-ubo
felixpalmer Apr 30, 2024
f1b53e2
Hack in project64 matrix to test
felixpalmer Apr 30, 2024
28addcf
Tidy
felixpalmer Apr 30, 2024
a4b45c1
Match order
felixpalmer Apr 30, 2024
af04130
Add geometry as default module
felixpalmer Apr 30, 2024
ae4edea
Pass modelMatrix to project
felixpalmer Apr 30, 2024
1d870cd
Merge branch 'master' into felix/project-ubo
felixpalmer May 7, 2024
f3f62b9
Set shader module props for fp64 in extension
felixpalmer May 7, 2024
dac757d
Remove project module hacks in transitions
felixpalmer May 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/api-reference/core/project.md
Expand Up @@ -151,6 +151,6 @@ Returns a matrix that rotates any vector defined in the default common space to

## Remarks

* For consistent results, the screen space pixels are logical pixels, not device pixels, i.e. functions in the project module multiply `pixels` with `project_uDevicePixelRatio`.
* For consistent results, the screen space pixels are logical pixels, not device pixels, i.e. functions in the project module multiply `pixels` with `project.devicePixelRatio`.
* The pixels offsets will be divided by the `w` coordinate of `gl_Position`. This is simply the GPUs standard treatment of any coordinate. This means that there will be more pixels closer to the camera and less pixels further away from the camer. Setting the `focalDistance` uniform controls this.
* To avoid pixel sizes scaling with distance from camera, simply set `focalDistance` to 1 and multiply clipspace offset with `gl_Position.w`
2 changes: 1 addition & 1 deletion docs/api-reference/core/project64.md
Expand Up @@ -5,7 +5,7 @@ The `project64` shader module is an extension of the [project](./project.md) sha

## getUniforms

The uniforms needed by `project64` are extracted from the `project` module uniforms `project_uViewProjectionMatrix` and `project_uScale`.
The uniforms needed by `project64` are extracted from the `project` module uniforms `project.viewProjectionMatrix` and `project.scale`.


## GLSL Uniforms
Expand Down
2 changes: 1 addition & 1 deletion docs/developer-guide/custom-layers/subclassed-layers.md
Expand Up @@ -225,7 +225,7 @@ void main(void) {
/* replaced uniform 'radiusPixels' with 'instanceRadiusPixels' */
gl_Position.xy += project_pixel_size_to_clipspace(positions.xy * instanceRadiusPixels);

vec3 lightColor = lighting_getLightColor(instanceColors.rgb, project_uCameraPosition, position_commonspace.xyz, project_normal(instanceNormals));
vec3 lightColor = lighting_getLightColor(instanceColors.rgb, project.cameraPosition, position_commonspace.xyz, project_normal(instanceNormals));

vColor = vec4(lightColor, instanceColors.a * opacity) / 255.0;

Expand Down
Expand Up @@ -39,7 +39,7 @@ out vec4 vColor;
// offset_direction is -1 (left) or 1 (right)
vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace * project_uViewportSize);
vec2 dir_screenspace = normalize(line_clipspace * project.viewportSize);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);

Expand Down
2 changes: 1 addition & 1 deletion examples/website/plot/plot-layer/grid-vertex.glsl.ts
Expand Up @@ -38,7 +38,7 @@ out float shouldDiscard;

// determines if the grid line is behind or in front of the center
float frontFacing(vec3 v) {
vec4 v_clipspace = project_uViewProjectionMatrix * project_uModelMatrix * vec4(v, 0.0);
vec4 v_clipspace = project.viewProjectionMatrix * project.modelMatrix * vec4(v, 0.0);
return step(v_clipspace.z, 0.0);
}

Expand Down
2 changes: 1 addition & 1 deletion examples/website/plot/plot-layer/label-vertex.glsl.ts
Expand Up @@ -50,7 +50,7 @@ float sum3(vec3 v) {

// determines if the grid line is behind or in front of the center
float frontFacing(vec3 v) {
vec4 v_clipspace = project_uViewProjectionMatrix * project_uModelMatrix * vec4(v, 0.0);
vec4 v_clipspace = project.viewProjectionMatrix * project.modelMatrix * vec4(v, 0.0);
return step(v_clipspace.z, 0.0);
}

Expand Down
Expand Up @@ -134,7 +134,7 @@ void main(void) {
vec3 normals_commonspace = project_normal(normals);

if (extruded) {
vec3 lightColor = lighting_getLightColor(color.rgb, project_uCameraPosition, geometry.position.xyz, normals_commonspace);
vec3 lightColor = lighting_getLightColor(color.rgb, project.cameraPosition, geometry.position.xyz, normals_commonspace);
vColor = vec4(lightColor, color.a * opacity) / 255.;
} else {
vColor = vec4(color.rgb, color.a * opacity) / 255.;
Expand Down
Expand Up @@ -20,7 +20,15 @@

import {Texture} from '@luma.gl/core';
import {Model, Geometry} from '@luma.gl/engine';
import {Layer, LayerProps, log, picking, UpdateParameters, DefaultProps} from '@deck.gl/core';
import {
Layer,
LayerProps,
log,
project32,
picking,
UpdateParameters,
DefaultProps
} from '@deck.gl/core';
import {defaultColorRange, colorRangeToFlatArray} from '../utils/color-utils';
import vs from './screen-grid-layer-vertex.glsl';
import fs from './screen-grid-layer-fragment.glsl';
Expand Down Expand Up @@ -59,7 +67,7 @@ export default class ScreenGridCellLayer<DataT = any, ExtraPropsT extends {} = {
};

getShaders(): {vs: string; fs: string; modules: ShaderModule[]} {
return {vs, fs, modules: [picking as ShaderModule]};
return {vs, fs, modules: [project32, picking]};
}

initializeState() {
Expand Down
6 changes: 3 additions & 3 deletions modules/carto/src/layers/raster-layer-vertex.glsl.ts
Expand Up @@ -46,8 +46,8 @@ void main(void) {
// Important to set geometry.position before using project_ methods below
// as geometry.worldPosition is not set (we don't know our lat/long)
geometry.position = vec4(common_position, 0.0, 1.0);
if (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
geometry.position.xyz -= project_uCommonOrigin;
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
geometry.position.xyz -= project.commonOrigin;
}

// calculate elevation, if 3d not enabled set to 0
Expand Down Expand Up @@ -86,7 +86,7 @@ void main(void) {
position_commonspace = geometry.position;
vColor = vec4(color.rgb, color.a * opacity);
#else
vec3 lightColor = lighting_getLightColor(color.rgb, project_uCameraPosition, geometry.position.xyz, geometry.normal);
vec3 lightColor = lighting_getLightColor(color.rgb, project.cameraPosition, geometry.position.xyz, geometry.normal);
vColor = vec4(lightColor, color.a * opacity);
#endif
} else {
Expand Down
4 changes: 2 additions & 2 deletions modules/core/src/effects/lighting/camera-light.ts
Expand Up @@ -8,15 +8,15 @@ export default class CameraLight extends PointLight {
const {projectedLight} = this;
const viewport = layer.context.viewport;
const {coordinateSystem, coordinateOrigin, modelMatrix} = layer.props;
const {project_uCameraPosition} = getUniformsFromViewport({
const {cameraPosition} = getUniformsFromViewport({
viewport,
modelMatrix,
coordinateSystem,
coordinateOrigin
});
projectedLight.color = this.color;
projectedLight.intensity = this.intensity;
projectedLight.position = project_uCameraPosition;
projectedLight.position = cameraPosition;
felixpalmer marked this conversation as resolved.
Show resolved Hide resolved
return projectedLight;
}
}
6 changes: 5 additions & 1 deletion modules/core/src/lib/layer.ts
Expand Up @@ -1065,8 +1065,12 @@ export default abstract class Layer<PropsT extends {} = {}> extends Component<
// TODO/ib - hack move to luma Model.draw
if (moduleParameters) {
const {isActive, isAttribute} = moduleParameters.picking;
const {viewport, devicePixelRatio, coordinateSystem, coordinateOrigin} = moduleParameters;
this.setModuleParameters(moduleParameters);
this.setShaderModuleProps({picking: {isActive, isAttribute}});
this.setShaderModuleProps({
picking: {isActive, isAttribute},
project32: {viewport, devicePixelRatio, coordinateSystem, coordinateOrigin}
});
}

// Apply polygon offset to avoid z-fighting
Expand Down
118 changes: 62 additions & 56 deletions modules/core/src/shaderlib/project/project.glsl.ts
Expand Up @@ -36,23 +36,28 @@ ${COORDINATE_SYSTEM_GLSL_CONSTANTS}
${PROJECTION_MODE_GLSL_CONSTANTS}
${UNIT_GLSL_CONSTANTS}

uniform int project_uCoordinateSystem;
uniform int project_uProjectionMode;
uniform float project_uScale;
uniform bool project_uWrapLongitude;
uniform vec3 project_uCommonUnitsPerMeter;
uniform vec3 project_uCommonUnitsPerWorldUnit;
uniform vec3 project_uCommonUnitsPerWorldUnit2;
uniform vec4 project_uCenter;
uniform mat4 project_uModelMatrix;
uniform mat4 project_uViewProjectionMatrix;
uniform vec2 project_uViewportSize;
uniform float project_uDevicePixelRatio;
uniform float project_uFocalDistance;
uniform vec3 project_uCameraPosition;
uniform vec3 project_uCoordinateOrigin;
uniform vec3 project_uCommonOrigin;
uniform bool project_uPseudoMeters;
uniform project32Uniforms {
felixpalmer marked this conversation as resolved.
Show resolved Hide resolved
bool autoWrapLongitude;
int coordinateSystem;
vec3 commonUnitsPerMeter;
int projectionMode;
float scale;

vec3 commonUnitsPerWorldUnit;
vec3 commonUnitsPerWorldUnit2;
vec4 center;
mat4 modelMatrix;
mat4 viewProjectionMatrix;
vec2 viewportSize;
float devicePixelRatio;
float focalDistance;
vec3 cameraPosition;
vec3 coordinateOrigin;
vec3 commonOrigin;
bool pseudoMeters;
} project;



const float TILE_SIZE = 512.0;
const float PI = 3.1415926536;
Expand All @@ -68,9 +73,9 @@ float project_size_at_latitude(float lat) {
}

float project_size() {
if (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR &&
project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT &&
project_uPseudoMeters == false) {
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR &&
project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT &&
project.pseudoMeters == false) {

// uCommonUnitsPerMeter in low-zoom Web Mercator is non-linear
// Adjust by 1 / cos(latitude)
Expand All @@ -95,27 +100,28 @@ float project_size() {
}

float project_size_at_latitude(float meters, float lat) {
return meters * project_uCommonUnitsPerMeter.z * project_size_at_latitude(lat);
return meters * project.commonUnitsPerMeter.z * project_size_at_latitude(lat);
}

//
// Scaling offsets - scales meters to "world distance"
// Note the scalar version of project_size is for scaling the z component only
//
float project_size(float meters) {
return meters * project_uCommonUnitsPerMeter.z * project_size();
// For scatter relevant
return meters * project.commonUnitsPerMeter.z * project_size();
}

vec2 project_size(vec2 meters) {
return meters * project_uCommonUnitsPerMeter.xy * project_size();
return meters * project.commonUnitsPerMeter.xy * project_size();
}

vec3 project_size(vec3 meters) {
return meters * project_uCommonUnitsPerMeter * project_size();
return meters * project.commonUnitsPerMeter * project_size();
}

vec4 project_size(vec4 meters) {
return vec4(meters.xyz * project_uCommonUnitsPerMeter, meters.w);
return vec4(meters.xyz * project.commonUnitsPerMeter, meters.w);
}

// Get rotation matrix that aligns the z axis with the given up vector
Expand All @@ -129,7 +135,7 @@ mat3 project_get_orientation_matrix(vec3 up) {
}

bool project_needs_rotation(vec3 commonPosition, out mat3 transform) {
if (project_uProjectionMode == PROJECTION_MODE_GLOBE) {
if (project.projectionMode == PROJECTION_MODE_GLOBE) {
transform = project_get_orientation_matrix(commonPosition);
return true;
}
Expand All @@ -142,8 +148,8 @@ bool project_needs_rotation(vec3 commonPosition, out mat3 transform) {
//
vec3 project_normal(vec3 vector) {
// Apply model matrix
vec4 normal_modelspace = project_uModelMatrix * vec4(vector, 0.0);
vec3 n = normalize(normal_modelspace.xyz * project_uCommonUnitsPerMeter);
vec4 normal_modelspace = project.modelMatrix * vec4(vector, 0.0);
vec3 n = normalize(normal_modelspace.xyz * project.commonUnitsPerMeter);
mat3 rotation;
if (project_needs_rotation(geometry.position.xyz, rotation)) {
n = rotation * n;
Expand All @@ -153,7 +159,7 @@ vec3 project_normal(vec3 vector) {

vec4 project_offset_(vec4 offset) {
float dy = offset.y;
vec3 commonUnitsPerWorldUnit = project_uCommonUnitsPerWorldUnit + project_uCommonUnitsPerWorldUnit2 * dy;
vec3 commonUnitsPerWorldUnit = project.commonUnitsPerWorldUnit + project.commonUnitsPerWorldUnit2 * dy;
return vec4(offset.xyz * commonUnitsPerWorldUnit, offset.w);
}

Expand All @@ -162,7 +168,7 @@ vec4 project_offset_(vec4 offset) {
//
vec2 project_mercator_(vec2 lnglat) {
float x = lnglat.x;
if (project_uWrapLongitude) {
if (project.autoWrapLongitude) {
felixpalmer marked this conversation as resolved.
Show resolved Hide resolved
x = mod(x + 180., 360.0) - 180.;
}
float y = clamp(lnglat.y, -89.9, 89.9);
Expand All @@ -186,55 +192,55 @@ vec3 project_globe_(vec3 lnglatz) {
}

//
// Projects positions (defined by project_uCoordinateSystem) to common space (defined by project_uProjectionMode)
// Projects positions (defined by project.coordinateSystem) to common space (defined by project.projectionMode)
//
vec4 project_position(vec4 position, vec3 position64Low) {
vec4 position_world = project_uModelMatrix * position;
vec4 position_world = project.modelMatrix * position;

// Work around for a Mac+NVIDIA bug https://github.com/visgl/deck.gl/issues/4145
if (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR) {
if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
return vec4(
project_mercator_(position_world.xy),
project_size_at_latitude(position_world.z, position_world.y),
position_world.w
);
}
if (project_uCoordinateSystem == COORDINATE_SYSTEM_CARTESIAN) {
position_world.xyz += project_uCoordinateOrigin;
if (project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN) {
position_world.xyz += project.coordinateOrigin;
}
}
if (project_uProjectionMode == PROJECTION_MODE_GLOBE) {
if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
if (project.projectionMode == PROJECTION_MODE_GLOBE) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
return vec4(
project_globe_(position_world.xyz),
position_world.w
);
}
}
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) {
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
if (abs(position_world.y - project.coordinateOrigin.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_mercator_(position_world.xy) - project.commonOrigin.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 ||
project_uCoordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) {
if (project.projectionMode == PROJECTION_MODE_IDENTITY ||
(project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET &&
(project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT ||
project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) {
// Subtract high part of 64 bit value. Convert remainder to float32, preserving precision.
position_world.xyz -= project_uCoordinateOrigin;
position_world.xyz -= project.coordinateOrigin;
}

// Translation is already added to the high parts
return project_offset_(position_world) + project_offset_(project_uModelMatrix * vec4(position64Low, 0.0));
return project_offset_(position_world) + project_offset_(project.modelMatrix * vec4(position64Low, 0.0));
}

vec4 project_position(vec4 position) {
Expand Down Expand Up @@ -262,31 +268,31 @@ vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatr

//
// Projects from common space coordinates to clip space.
// Uses project_uViewProjectionMatrix
// Uses project.viewProjectionMatrix
//
vec4 project_common_position_to_clipspace(vec4 position) {
return project_common_position_to_clipspace(position, project_uViewProjectionMatrix, project_uCenter);
return project_common_position_to_clipspace(position, project.viewProjectionMatrix, project.center);
}

// Returns a clip space offset that corresponds to a given number of screen pixels
vec2 project_pixel_size_to_clipspace(vec2 pixels) {
vec2 offset = pixels / project_uViewportSize * project_uDevicePixelRatio * 2.0;
return offset * project_uFocalDistance;
vec2 offset = pixels / project.viewportSize * project.devicePixelRatio * 2.0;
return offset * project.focalDistance;
}

float project_size_to_pixel(float meters) {
return project_size(meters) * project_uScale;
return project_size(meters) * project.scale;
}
float project_size_to_pixel(float size, int unit) {
if (unit == UNIT_METERS) return project_size_to_pixel(size);
if (unit == UNIT_COMMON) return size * project_uScale;
if (unit == UNIT_COMMON) return size * project.scale;
// UNIT_PIXELS
return size;
}
float project_pixel_size(float pixels) {
return pixels / project_uScale;
return pixels / project.scale;
}
vec2 project_pixel_size(vec2 pixels) {
return pixels / project_uScale;
return pixels / project.scale;
}
`;