投光物

Posted chen9510

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了投光物相关的知识,希望对你有一定的参考价值。

 

  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();
    

  硬影效果图:

  技术图片

  软影效果图:

  技术图片

  

以上是关于投光物的主要内容,如果未能解决你的问题,请参考以下文章

昂宝OB3635AMPOB33398MP大功率投光灯80W驱动照明

RT7304GE隔离大功率50-100W路灯/投光灯照明驱动

如何在家自制LED灯?很简单,我来告诉你!

聊聊恺明大神MAE的成功之处!

聊聊恺明大神MAE的成功之处!

致力于知识开源的我们,你愿意加入吗?