1、平行光
给出光源的方向向量即可,没有位置(这里不作代码展示了,很简单)。
2、点光源
点光源包含衰减过程。需要给出光源的位置,衰减的三个系数。
片段着色器代码如下:
- #version 430 core
- out vec4 color;
- in VS_OUT{
- vec3 FragPos;
- vec3 Normal;
- vec2 TexCoords;
- }vs_in;
- struct Material{
- sampler2D diffuse;
- sampler2D specular;
- float shininess;
- };
- struct Light{
- vec3 position;
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
- float constant;
- float linear;
- float quadratic;
- };
- uniform Material material;
- uniform Light light;
- uniform vec3 viewPos;
- void main()
- {
- float distance=length(light.position-vs_in.FragPos);
- float attenuation=10.0f/(light.constant+light.linear*distance+light.quadratic*(distance*distance));
- vec3 ambient=light.ambient * vec3(texture(material.diffuse, vs_in.TexCoords));
- ambient*=attenuation;
- vec3 norm=normalize(vs_in.Normal);
- vec3 lightDir=normalize(light.position-vs_in.FragPos);
- float diff=max(dot(norm,lightDir),0.0f);
- vec3 diffuse=light.diffuse * diff * vec3(texture(material.diffuse, vs_in.TexCoords));
- diffuse*=attenuation;
- vec3 viewDir=normalize(viewPos-vs_in.FragPos);
- vec3 reflectDir=reflect(-lightDir,norm);
- float spec=pow(max(dot(viewDir,reflectDir),0.0f),material.shininess);
- vec3 specular=light.specular * spec * vec3(texture(material.specular, vs_in.TexCoords));
- specular*=attenuation;
- color = vec4(ambient+diffuse+specular, 1.0f);
- }
渲染代码如下:
- void SceneRendering::CubeRendering() {
- //update uniform buffer
- cube->setViewMat(phc->getViewMatrix());
- cube->setProjectionMat(phc->getProjectionMatrix());
- shader_cube->use();
- shader_cube->setInt("material.diffuse", 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, container);
- shader_cube->setInt("material.specular", 1);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, container_specular);
- shader_cube->setFloat("material.shininess", 500);
- shader_cube->setVec3("light.ambient", 0.2f, 0.2f, 0.2f);
- shader_cube->setVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
- shader_cube->setVec3("light.specular", 1.0f, 1.0f, 1.0f);
- shader_cube->setVec3("light.position", 0.0f, 0.0f, 10.0f);
- shader_cube->setFloat("light.constant", 1.0f);
- shader_cube->setFloat("light.linear", 0.09f);
- shader_cube->setFloat("light.quadratic", 0.032f);
- shader_cube->setVec3("viewPos", phc->getPos());
- // draw cubes
- for (unsigned int i = 0; i < 10; i++)
- {
- glm::mat4 model;
- model = glm::scale(model, glm::vec3(5));
- model = glm::translate(model, cube->cubePositions[i]);
- float angle = 20.0f * i;
- model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
- shader_cube->setMat4("model", model);
- cube->DrawCube();
- }
- }
效果图:

3、聚光灯
聚光灯除了衰减以外,加入了照射范围限制,光源有位置、照射方向、cut角。
片段着色器代码如下:
- #version 430 core
- out vec4 color;
- in VS_OUT{
- vec3 FragPos;
- vec3 Normal;
- vec2 TexCoords;
- }vs_in;
- struct Material{
- sampler2D diffuse;
- sampler2D specular;
- float shininess;
- };
- struct Light{
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
- float constant;
- float linear;
- float quadratic;
-
- vec3 position;
- vec3 direction;
- float cutOff;
- float outerCutOff;
- };
- uniform Material material;
- uniform Light light;
- uniform vec3 viewPos;
- void main()
- {
- float distance=length(light.position-vs_in.FragPos);
- float attenuation=10.0f/(light.constant+light.linear*distance+light.quadratic*(distance*distance));
- vec3 ambient=light.ambient * vec3(texture(material.diffuse, vs_in.TexCoords));
- ambient*=attenuation;
- vec3 norm=normalize(vs_in.Normal);
- vec3 lightDir=normalize(light.position-vs_in.FragPos);
- float diff=max(dot(norm,lightDir),0.0f);
- vec3 diffuse=light.diffuse * diff * vec3(texture(material.diffuse, vs_in.TexCoords));
- diffuse*=attenuation;
- vec3 viewDir=normalize(viewPos-vs_in.FragPos);
- vec3 reflectDir=reflect(-lightDir,norm);
- float spec=pow(max(dot(viewDir,reflectDir),0.0f),material.shininess);
- vec3 specular=light.specular * spec * vec3(texture(material.specular, vs_in.TexCoords));
- specular*=attenuation;
- float theta=dot(lightDir,normalize(-light.direction));
- float epsilon=light.cutOff-light.outerCutOff;
- float intensity=clamp((theta-light.outerCutOff)/epsilon,0.0,1.0);
- //ambient*=intensity;
- diffuse*=intensity;
- specular*=intensity;
- color = vec4(ambient+diffuse+specular, 1.0f);
- }
渲染代码如下:
- void SceneRendering::CubeRendering() {
- //update uniform buffer
- cube->setViewMat(phc->getViewMatrix());
- cube->setProjectionMat(phc->getProjectionMatrix());
- shader_cube->use();
- shader_cube->setInt("material.diffuse", 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, container);
- shader_cube->setInt("material.specular", 1);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, container_specular);
- shader_cube->setFloat("material.shininess", 500);
- shader_cube->setVec3("light.ambient", 0.2f, 0.2f, 0.2f);
- shader_cube->setVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
- shader_cube->setVec3("light.specular", 1.0f, 1.0f, 1.0f);
- shader_cube->setFloat("light.constant", 1.0f);
- shader_cube->setFloat("light.linear", 0.09f);
- shader_cube->setFloat("light.quadratic", 0.032f);
- shader_cube->setVec3("light.position", phc->getPos());
- shader_cube->setVec3("light.direction", phc->GetForwardVec());
- shader_cube->setFloat("light.cutOff", glm::cos(glm::radians(12.5f)));
- shader_cube->setFloat("light.outerCutOff", glm::cos(glm::radians(17.5f)));
- shader_cube->setVec3("viewPos", phc->getPos());
- // draw cubes
- for (unsigned int i = 0; i < 10; i++)
- {
- glm::mat4 model;
- model = glm::scale(model, glm::vec3(5));
- model = glm::translate(model, cube->cubePositions[i]);
- float angle = 20.0f * i;
- model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
- shader_cube->setMat4("model", model);
- cube->DrawCube();
- }
- }
硬影效果图:

软影效果图:
