2015-09-11 3 views
0

Я рисую данные о береговой линии на сфере, используя интерфейс vispy для OpenGL ES 2.0. Я использую значения широты и долготы, чтобы выработать 3d-координаты для данных на сфере и просто строить их. Я могу успешно нарисовать данные, но я хотел видеть только те точки данных на стороне сферы, которые будут видны из окна просмотра.Самолет через центр сфера единицы смещается в OpenGL ES 2.0

Я попытался использовать два совершенно разных подхода для создания этого эффекта, но оба они привели к одной и той же проблеме. Во-первых, я вычислил точечный продукт направления представления и положения данных и привлек только те, у кого есть отрицательный результат (т. Е. Только те точки, которые смотрят на окно просмотра), и, во-вторых, я просто нарисовал плоскость через центр сферы, перпендикулярный направление просмотра.

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

Я проверил, что точки, которые я рисую, на самом деле находятся на единичной сфере, и я уверен, что с точки зрения 3D-мира все звучит. То, чем я менее уверенно отношусь, как относительный новичок к 3D-графике, заключается в том, что я что-то недопонимаю с матрицей проекции. Я сделал некоторое чтение, но мое понимание заставляет меня думать, что проекция не должна изменять порядок точек в направлении «Z» (направление, на которое смотрит видоискатель).

Я уверен, что это не является проблемой глубинного теста, так как мой первый подход не включал проверку глубины и маскирование выполнялось в вершинном шейдере (путем установки цвета фрагмента альфа в 0.0). Помимо этого, я не смог найти другого объяснения проблемы.

Вот код для плоского подхода:

import numpy as np 
import cartopy 
from vispy import app 
from vispy import gloo 
import time 
from vispy.util.transforms import perspective, translate, rotate 

xpts = [] 
ypts = [] 

#getting coastlines data 

for string in cartopy.feature.NaturalEarthFeature('physical', 'coastline', '10m').geometries(): 
    for line in string: 
     points = list(line.coords) 
     for point in points: 
      xpts.append(point[0]) 
      ypts.append(point[1]) 

coasts = np.array(zip(xpts,ypts), dtype=np.float32) 

theta = (np.pi/180)*np.array(xpts, dtype=np.float32) 
phi = (np.pi/180)*np.array(ypts, dtype=np.float32) 

x3d = np.cos(phi)*np.cos(theta) 
y3d = np.sin(theta)*np.cos(phi) 
z3d = np.sin(phi) 



vertex = """ 
// Uniforms 
uniform mat4 u_model; 
uniform mat4 u_view; 
uniform mat4 u_projection; 
uniform vec3 u_color; 

attribute vec3 a_position; 
void main (void) 
{ 
    gl_Position = u_projection*u_view*u_model*vec4(a_position, 1.0); 
} 
""" 

fragment = """ 
// Uniforms 
uniform vec3 u_color; 

void main() 
{ 
    gl_FragColor = vec4(u_color, 1.0); 
} 
""" 

class Canvas(app.Canvas): 
    def __init__(self): 
     app.Canvas.__init__(self, keys='interactive') 

     gloo.set_state(clear_color = 'red', depth_test=True, blend=True, blend_func=('src_alpha', 'one_minus_src_alpha')) 

     self.x = 0 

     self.plane = 5*np.array([(0.,-1., -1.,1), (0, -1., +1.,1), (0, +1., -1.,1), (0, +1., +1.,1)], dtype=np.float32) 

     self._timer = app.Timer(connect=self.on_timer, start=True) 
     self.program = gloo.Program(vertex, fragment) 

     self.view = np.dot(rotate(-90, (1, 0, 0)), np.dot(translate((-3, 0, 0)), rotate(-90.0, (0.0,1.0,0.0)))) 
     self.model = np.eye(4, dtype=np.float32) 
     self.projection = perspective(45.0, self.size[0]/float(self.size[1]), 2.0, 10.0) 

     self.program['u_projection'] = self.projection 
     self.program['u_view'] = self.view 
     self.program['u_model'] = self.model 
     self.program['u_color'] = np.array([0.0, 0.0, 0.0], dtype=np.float32) 

     self.program2 = gloo.Program(vertex, fragment) 

     self.program2['u_projection'] = self.projection 
     self.program2['u_view'] = self.view 
     self.program2['u_model'] = self.model 
     self.program2['u_color'] = np.array([1.0, 1.0, 1.0], dtype=np.float32) 

     self.program2['a_position'] = self.plane[:,:3].astype(np.float32) 

    def on_timer(self, event): 
     self.x += 0.05 
     self.model = rotate(self.x, (0.0,0.0,1.0)) 
     pointys = np.concatenate((x3d,y3d,z3d)).reshape((3, -1)).T 
     self.program['a_position'] = pointys 
     self.program['u_model'] = self.model 

     self.update() 


    def on_resize(self, event): 
     gloo.set_viewport(0, 0, *event.size) 
     self.projection = perspective(45.0, event.size[0]/float(event.size[1]), 2.0, 10.0) 
     self.program['u_projection'] = self.projection 
     self.program2['u_projection'] = self.projection 


    def on_draw(self, event): 
     gloo.clear((1,1,1,1)) 
     self.program2.draw('triangle_strip') 
     self.program.draw('points') 

Canvas().show() 
app.run() 

ответ

0

Как я понимаю ваше описание, что вы видите, является результатом перспективной проекции. Я использовал все свои навыки рисования MS, чтобы создать эту очень сложную схему ситуации смотреть со стороны:

Sphere with perspective

Контуры сферы рисуется в черном цвете. Красная линия указывает плоскость через центр сферы.

Синие линии показывают две линии зрения с точки зрения, которая находится внизу диаграммы. Если вы рисуете результат после нанесения проекции, то, что появляется, когда передняя часть сферы в визуализированном изображении находится под зеленой линией. Части сферы над зеленой линией образуют обратную сторону части сферы в полученном рендеринге.

Иными словами, зеленая линия показывает плоскость, соответствующую контуру сферы в полученном рендеринге.

Как вы можете видеть из этого, плоскость, проходящая через центр сферы, действительно находится на некотором расстоянии позади участка сферы, который отображается как лицевая сторона сферы в визуализированном изображении. Это просто характер перспективной проекции. Расстояние между красной плоскостью и зеленой плоскостью будет уменьшаться с меньшим углом обзора (т. Е. Более слабая перспектива), и оба они одинаковы при использовании параллельной проекции.