OpenGL 简化点光源与平行光的对比实验

OpenGL 简化点光源与平行光的对比实验

由于光照位置和物体面积不够导致简化点光源(无衰减)和平行光的漫反射看起来区别不大,所以设计如下实验,让两者区别在视觉效果上更加明显,更能说明问题。

投光物类:参数1:光源位置,参数二,光线方向旋转角度,参数3:光的颜色(传参数1还是参数2在我)

在这里插入图片描述

大多数操作在fragment shader中进行,代码如下:

#version 330 core
in vec3 FragPos;
in vec3 Normal;
in vec2 Texcoord;

struct Material
{
vec3 ambient;

//漫反射贴图
sampler2D diffuse;

//镜面反射贴图
sampler2D specular;

//放射光贴图(Emission Map)
sampler2D EmissionMap;

//反光度
float shininess;

};

uniform Material material;

uniform vec3 objColor;
uniform vec3 ambientColor;
//uniform vec3 lightPos;
uniform vec3 lightDir;
uniform vec3 lightColor;
uniform vec3 cameraPos;

//uniform sampler2D ourTexture;
//uniform sampler2D ourface;

out vec4 FragColor;

void main()
{

//光源方向,其反向就是入射光线方向,此处反应点光源和平行光的区别,点光源光线方向与各个片段的位置有关系,而平行光方向是独立的与片段位置无关
//vec3 lightDir=normalize(lightPos-FragPos);

//计算反射光线方向向量
vec3 reflectVec=reflect(-lightDir,Normal);//参数1:入射光线方向;参数2:法向量

//摄像机方向
vec3 cameraVec=normalize(cameraPos-FragPos);

//漫反射区分黑白灰面,与观察位置无关,因为法向量和光源位置目前都是死的
//max设置最小值,min设置最大值,此处为了不出现负值而抵消其他种类光照强度。
float diff=max(dot(Normal, lightDir), 0.0);

//摄像机方向与反射光线方向点乘后取shininess(反光度)次幂
float specularAmount=pow(max(dot(cameraVec,reflectVec),0),material.shininess);

//环境光
vec3 ambient=ambientColor*texture(material.diffuse, Texcoord).rgb;

//漫反射
vec3 diffuse=lightColor*diff*texture(material.diffuse, Texcoord).rgb;

//镜面反射
//镜面高光的强度可以通过图像每个像素的亮度来获取。镜面光贴图上的每个像素都可以由一个颜色向量来表示,
//比如说黑色代表颜色向量vec3(0.0),灰色代表颜色向量vec3(0.5)。
//在片段着色器中,我们接下来会取样对应的颜色值并将它乘以光源的镜面强度。一个像素越「白」,乘积就会越大,物体的镜面光分量就会越亮。
vec3 specular=lightColor*specularAmount*texture(material.specular, Texcoord).rgb;//在特殊位置才能够看见这张帖图产生的效果,其他部分效果仍由漫反射贴图产生

//放射光贴图
vec3 emission=texture(material.EmissionMap, Texcoord).rgb;

//片段最终颜色
//FragColor=vec4(ambient+diffuse,1.0f);

`}

实验1.1:多个立方体在简化点光源环境下的效果,光源位置(1.0f,0.0f,0.0f),即从右侧向左照。方向计算:vec3 lightDir =normalize(lightPos-FragPos);

在这里插入图片描述

实验1.2:多个立方体在平行光环境下的效果,方向(-1.0f,0.0f,0.0f),即从右侧向左照。(平行光无位置,只有方向)

在这里插入图片描述

实验2.1:巨大立方体(20 * 20 * 20)在关闭镜面反射的简化点光源环境下的效果,光源位置(12.0f, 0.0f,10.0f),即从右侧向左照。方向计算:vec3 lightDir=normalize(lightPos-FragPos);

解释:这里不是镜面反射而是漫反射,FragColor=vec4(ambient+diffuse,1.0f);简化的点光源位置为(12.0f, 0.0f,10.0f),距离平面很近,平面又是20*20的范围,中心位置是0.0f,所以在这个平面范围内的光线方向和法线的夹角会有较大的区别,float diff=max(dot(Normal, lightDir), 0.0); 夹角越大cos值越小,造成了这里亮周边暗的情况(ps:图2是箱子里面的状况,和外面是一模一样的,以后再讨论怎么样区分内外环境)

在这里插入图片描述
在这里插入图片描述

实验2.2:巨大立方体(20 * 20 * 20)在关闭镜面反射的平行光环境下的效果,光线方向(-1.0f,0.0f,0.0f),即从右侧向左照。

解释:整个平面内无区别

在这里插入图片描述

曾误认为点光源漫反射在一个面内的颜色没有区别,但通过此次实验的操作,能更加理解FragPos的作用,它对每一个片元都有影响(问题:即vec3 lightDir=normalize(lightPos-FragPos)的结果对各处都会有所影响,但不知道是生成了填充了中间像素的坐标还是对结果进行了类似内插的计算,综合片元颜色内插的经验,更倾向于后者)只不过物体之间的相对位置和物体受光面的大小的设计原因导致视觉上没有很大差异,造成了这种错觉,经过这次实验能够更加深刻理解点光源和平行光以及向量之间的运算。

此前对物体的变化过多,也造成了光源效果的观察并不是那么明显,所以要控制一些不必要的变量,才能够把这些特性更好地展现出来以便于观察。通知也不要主观臆断轻易相信自己的眼睛,多用代码来理解现象,多用思考验证直觉。

感谢阅读,欢迎批评指正!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zbx727259615/article/details/124653910