webviz-subsurface-components icon indicating copy to clipboard operation
webviz-subsurface-components copied to clipboard

`SubsurfaceViewer`: colorAbove/colorBelow/colorNaN possibly not working?

Open vegardkv opened this issue 9 months ago • 6 comments

Background for this issue is that the maps visualized in the CO2 leakage part of webviz-subsurface looks incorrect. Most likely coming from replacing DashSubsurfaceViewer with SubsurfaceViewer (https://github.com/equinor/webviz-subsurface/pull/1312):

Upper image is before, lower is after. The red area on the "outskirts" on the lower should be blue as in the upper:

Image

SubsurfaceViewer accepts a colorScales argument, which is a list of color scales, and where each color scale (according to the documentation) can have optional colorAbove/colorBelow/colorNaN properties. However, these setting does not seem to have any effect.

My suspicion is that this might be due to the getRgbData in a different repo, which I think should reference these properties somehow: https://github.com/emerson-eps/color-tables/blob/bb3d1e866c3fa0a7cedc71159169046b9703d6b3/react-app/src/component/Utils/legendCommonFunction.ts#L62

This function is invoked from: https://github.com/equinor/webviz-subsurface-components/blob/ca5e89beb6be2ec83fa2fc09ad6bac91bfa3bac3/typescript/packages/subsurface-viewer/src/layers/colormap/colormapLayer.ts#L23

Even though this is in a different repo, this is just my suspicion based on a brief investigation with limited react/tsx experience.

Apologize in advance for not producing a reproducible issue, but I'll get more info if needed and create one if worst comes to worst.

vegardkv avatar Mar 19 '25 11:03 vegardkv

@hkfb any chance this could be prioritized? We have several reports on it from users .

HansKallekleiv avatar Apr 10 '25 10:04 HansKallekleiv

Would you consider trying the MapLayer instead? Any issues you might find with it will likely affect also us, so it's easier to justify prioritizing that.

hkfb avatar Apr 25 '25 05:04 hkfb

Yes, got an hint that this was an alternative. At first glance, this seems to work quite well (https://github.com/AudunSektnanNR/webviz-subsurface-as/pull/70). Will report back if we run into any issues layer, otherwise, I think we will just stick to MapLayer, since I don't think we lose anything by switching.

vegardkv avatar Apr 25 '25 06:04 vegardkv

Please let us know how it works out. If no-one uses the Colormap and Hillshading layers and the MapLayer works sufficiently well as a replacement, then I would like to deprecate those. @HansKallekleiv

hkfb avatar Apr 25 '25 09:04 hkfb

Please let us know how it works out

Will do!

vegardkv avatar Apr 25 '25 10:04 vegardkv

We are still using the ColorMapLayer in our new application due to performance. When it comes to fast visualization of many surfaces in a 2d only setting the Colormap is significantly faster than the MapLayer. I much prefer the Maplayer visualization though, so perhaps we should revisit this. Look for any potential performance gains, etc.

HansKallekleiv avatar May 07 '25 18:05 HansKallekleiv

Agree, it would be great to identify where the MapLayer bottlenecks are. Should we create a new issue for that? And close this issue? @vegardkv @HansKallekleiv

hkfb avatar May 16 '25 07:05 hkfb

ColormapLayer is an extension of Deck.gl BitmapLayer. In short, it displays a rectangle (actually renders 2 triangles) with a texture. It will always have a "flat" geometry, even in 3D. It is really a "map", as a projection on a flat surface. It can not give a "sense" of the geometry.

Image

Note that the Hillshading2DLayer rendered on top of a colormap layer with some transparency is designed to add some shadowing to give the feeling of 3D. But the result in 3D is quite poor:

Image

The MapLayer (which is a very misleading name) can be imagined as an "extruded colormap layer", in the sense that it has a Z value for each texture pixel. Imagine a 2D regular grid, where each cell represents a texture pixel. Each cell has a color and each node has a Z value. It gets rendered as a 3D geometry: each cell is rendered as 2 triangles with X, Y and Z coordinates. This is consuming way more graphic resources.

Image

Here a closeup, with the cell lines to show each individual cell:

Image

w1nklr avatar May 16 '25 08:05 w1nklr

ColormapLayer is an extension of Deck.gl BitmapLayer. In short, it displays a rectangle (actually renders 2 triangles) with a texture. It will always have a "flat" geometry, even in 3D. It is really a "map", as a projection on a flat surface. It can not give a "sense" of the geometry.

@w1nklr @nilscb It should be fairly easy to emulate the ColormapLayer using the MapLayer with only two triangles. We can make the vertical extrusion optional for strictly 2D use cases (in fact I think it already is if you only supply a property map?). This allows us to skip triangulation and normals calculation. The edge of the map can be filtered in the fragment shader. Downside is we lose the hill shading.

But it would be good to assess first what are the most significant bottlenecks.

hkfb avatar May 16 '25 09:05 hkfb

Isn't it better to enhance the colormap layer a bit. It is used and highly effective. Possible enhancments:

  • Merge hillshading and colormap layer into one to ease usage.
  • Add colormap clamp-color similar to MapLayer.
  • Add contourlines as an option to the hill shading,

Image

nilscb avatar May 19 '25 10:05 nilscb

I have no strong preference if it is a faster MapLayer or an improved ColorMapLayer. Having contour lines in an efficient 2D visualization would be nice!

HansKallekleiv avatar May 22 '25 16:05 HansKallekleiv

Added a few more properties to colormap layer. See new story under HillshadingLayer folder. This will allow contour lines and hillshading directly in colormap.

Also added option to set clamp color. The previous behavior would clamp to colormap min and max value. This will give the option to clamp to a given fixed color. (or transparent)

New properties:

// If true, draw contour lines.  Default false.
contours: boolean;

// If true, apply hillshading. Default false.
hillshading: boolean;

// Contour reference height. Default 0.
contourReferencePoint: number;

// Height between contour lines. Default 50.
contourInterval: number;

/**  Clamp colormap to this color at ends.
 * Given as array of three values (r,g,b) e.g: [255, 0, 0]
 * If not set or set to true, it will clamp to color map min and max values.
 * If set to false the clamp color will be completely transparent.
 */
colorMapClampColor: Color | undefined | boolean;

// Optional height map. If set hillshading and contourlines will be based on this map.
heightMapUrl: string;

// Min and max values of optional height map.
// Defaults to "valueRange".
heightValueRange: [number, number];

nilscb avatar May 30 '25 08:05 nilscb