opengl平行光光源,点光源,聚光灯光源同台出现

该博客展示了在OpenGL中如何实现并同时使用三种不同的光源类型:平行光、点光源和聚光灯。通过一个效果图,可以观察到每种光源在场景中的独特效果,从左到右依次为平行光、点光源和聚光灯。在片元着色器的运用下,光源效果得以生动呈现。
摘要由CSDN通过智能技术生成

效果图:左起分别为 平行光光源,点光源,聚光灯光源


片元shader


uniform vec4 U_LightPos;//光源位置
uniform vec3 U_EyePos;//眼睛位置
uniform vec4 U_LightDirection;//聚光灯中心线向量
uniform float U_Cutoff;//聚光灯中心线向量和入射光线最大夹角
uniform float U_DiffuseIntensity; //漫反射光强度
uniform vec4 U_AmbientLightColor;//环境光颜色
uniform vec4 U_AmbientMaterial;//环境光材质
uniform vec4 U_DiffuseLightColor;//漫反射光颜色
uniform vec4 U_DiffuseMaterial;//漫反射光材质
uniform vec4 U_SpecularLightColor;//镜面光颜色
uniform vec4 U_SpecularMaterial;//镜面光材质

varying vec3 V_Normal; //转换到世界空间的法向量
varying vec3 V_WorldPos;

void main()
{
	//角度转弧度
	float radianCutoff=U_Cutoff*3.14/180.0;
	float cosThta=cos(radianCutoff);
	//聚光灯中心线向量归一化
	vec3 spotLightDirection=normalize(U_LightDirection.xyz);

	//--计算环境光
	vec4 ambientColor=U_AmbientLightColor*U_AmbientMaterial;

	//--计算漫反射光
	//入射光向量
	vec3 L=vec3(0.0);
	float distance=0.0;
	float attenuation=1.0;
	
	float constantFactor=0.5;
	float linearFactor=0.3;
	float expFactor=0.1;

	if(U_LightPos.w==0.0)//如果是方向光光源
	{
	//方向光光源  入射光线是平行的
		L=U_LightPos.xyz;
	}
	else  //如果是点光源  
	{
		//入射光线的方向是从被照射点指向光源的位置
		L=U_LightPos.xyz-V_WorldPos;
		//计算入射光线的长度 
		distance=length(L);
		//计算光线的衰减因子
		attenuation=1.0/(constantFactor+linearFactor*distance+expFactor*distance*distance);
	}

	//入射光线归一化
	L=normalize(L);

	//法向量归一化
	vec3 n=normalize(V_Normal);
	float diffuseIntensity=0.0;

	if(U_LightPos.w!=0.0f&&U_Cutoff>0.0)//如果是聚光灯
	{
		//计算聚光灯中心线和入射光线的夹角
		float currentCosThta=max(0.0,dot(-L,spotLightDirection));
		if(currentCosThta>cosThta)
		{
			if(dot(L,n)>0.0)//为了减少计算量,过滤掉照射到背面的光
			{
				//为了让聚光灯边缘变的光滑
				diffuseIntensity=pow(currentCosThta,U_LightDirection.w);
			}
		}
	}
	else
	{
		//点光源或者方向光
		diffuseIntensity=max(0.0,dot(L,n));
	}
	
	vec4 diffuseColor=U_DiffuseLightColor*U_DiffuseMaterial*diffuseIntensity*attenuation*U_DiffuseIntensity;
	
	//--镜面光的计算
	//计算眼睛到被观察点的向量
	vec3 viewDir=U_EyePos-V_WorldPos;
	viewDir=normalize(viewDir);

	//根据Blin-phone计算反射光  
	vec3 halfVector=L+viewD
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值