Я рисую данные о береговой линии на сфере, используя интерфейс 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()