Visualising sub-surface geology for geothermal planning

The task was to help planners determine the best location for a geothermal energy plant. The best location is determined by named underground potential sand layers at certain depths.

From the scientist, we have models laying out a topographic surface for known sand layers. These are available as 2D map services using pixel brightness as depth indicator.

The approach was to translate the 2D maps into points using html5 canvas and threejs.

Here is the result: (in Danish)

The location can be zoomed and navigated using the interactive map. Profiles can be drawn on the interactive map to highlight certain paths in the 3D space. Various controls in the bottom left are used to examine depth.


Hello Bjarni. I really like your subsurface viewer. I have some similar ideas that i would like use.
what is your input data for your surface points/pointclouds? xyz? heightmap? are you loading a file for each surface?


Thanks for the interest. I’m hooking into a 2D map with grayscale layers loaded. The layers visualize depth by color, so in effect you have a z-value for each pixel. Then, it’s just a question of turning these pixels into a point cloud.

Does it mean that you’re computing the position of each point on javascript side?

Yes, exactly. You can watch the layers loading in the browser network info (F12).

Using of heightmaps, as @pacsiah mentioned, would be more efficient.
Take a look at this example: How to implement heatmap?
It takes a grayscale texture (it uses r-channel though) in the uniform and apply its values in vertex shader for y-values of points.

Possibly true. I don’t understand much from the link… And not sure the 2D map can read heightmaps which is key to my implementation. The 2D map is both an essential part of the UI and an effective way of minimizing the data load between server and client.

Imagine, that grayscale texture at the top-left corner is your loaded grayscale layer. So simply pass is in the uniform of vertex shader:

  uniforms: {
    heightMap: {value: heightMap}, 
    heightRatio: {value: 10},
    heightBias: {value: 0}

Play with gui controls and see how reactive the point cloud is.


Wow, yes, that’s impressive. So, if I have a png in a canvas, I can just load it like this. Nice. Will try it out. Thanks.