Skip to content

Commit 28e269b

Browse files
committed
Resolve conflicts.
1 parent eabe2a2 commit 28e269b

File tree

3 files changed

+122
-10
lines changed

3 files changed

+122
-10
lines changed

typescript/packages/subsurface-viewer/src/layers/colormap/colormap.fs.glsl.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ in vec2 vTexCoord;
88
out vec4 fragColor;
99
1010
uniform sampler2D bitmapTexture; // Property map
11-
uniform sampler2D colormap;
11+
uniform sampler2D colormapTexture;
12+
uniform sampler2D heightMapTexture; // Height map texture, if defined.
1213
1314
// Compute the normal value for every pixel, based on the current value and two values aroud it.
1415
vec3 normal(float val) {
@@ -17,8 +18,17 @@ vec3 normal(float val) {
1718
float valueRangeSize = map.valueRangeMax - map.valueRangeMin;
1819
float p0 = valueRangeSize * val;
1920
20-
float px = valueRangeSize * decode_rgb2float(texture(bitmapTexture, vTexCoord + vec2(1.0, 0.0) / map.bitmapResolution).rgb);
21-
float py = valueRangeSize * decode_rgb2float(texture(bitmapTexture, vTexCoord + vec2(0.0, 1.0) / map.bitmapResolution).rgb);
21+
float px = valueRangeSize;
22+
float py = valueRangeSize;
23+
if (map.isHeightMapTextureDefined) {
24+
px *= decode_rgb2float(texture(heightMapTexture, vTexCoord + vec2(1.0, 0.0) / map.bitmapResolution).rgb);
25+
py *= decode_rgb2float(texture(heightMapTexture, vTexCoord + vec2(0.0, 1.0) / map.bitmapResolution).rgb);
26+
}
27+
else {
28+
px *= decode_rgb2float(texture(bitmapTexture, vTexCoord + vec2(1.0, 0.0) / map.bitmapResolution).rgb);
29+
py *= decode_rgb2float(texture(bitmapTexture, vTexCoord + vec2(0.0, 1.0) / map.bitmapResolution).rgb);
30+
}
31+
2232
vec3 dx = vec3(1.0, 0.0, px - p0);
2333
vec3 dy = vec3(0.0, 1.0, py - p0);
2434
@@ -64,11 +74,11 @@ void main(void) {
6474
x = max(0.0, x);
6575
x = min(1.0, x);
6676
67-
color = texture(colormap, vec2(x, 0.5));
77+
color = texture(colormapTexture, vec2(x, 0.5));
6878
}
6979
}
7080
else {
71-
color = texture(colormap, vec2(x, 0.5));
81+
color = texture(colormapTexture, vec2(x, 0.5));
7282
}
7383
fragColor = vec4(color.rgb, color.a * bitmapColor.a * layer.opacity);
7484
@@ -83,6 +93,16 @@ void main(void) {
8393
8494
// Contour lines.
8595
if (map.contours) {
96+
vec4 texture_val;
97+
if (map.isHeightMapTextureDefined) {
98+
texture_val = texture(heightMapTexture, vTexCoord);
99+
}
100+
else {
101+
texture_val = texture(bitmapTexture, vTexCoord);
102+
}
103+
float val = decode_rgb2float(texture_val.rgb);
104+
float property = val * (map.valueRangeMax - map.valueRangeMin) + map.valueRangeMin;
105+
86106
float x = (property - map.contourReferencePoint) / map.contourInterval;
87107
float f = fract(x);
88108
float df = fwidth(x);

typescript/packages/subsurface-viewer/src/layers/colormap/colormapLayer.ts

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { LayerProps, PickingInfo } from "@deck.gl/core";
2-
import { project32 } from "@deck.gl/core";
31
import type { BitmapLayerPickingInfo, BitmapLayerProps } from "@deck.gl/layers";
42
import { BitmapLayer } from "@deck.gl/layers";
3+
import type { colorTablesArray } from "@emerson-eps/color-tables/";
4+
import { getRgbData } from "@emerson-eps/color-tables";
55
import type { Color, LayerProps, PickingInfo } from "@deck.gl/core";
66
import { project32 } from "@deck.gl/core";
77
import type {
@@ -18,6 +18,7 @@ import type { ContinuousLegendDataType } from "../../components/ColorLegend";
1818
import type { ShaderModule } from "@luma.gl/shadertools";
1919
import type { Model } from "@luma.gl/engine";
2020
import type { Texture } from "@luma.gl/core";
21+
import * as png from "@vivaxy/png";
2122

2223
function getImageData(
2324
colorMapName: string,
@@ -108,6 +109,10 @@ export interface ColormapLayerProps
108109
*/
109110
colorMapClampColor: Color | undefined | boolean;
110111

112+
// If set will calculate contour lines and hillshading based on this map instead.
113+
// Default undfined.
114+
heightMapUrl: string;
115+
111116
// Non public properties:
112117
reportBoundingBox?: React.Dispatch<ReportBoundingBoxAction>;
113118
}
@@ -133,9 +138,70 @@ const defaultProps = {
133138
hillshading: false,
134139
contourReferencePoint: 0,
135140
contourInterval: 50, // 50 meter by default
141+
142+
propertiesUrl: "",
136143
};
137144

138145
export default class ColormapLayer extends BitmapLayer<ColormapLayerProps> {
146+
initializeState(): void {
147+
super.initializeState();
148+
149+
const createPropertyTexture = async () => {
150+
const response = await fetch(this.props.heightMapUrl);
151+
if (!response.ok) {
152+
console.error("Could not load ", this.props.heightMapUrl);
153+
} else {
154+
const blob = await response.blob();
155+
const contentType = response.headers.get("content-type");
156+
const isPng = contentType === "image/png";
157+
if (isPng) {
158+
const heightMapTexture = await new Promise((resolve) => {
159+
const fileReader = new FileReader();
160+
fileReader.readAsArrayBuffer(blob);
161+
fileReader.onload = () => {
162+
const arrayBuffer = fileReader.result;
163+
const imgData = png.decode(
164+
arrayBuffer as ArrayBuffer
165+
);
166+
const w = imgData.width;
167+
const h = imgData.height;
168+
169+
console.log("png metadata", w, h);
170+
const data = imgData.data; // array of int's
171+
const n = data.length;
172+
const buffer = new ArrayBuffer(n);
173+
const view = new DataView(buffer);
174+
for (let i = 0; i < n; i++) {
175+
view.setUint8(i, data[i]);
176+
}
177+
178+
const array = new Uint8Array(buffer);
179+
const propertyTexture =
180+
this.context.device.createTexture({
181+
sampler: {
182+
addressModeU: "clamp-to-edge",
183+
addressModeV: "clamp-to-edge",
184+
minFilter: "linear",
185+
magFilter: "linear",
186+
},
187+
width: w,
188+
height: h,
189+
format: "rgba8unorm",
190+
data: array as Uint8Array,
191+
});
192+
resolve(propertyTexture);
193+
};
194+
});
195+
this.setState({
196+
...this.state,
197+
heightMapTexture,
198+
});
199+
}
200+
}
201+
};
202+
createPropertyTexture();
203+
}
204+
139205
setShaderModuleProps(
140206
...props: Parameters<Model["shaderInputs"]["setProps"]>
141207
): void {
@@ -181,7 +247,7 @@ export default class ColormapLayer extends BitmapLayer<ColormapLayerProps> {
181247
const colorMapRangeMin = this.props.colorMapRange?.[0] ?? valueRangeMin;
182248
const colorMapRangeMax = this.props.colorMapRange?.[1] ?? valueRangeMax;
183249

184-
const colormap = this.context.device.createTexture({
250+
const colormapTexture = this.context.device.createTexture({
185251
width: 256,
186252
height: 1,
187253
format: "rgb8unorm-webgl",
@@ -192,7 +258,29 @@ export default class ColormapLayer extends BitmapLayer<ColormapLayerProps> {
192258
),
193259
});
194260

195-
this.state.model?.setBindings({ colormap });
261+
// eslint-disable-next-line
262+
// @ts-ignore
263+
let heightMapTexture = this.state.heightMapTexture;
264+
const isHeightMapTextureDefined =
265+
typeof heightMapTexture !== "undefined";
266+
267+
if (!isHeightMapTextureDefined) {
268+
// Create a dummy texture
269+
heightMapTexture = this.context.device.createTexture({
270+
sampler: {
271+
addressModeU: "clamp-to-edge",
272+
addressModeV: "clamp-to-edge",
273+
minFilter: "linear",
274+
magFilter: "linear",
275+
},
276+
width: 1,
277+
height: 1,
278+
format: "rgba8unorm",
279+
data: new Uint8Array([1, 1, 1, 1]),
280+
});
281+
}
282+
283+
this.state.model?.setBindings({ colormapTexture, heightMapTexture });
196284

197285
const bitmapResolution = this.props.image
198286
? [
@@ -236,6 +324,7 @@ export default class ColormapLayer extends BitmapLayer<ColormapLayerProps> {
236324
isClampColor,
237325
colorMapClampColor,
238326
isColorMapClampColorTransparent,
327+
isHeightMapTextureDefined,
239328
rgbScaler: this.props.valueDecoder.rgbScaler,
240329
floatScaler: this.props.valueDecoder.floatScaler,
241330
offset: this.props.valueDecoder.offset,
@@ -320,6 +409,7 @@ uniform mapUniforms {
320409
bool isClampColor;
321410
vec3 colorMapClampColor;
322411
bool isColorMapClampColorTransparent;
412+
bool isHeightMapTextureDefined;
323413
vec3 rgbScaler; // r, g and b multipliers
324414
float floatScaler; // value multiplier
325415
float offset; // translation of the r, g, b sum
@@ -352,6 +442,7 @@ type Map2DUniformsType = {
352442
isClampColor: boolean;
353443
colorMapClampColor: [number, number, number];
354444
isColorMapClampColorTransparent: boolean;
445+
isHeightMapTextureDefined: boolean;
355446
rgbScaler: [number, number, number];
356447
floatScaler: number;
357448
offset: number;
@@ -376,6 +467,7 @@ const map2DUniforms = {
376467
isClampColor: "u32",
377468
colorMapClampColor: "vec3<f32>",
378469
isColorMapClampColorTransparent: "u32",
470+
isHeightMapTextureDefined: "u32",
379471
rgbScaler: "vec3<f32>",
380472
floatScaler: "f32",
381473
offset: "f32",

typescript/packages/subsurface-viewer/src/storybook/layers/MapLayer.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ const ColorMapLayerComponent: React.FC<{
273273
{
274274
"@@type": "ColormapLayer",
275275
image: "propertyMap.png",
276-
propertiesUrl: "propertyMap.png",
276+
heightMapUrl: "propertyMap.png",
277277
rotDeg: args.rotDeg,
278278
bounds: [432205, 6475078, 437720, 6481113],
279279

0 commit comments

Comments
 (0)