Skip to content

Commit 29dd8d3

Browse files
committed
Discard NaN nodata in deck COG render (transparent oceans)
Float scientific COGs encode nodata as NaN (GDAL_NODATA=nan); FilterNoDataVal's == equality never matches NaN. Add a FilterNaN GPU module (color.r != color.r self-inequality test) after CreateTexture so NaN fill pixels are discarded. Verified live on CMIP6 tasmax: oceans render transparent (basemap shows through).
1 parent 28d71cb commit 29dd8d3

1 file changed

Lines changed: 24 additions & 1 deletion

File tree

src/essence/Basics/MapEngines/Adapters/DeckCOGLayer.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ async function cogGetTileData(
165165
* overridden `_renderTileCallback()` below, so this is never invoked. */
166166
const RENDER_TILE_PLACEHOLDER = (): null => null
167167

168+
/**
169+
* GPU module that discards NaN pixels. Float COGs almost always encode nodata
170+
* as NaN (GDAL_NODATA="nan"), and the library's FilterNoDataVal uses `==`
171+
* equality — which never matches NaN. `color.r != color.r` is the portable
172+
* self-inequality NaN test (NaN is the only value not equal to itself), so this
173+
* discards ocean/fill pixels and leaves them transparent. Harmless for integer
174+
* data (no pixel is NaN). Runs right after CreateTexture, before rescale.
175+
*/
176+
const FilterNaN = {
177+
name: 'filter-nan',
178+
inject: {
179+
'fs:DECKGL_FILTER_COLOR': `
180+
if (color.r != color.r) { discard; }
181+
`,
182+
},
183+
}
184+
168185
// ---------------------------------------------------------------------------
169186
// ColormappedCOGLayer
170187
// ---------------------------------------------------------------------------
@@ -248,7 +265,13 @@ export class ColormappedCOGLayer extends COGLayer<any> {
248265
return (data: any) => {
249266
if (!data || !data.texture) return null
250267
return composeColormapPipeline(
251-
{ renderPipeline: [{ module: CreateTexture, props: { textureName: data.texture } }] },
268+
{
269+
renderPipeline: [
270+
{ module: CreateTexture, props: { textureName: data.texture } },
271+
// Discard NaN nodata (oceans/fill) → transparent.
272+
{ module: FilterNaN },
273+
],
274+
},
252275
{ rescaleMin, rescaleMax, colormapTexture, nodata }
253276
)
254277
}

0 commit comments

Comments
 (0)