计算机图形学(OPENGL):材质

计算机图形学(OPENGL):材质,第1张

本文同时发布在我的个人博客上: https://dragon_boy.gitee.io

  在真实世界中,每种物体对灯光的反应都不同,我们在OpenGL中定义不同的材质来模拟不同种类的物体。在OpenGL中,我们可以定义一个材质结构体管理对光照的影响信息(比如Phong模型),例如:

  这里提供一个 网站 ,总结了一些不同物体的材质.

  下面是上面创建的结构体在片元着色器的main方法中的应用(针对Phong模型):

  可以看到,我们通过 来访问结构体的属性,这和C语言类似。虽然我们全局声明了材质结构体,但若是要为材质结构体的属性赋值,我们还是必须逐一赋值:

  运行程序我们会发现场景太亮:

  为解决场景过亮问题,我们可以定义一个灯光结构体:

  灯光结构体中的ambient,diffuse,specular分别代表对各个类型光的强度影响。我们可以这样计算各个光照的效果:

  设置灯光结构体的属性:

  运行结果如下:

  可以看到结果好了很多。通过这种方式,我们就可以通过改变属性来模拟不同的材质在不同灯光下的效果。

这个的话先用glEnable(GL_LIGHT0)开启0号光源,之后设置光源位置,position={x,y,z,w},x,y,z是一个向量,代表方向。x/w,t/w,z/w是位置坐标。w为零时,前面三者趋近无穷大,代表平行光。

之后输入glLightfv(GL_LIGHT0, GL_POSITION, position),这样0号光源位置确定。接下来设置环境光线强度,漫反射光线强度,镜面反射光线强度,都是r,g,b,alpha参数,这个知道怎么设吧。

设定好参数后,输入

glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse)

glMaterialfv(GL_FRONT, GL_SPECULAR, specular)

glMaterialfv(GL_FRONT, GL_EMISSION, emission)

光源设定完成。

材质设定是glMaterialfv(GL_FRONT, XXXXX,XXXXX)和光线类似,第一个XXXX写GL_DIFFUSE,GL_SPECULAR, GL_EMISSION这类的。多出一个shininess,这个是代表镜面指数,越大耗费资源越多,越精细。

呼~打得好累,最后给你编了一个例子。打了这么多字,别忘了采纳。

#include<gl/glut.h>

#include<stdio.h>

void myDisplay()

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

glMatrixMode(GL_PROJECTION)

glLoadIdentity()

gluPerspective(75, 1, 9, 60)

glMatrixMode(GL_MODELVIEW)

glLoadIdentity()

gluLookAt(0, -20, 20, 0, 0, 0, 0, 0, 1)

{

GLfloat light_position[]={0.0f,0.0f,0.0f,1.0f}

GLfloat light_ambient[]={0.0f,0.0f,0.0f,1.0f}

GLfloat light_diffuse[]={1.0f,1.0f,1.0f,1.0f}

GLfloat light_specular[]={1.0f,1.0f,1.0f,1.0f}

glLightfv(GL_LIGHT0,GL_POSITION,light_position)

glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient)

glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse)

glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular)

glEnable(GL_LIGHT0)

glEnable(GL_LIGHTING)

glEnable(GL_DEPTH_TEST)

}

{

GLfloat mat_ambient[]={0.4f,0.4f,0.4f,1.0f}

GLfloat mat_diffuse[]={0.4f,0.4f,0.4f,1.0f}

GLfloat mat_specular[]={0.7f,0.7f,0.7f,1.0f}

GLfloat mat_emission[]={0.0f,0.0f,0.0f,1.f}

GLfloat mat_shininess=60.0f

glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient)

glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse)

glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular)

glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission)

glMaterialf(GL_FRONT,GL_SHININESS, mat_shininess)

glTranslatef(15, 5, 5)

glutSolidSphere(10, 100, 20)

}

glFlush()

glutSwapBuffers()

}

int main(int argc,char *argv[])

{

glutInit(&argc,argv)

glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE)

glutInitWindowPosition(100,100)

glutInitWindowSize(800,800)

glutCreateWindow("一个灰球")

glutDisplayFunc(&myDisplay)

glutMainLoop()

return 0

}

OpenGL可以读取模型的顶点,材质需要在OpenGL中进行设置,一般使用.bmp格式的图片作为模型的纹理贴图。我是用3DExploration将.3ds的文件转化成.cpp文件(存放顶点数组)载入OpenGL程序中,纹理贴图另外指定。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11237809.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存