2016-11-07 8 views
1

В настоящее время я использую OpenGL (точнее, через привязки VisPy) для визуализации некоторых научных данных. У меня объемный набор данных, и я хотел бы визуализировать некоторые изоповерхности, присутствующие внутри него. Я генерирую изоповерхности, используя встроенный алгоритм маршевых кубов в библиотеке skimage.measure Python.Визуализация изоповерхности, сгенерированной с помощью маршевых кубов

Итак, у меня есть набор вершин, и у меня есть набор индексов, которые определяют триангуляцию сетки как вывод на skimage.measure.marching_cubes. Они могут быть напрямую преобразованы в VertexBuffer и IndexBuffer объектов для рендеринга. Но каков правильный способ нанесения текстуры на изоповерхность? Мне не нужно делать ничего необычного, в основном только какого-то цвета, чтобы его можно было визуализировать более четко.

По существу, вот моя точка смущения. Координаты вершин определяются на поле [0,2] x [0,2] x [0, 1], так как мой объем в два раза длиннее в x и y, как и в z. Координаты текстуры всегда определяются на кубе [0,1] x [0,1] x [0, 1], если мое понимание верное. Я пытаюсь создать простую объемную текстуру, преобразовывая координаты вершин в координаты текстуры, деля компоненты x и y на два, а затем используя эти координаты в объемной текстуре как texcoord. Но это не работает (см. Прикрепленное изображение). Вот код:

Vertex Shader:

uniform mat4 u_model; 
uniform mat4 u_view; 
uniform mat4 u_projection; 
attribute vec3 a_position; 
attribute vec3 a_texcoord; 
varying vec3 v_texcoord; 
void main() { 
    gl_Position = u_projection * u_view * u_model * vec4(a_position, 1.0); 
    v_texcoord = a_texcoord; 
} 

Фрагмент Shader:

uniform sampler3D u_texture; 
varying vec3 v_texcoord; 
void main() { 
    float r = texture3D(u_texture, v_texcoord).r; 
    float g = texture3D(u_texture, v_texcoord).g; 
    float b = texture3D(u_texture, v_texcoord).b; 
    gl_FragColor = vec4(r, g, b, 1); 
} 

3D-текстуры в настоящее время устанавливается в следующем. Обратите внимание, что эта текстура не должна означать так много; Я просто пытаюсь поместить градиент в разные стороны и поиграть с настройками, чтобы я мог видеть разницу в выходе. Изменение этой текстуры не влияет на то, что я вижу.

D, H, W = 64, 128, 128 
texture_arr = np.ones((W, H, D, 4)).astype(np.float32) 
texture_arr[...] *= np.linspace(0, 1, W)[:, np.newaxis, np.newaxis, np.newaxis] 
texture_arr[...] *= np.linspace(0, 1, H)[np.newaxis, :, np.newaxis, np.newaxis] 
texture_arr[...] *= np.linspace(0, 1, D)[np.newaxis, np.newaxis, :, np.newaxis] 

VertexBuffer и IndexBuffer точно в качестве вывода по алгоритму марширующих кубов. Как описано выше, texcoord представляет собой просто координату вершин с координатами x и y, разделенными на два.

Вот скриншот того, что я вижу, который имеет правильную форму изоповерхности, но текстурирован ужасно неправильно.

A horribly textured isosurface.

ответ

0

gl_FragColor устарела, так как OpenGL 3.0, вы используете более старую или новую версию OpenGL? Возможно, вы можете попробовать этот шейдер фрагмента.

uniform sampler3D u_texture; 
varying vec3 v_texcoord; 
out vec4 FragColor;  
void main() 
{ 
    FragColor = vec4(texture(u_texture, v_texcoord), 1); 
}