颜色和光照

来源:互联网 发布:c语言中的注释 编辑:程序博客网 时间:2024/04/30 15:27

颜色

眼睛看到的不同的颜色是由于不同频率的光子混合后的结果。当视网膜里的特定细胞受到光的刺激后,产生神经冲动传入大脑, 人眼便看到了颜色。所以计算机的显示器也是通过在发光像素点按一定比例混合红、绿、蓝三色,来模拟可见颜色。为了显示一种特定的颜色, 显示器发射恰当数量的红光、绿光、蓝光。在计算机中,硬件激发屏幕上的每一个像素点,发出不同数量的三种光, 这些光的数量称为数值R G B。这三个值通常放在一起。或者用颜色索引方式存储, 在该模式下,保存了每一个像素点的单一数值。

光照

隐藏面消隐修补工具箱:

在现实场景中,通常是由好多物体组成的, 我们站在一个位置观看场景,和在另一个位置看的是完全不一样的。因为一个物体可能会挡住其他物体。

所以我们提出隐藏面消隐的概念: 那些实体对象被其他实体对象遮掩的部分,将会被隐藏。实现它最好的概念就是利用深度缓存。

深度缓存的工作基础:将距离近裁剪面的深度和窗口中的每一个像素联系起来。

在激活深度缓存(GL_DEPTH_BUFFER_BIT)的情况下,在绘制每个像素之前,首先对那些存储在像素中的深度值进行比较。 如果新的像素的颜色和深度值会代替那些已经写入像素的当前值。

在每一次绘制场景之前,必须清除深度缓存, 然后在场景中以任意的顺序绘制物体。

真实世界与opengl光照:

opengl的光照模型将光照分为四个独立的成分: 环境光、散射光、镜面反射光、发射光。这四种成分独立的进行计算,然后叠加到一起。在思考这个过程,我总是过度的在意计算机的程序性能, 这是本末倒置呀,其实做一件事的时候,首先先理清概念才是主要的,然后其次在考虑实现方法。有什么样的概念,就会相应的有相关的方法,当然概念的提的好,可能对相应的方法实现有帮助。在学习过程中,首先把既有的概念方法了解透,你才可以判断它的好坏,或者提出你自己的概念。毕竟留下来的东西,都有闪光点。

环境光: 从某个光源发出,并经由环境多次散射得到, 难以确定其最初的方向。背景光照射到一个表面上时, 将均匀的在各方面产生散射。

散射光:来自于一个固定的方向, 一旦光线照到表面上, 就会均匀的在各个方向上都发生散射,因此不论观察点在哪一个位置,其亮度都是一样的。

镜面反射光:来自于特定的方向上,也趋于反射到特定的方向上。

发射光:它模拟了来自物体的光。表面的发射颜色为物体增加了亮度,但是它不受任何光源的影响。

材料颜色:

是由它对红绿蓝光各反射百分比的叠加结果决定的。例如一个纯红色球体将反射全部的红色入射光,并吸收全部的绿色和蓝色入射光。如果是白光照射,它只反射其中的红光部分,看得是红色的球体。如果是绿光照射,因为绿光中没有红光,球体它会吸收全部的绿色。没有反射光,所以你看到的是一个黑色的。

同光线一样, 材料也有不同的环境色、散射色、镜面反射色,它们决定了材质对环境光、散射光、和镜面反射光的系数。环境光(散射光、镜面反射光)的反射系数是每种入射光中环境颜色(散射颜色、镜面反射色)成分的叠加。

环境光和散射光的反射系数决定了材质的颜色。镜面反射光的反射系数通常是白或者灰,所以亮度与光源中镜面反射光的强度有关。

光线与材质的RGB值

为光线指定颜色成分意味着光的颜色与材料的颜色是不同的。对光线: 每种颜色的数值对应于它所占光强的百分比。如果RGB都是1.0,它是最亮的白光,如果RGB都是0.5,颜色仍然是白光,但是亮度是刚才的一半,所以这种光看起来是灰色的。

对材质来讲: RGB值对应着材质对这些颜色光的反射比例。如材料的R=1, G=0.5,B=0, 说明这种材质反射全部入射的红光,反射一半入射的绿光,不反射蓝光。

如果光线的RGB的分量值为: (LR, LG, LB), 材料的RGB值为(MR, MG, MB), 那么最后进入人眼中光的RGB值为(LRxMR, LGxMG, LBxMB).类似的如果有两束光(R1, G1,B1), (R2, G2, B2),进入人眼, OPENGL将其相加后, 合成为(R1+R2, G1+G2, B1+B2),当前任一分量大于1, 将其截断为1.

一个简单的例子:

#include <gl\glut.h>#include <cstdlib>void init(){    glClearColor(0, 0, 0, 0);    glShadeModel(GL_SMOOTH);    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };    GLfloat mat_shininess[] = { 50.0 };    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);   // 镜面反射    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);     // 设定环境光的颜色,亮度。这里为白色。    GLfloat eviroment_light[] = { 1, 0, 0, 1};    glLightfv(GL_LIGHT0, GL_AMBIENT, eviroment_light);    // 设定光源的位置    GLfloat light_position[] = { 1.0, 4.0, 0.0, 1.0 };    glLightfv(GL_LIGHT0, GL_POSITION, light_position);    // 指定了一个白色光源。    GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };    glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);  // 散射    glLightfv(GL_LIGHT0, GL_SPECULAR, white_light); // 镜面反射    glEnable(GL_LIGHTING);    glEnable(GL_LIGHT0);    glEnable(GL_DEPTH_TEST);}// 显示了三个球体void display(){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glPushMatrix();    glTranslatef(0, 2, 0);    glutSolidSphere(1.0, 20, 16);    glPopMatrix();    glPushMatrix();    glTranslatef(2, 0, 0);    glutSolidSphere(1.0, 20, 16);    glPopMatrix();    glPushMatrix();    glutSolidSphere(1.0, 20, 16);    glPopMatrix();    glFlush();}void reshape(int width, int height){    glViewport(0, 0, width, height);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    float length = 4;    if (width <= height)    {        glOrtho(-length, length, -length * height / width, length * height / width, -10, 10);    }    else    {        glOrtho(-length*height / width, length * height / width, -length, length, -10, 10);    }    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();}int main(int argc, char* argv[]){    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);    glutInitWindowSize(500, 500);    glutInitWindowPosition(100, 100);    glutCreateWindow(argv[0]);    init();    glutDisplayFunc(display);    glutReshapeFunc(reshape);    glutMainLoop();return 0;}

 

 

0 0
原创粉丝点击