Skip to content

Commit 39e9e8d

Browse files
committed
simplify 4326 path further
1 parent d2851fe commit 39e9e8d

File tree

6 files changed

+78
-238
lines changed

6 files changed

+78
-238
lines changed

packages/deck.gl-raster/src/gpu-modules/index.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,5 @@ export { CMYKToRGB, cieLabToRGB, YCbCrToRGB } from "./color";
22
export { Colormap } from "./colormap";
33
export { CreateTexture } from "./create-texture";
44
export { FilterNoDataVal } from "./filter-nodata";
5-
export {
6-
computeReproject4326Props,
7-
latToMercatorNorm,
8-
Reproject4326,
9-
} from "./reproject-4326";
5+
export { latToMercatorNorm, Reproject4326 } from "./reproject-4326";
106
export type { RasterModule } from "./types";

packages/deck.gl-raster/src/gpu-modules/reproject-4326.ts

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,17 @@ export function latToMercatorNorm(lat: number): number {
4343
);
4444
}
4545

46-
/**
47-
* Compute the reprojection props from latitude bounds and data orientation.
48-
*/
49-
export function computeReproject4326Props(
50-
latMin: number,
51-
latMax: number,
52-
latIsAscending: boolean,
53-
): Reproject4326Props {
54-
// Compute Mercator Y bounds from latitude
55-
// mercatorYBounds[0] = north (smaller Y value), mercatorYBounds[1] = south (larger Y value)
56-
const mercYNorth = latToMercatorNorm(latMax);
57-
const mercYSouth = latToMercatorNorm(latMin);
46+
/** Module name - must match uniform block name */
47+
const MODULE_NAME = "reproject4326";
5848

59-
return {
60-
latBounds: [latMin, latMax],
61-
mercatorYBounds: [mercYNorth, mercYSouth],
62-
latIsAscending,
63-
};
64-
}
49+
/** Uniform block for luma.gl v9 pattern */
50+
const uniformBlock = /* glsl */ `\
51+
uniform ${MODULE_NAME}Uniforms {
52+
vec2 latBounds;
53+
vec2 mercatorYBounds;
54+
int latIsAscending;
55+
} ${MODULE_NAME};
56+
`;
6557

