Opengl知识点(2)

颜色

现实中所有物体都有颜色,在Opengl中我们可以通过三个分量来设置一个颜色。在自然界中·我们看到的物体的颜色时它反射的颜色
颜色的反射规律在OpenGL中两个三维坐标相乘是三个分量逐步分量,用这个我们可以模拟物体颜色的反射。

※不等比缩放会破坏法向量,而且法向量用于光照计算也要转到相应的世界坐标里,这里就用到了正规矩阵,在opengl中通过

在这里插入图片描述

光照基础

冯氏光照模型(Phone Light Model)
why:现实中光照我们无法模拟
what:对现实生活中的光照进行模拟
how:由三个基本的元素组成环境(Ambient),漫反射(Diffuse光),镜面(Specular)光照。

参考
在这里插入图片描述
环境光照
why:全局照明(物体不止会受到直射光的影响,还会受到非直射光的影响)的算法复杂开销大,所以我们将用到简化模型,环境照明。
what:物体自身所带的光
how:用光的颜色乘环境因子的到环境光照

漫反射光照
what:投射到粗糙表面的一种反射现象,是该模型的显著部分,面向光源比较亮。
how:用光照方向,乘以法向量,来模拟why(向量点乘相乘,夹角越小值越大,夹角为90°点乘为0影响最小)

在这里插入图片描述
镜面光照
what:光投射到光滑表面的一种反射现象,出现的亮点。
how:根据观察角度,用反射后的光照向量点乘观察者角度向量

在这里插入图片描述

在这里插入图片描述
然后把计算的每个光照乘以这个模型的颜色,然后输入到片段着色器中。

材质

why:在真实世界,不同材质的物体,对光照有不同的反应,比如花瓶陶瓷材质在光照下会变得亮闪闪,而木头箱子对光照的反应微乎其微。
what:材质和光照一样,他也需要相应的元素来定义它的属性,就比如,环境光照,漫反射光照,镜面光照,和高光散射。
how:定义结构体,然后将相应的光照模型乘以材质模型即可。

光照贴图

把前面学的贴图和这一张结合起来。材质里的结构体改成贴图类型,然后赋值。

投光物

光的种类又分为 点光源,平行光,手电筒,每一个物体的受光情况根据之前提出的光照模型(环境光,漫反射光照,镜面反射光照)。

平行光:(what)光源发出的光每一条都是平行的,每一条光线独立于光源位置。(why)模拟太阳光。(how)设置光的 颜色和方向即可。然后根据光照模型计算。

点光源:(what)向所有位置发光,但是根据据光源的距离增加逐渐减弱。
(why)模拟场景中的灯泡等。(how)设置光的位置方向颜色,衰减。

衰减(attenuation)how:通过数学公式
在这里插入图片描述
在这里插入图片描述
手电筒(聚光):(what)他结合了前面两种光源的特点,某一方向照射,随着物体距离光源的距离的增加而减弱。(why)模拟手电筒或者聚光灯。(how)设置光的位置方向颜色,衰减,以及光的内角度(在内角度内的光照强度相同),外角度(内角度到外角度之间的光照逐渐减弱),这两者用来软化边缘。

在这里插入图片描述

点光源和手电筒算出的衰减和边缘软化,最后都要乘以光照模型的diffuse和specular来达到效果,

以下是源码
片段着色器

#version 330 core						
in vec4 vertexColor;     
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoord;
       
struct Material
{
	vec3 ambient;
	sampler2D diffuse;
	sampler2D specular;
	float shininess;
	
};

struct LightPoint
{
	vec3 pos;
	vec3 color;
	vec3 dirToLight;
	float constant;
	float linear;
	float quadratic;
};

struct LightDirectional
{
	vec3 pos;
	vec3 color;
	vec3 dirToLight;
};


struct LightSpot
{
	vec3 pos;
	vec3 color;
	vec3 dirToLight;
	float constant;
	float linear;
	float quadratic;
	float CosPhyInner;
	float CosPhyOutter;
};

