project (Shader Module)
The project
shader module is part of the core of deck.gl. It makes it easy to write shaders that support all of deck.gl's projection modes and it supports some advanced rendering techniques such as pixel space rendering etc.
The project
module has two extensions:
- project32 shorthand functions for projecting directly from worldspace to clipspace.
- project64 counterpart of
project32
that enables 64 bit projections, providing an increase in precision, at the cost of performance.
Usage
Projects worldspace coordinates to clipspace coordinates.
// instanced geometry
in vec3 positions;
// instance attributes
in vec3 instanceCenter;
in float instanceSize;
void main(void) {
vec3 center = project_position(instanceCenter);
vec3 vertex = positions * project_size(instanceSize);
gl_Position = project_common_position_to_clipspace(center + vertex);
}
getUniforms
The JavaScript uniforms are extracted from both contextual and per-layer props. The following information are used:
viewport
devicePixelRatio
coordinateSystem
coordinateOrigin
modelMatrix
GLSL Uniforms
Uniforms are considered private to each shader module. They may change in between patch releases. Always use documented functions instead of accessing module uniforms directly.
The uniforms of the project
shader module are prefixed with project_
in their names.
GLSL Functions
The projection module enables you to write vertex shaders that support deck.gl's coordinate systems and projection methods. Using the projection module ensures that you layer will be able accept position coordinates in the various formats supported by deck.gl, such as [longitude, latitude, altitude]
or [metersX, metersY, metersZ]
. To support the basic features expected of a deck.gl layer, such as various viewport types and coordinate systems, your own shaders should always use the built-in projection functions.
The functions converts positions/vectors between 4 coordinate spaces:
Name | Short Name | Description |
---|---|---|
World space | world | The coordinate system defined by the layer, not necessarily linear or uniform. |
Common space | common | A normalized intermediate 3D space that deck.gl uses for consistent processing of geometries, guaranteed to be linear and uniform. Therefore, it is safe to add/rotate/scale positions and vectors in this space. |
Screen space | pixel | Top-left coordinate system runs from [0, 0] to [viewportWidth, viewportHeight] (see remarks below). |
Clip space | clipspace | Output of the vertex shader. |
More detailed explanation of each coordinate space can be found in the coordinate systems guide.
The GLSL functions of the project
shader module uses the following naming convention:
project_[<source_space>]_<object_type>_[to_<target_space>]
source_space
: the short name of the coordinate space of the input. If not specified, the input is always in theworld
space.object_type
: one of the followingposition
: absolute position of a pointoffset
: the delta between two positionsnormal
: the normal vector of a surfacesize
: the measurement of a geometry. This is different fromoffset
in thatsize
is uniform on all axes (e.g. [x, y, z] in meters inLNGLAT
world space) andoffset
may not be (e.g. [dLon, dLat, dAlt] in degrees, degrees, and meters respectively inLNGLAT
world space).
target_space
: the short name of the coordinate space of the output. If not specified, the output is always in thecommon
space.
project_position
vec2 project_position(vec2 position)
vec3 project_position(vec3 position)
vec3 project_position(vec3 position, vec3 position64Low)
vec4 project_position(vec4 position)
vec4 project_position(vec4 position, vec3 position64Low)
Converts the coordinates of a point from the world space to the common space. The coordinates are interpreted according to coordinateSystem
and modelMatrix
is applied.
project_size
float project_size(float meters)
vec2 project_size(vec2 meters)
vec3 project_size(vec3 meters)
vec4 project_size(vec4 meters)
Converts the size of a geometry from the world space (meters if geospatial, and absolute units otherwise) to the common space.
project_size_to_pixel
float project_size_to_pixel(float size)
float project_size_to_pixel(float size, int units)
Converts the size of a geometry from the given units in the world space to the common space. If unspecified, units is meters. The result corresponds to the number of screen pixels when the given size is viewed with a top-down camera.
project_pixel_size
float project_pixel_size(float pixels)
float project_pixel_size(vec2 pixels)
Converts the size of a geometry from the screen space to the common space.
project_pixel_size_to_clipspace
vec2 project_pixel_size_to_clipspace(vec2 pixels)
Converts the size of a geometry from the screen space to the clip space.
project_normal
vec3 project_normal(vec3 vector)
Converts position deltas from the world space to normalized vector in the common space.
project_common_position_to_clipspace
vec4 project_common_position_to_clipspace(vec4 position)
Converts the coordinates of a point from the common space to the clip space, which can be assigned to gl_Position
as the "return value" from the vertex shader.
project_get_orientation_matrix
mat3 project_get_orientation_matrix(vec3 up)
Returns a matrix that rotates any vector defined in the default common space to a new orientation, such that vec3(0, 0, 1)
is aligned with up
. up
is a normal in common space.
Remarks
- For consistent results, the screen space pixels are logical pixels, not device pixels, i.e. functions in the project module multiply
pixels
withproject_uDevicePixelRatio
. - The pixels offsets will be divided by the
w
coordinate ofgl_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 thefocalDistance
uniform controls this. - To avoid pixel sizes scaling with distance from camera, simply set
focalDistance
to 1 and multiply clipspace offset withgl_Position.w