【问题标题】:OpenGL - rendering a textured teapot - .obj faces and normalsOpenGL - 渲染一个带纹理的茶壶 - .obj 面和法线
【发布时间】:2015-07-29 07:48:12
【问题描述】:

我有一个只有 vf 参数的 .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?

【问题讨论】:

    标签: python opengl texturing


    【解决方案1】:

    可能您的面顶点的缠绕方向不一致,导致一些法线指向内部,从而打乱了您的照明计算。理想情况下,模型文件中的数据具有正确定向的面,但您可以从种子面开始重新定向面并从那里开始工作。此问题已在此处讨论:How to unify normal orientation

    快速解决方法是实现双面照明模式;本质上,如果基元背面朝… * !gl_FrontFacing ? -1 : 1,则在钳制为正值之前,您会否定照明点积的结果。

    至于纹理坐标生成:从技术上讲,您可以实现一个立方体贴图纹理坐标映射,它使用一张图片用于立方体的所有 6 个面,并使用顶点位置作为纹理坐标。或者您只需将相同的图像加载到立方体贴图的 6 个子图像中,然后直接使用位置属性作为纹理查找的坐标。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2013-12-27
      • 2013-09-28
      • 2014-08-09
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多