1

I have a simple OpenGL code, using glumpy in python, to plot an interpolated 2D array:

enter image description here

I would like to plot a 3D interpolated array, in the following way: slice it into 10 (say) planes perpendicular to the viewer and adding transparency so as to give the impression of depth.

To start with, I would like to plot my 2D array above, but as a slice into a 3D cube, like I drew below.

enter image description here

How would I even start doing this?


MWE:

import numpy as np
from PIL import Image
from glumpy import app, gl, gloo, data, library
from glumpy.geometry import primitives
from glumpy.transforms import Trackball

vertex = """
#include "misc/spatial-filters.frag"
uniform sampler2D data;
uniform vec2 data_shape;
attribute vec3 position;
attribute vec2 texcoord;
varying float zz;
void main()
{
    float z = Bicubic(data, data_shape, texcoord).x;
    zz = z;
    gl_Position = <transform>;
}
"""

fragment = """
#include "misc/spatial-filters.frag"
#include "colormaps/colormaps.glsl"
varying float zz;

void main()
{
    vec4 col = vec4(colormap_icefire(zz),1);
    gl_FragColor = col;

} """

def func3(x,y,t):
    return np.exp(-10*(x-0.5*np.cos(t))**2-10*(y-0.5*np.sin(t))**2)

x = np.linspace(-2.0, 2.0, 64).astype(np.float32)
y = np.linspace(-2.0, 2.0, 64).astype(np.float32)
X,Y = np.meshgrid(x, y)
Z = func3(X,Y,0)

window = app.Window(width=1200, height=800, color = (1,1,1,1))

@window.event
def on_draw(dt):

    window.clear()

    surface['data'] = Z 

    surface.draw(gl.GL_TRIANGLES, s_indices)

n = 100
surface = gloo.Program(vertex, fragment)
vertices, s_indices = primitives.plane(2.0, n=n)
surface.bind(vertices)

surface['data_shape'] = Z.shape[1], Z.shape[0]

surface['u_kernel'] = data.get("spatial-filters.npy")
surface['u_kernel'].interpolation = gl.GL_LINEAR

transform = Trackball("vec4(position.xy, 0, 1.0)")
surface['transform'] = transform
window.attach(transform)

app.run()
SuperCiocia
  • 1,823
  • 6
  • 23
  • 40
  • I'm not entirely sure how this "slice" looks, are you simply projecting/spraypainting it onto the isometric view, which then gives an "elevation" for the center of the texture? In such way that looking along the isometric it looks like the original texture and rotating the cube will reveal that the middle corner is protuded? This sounds more complicated than it needs to be, my first instinct would be to build a surface or array of rectangular prisms, which the height is represented by your data, with constant width/length for the grid. – Mudkip Hacker Mar 23 '21 at 04:59
  • 1
    Well I have a 3D array and need to visualise the function that it displays. As a start I would like to be able to choose a plane through my cube, interpolate my 3D function on that plane, and plot it. – SuperCiocia Mar 23 '21 at 05:14
  • I don't have knowledge about this particular library. But here's what I do to get familiarity with drawing related problems. First I would try do draw a simple cube and play with it. How will I position it? how should it be rotated? Next, given the coordinates in the interior of the cube, how can I map it to my function? Finally I would wrap my head around the opacity factor issue. By your description maybe you're trying to acquire a Volume Rendering of a simple 3D function. I would look-up tutorials around this technique. – lfn Mar 24 '21 at 15:28

0 Answers0