6658
/**
6759
* Reprojection shader module for EPSG:4326 source data.
@@ -73,16 +65,12 @@ export function computeReproject4326Props(
7365
* texture sampling module (e.g., CreateTexture).
7466
*/
7567
export const Reproject4326 = {
76-
name: "reproject-4326",
68+
name: MODULE_NAME,
69+
fs: uniformBlock,
7770
inject: {
7871
"fs:#decl": /* glsl */ `
7972
const float PI_REPROJECT_4326 = 3.14159265358979323846;
8073
81-
// Uniforms for EPSG:4326 reprojection
82-
uniform vec2 reproject4326_latBounds; // [latMin, latMax] in degrees
83-
uniform vec2 reproject4326_mercatorYBounds; // [mercY_north, mercY_south] in [0,1]
84-
uniform int reproject4326_latIsAscending; // 1 = row 0 is south, 0 = row 0 is north
85-
8674
// Invert Mercator Y to latitude in degrees
8775
float mercatorYToLat(float mercY) {
8876
// mercY is normalized [0,1] where 0=north, 1=south
@@ -97,15 +85,15 @@ export const Reproject4326 = {
9785
float lat = mercatorYToLat(mercY);
9886
9987
// Map latitude to texture V coordinate based on data orientation
100-
float latRange = reproject4326_latBounds.y - reproject4326_latBounds.x;
88+
float latRange = reproject4326.latBounds.y - reproject4326.latBounds.x;
10189
float texV;
10290
103-
if (reproject4326_latIsAscending == 1) {
91+
if (reproject4326.latIsAscending == 1) {
10492
// Row 0 = south (latMin), row N = north (latMax)
105-
texV = (lat - reproject4326_latBounds.x) / latRange;
93+
texV = (lat - reproject4326.latBounds.x) / latRange;
10694
} else {
10795
// Row 0 = north (latMax), row N = south (latMin)
108-
texV = (reproject4326_latBounds.y - lat) / latRange;
96+
texV = (reproject4326.latBounds.y - lat) / latRange;
10997
}
11098
11199
return texV;
@@ -114,36 +102,50 @@ export const Reproject4326 = {
114102
// Inject BEFORE DECKGL_FILTER_COLOR to modify geometry.uv before texture sampling
115103
// Using the fs:#main-start hook which runs at the beginning of main()
116104
"fs:#main-start": /* glsl */ `
117-
// Only apply reprojection if mercatorYBounds are set (non-zero range)
118-
float mercRange = reproject4326_mercatorYBounds.y - reproject4326_mercatorYBounds.x;
119-
if (abs(mercRange) > 0.0001) {
120-
// Compute current Mercator Y from UV
121-
// vTexCoord.y maps linearly across the mesh, which is positioned in Mercator space
122-
// We need to interpolate between the north and south Mercator Y bounds
123-
float currentMercY = mix(
124-
reproject4326_mercatorYBounds.x,
125-
reproject4326_mercatorYBounds.y,
105+
// Discard when bounds not set (prevents flash during loading)
106+
float latRange = reproject4326.latBounds.y - reproject4326.latBounds.x;
107+
if (abs(latRange) < 0.0001) {
108+
discard;
109+
}
110+
111+
// Compute current Mercator Y from UV
112+
// vTexCoord.y maps linearly across the mesh, which is positioned in Mercator space
113+
// We need to interpolate between the north and south Mercator Y bounds
114+
float currentMercY;
115+
if (reproject4326.latIsAscending == 1) {
116+
// UV.y: 0 at south, 1 at north
117+
currentMercY = mix(
118+
reproject4326.mercatorYBounds.y, // south (at y=0)
119+
reproject4326.mercatorYBounds.x, // north (at y=1)
126120
vTexCoord.y
127121
);
122+
} else {
123+
// UV.y: 0 at north, 1 at south
124+
currentMercY = mix(
125+
reproject4326.mercatorYBounds.x, // north (at y=0)
126+
reproject4326.mercatorYBounds.y, // south (at y=1)
127+
vTexCoord.y
128+
);
129+
}
128130
129-
// Compute reprojected texture V
130-
float reprojectTexV = computeReprojectTexV(currentMercY);
131+
// Compute reprojected texture V
132+
float reprojectTexV = computeReprojectTexV(currentMercY);
131133
132-
// Store original UV for later restoration if needed
133-
// Override geometry.uv with reprojected coordinates
134-
geometry.uv = vec2(vTexCoord.x, reprojectTexV);
135-
}
134+
// Override geometry.uv with reprojected coordinates
135+
geometry.uv = vec2(vTexCoord.x, reprojectTexV);
136136
`,
137137
},
138+
// Uniform types for luma.gl v9 (must match uniform block order)
139+
uniformTypes: {
140+
latBounds: "vec2<f32>",
141+
mercatorYBounds: "vec2<f32>",
142+
latIsAscending: "i32",
143+
},
138144
getUniforms: (props: Partial<Reproject4326Props> = {}) => {
139-
const latBounds = props.latBounds ?? [0, 0];
140-
const mercatorYBounds = props.mercatorYBounds ?? [0, 0];
141-
const latIsAscending = props.latIsAscending ?? false;
142-
143145
return {
144-
reproject4326_latBounds: latBounds,
145-
reproject4326_mercatorYBounds: mercatorYBounds,
146-
reproject4326_latIsAscending: latIsAscending ? 1 : 0,
146+
latBounds: props.latBounds ?? [0, 0],
147+
mercatorYBounds: props.mercatorYBounds ?? [0, 0],
148+
latIsAscending: props.latIsAscending ? 1 : 0,
147149
};
148150
},
149151
} as const;

packages/deck.gl-raster/src/gpu-modules/reproject-texture.ts

Lines changed: 0 additions & 125 deletions
This file was deleted.

packages/deck.gl-raster/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export {
2-
computeReproject4326Props,
32
latToMercatorNorm,
43
Reproject4326,
54
} from "./gpu-modules/reproject-4326.js";

packages/deck.gl-raster/src/mesh-layer/mesh-layer.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,18 @@ export class MeshTextureLayer extends SimpleMeshLayer<
4040
}
4141

4242
override draw(opts: any): void {
43-
// Build props object keyed by module name for shaderInputs
44-
// With proper uniformTypes, setProps should handle non-texture uniforms
43+
// Build props and collect texture bindings in a single pass
4544
const shaderProps: Record<string, Record<string, unknown>> = {};
45+
const textureBindings: Record<string, unknown> = {};
46+
4647
for (const m of this.props.renderPipeline) {
4748
shaderProps[m.module.name] = m.props || {};
48-
}
4949

50-
// Collect texture bindings from modules (textures can't go in uniform blocks)
51-
const textureBindings: Record<string, unknown> = {};
52-
for (const m of this.props.renderPipeline) {
5350
if (m.module.getUniforms && m.props) {
54-
const moduleUniforms = m.module.getUniforms(m.props);
55-
for (const [key, value] of Object.entries(moduleUniforms)) {
51+
for (const [key, value] of Object.entries(
52+
m.module.getUniforms(m.props),
53+
)) {
54+
// Textures have a "handle" property
5655
if (value && typeof value === "object" && "handle" in value) {
5756
textureBindings[key] = value;
5857
}
@@ -61,13 +60,10 @@ export class MeshTextureLayer extends SimpleMeshLayer<
6160
}
6261

6362
for (const model of super.getModels()) {
64-
// setProps should handle uniform block values via uniformTypes
63+
// uniformTypes enables setProps to handle uniform block values
6564
model.shaderInputs.setProps(shaderProps);
66-
67-
// Textures need to be set via bindings (can't be in uniform blocks)
68-
if (Object.keys(textureBindings).length > 0) {
69-
model.setBindings(textureBindings as Record<string, any>);
70-
}
65+
// Textures must be set via bindings (can't go in uniform blocks)
66+
model.setBindings(textureBindings as Record<string, any>);
7167
}
7268

7369
super.draw(opts);

0 commit comments

Comments
 (0)