open那个C加加 2016-08-17 01:26 采纳率: 50%
浏览 2787
已采纳

openGL实现多光源光照效果

最近正在学openGL,用的是learnOpenGL,一个网址,学到Multiple lights多光源这一章的时候遇到了问题。我想实现的是一个平行光(无光源),4个点光源,一个聚光灯源对十个箱子的光照效果。但是当我在着色器源码中将聚光灯的光照效果注释掉以后,物体呈现了黑色,也就是说平行光以及点光源对物体的光照效果没有实现。我反复看了代码,不知道错在哪里。以下是我的物体的着色器源码:

#version 330 core
//物体结构体
struct Material
{
sampler2D texture0;
sampler2D texture1;
sampler2D texture2;

float shininess;
};

//聚光灯结构体
struct FlashLight
{
vec3 ambient; // 物体ambient颜色要素的因素因子
vec3 diffuse; // 光的颜色,一般设置为白色
vec3 specular; // 物体specular颜色要素的因素因子
vec3 position; // 点的位置
vec3 directional; // 光源的方向
float cutoff; // 内余弦
float outcutoff; // 外余弦
float constant; // 光强度衰减方程式常数项
float linear; // 光强度衰减方程式一次项
float quadratic; // 光强度衰减方程式二次项
};

//点光源结构体
struct PointLight
{
vec3 ambient; // 物体ambient颜色要素的因素因子
vec3 diffuse; // 光的颜色,一般设置为白色
vec3 specular; // 物体specular颜色要素的因素因子
vec3 position; // 点的位置
float constant; //光强度衰减方程式常数项
float linear; //光强度衰减方程式一次项
float quadratic; //光强度衰减方程式二次项
};

//平行光源结构体
struct DirectLight
{
vec3 ambient; // 物体ambient颜色要素的因素因子
vec3 diffuse; // 光的颜色,一般设置为白色
vec3 specular; // 物体specular颜色要素的因素因子
vec3 directional; //光的方向
};

in vec3 Normal;
in vec3 fragPos;
in vec2 TexCoord;

out vec4 color;

uniform Material material;
//有四个点光源
uniform PointLight pointlight[4];
uniform FlashLight flashlight;
uniform DirectLight directlight;
uniform vec3 cameraPos;

//声明各个光源的光照函数
vec3 calcFlashLight(FlashLight light,vec3 fragPos,vec3 normal,vec3 viewDir);
vec3 calcPointLight(PointLight light,vec3 fragPos,vec3 normal,vec3 viewDir);
vec3 calcDirectLight(DirectLight light,vec3 normal,vec3 viewDir);

void main()
{
vec3 normal=normalize(Normal);

vec3 viewDir=normalize(cameraPos-fragPos);

vec3 result =calcDirectLight(directlight,normal,viewDir);
for(int i=0;i<4;i++)
    result +=calcPointLight(pointlight[i],fragPos,normal,viewDir);
result +=calcFlashLight(flashlight,fragPos,normal,viewDir);
color=vec4(result,1.0f);   

}

//聚光灯
vec3 calcFlashLight(FlashLight light,vec3 fragPos,vec3 normal,vec3 viewDir)
{
float distance=length(light.position-fragPos);
float attenuation=1.0f/(light.constant+light.linear*distance+light.quadratic*(distance*distance));
//ambient
vec3 ambient=light.ambient*vec3(texture(material.texture0,TexCoord));
//diffuse
vec3 lightDir=normalize(light.position-fragPos);
float diff=max(dot(lightDir,normal),0.0);
vec3 diffuse=light.diffuse*diff*vec3(texture(material.texture0,TexCoord));

//specular
vec3 refletDir=reflect(-lightDir,normal);
float spec=pow(max(dot(viewDir,refletDir),0.0),material.shininess);
vec3 specular=light.specular*spec*vec3(texture(material.texture1,TexCoord));
//attenuation
ambient *=attenuation; //由于我们不希望在多光源下,ambient会累积增加,所以我们这边进行一个衰减
diffuse *=attenuation;
specular *=attenuation;
//cutoff
float theta=dot(normalize(-light.directional),lightDir);
float intensity=clamp((theta-light.outcutoff)/(light.cutoff-light.outcutoff),0.0,1.0); //我们不希望强度值在0与1之外
diffuse *=intensity;
specular *=intensity;

return (ambient+diffuse+specular);

}

//点光源
vec3 calcPointLight(PointLight light,vec3 fragPos,vec3 normal,vec3 viewDir)
{
float distance=length(light.position-fragPos);
float attenuation=1.0f/(light.constant+light.linear*distance+light.quadratic*(distance*distance));
//ambient
vec3 ambient=light.ambient*vec3(texture(material.texture0,TexCoord));
//diffuse
vec3 lightDir=normalize(light.position-fragPos);
float diff=max(dot(lightDir,normal),0.0);
vec3 diffuse=light.diffuse*diff*vec3(texture(material.texture0,TexCoord));

//specular
vec3 refletDir=reflect(-lightDir,normal);
float strength=pow(max(dot(viewDir,refletDir),0.0),material.shininess);
vec3 specular=light.specular*strength*vec3(texture(material.texture1,TexCoord));
//attenuation
ambient *=attenuation; //由于我们不希望在多光源下,ambient会累积增加,所以我们这边进行一个衰减
diffuse *=attenuation;
specular *=attenuation;

return (ambient+diffuse+specular);

}

//平行光
vec3 calcDirectLight(DirectLight light,vec3 normal,vec3 viewDir)
{
//ambient
vec3 ambient=light.ambient*vec3(texture(material.texture0,TexCoord));
//diffuse
vec3 directional=normalize(-light.directional);
float diff=max(dot(directional,normal),0.0);
vec3 diffuse=light.diffuse*diff*vec3(texture(material.texture0,TexCoord));
//specular
vec3 refletDir=reflect(-directional,normal);
float spec=pow(max(dot(viewDir,refletDir),0.0),material.shininess);
vec3 specular=light.specular*spec*vec3(texture(material.texture1,TexCoord));

return (ambient+diffuse+specular);

}

我第一次发帖,没有C币也,sorry. 等我有了再给你们。 VS中的代码我没贴,不知道贴哪段,谢谢过来参观以及帮我解答的人。

  • 写回答

2条回答

  • 阿卡阿卡 2016-08-17 03:52
    关注

    材料属性有没有设置?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突