2015-05-17 4 views
2

У меня есть файл .obj только с против и F параметров.OpenGL - рендеринг текстурированного чайника - .obj лиц и нормали

У меня есть задача, чтобы текстурировать его, «заключая» его в кубик (определяемый вершинами макс и мин на каждой оси), вычисляя его центр, а затем разделяя пространственные координаты вершин чайника от центральных координат, поэтому что я получаю векторы с началом в центре чайника и конец на его поверхности, а затем, чтобы найти, где эти векторы (лучи) пересекают поверхность внешнего кубоида. Каждая грань кубоида должна имитировать изображение. После этого мне нужно рассчитать, какие координаты текстуры для каждой вершины - просто взяв 2D-параметры из точек 3D-пересечения, а затем нормализуя результаты, чтобы они лежали между 0 и 1 (в двух измерениях).

Итак, я открываю файл .obj с некоторыми правильными строками кода, затем я делаю все описанные вычисления для поиска параметров vt, а затем использую функцию, которая позволяет мне получить NORMALS, используя список индексированных вершин, который сделать треугольники (атрибуты лица) и список вершин.

Похоже, что (она состоит из двух функций в самом деле, в двух разных файлах):

1)

def getNormals4Triangles(self): 

    tind = np.resize(self.indx,(len(self.indx)/3,3)) 
    return VOB.getNormals(self.arrs[0],tind) 

Где self.arrs [0] является список атрибутов v приняты из .obj и tind - список из 3 списков элементов вершин, которые образуют грани.

2)

@staticmethod 
def getNormals(verts,tinds): 
    print("Shape verts: ",verts.shape) 
    print("Shape tinds: ",tinds.shape) 

    if len(verts[0])==3: 
     xyz = verts 
    elif len(verts[0])==4: 
     xyz = verts[:,:3]/np.outer(1/verts[:,3],[1,1,1]) 
    else: 
     raise Exception('No cross product defined') 
    txyz = xyz[tinds,:] 
    txy = txyz[:,2,:]-txyz[:,0,:] 
    txz = txyz[:,1,:]-txyz[:,0,:] 
    nrmls = np.cross(txy,txz) 
    len_nrmls = norm(nrmls,axis=1) 
    return nrmls/np.outer(len_nrmls,[1,1,1]) 

Где "норма" является функцией от линейной алгебры NumPy множества.

После этого я создаю объект VOB:

self.vob = VOB(arrs = [vert, point, normals],indx=self.obj.indx) 

Короче говоря, я посылаю его на GPU с помощью объекта VOB.

верт - список вершин, взятых из .obj точки - список координат текстуры рассчитаны таким образом, описанным выше нормалей - список нормальных векторов, рассчитанных с использованием функций, описанных выше self.obj.indx - список сделано из F атрибутов из .obj

изображения текстуры я использую: texture

Когда я пытаюсь показать его с помощью классических ligthing:

gl.glShadeModel(gl.GL_SMOOTH) 
gl.glEnable(gl.GL_LIGHTING) 
gl.glEnable(gl.GL_LIGHT0) 
gl.glLightModeli(gl.GL_LIGHT_MODEL_TWO_SIDE, 0) 
gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, [4, 4, 4, 1]) 
lA = 0.8 
gl.glLightfv(gl.GL_LIGHT0, gl.GL_AMBIENT, [lA, lA, lA, 1]) 
lD = 1 
gl.glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE, [lD, lD, lD, 1]) 
lS = 1 
gl.glLightfv(gl.GL_LIGHT0, gl.GL_SPECULAR, [lS, lS, lS, 1]) 
gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, [0.9, 0.8, 0.7, 1]) 
gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_DIFFUSE, [0.7, 0.8, 0.9, 1]) 
gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_SPECULAR, [0.9, 0.9, 0.9, 1]) 
gl.glMaterialf(gl.GL_FRONT_AND_BACK, gl.GL_SHININESS, 100) 

я могу увидеть что-то вроде этого: normal lighting

Но когда я использую Blinn и Фонг модель затенения (я уклонюсь склеиванием это все, с надеждой, что, может быть, кто-то встретили подобную проблему) это выглядит следующим образом: blinn i phong

Почему в любой из двух ситуаций я не вижу хорошо текстурированного чайника? Является ли это тем, что мне нужно подготовить новые атрибуты f для отправки в VOB после получения нормалей и координат vt?

ответ

0

Вероятно, направления намотки ваших вершин лица непоследовательны, что приводит к тому, что некоторые нормали, указывающие внутрь, испортили вычисление освещения. В идеале данные в файле модели имеют правильно ориентированные лица, но вы можете переориентировать лица, начиная с посевного лица и работать оттуда. Эта проблема была рассмотрена здесь: How to unify normal orientation

Быстрое исправление заключается в реализации режима двусторонней подсветки; по сути, вы отрицаете результат продукта точки освещения, если примитив обращен назад … * !gl_FrontFacing ? -1 : 1, прежде чем прижимать к положительным значениям.

Что касается формирования координат текстуры: технически вы можете реализовать сопоставление координат текстуры куба, которое использует одно изображение для всех 6 граней куба и использует положения вершин в качестве координаты текстуры. Или вы просто загружаете одно и то же изображение в 6 субизображений куб-карты и используете атрибут position непосредственно в качестве координаты для поиска текстуры.