我需要你的帮助。使用python,我必须通过phong模型实现三维形状的照明。我的身材是一个三角形的二十面体。我能够构建这个形状,找到顶点的坐标,并计算每个面的法线
我使用了pygame,pyopengl
为了实现phong照明模型,我成功地创建了环境照明和漫反射照明,但我不知道镜面反射照明使用什么功能
我试着用不同的参数应用函数,比如glMaterialfv(),但没有成功
这是我的密码:
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
verticies = (
(0, - 0, 1.15894198417663574),
(0.63384598493576048, -0.63384598493576048, 0.63384598493576048),
(0.81949597597122192, 0, 0.81949597597122192),
(1.15894198417663574, 0, -0),
(0.81949597597122192, 0.81949597597122192, -0),
(0.81949597597122192, 0, -0.81949597597122192),
(0.63384598493576048, 0.63384598493576048, 0.63384598493576048),
(0.81949597597122192, -0.81949597597122192, 0),
(-0, 0.81949597597122192, 0.81949597597122192),
(-0.81949597597122192, 0, 0.81949597597122192),
(0.63384598493576048, 0.63384598493576048, -0.63384598493576048),
(0, 0, -1.15894198417663574),
(0, -0.81949597597122192, -0.81949597597122192),
(-0.81949597597122192, 0, -0.81949597597122192),
(0, 0.81949597597122192, -0.81949597597122192),
(0.63384598493576048, -0.63384598493576048, -0.63384598493576048),
(-0, 1.15894198417663574, 0),
(-0.81949597597122192, 0.81949597597122192, 0),
(-1.15894198417663574, 0, 0),
(-0.63384598493576048, 0.63384598493576048, 0.63384598493576048),
(0, -1.15894198417663574, 0),
(-0.81949597597122192, -0.81949597597122192, 0),
(0, -0.81949597597122192, 0.81949597597122192),
(-0.63384598493576048, -0.63384598493576048, 0.63384598493576048),
(-0.63384598493576048, 0.63384598493576048, -0.63384598493576048),
(-0.63384598493576048, -0.63384598493576048, -0.63384598493576048),
)
surfaces = (
(20, 21, 25, 12),
(21, 25, 13, 18),
(17, 24, 14, 16),
(18, 13, 24, 17),
(16, 14, 10, 4),
(3, 5, 15, 7),
(0, 2, 6, 8),
(0, 2, 1, 22),
(0, 22, 23, 9),
(0, 9, 19, 8),
(13, 11, 12, 25),
(11, 13, 24, 14),
(11, 14, 10, 5),
(11, 5, 15, 12),
(3, 5, 10, 4),
(17, 18, 9, 19),
(17, 19, 8, 16),
(16, 8, 6, 4),
(3, 2, 6, 4),
(3, 2, 1, 7),
(7, 1, 22, 20),
(20, 21, 23, 22),
(9, 23, 21, 18),
(15, 7, 20, 12),
)
normals = [
(-0.35740624923526854, -0.8628558767968414, -0.3574080425574267),
(-0.8628548655932644, -0.3574083665235253, -0.3574083665235253),
(-0.3574083665235253, 0.8628548655932644, -0.3574083665235253),
(-0.8628558767968414, 0.3574080425574267, -0.35740624923526854),
(0.3574080425574267, 0.8628558767968414, -0.35740624923526854),
(0.8628558767968414, -0.3574080425574267, -0.35740624923526854),
(0.35740624923526854, 0.3574080425574267, 0.8628558767968414),
(0.35740624923526854, -0.3574080425574267, 0.8628558767968414),
(-0.3574080425574267, -0.35740624923526854, 0.8628558767968414),
(-0.35740624923526854, 0.3574080425574267, 0.8628558767968414),
(-0.35740647831364963, -0.35740647831364963, -0.8628564298415289),
(-0.35740624923526854, 0.3574080425574267, -0.8628558767968414),
(0.3574080425574267, 0.35740624923526854, -0.8628558767968414),
(0.35740624923526854, -0.3574080425574267, -0.8628558767968414),
(0.8628558767968414, 0.3574080425574267, -0.35740624923526854),
(-0.8628564298415289, 0.35740647831364963, 0.35740647831364963),
(-0.3574083665235253, 0.8628548655932644, 0.3574083665235253),
(0.3574080425574267, 0.8628558767968414, 0.35740624923526854),
(0.8628558767968414, 0.3574080425574267, 0.35740624923526854),
(0.8628558767968414, -0.3574080425574267, 0.35740624923526854),
(0.3574083665235253, -0.8628548655932644, 0.3574083665235253),
(-0.35740624923526854, -0.8628558767968414, 0.3574080425574267),
(-0.8628548655932644, -0.3574083665235253, 0.3574083665235253),
(0.35740624923526854, -0.8628558767968414, -0.3574080425574267)
]
colors = (
(1,1,1),
(0,1,0),
(0,0,1),
(0,1,0),
(0,0,1),
(1,0,1),
(0,1,0),
(1,0,1),
(0,1,0),
(0,0,1),
)
edges = (
(16, 17),
(17, 18),
(18, 21),
(20, 21),
(3, 4),
(4, 16),
(7, 3),
(20, 7),
(0, 2),
(0, 9),
(0, 22),
(0, 8),
(11, 13),
(11, 12),
(11, 14),
(2, 3),
(8, 16),
(9, 18),
(22, 20),
(2, 1),
(1, 22),
(1, 7),
(5, 11),
(5, 15),
(15, 12),
(15, 7),
(5, 3),
(12, 20),
(16, 14),
(22, 23),
(23, 9),
(23, 21),
(13, 24),
(14, 24),
(17, 24),
(13, 25),
(12, 25),
(25, 21),
(13, 18),
(8, 6),
(2, 6),
(6, 4),
(10, 4),
(14, 10),
(5, 10),
(17, 19),
(19, 9),
(19, 8),
)
def Cube():
glBegin(GL_QUADS)
for i_surface, surface in enumerate(surfaces):
x = 0
glNormal3fv(normals[i_surface])
for vertex in surface:
#x+=1
glColor3fv(colors[x])
glVertex3fv(verticies[vertex])
glEnd()
glColor3fv(colors[0])
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
glEnd()
def main():
global surfaces
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
clock = pygame.time.Clock()
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0, 0, -5)
# Источник света - "от нас"
glLight(GL_LIGHT0, GL_POSITION, (0, 0, 1, 0.4))
# Ambient lighting
glLightfv(GL_LIGHT0, GL_AMBIENT, (0, 0, 0, 1))
# Diffuse lighting
glLightfv(GL_LIGHT0, GL_DIFFUSE, (0, 0.5, 0.1, 0))
#---------------------------------Specular Lighting------------It does not work!!!-----------
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (1,1,1,0))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128)
#--------------------------------------------------------------------------------------------
glEnable(GL_DEPTH_TEST)
while True:
# Обрабатываем события
for event in pygame.event.get():
# Если нажимаем крестик на окошке - выходим
if event.type == pygame.QUIT:
pygame.quit()
quit()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE )
#glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
glRotatef(10, 0, 1, 0)
elif keys[pygame.K_RIGHT]:
glRotatef(-10, 0, 1, 0)
elif keys[pygame.K_UP]:
glRotatef(10, 1, 0, 0)
elif keys[pygame.K_DOWN]:
glRotatef(-10, 1, 0, 0)
Cube()
glDisable(GL_LIGHT0)
glDisable(GL_LIGHTING)
glDisable(GL_COLOR_MATERIAL)
pygame.display.flip()
clock.tick(20)
if __name__ == '__main__':
main()
代码中的所有内容都是正确的。使用传统的OpenGL固定功能管道,这是您可以获得的最佳结果。
固定函数管道使用Blinn–Phong reflection model。但是,使用了Gouraud Shading而不是Phong Shading。Phong着色通常是指每个片段进行灯光计算的技术,而在Gouraud着色中,灯光计算是每个顶点进行的。计算出的光沿(三角形)Primitives插值。
在镜面反射高光的情况下,灯光分布不是线性的,无法使用线性插值进行计算。效果被扭曲或完全消失。
见what the difference between phong shading and gouraud shading?和OpenGL Lighting on texture plane is not working
通过将网格细分为小三角形,可以改善照明效果。这会导致为更多点(顶点)计算灯光,而插值的效果较小
现在,光照是按片段计算的(Phong着色)。为此,您需要实现一个Shader程序。见GLSL fixed function fragment program replacement
详细描述这一点对于单个堆栈溢出的回答来说太宽泛了。我建议阅读一本好的OpenGL教程。例如:Python Opengl(我最喜欢的是C++ +{a10})。
要为特定的遗留代码实现Phong着色,需要编写version 1.10 GLSL着色器。有关一个很好的示例,请参见Per Fragment Lighting。您需要对着色器程序进行一些调整,以使颜色材质正常工作
顶点着色器
片段着色器
使用PyOpenGLs^{} 模块编译并链接着色器:
在绘制多边形之前安装着色器并启用照明,在绘制线框之前禁用is。e、 g:
完整示例:
相关问题 更多 >
编程相关推荐