【OpenGL】笔记十、颜色

1. 流程

光打在一个物体上,它反射出来的光是什么颜色的?

比如白色的太阳光,打在红色的物体上,我们看到的就是红色,而又因为白色光是所有可见颜色的集合,我们可不可以这样想:

白光打在物体上面,物体选择性接收rgb通道的光,反射出来的就是没有吸收的,比如下面这个例子,物体的颜色可以看作RGB反射率,白光与物体颜色相乘,结果就是反射出来的光

glm::vec3 lightColor(1.0f, 1.0f, 1.0f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (1.0f, 0.5f, 0.31f);

再比如绿光打到物体上,反射出来的也就是G通道的光

glm::vec3 lightColor(0.0f, 1.0f, 0.0f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (0.0f, 0.5f, 0.0f);

有了这个假设,我们就可以搭建一个简单的光照场景:

一个白光灯立方体和数个珊瑚红的立方体

那么对于普通物体,它的片段着色器就应该是这样:

#version 330 core
out vec4 FragColor;

uniform vec3 objectColor;
uniform vec3 lightColor;

void main()
{
    FragColor = vec4(lightColor * objectColor, 1.0);
}

而我们不希望光源的颜色一直变化,就这样新定义一个灯光的片段着色器:

#version 330 core
out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0); // 将向量的四个分量全部设置为1.0
}

同样的为了区别于其他物体,我们也给灯光绑定一个自己的VAO:

    unsigned int lightVAO;
    glGenVertexArrays(1, &lightVAO);
	glBindVertexArray(lightVAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);//都是立方体,VBO可以通用,不用再设
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

然后在全局定义灯光的位置:

glm::vec3 lightPos(1.2f, 1.0f, 2.0f);

然后给它位移、缩小一下:

model = glm::mat4();
model = glm::translate(model, lightPos);
model = glm::scale(model, glm::vec3(0.2f));

接下来就分别渲染物体和灯光:

		ourShader.use();
        glBindVertexArray(VAO); // 一般每次使用时再绑定,这里只有一个VAO,所以实际上可以不绑
        for (unsigned int i = 0; i < 10; i++)
        {
            model =  view = projection = glm::mat4(1.0f);

            projection = glm::perspective(glm::radians(fov), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);

            view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);

            model = glm::translate(model, cubePositions[i]);
            model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));

            ourShader.setMat4("model",model);
            ourShader.setMat4("view",view);
            ourShader.setMat4("projection",projection);
            ourShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
            ourShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
            glDrawArrays(GL_TRIANGLES, 0, 36);
        }
        
        lightShader.use();
        model = glm::mat4(1.0f);
        model = glm::translate(model, lightPos);
        model = glm::scale(model, glm::vec3(0.2f));
        lightShader.setMat4("model", model);
        lightShader.setMat4("view", view);
        lightShader.setMat4("projection", projection);
        glBindVertexArray(lightVAO);

效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ycr的帐号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值