/* Phong模型的实验代码在github的raytracing-phong项目中,Gouraud模型的实验代码在github的raytracing-gouraud项目中, 实验报告在github的raytracing-phong项目中,欢迎下载。 */

一. 实验要求

(1) 利用Phong shaing模型和Gouraud shading模型实现光线的追踪,画出光照模型。
(2) 比较Phong shaing模型和Gouraud shading模型的异同,更好地理解光照两种模型。
(3) 通过环境光、漫反射和镜面反射参数的设置,使场景更加真实自然。

二.完成情况

(1) 场景的绘制:由一个桌面和三个小球组成,三个小球分别是蓝色,红色和黑色。这里图形的绘制上个实验已经讲解的很清楚,不再累赘。
(2) 定义点光源:光源所在的位置坐标和光源方向。
(3) 编写程序,描绘光线照射小球时,人眼所看到的场景:物体的颜色,形状,光线直射物体时它所发生的镜面反射, 以及没有直射到的部分所受到的光的漫反射。
(4) 小球在桌面的阴影的实现:递归地进行光线追踪,因此还需要设置追踪深度。不断的以新交点为起始点,以反射光方向为方向 进行在一个的求交点的过程中,直到到达我们设定的深度。
(5) 使用了Phong模型和Gouraud模型两种模型实现以上四点要求。

三.具体实验过程

(一)Phong模型

1. 绘制场景

一个桌面,一个蓝色的球,一个红色的球,一个黑色的球。

2.定义点光源

设置光源颜色为白色的点光源,设置它的位置为(0,5,-5)

m_Primitive[4] = new Sphere(vector3(0, 5, -5), 0.1f);
	m_Primitive[4]->Light(true);
	m_Primitive[4]->GetMaterial()->SetColor(Color(1.0f, 1.0f, 1.0f));

3. 利用Phong模型处理光照场景

(1)发射光线,找到光线到达的物体的第一个点,获取这个点的颜色和这点入射光线的法向量。
(2)利用法向量得到球体一点的漫反射;假设人眼观察的地方在点光源的地方,由此根据观察向量和反射向量得到镜面反射;环境光是 一个常数,根据点光源强度可以求出。然后将三者相加我们就可以得到球体在点光源下的光照情况。光照公式如下:
Markdown
其中,漫反射和镜面反射的示意图(即公式的第二部分和第三部分)如下:
Markdown

4.实现阴影的绘制

设置追踪深度,不断的以新交点为起始点,以反射光方向为方向进行一个求交点的过程,直到到达我们设定的深度。

(二)Gouraud模型

基本过程与Phong模型大致相同,但是Gouraud模型是在物体的顶点处求光照强度,然后插值法求物体内部的光照强度,不必求每一点的 法向量和光照强度。 这里使用opengl自带的函数定义它的光源位置在坐标系的右上角。

//光源的位置在世界坐标系右上角
		GLfloat sun_light_position[] = { 1.0f, 1.0f, 0.0f, 0.0f }; 

四.Phong模型和Gouraud模型对比

Phong模型处理,通过差值计算每个顶点的法向量,然后计算每个点上的光照强度值,这样效果好,但计算复杂; 而Gouraud模型处理只在多边形顶点处采用Phong局部反射模型计算光照强度,在多边形内的其他点采用双向线性插值, 这样做的优点是高效,但是处理的效果不如Phong模型好。如下图:
Markdown

五.实验结果

Phong模型和Gouraud模型的实验结果截图分别如下:
Markdown
Markdown