我有一个只有v和f参数的.obj文件。
我有一个任务,通过将它“封闭”在一个长方体中(由每个轴上的最大和最小顶点定义)来纹理化它,计算它的中心,然后将茶壶顶点的空间坐标与中心坐标相除,这样我就得到了向量以茶壶的中心为起点,以茶壶的表面为终点,然后找到这些向量(射线)与外部长方体表面相交的位置。长方体的每个面都必须模拟一个图像。之后,我必须计算每个顶点的纹理坐标——只需从 3D 交点获取 2D 参数,然后对结果进行归一化,使它们位于 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] 是从 .obj 获取的 v 属性列表,而 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])
其中“norm”是线性代数 NumPy 集中的一个函数。
之后,我创建了一个 VOB 对象:
self.vob = VOB(arrs = [vert, point, normals],indx=self.obj.indx)
简而言之,我使用 VOB 对象将其发送到 GPU。
vert - 从 .obj 获取的顶点列表 point - 以上述方式计算的纹理坐标列表 normals - 使用上述函数计算的法线向量列表 self.obj.indx - 由来自 .obj 的 f 属性组成的列表
我使用的纹理图像:
当我尝试使用经典的 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 )
我可以看到这样的东西:
但是当我使用 Blinn 和 Phong 着色模型时(我会避免全部粘贴,希望有人遇到过类似的问题),它是这样的:
为什么在这两种情况下我都看不到质地良好的茶壶?是不是我必须在获得法线和vt坐标后准备新的f属性才能发送到VOB?