opengl学习-多光源(随心记录)(包括手电筒图片)

多光源 - LearnOpenGL CN

我们在前面的教程中已经学习了许多关于OpenGL中光照的知识,其中包括冯氏着色(Phong Shading)、材质(Material)、光照贴图(Lighting Map)以及不同种类的投光物(Light Caster)。在这一节中,我们将结合之前学过的所有知识,创建一个包含六个光源的场景。我们将模拟一个类似太阳的定向光(Directional Light)光源,四个分散在场景中的点光源(Point Light),以及一个手电筒(Flashlight)。

为了在场景中使用多个光源,我们希望将光照计算封装到GLSL函数中。这样做的原因是,每一种光源都需要一种不同的计算方法,而一旦我们想对多个光源进行光照计算时,代码很快就会变得非常复杂。如果我们只在main函数中进行所有的这些计算,代码很快就会变得难以理解。

GLSL中的函数和C函数很相似,它有一个函数名、一个返回值类型,如果函数不是在main函数之前声明的,我们还必须在代码文件顶部声明一个原型。我们对每个光照类型都创建一个不同的函数:定向光、点光源和聚光。

当我们在场景中使用多个光源时,通常使用以下方法:我们需要有一个单独的颜色向量代表片段的输出颜色。对于每一个光源,它对片段的贡献颜色将会加到片段的输出颜色向量上。所以场景中的每个光源都会计算它们各自对片段的影响,并结合为一个最终的输出颜色。大体的结构会像是这样:

out vec4 FragColor;

void main()
{
  // 定义一个输出颜色值
  vec3 output;
  // 将定向光的贡献加到输出中
  output += someFunctionToCalculateDirectionalLight();
  // 对所有的点光源也做相同的事情
  for(int i = 0; i < nr_of_point_lights; i++)
    output += someFunctionToCalculatePointLight();
  // 也加上其它的光源(比如聚光)
  output += someFunctionToCalculateSpotLight();

  FragColor = vec4(output, 1.0);
}

定向光

意思是我们可以单独定义一个定向光的结构体,然后定向光的函数,如果场景需要定向光,则加上这个定向光就可以了。

定义定向光的函数和结构体。

定向光主要就是光线的相对物体上每个点的向量方向都是一样的,所以直接取反

#version 330 core
in vec3 to_fragment_normal;
in vec2 to_fragment_texCoord;
in vec3 to_fragment_POS;
uniform vec3 cameraPOS;
out vec4 FragColor;
struct Material{
    sampler2D diffuse;
    sampler2D specular;
    float shininess;
};
uniform Material material;
struct DIRECTLIGHT{
    vec3 light_position;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
uniform DIRECTLIGHT direcLight;
vec3 CalDirecLight(DIRECTLIGHT _direcLight,vec3 view_position,vec3 normal){//定向光
    vec3 res_direc_light;
    vec3 lightVetor=normalize(-_direcLight.light_position);
    vec3 ambient_light=vec3(texture(material.diffuse,to_fragment_texCoord))*_direcLight.ambient;//忽略掉alpha的变量
    vec3 diffuse_light=vec3(texture(material.diffuse,to_fragment_texCoord))*max(dot(lightVetor,normal),0)*_direcLight.diffuse;
    vec3 viewVector=view_position-to_fragment_POS;
    vec3 h=normalize(viewVector+lightVetor);
    vec3 specular_light=pow(max(dot(h,normal),0),material.shininess)*_direcLight.specular*vec3(texture(material.specular,to_fragment_texCoord));
    res_direc_light+=spe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值