注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[ogl] lighting(光照)  

2008-12-24 23:22:51|  分类: 3d |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
最近在尝试实现'影子',顺带熟悉下 OpenGL 中 lighting 部分的知识。

在没有开启光照前,所有 vertex 的颜色是由 glColor 决定的。比如下面绘制一个三角形。
    glBegin(GL_TRIANGLES);
        glColor3f(1.0, 0, 0);
        glVertex3f(0.0, 1.0, -2.0);
        glColor3f(0, 1.0, 0);
        glVertex3f(1.0, -1.0, -2.0);
        glColor3f(0, 0, 1.0);
        glVertex3f(-1.0, -1.0, -2.0);
    glEnd();

而通过 glEnable(GL_LIGHTING) 开启光照后,则 vertex 的颜色则由 (1) 此顶点的 material 和 (2) 场景的环境光 (3) 场景中的点光源 有关。
(1) vertex 的 material 决定了此顶点不同类型光的反射程度
(2) 场景的环境光可通过 glLightModel(GL_LIGHT_MODEL_AMBIENT) 设置
(3) 而点光源通过 glLight() 设置属性,glEnable(GL_LIGHTx) 开启

无论是光源还是 vertex or 物品 本身,对光照的描述都分为四部分:ambient, diffuse, specular, emissive。光照公式就是这几个值配合几个参数组成的。为啥由这几个部分来描述光照我们就不用深究了,反正学院派的科学老头已经用无数论文证明这个公式模拟出来的光照效果不错。

我们可以通过 glShadeModel(mode) 来设定光照模型,GL_FLAT 表示 flat shading,每个 surface pixel 只使用某个 vertex 的颜色;而 GL_SMOOTH 表示 Gouraud shading,每个 vertex 通过计算得到自己独立的颜色,而 surface pixel 则通过 vertex颜色 线性插值得到;而 Phong shading 则需要自己写 shader 来实现了,Phong 是 Gouraud 的改良版,就是 surface pixel 根据 vertex 的发向量(normal) 进行插值,算出自己的 normal,并独立计算 pixel 自己的颜色。

例子:看下面的 yellow cube,首先 light0 是 (1.0, 1.0, 1.0) 的白光;下面 cube 的效果,基本上是因为 material 的因素决定的。光照不到的地方,微微泛绿色,是因为开了(0, 0.5, 0)的绿色 ambient;而大部分的黄色是因为 diffuse 为 (0.75, 0.75, 0.0) 的黄光;黄色中间的高光(highlight),是因为 (1.0, 1.0, 1.0) 的 specular 带来的效果。
[ogl] lighting(光照) - kasicass - Code@Pig Home

代码:
// 初始化
    // lights
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 0.15 };
    GLfloat mat_shininess[] = { 100.0 };
    GLfloat position[] = { 0.5, 0.5, 1.0, 0.0 };

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
    glLightfv(GL_LIGHT0, GL_POSITION, position);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

// 绘制
    GLfloat mat_solid[] = { 0.75, 0.75, 0.0, 1.0 };
    GLfloat mat_zero[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat mat_ambient[] = { 0.0, 0.5, 0.0, 1.0 };

    glMaterialfv(GL_FRONT, GL_EMISSION, mat_zero);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_solid);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glCallList(sphereList);

  评论这张
 
阅读(671)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017