首页 > 编程语言 >阅读《计算机图形学编程(使用OpenGL和C++)》12 - 光照

阅读《计算机图形学编程(使用OpenGL和C++)》12 - 光照

时间:2022-08-30 17:14:36浏览次数:43  
标签:12 1.0 OpenGL 0.0 Utils float 图形学 漫反射 return

现在最常见的光照模型称为“ADS”模型,因为它们基于标记为A、D和S的3种类型的反射。

环境光反射Ambient reflection)模拟低级光照,影响场景中的所有物体。

漫反射Diffuse reflection)根据光线的入射角度调整物体亮度。

镜面反射Specular reflection)用以展示物体的光泽,通过在物体表面上,光线最直接地反射到我们的眼睛的位置,策略性地放置适当大小的高光来实现。

ADS模型可用于模拟不同的光照效果和各种材质。

场景的绘制最终是由片段着色器为屏幕上的每个像素输出颜色而实现的。使用ADS光照模型需要指定由于像素的RGBA输出值上的光照而产生的分量。因素包括:

●光源类型及其环境、漫反射和镜面反射特性;

●对象材质的环境、漫反射和镜面反射特征;

●对象的材质指定为“光泽”;

●光线照射物体的角度;

●从中查看场景的角度。

光源有许多类型,每种光源具有不同的特性,需要不同的步骤来模拟其效果。常见光源类型有:

全局环境光是最简单的光源模型。它没有光源位置——无论场景中的对象在何处,其上的每个像素都有着相同的光照。仅具有环境光反射分量,用RGBA值设定;它没有漫反射或镜面反射分量。例如,全局环境光可以定义如下:

float globalAmbient[4] = { 0.7f, 0.7f, 0.7f, 1.0f };

RGBA的取值范围为0~1,全局环境光通常被建模为偏暗的白光,其中RGB各值设为0~1的相同的小数,alpha设置为1。

定向光远距离光也没有源位置,但它具有方向。它可以用来模拟光源距离非常远,以至于光线接近平行的情况,例如阳光。建模定向光需要指定其方向(以向量形式)及其环境、漫反射和镜面特征(以RGBA值)。指向Z轴负方向的红色定向光可以指定如下:

float lightAmbient[4] = { 0.1f, 0.0f, 0.0f, 1.0f };
float lightDiffuse[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
float lightSpecular[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
float lightSpecular[3] = { 0.0f, 0.0f, -1.0f};

位置光在3D场景中具有特定位置。靠近场景的光源,例如台灯,蜡烛等。位置光还可以包含衰减因子,以模拟它们的强度随距离减小的程度。与我们看到的其他类型的光源一样,位置光具有指定为RGBA值的环境光反射、漫反射和镜面反射特性。位置(5,2,−3)处的红色位置光可以指定如下例:

float lightAmbient[4] = { 0.1f, 0.0f, 0.0f, 1.0f };
float lightDiffuse[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
float lightSpecular[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
float lightSpecular[3] = { 5.0f, 2.0f, -3.0f};

衰减因子有多种建模方式。其中一种方式是使用恒定、线性和二次方(分别称为kc, kl和kq)衰减,并引入非负可调参数。这些参数与离光源的距离(d)结合进行计算:

 

 

 将这个因子与光的强度相乘可以使距光更远时,光的强度衰减更多。注意,kc应当永远设置为大于等于1的值,从而使得衰减因子落入[0…1]区间,并当d增大时接近于0。

聚光灯(spotlight)同时具有位置和方向。其“锥形”效果可以使用0°~90°的截光角θ来模拟,指定光束的半宽度,并使用衰减指数来模拟随光束角度的强度变化。如图所示,我们确定聚光灯方向与从聚光灯到像素的向量之间的角度φ。当φ小于θ时,我们通过将φ的余弦提高到衰减指数来计算强度因子(当φ大于θ时,强度因子设置为0)。结果是强度因子的范围为0~1。衰减指数会影响当角度φ增加时,强度因子趋于0的速率。然后将强度因子乘以光的强度以模拟锥形效果。

 

通过指定4个值(我们已经熟悉其中3个值——环境光、漫反射和镜面RGB颜色),可以在ADS光照模型中模拟材质。第四种叫作光泽,它被用来为所选材质建立一个合适的镜面高光。 

透明度由RGBA标准中的第四个(alpha)通道的不透明度来实现。取值为1.0是表示完全不透明,取值为0时表示完全透明。

预定义一些可供选择的材质,在使用时会很方便。因此我们需要在Utils.cpp文件中添加如下代码:

 1 // 黄金材质 — 环境光、漫反射、镜面反射和光泽
 2 float * Utils::goldAmbient()
 3 {
 4     static float a[4] = { 0.2473f, 0.1995f, 0.0745f, 1 };
 5     return (float*)a;
 6 }
 7 
 8 float * Utils::goldDiffuse()
 9 {
10     static float a[4] = { 0.7516f, 0.6065f, 0.2265f, 1 };
11     return (float*)a;
12 }
13 
14 float * Utils::goldSpecular()
15 {
16     static float a[4] = { 0.6283f, 0.5559f, 0.3661f, 1 };
17     return (float*)a;
18 }
19 
20 float Utils::goldShininess()
21 {
22     return 51.2f;
23 }
24 // 白银材质 — 环境光、漫反射、镜面反射和光泽
25 float * Utils::silverAmbient()
26 {
27     static float a[4] = { 0.1923f, 0.1923f, 0.1923f, 1 };
28     return (float*)a;
29 }
30 
31 float * Utils::silverDiffuse()
32 {
33     static float a[4] = { 0.5075f, 0.5075f, 0.5075f, 1 };
34     return (float*)a;
35 }
36 
37 float * Utils::silverSpecular()
38 {
39     static float a[4] = { 0.5083f, 0.5083f, 0.5083f, 1 };
40     return (float*)a;
41 }
42 
43 float Utils::silverShininess()
44 {
45     return 51.2f;
46 }
47 // 青铜材质 — 环境光、漫反射、镜面反射和光泽
48 float * Utils::bronzeAmbient()
49 {
50     static float a[4] = { 0.2125f, 0.1275f, 0.0540f, 1 };
51     return (float*)a;
52 }
53 
54 float * Utils::bronzeDiffuse()
55 {
56     static float a[4] = { 0.7140f, 0.4284f, 0.1814f, 1 };
57     return (float*)a;
58 }
59 
60 float * Utils::bronzeSpecular()
61 {
62     static float a[4] = { 0.3936f, 0.2719f, 0.1667f, 1 };
63     return (float*)a;
64 }
65 
66 float Utils::bronzeShininess()
67 {
68     return 25.6f;
69 }

 

标签:12,1.0,OpenGL,0.0,Utils,float,图形学,漫反射,return
From: https://www.cnblogs.com/lely/p/16640053.html

相关文章

  • Python自学教程12-类和对象怎么用
    Python是一门现代化的编程语言,也是一门面向对象的编程语言。现代编程语言几乎都支持面向对象编程,面向对象编程是最有效的软件编写方法之一。你可以用类和对象来表示现实当......
  • C20220712T3 牛半仙的妹子Tree
    给定一棵树,要求执行3种操作:给树上某一结点涂色,从下一次操作起每一次向周围传染一个单位。树上所有点变为正常询问某个点是否被感染。\(n,m\leq10^5\)。首先想到暴......
  • C20220712T1 牛半仙的妹子数
    给定\(A,B,C\),操作\(K\)次,每次操作若\(A+B\leqC\)则\(A=2A,B=2B,C=C-A-B\),否则记\(A,B\)中较小的为\(W\),\(P=min(\frac{C}{2},W-1)\),则\(A=A-P,B=B+P-C,C=......
  • C20220712T2 牛半仙的妹子图
    给定\(n\)个点和\(m\)条边,起点\(s\),每个点有颜色。给定多组\([l,r]\),求最大走\(l...r\)边权所有可以走到的不同颜色数之和。(同一种颜色在不同区间内算多组)。\(n......
  • OpenGL 4.5+ 的 VAO、VBO、IBO写法
    写法opengl4.5新增了DSA(direct_state_access),可以不用glBindBuffer()和glBindVertexArray()直接设置好VAO、VBO、IBO,只需要draw之前bind即可新旧函数对比(左侧为新函......
  • 阅读《计算机图形学编程(使用OpenGL和C++)》11 - 加载外部obj模型
    复杂的3D模型可以借助建模工具生成,这种工具能够在3D空间中构建任意形状并自动生成顶点、纹理坐标、顶点法向量等。模型生成后可导出成obj文件格式,这种格式有很多,OBJ文件很......
  • 12. SQL--重命名表
    1.前言SQL允许对表进行重命名。有时候我们为表使用了无意义的名称,因此需要更正。2.语法SQL支持两种重命名表的方式:altertableold_table_namerenametonew_ta......
  • m12
    rcnn=regionproposals(候选区域)+CNN1、用SelectiveSearch(选择性搜索)产生候选区域,是基于像素相似性进行的分割1️⃣用论文《EfficientGraph-BasedImageSegmentation》......
  • 11-12-13-14-15-16-17-18-19-20-21-22-23-24-25不知道在干啥,忘了
    时间过的好快啊,已经过去了2个星期了!!!! 而我不知道都干了什么,距离玩游戏已经过去了俩星期了,不可思议,我觉得才完了三五天而已人脑子会欺骗自己的啊我想换个键盘,换个按键轻......
  • OpenGL之渲染管线-VBO-VAO
    在OpenGL中,一切都是3D的,但屏幕或窗口是一个2D像素阵列,因此OpenGL的大部分工作是将所有3D坐标转换为适合屏幕的2D像素。这个过程由OpenGL的渲染管线管理。渲染管线可以分为......