OpenGL学习之路18---- 点光源

代码放在github上

根据教程:ogldev一步步开始,记录学习历程

之前学习了三个基于平行光的光照模型,相关博文如下:

OpenGL学习之路15—-环境光

OpenGL学习之路16—- 漫射光

OpenGL学习之路17—- 镜面反射光

平行光没有起点,通过方向向量来表示,不会随着距离增大而衰减

点光源

点光源即为有起点的光源,有衰减现象(即离光源越远光线越弱)。生活中常见的点光源为电灯泡。

点光源的衰减:
光线强度离光源的距离平方成反比,数学原理公式如下:
这里写图片描述
我们可以根据这个公式来计算点光源的亮度,但是在3D图形中,这样的效果并不是很好。如果距离很近时,光强便接近无限大,所以将公式进行微整:
这里写图片描述
- 分母上添加了三个衰减参数:一个常量参数、一个线性参数和一个指数参数
- 当常量参数设为1,此时就算距离很小,也不会产生无限大的光强,起到滤波的作用,过滤掉不正常数据
- 线性参数用来控制缓慢的衰减效果
- 指数因子可以控制迅速的衰减 效果

点光源的结构体表示:

struct BaseLight
{
    Vector3f Color;
    float AmbientIntensity;
    float DiffuseIntensity;
};

struct PointLight : public BaseLight
{
    Vector3f Position;

    struct
    {
        float Constant;
        float Linear;
        float Exp;
    } Attenuation;

};
  • 首先是跟平行光共同拥有的元素:光的颜色,环境光强度和漫射光强度
  • 其次是点光源自身的位置
  • 还有上面讲到的为了计算衰减后的光强的三个参数

实现点光源

因为之前所有光源实现部分都是在我们的主程序中实现,使得主程序有些臃肿,现在把光源实现部分都放在opengl_light.h中。

首先定义光源的结构体,用来表示光源:

struct BaseLight
{
    Vector3f Color;
    float AmbientIntensity;
    float DiffuseIntensity;

    BaseLight()
    {
        LoadVector3(Color,0.0f, 0.0f, 0.0f);
        AmbientIntensity = 0.0f;
        DiffuseIntensity = 0.0f;
    }
};

struct DirectionalLight:public BaseLight
{

    Vector3f Direction;

    DirectionalLight()
    {
        LoadVector3(Direction,0.0f, 0.0f, 0.0f);
    }
};

struct PointLight : public BaseLight
{
    Vector3f Position;

    struct
    {
        float Constant;
        float Linear;
        float Exp;
    } Attenuation;

    PointLight()
    {
        LoadVector3(Position, 0.0f, 0.0f, 0.0f);
        Attenuation.Constant = 1.0f;
        Attenuation.Linear = 0.0f;
        Attenuation.Exp = 0.0f;
    }
};
  • 点光源和平行光都有的部分用BaseLight结构体来封装
  • 平行光的特殊参数是方向向量,而点光源是光源位置,点光源通过自身位置和物体位置,在着色器中计算光线方向

定义一个Light类,用来获得Uniform变量的索引,传递Uniform变量的值。

class Light
{
public:
    Light(GLuint ShaderProgram)
    {
        m_shaderProg = ShaderProgram;
    }
    bool GetUniformLocations();
    void SetDirectionalLight(const DirectionalLight& Light);
    void SetEyeWorldPos(const Vector3f& EyeWorldPos);
    void SetMatSpecularIntensity(float Intensity);
    void SetMatSpecularPower(float Power);
    void SetPointLights(unsigned int NumLights, const PointLight* pLights);

private:
    static const unsigned int MAX_POINT_LIGHTS = 2;

    GLuint m_shaderProg;

    GLuint m_eyeWorldPosLocation;
    GLuint m_matSpecularIntensityLocation;
    GLuint m_matSpecularPowerLocation;
    GLuin
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值