uniform Material material;

uniform LightDirectional lightD;
uniform LightPoint lightP0;
uniform LightPoint lightP1;
uniform LightPoint lightP2;
uniform LightPoint lightP3;
uniform LightSpot lightS;

uniform vec3 objColor;
uniform vec3 ambientColor;
uniform vec3 cameraPos;

out vec4 FragColor;	


vec3 CalcLightDirctional(LightDirectional light,vec3 uNormal,vec3 dirToCamera)
{
	//diffuse
	float diffIntensity = max(dot(light.dirToLight,uNormal),0);
	vec3 diffColor = diffIntensity*light.color *texture(material.diffuse,TexCoord).rgb;

	//specular
	vec3 R = normalize(reflect(-light.dirToLight,uNormal));
	float specIntensity = pow(max(dot(R,dirToCamera),0),material.shininess);
	vec3 specColor = specIntensity*light.color*texture(material.specular,TexCoord).rgb;

	vec3 result = diffColor +specColor;
	return result;
	
}

vec3 CalcLightPoint(LightPoint light,vec3 uNormal,vec3 dirToCamera)
{
	//attenuation
	float dist = length(light.pos-FragPos);
	float attenuation = 1/(light.constant+light.linear*dist+light.quadratic*(dist*dist));

	//diffuse
	float diffIntensity = max(dot(normalize(light.pos-FragPos),uNormal),0)*attenuation;
	vec3 diffColor = diffIntensity*light.color *texture(material.diffuse,TexCoord).rgb;

	//specular
	vec3 R = normalize(reflect(-normalize(light.pos-FragPos),uNormal));
	float specIntensity = pow(max(dot(R,dirToCamera),0),material.shininess);
	vec3 specColor = specIntensity*light.color*texture(material.specular,TexCoord).rgb;

	vec3 result  = diffColor+specColor;
	return result;

}

vec3 CalcLightSpot(LightSpot light,vec3 uNormal,vec3 dirToCamera)
{
	float dist = length(light.pos-FragPos);
	float attenuation = 1/(light.constant+light.linear*dist+light.quadratic*(dist*dist));

	float spotRation = 0;
	float CostTheta = dot(normalize(FragPos-light.pos),-light.dirToLight);

	if(CostTheta>light.CosPhyInner)
	{
		spotRation = 1.0f;
	}

	else if(CostTheta>light.CosPhyOutter)
	{
		spotRation = (CostTheta-light.CosPhyOutter)/(light.CosPhyInner-light.CosPhyOutter);
	}

	else
	{
		spotRation = 0;
	}

	//diffuse
	float diffIntensity = max(dot(normalize(light.pos-FragPos),uNormal),0)*attenuation*spotRation;
	vec3 diffColor = diffIntensity*light.color *texture(material.diffuse,TexCoord).rgb;


	//specular
	vec3 R = normalize(reflect(-normalize(light.pos-FragPos),uNormal));
	float specIntensity = pow(max(dot(R,dirToCamera),0),material.shininess);
	vec3 specColor = specIntensity*light.color*texture(material.specular,TexCoord).rgb*attenuation*spotRation;

	vec3 result = diffColor+specColor;
	return result;
}




void main(){					

	vec3 finalResult = vec3(0,0,0);
	vec3 uNormal = normalize(Normal);
	vec3 dirToCamera = normalize(cameraPos-FragPos);

/*	finalResult += CalcLightDirctional(lightD,uNormal,dirToCamera);

	finalResult += CalcLightPoint(lightP0,uNormal,dirToCamera);
	finalResult += CalcLightPoint(lightP1,uNormal,dirToCamera);
	finalResult += CalcLightPoint(lightP2,uNormal,dirToCamera);
	finalResult += CalcLightPoint(lightP3,uNormal,dirToCamera);*/

	finalResult += CalcLightSpot(lightS,uNormal,dirToCamera);
	FragColor = vec4(finalResult,1.0f);

} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值