- #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 DirLight{
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
- vec3 direction;
- };
- struct PointLight{
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
- float constant;
- float linear;
- float quadratic;
-
- vec3 position;
- };
- struct SpotLight{
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
- float constant;
- float linear;
- float quadratic;
-
- vec3 position;
- vec3 direction;
- float cutOff;
- float outerCutOff;
- };
- #define NR_POINT_LIGHTS 4
- uniform Material material;
- uniform DirLight dirLight;
- uniform PointLight pointLights[NR_POINT_LIGHTS];
- uniform SpotLight spotLight;
- uniform vec3 viewPos;
- vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
- {
- vec3 lightDir=normalize(-light.direction);
- vec3 ambient=light.ambient * vec3(texture(material.diffuse, vs_in.TexCoords));
-
- float diff=max(dot(normal,lightDir),0.0f);
- vec3 diffuse=light.diffuse * diff * vec3(texture(material.diffuse, vs_in.TexCoords));
-
- vec3 reflectDir=reflect(-lightDir,normal);
- float spec=pow(max(dot(viewDir,reflectDir),0.0f),material.shininess);
- vec3 specular=light.specular * spec * vec3(texture(material.specular, vs_in.TexCoords));
- return (ambient+diffuse+specular);
- }
- vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
- {
- vec3 lightDir = normalize(light.position - fragPos);
- // 漫反射着色
- float diff = max(dot(normal, lightDir), 0.0);
- // 镜面光着色
- vec3 reflectDir = reflect(-lightDir, normal);
- float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
- // 衰减
- float distance = length(light.position - fragPos);
- float attenuation = 1.0 / (light.constant + light.linear * distance +
- light.quadratic * (distance * distance));
- // 合并结果
- vec3 ambient = light.ambient * vec3(texture(material.diffuse, vs_in.TexCoords));
- vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, vs_in.TexCoords));
- vec3 specular = light.specular * spec * vec3(texture(material.specular, vs_in.TexCoords));
- ambient *= attenuation;
- diffuse *= attenuation;
- specular *= attenuation;
- return (ambient + diffuse + specular);
- }
- vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
- {
- vec3 lightDir = normalize(light.position - fragPos);
- // 漫反射着色
- float diff = max(dot(normal, lightDir), 0.0);
- // 镜面光着色
- vec3 reflectDir = reflect(-lightDir, normal);
- float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
- // 衰减
- float distance = length(light.position - fragPos);
- float attenuation = 1.0 / (light.constant + light.linear * distance +
- light.quadratic * (distance * distance));
- // 合并结果
- vec3 ambient = light.ambient * vec3(texture(material.diffuse, vs_in.TexCoords));
- vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, vs_in.TexCoords));
- vec3 specular = light.specular * spec * vec3(texture(material.specular, vs_in.TexCoords));
- //ambient *= attenuation;
- //diffuse *= attenuation;
- //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;
- return (ambient + diffuse + specular);
- }
- void main()
- {
- vec3 norm=normalize(vs_in.Normal);
- vec3 viewDir=normalize(viewPos-vs_in.FragPos);
- //定向光
- vec3 result=CalcDirLight(dirLight, norm, viewDir);
- //点光源
- for(int i=0;i<NR_POINT_LIGHTS;i++){
- result+=CalcPointLight(pointLights[i], norm, vs_in.FragPos, viewDir);
- }
- //聚光灯
- result+=CalcSpotLight(spotLight, norm, vs_in.FragPos, viewDir);
- color=vec4(result,1.0f);
- }
- void SceneRendering::CubeRendering() {
- //update uniform buffer
- cube->setViewMat(phc->getViewMatrix());
- cube->setProjectionMat(phc->getProjectionMatrix());
- shader_multiLights->use();
- shader_multiLights->setInt("material.diffuse", 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, container);
- shader_multiLights->setInt("material.specular", 1);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, container_specular);
- shader_multiLights->setFloat("material.shininess", 500);
- shader_multiLights->setVec3("viewPos", phc->getPos());
- glm::vec3 pointLightPositions[] = {
- glm::vec3(0.7f, 0.2f, 2.0f),
- glm::vec3(2.3f, -3.3f, -4.0f),
- glm::vec3(-4.0f, 2.0f, -12.0f),
- glm::vec3(0.0f, 0.0f, -3.0f)
- };
- glm::vec3 pointLightColors[] = {
- glm::vec3(1.0f, 0.6f, 0.0f),
- glm::vec3(1.0f, 0.0f, 0.0f),
- glm::vec3(0.0f, 1.0, 0.0),
- glm::vec3(0.2f, 0.2f, 1.0f)
- };
- // Directional light
- shader_multiLights->setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f);
- shader_multiLights->setVec3("dirLight.ambient", 0.3f, 0.24f, 0.14f);
- shader_multiLights->setVec3("dirLight.diffuse", 0.7f, 0.42f, 0.26f);
- shader_multiLights->setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
- // Point light 1
- shader_multiLights->setVec3("pointLights[0].position", pointLightPositions[0].x, pointLightPositions[0].y, pointLightPositions[0].z);
- shader_multiLights->setVec3("pointLights[0].ambient", pointLightColors[0].x * 0.1, pointLightColors[0].y * 0.1, pointLightColors[0].z * 0.1);
- shader_multiLights->setVec3("pointLights[0].diffuse", pointLightColors[0].x, pointLightColors[0].y, pointLightColors[0].z);
- shader_multiLights->setVec3("pointLights[0].specular", pointLightColors[0].x, pointLightColors[0].y, pointLightColors[0].z);
- shader_multiLights->setFloat("pointLights[0].constant", 1.0f);
- shader_multiLights->setFloat("pointLights[0].linear", 0.09f);
- shader_multiLights->setFloat("pointLights[0].quadratic", 0.032f);
- // Point light 2
- shader_multiLights->setVec3("pointLights[1].position", pointLightPositions[1].x, pointLightPositions[1].y, pointLightPositions[1].z);
- shader_multiLights->setVec3("pointLights[1].ambient", pointLightColors[1].x * 0.1, pointLightColors[1].y * 0.1, pointLightColors[1].z * 0.1);
- shader_multiLights->setVec3("pointLights[1].diffuse", pointLightColors[1].x, pointLightColors[1].y, pointLightColors[1].z);
- shader_multiLights->setVec3("pointLights[1].specular", pointLightColors[1].x, pointLightColors[1].y, pointLightColors[1].z);
- shader_multiLights->setFloat("pointLights[1].constant", 1.0f);
- shader_multiLights->setFloat("pointLights[1].linear", 0.09f);
- shader_multiLights->setFloat("pointLights[1].quadratic", 0.032f);
- // Point light 3
- shader_multiLights->setVec3("pointLights[2].position", pointLightPositions[2].x, pointLightPositions[2].y, pointLightPositions[2].z);
- shader_multiLights->setVec3("pointLights[2].ambient", pointLightColors[2].x * 0.1, pointLightColors[2].y * 0.1, pointLightColors[2].z * 0.1);
- shader_multiLights->setVec3("pointLights[2].diffuse", pointLightColors[2].x, pointLightColors[2].y, pointLightColors[2].z);
- shader_multiLights->setVec3("pointLights[2].specular", pointLightColors[2].x, pointLightColors[2].y, pointLightColors[2].z);
- shader_multiLights->setFloat("pointLights[2].constant", 1.0f);
- shader_multiLights->setFloat("pointLights[2].linear", 0.09f);
- shader_multiLights->setFloat("pointLights[2].quadratic", 0.032f);
- // Point light 4
- shader_multiLights->setVec3("pointLights[3].position", pointLightPositions[3].x, pointLightPositions[3].y, pointLightPositions[3].z);
- shader_multiLights->setVec3("pointLights[3].ambient", pointLightColors[3].x * 0.1, pointLightColors[3].y * 0.1, pointLightColors[3].z * 0.1);
- shader_multiLights->setVec3("pointLights[3].diffuse", pointLightColors[3].x, pointLightColors[3].y, pointLightColors[3].z);
- shader_multiLights->setVec3("pointLights[3].specular", pointLightColors[3].x, pointLightColors[3].y, pointLightColors[3].z);
- shader_multiLights->setFloat("pointLights[3].constant", 1.0f);
- shader_multiLights->setFloat("pointLights[3].linear", 0.9f);
- shader_multiLights->setFloat("pointLights[3].quadratic", 0.032f);
- // Spot light
- shader_multiLights->setVec3("spotLight.position", phc->getPos());
- shader_multiLights->setVec3("spotLight.direction", phc->GetForwardVec());
- shader_multiLights->setVec3("spotLight.ambient", 0.0f, 0.0f, 0.0f);
- shader_multiLights->setVec3("spotLight.diffuse", 1.0f, 1.0f, 0.0f);
- shader_multiLights->setVec3("spotLight.specular", 1.0f, 1.0f, 0.0f);
- shader_multiLights->setFloat("spotLight.constant", 1.0f);
- shader_multiLights->setFloat("spotLight.linear", 0.9f);
- shader_multiLights->setFloat("spotLight.quadratic", 0.032f);
- shader_multiLights->setFloat("spotLight.cutOff", glm::cos(glm::radians(12.5f)));
- shader_multiLights->setFloat("spotLight.outerCutOff", glm::cos(glm::radians(14.5f)));
- // 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_multiLights->setMat4("model", model);
- cube->DrawCube();
- }
- }