化隆网站建设公司,网站建设推广总结,开发app的软件,二级域名站群引言
现实生活中的光照极其复杂#xff0c;而且会收到很多因素的影响#xff0c;是我们当前计算机的算力无法模拟的。因此我们会根据一些简化的模型来模拟现实光照#xff0c;这样在可以模拟出近似的光照感受#xff0c;但是又没有那么复杂的计算。 常用的光照模型有…引言
现实生活中的光照极其复杂而且会收到很多因素的影响是我们当前计算机的算力无法模拟的。因此我们会根据一些简化的模型来模拟现实光照这样在可以模拟出近似的光照感受但是又没有那么复杂的计算。 常用的光照模型有兰伯特光照模型主要是模拟漫反射半兰伯特光照模型调优兰伯特全黑的缺点Phong光照模型模拟镜面反射BlinnPhong光照模型兰伯特Phong等
Phong光照模型
从模拟光照的角度我们主要有3种光照环境光、漫反射光照、镜面反射。
环境光 现实生活中光照通常来自于多个光源并且会在多个物体之间发散和反弹一个物体的光照可能受到来自一个非直射的光源影响最后才进入人眼也就是所谓的间接光照。考虑到这种情况的算法叫做全局照明(Global Illumination)算法但是这种算法既开销高昂又极其复杂。 所以我们将会使用一种简化的全局照明模型叫做环境光照(Ambient Lighting)。我们使用一个很小的常量(光)颜色添加进物体片段的最终颜色里这看起来就像即使没有直射光源也始终存在着一些发散的光。
漫反射光 光线照在粗糙物体表面随机散射到各个方向漫反射中视角的位置是不重要的因为反射是完全随机的所以在任何反射方向都是随机的。我们需要测量这个光线与它所接触片段之间的角度。如果光线垂直于物体表面这束光对物体的影响会最大。
镜面反射 是光线经过物体表面反射到视野中当反射光线与人的眼睛看得方向平行时强度最大高光效果最明显夹角为90度时强度最小。
光源类型
定向光平行光
当一个光源很远的时候来自光源的每条光线接近于平行。这看起来就像所有的光线来自于同一个方向无论物体和观察者在哪儿。当一个光源被设置为无限远时它被称为定向光(Directional Light)因为所有的光线都有着同一个方向它会独立于光源的位置。 我们知道的定向光源的一个好例子是太阳。太阳和我们不是无限远但它也足够远了在计算光照的时候我们感觉它就像无限远。在下面的图片里来自于太阳的所有的光线都被定义为平行光如下图所示 点光源
某一个位置发出的光源并且该光照强度会根据距离该光源的位置发生变化距离光源位置越远光照越弱光照会随着距离发生衰减。衰减如下图所示 聚光灯
聚光是一种位于环境中某处的光源它不是向所有方向照射而是只朝某个方向照射。结果是只有一个聚光照射方向的确定半径内的物体才会被照亮其他的都保持黑暗。 聚光的好例子是路灯或手电筒OpenGL中的聚光用世界空间位置一个方向和一个指定了聚光半径的切光角来表示。我们计算的每个片段如果片段在聚光的切光方向之间就是在圆锥体内我们就会把片段照亮。如下图所示 Phong光照模型GLSL代码
顶点着色器代码
脚本VertexShaderSource2_1_1.txt
#version 330 core
layout (location 0) in vec3 position;
layout (location 1) in vec3 normal;
layout (location 2) in vec2 texCoords;out vec3 Normal;
out vec3 FragPos;
out vec2 TexCoords;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{gl_Position projection * view * model * vec4(position, 1.0f);FragPos vec3(model * vec4(position, 1.0f));Normal mat3(transpose(inverse(model))) * normal; TexCoordstexCoords;
}片段着色器代码
脚本FragmentShaderSource2_1_1.txt
#version 330 core
out vec4 color;//片段UV坐标
in vec2 TexCoords;
//片段世界空间位置坐标
in vec3 FragPos;
//片段世界空间法线
in vec3 Normal; struct Material
{vec3 ambient;//漫反射贴图sampler2D diffuse;//镜面反射贴图sampler2D specular;//镜面反射系数float shininess;
};//平行光封装结构体
struct DirLight {vec3 direction;vec3 ambient;vec3 diffuse;vec3 specular;
};//点光源封装结构体
struct PointLight {vec3 position;float constant;float linear;float quadratic; vec3 ambient;vec3 diffuse;vec3 specular;
};//聚光灯封装结构体
struct SpotLight {vec3 ambient;vec3 diffuse;vec3 specular;//衰减参数float constant;float linear;float quadratic;vec3 position;vec3 direction;//内部切光角float cutOff;//外部切光角float outerCutOff;
};//观察者位置坐标
uniform vec3 viewPos;
uniform Material material;uniform DirLight dirLight;
uniform SpotLight spotLight;
#define NR_POINT_LIGHTS 4
uniform PointLight pointLights[NR_POINT_LIGHTS];vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
vec3 CalcSpotLight(SpotLight light, vec3 noraml, vec3 fragPos, vec3 viewDir);void main()
{ vec3 norm normalize(Normal);vec3 viewDir normalize(viewPos - FragPos);// 第一步计算平行光照vec3 result CalcDirLight(dirLight, norm, viewDir);// 第二步计算点光源光照for(int i 0; i NR_POINT_LIGHTS; i)result CalcPointLight(pointLights[i], norm, FragPos, viewDir);// 第三部计算聚光灯光照//result CalcSpotLight(spotLight, norm, FragPos, viewDir);color vec4(result, 1.0);
}vec3 CalcDirLight(DirLight light,vec3 normal,vec3 viewDir)
{vec3 lightDir normalize(-light.direction);float diff max(dot(normal, lightDir), 0.0);vec3 reflectDir reflect(-lightDir, normal); float spec pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);vec3 ambient light.ambient * vec3 (texture(material.diffuse,TexCoords));vec3 diffuse light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));vec3 specular light.specular * spec * vec3(texture(material.specular, TexCoords));return (ambient diffuse specular);
}vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{vec3 lightDirnormalize(light.position-fragPos);float diffmax(dot(lightDir,normal),0.0f);vec3 reflectDirreflect(-lightDir,normal);float specpow(max(dot(viewDir,reflectDir),0.0f),material.shininess);float distancelength(light.position-fragPos);float attenuation1.0f/(light.constantlight.linear*distancelight.quadratic*distance*distance);vec3 ambient light.ambient * vec3(texture(material.diffuse,TexCoords));vec3 diffuse light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));vec3 specular light.specular * spec * vec3(texture(material.specular, TexCoords));ambient * attenuation;diffuse * attenuation;specular * attenuation;return (ambient diffuse specular);
}vec3 CalcSpotLight(SpotLight light, vec3 noraml, vec3 fragPos, vec3 viewDir)
{vec3 lightDirnormalize(light.position-fragPos);float theta dot(lightDir, normalize(-light.direction));float epsilon light.cutOff - light.outerCutOff;float intensity clamp((theta - light.outerCutOff) / epsilon,0.0, 1.0);float diffmax(dot(lightDir,noraml),0.0f);vec3 reflectDirreflect(-lightDir,noraml);float specpow(max(dot(viewDir,reflectDir),0.0f),material.shininess);float distancelength(light.position-fragPos);float attenuation1.0f/(light.constantlight.linear*distancelight.quadratic*distance*distance);vec3 ambient light.ambient * vec3(texture(material.diffuse,TexCoords));vec3 diffuse light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));vec3 specular light.specular * spec * vec3(texture(material.specular, TexCoords));ambient * attenuation;diffuse * attenuation;specular * attenuation;diffuse * intensity;specular * intensity;return (ambient diffuse specular);
}
渲染流程代码
GLSL渲染代码
#include iostream
#include cmath// GLEW
#define GLEW_STATIC
#include GL/glew.h// GLFW
#include GLFW/glfw3.h// Other Libs
#include SOIL.h
// GLM Mathematics
#include glm/glm.hpp
#include glm/gtc/matrix_transform.hpp
#include glm/gtc/type_ptr.hpp// Other includes
#include Shader.h// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void do_movement();// Window dimensions
const GLuint WIDTH 800, HEIGHT 600;// Camera
glm::vec3 cameraPos glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraFront glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp glm::vec3(0.0f, 1.0f, 0.0f);
GLfloat yaw -90.0f; // Yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction vector pointing to the right (due to how Eular angles work) so we initially rotate a bit to the left.
GLfloat pitch 0.0f;
GLfloat lastX WIDTH / 2.0;
GLfloat lastY HEIGHT / 2.0;
bool keys[1024];// Light attributes
glm::vec3 lightPos(1.2f, 1.0f, 2.0f);// Deltatime
GLfloat deltaTime 0.0f; // Time between current frame and last frame
GLfloat lastFrame 0.0f; // Time of last frame// The MAIN function, from here we start the application and run the game loop
int main()
{// Init GLFWglfwInit();// Set all the required options for GLFWglfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);// Create a GLFWwindow object that we can use for GLFWs functionsGLFWwindow* window glfwCreateWindow(WIDTH, HEIGHT, LearnOpenGL, nullptr, nullptr);glfwMakeContextCurrent(window);// Set the required callback functionsglfwSetKeyCallback(window, key_callback);glfwSetCursorPosCallback(window, mouse_callback);glfwSetScrollCallback(window, scroll_callback);// GLFW OptionsglfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensionsglewExperimental GL_TRUE;// Initialize GLEW to setup the OpenGL Function pointersglewInit();// Define the viewport dimensionsglViewport(0, 0, WIDTH, HEIGHT);// OpenGL optionsglEnable(GL_DEPTH_TEST);// Build and compile our shader programShader lightingShader(VertexShaderSource2_1_1.txt, FragmentShaderSource2_1_1.txt);Shader lampShader(VertexShaderSource1_7_1.txt, FragmentShaderSource1_7_1.txt);// Set up vertex data (and buffer(s)) and attribute pointers// Set up vertex data (and buffer(s)) and attribute pointersGLfloat vertices[] {// Positions // Normals // Texture Coords-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f};// Positions all containersglm::vec3 cubePositions[] {glm::vec3(0.0f, 0.0f, 0.0f),glm::vec3(2.0f, 5.0f, -15.0f),glm::vec3(-1.5f, -2.2f, -2.5f),glm::vec3(-3.8f, -2.0f, -12.3f),glm::vec3(2.4f, -0.4f, -3.5f),glm::vec3(-1.7f, 3.0f, -7.5f),glm::vec3(1.3f, -2.0f, -2.5f),glm::vec3(1.5f, 2.0f, -2.5f),glm::vec3(1.5f, 0.2f, -1.5f),glm::vec3(-1.3f, 1.0f, -1.5f)};// Positions of the point lightsglm::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)};// First, set the containers VAO (and VBO)GLuint VBO, containerVAO;glGenVertexArrays(1, containerVAO);glGenBuffers(1, VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindVertexArray(containerVAO);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));glEnableVertexAttribArray(2);glBindVertexArray(0);// Then, we set the lights VAO (VBO stays the same. After all, the vertices are the same for the light object (also a 3D cube))GLuint lightVAO;glGenVertexArrays(1, lightVAO);glBindVertexArray(lightVAO);// We only need to bind to the VBO (to link it with glVertexAttribPointer), no need to fill it; the VBOs data already contains all we need.glBindBuffer(GL_ARRAY_BUFFER, VBO);// Set the vertex attributes (only position data for the lamp))glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); // Note that we skip over the other data in our buffer object (we dont need the normals/textures, only positions).glEnableVertexAttribArray(0);glBindVertexArray(0);// Load texturesGLuint diffuseMap;glGenTextures(1, diffuseMap);int width, height;unsigned char* image;// Diffuse mapimage SOIL_load_image(container2.png, width, height, 0, SOIL_LOAD_RGB);glBindTexture(GL_TEXTURE_2D, diffuseMap);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);SOIL_free_image_data(image);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);GLuint specularMap;glGenTextures(1, specularMap);image SOIL_load_image(container2_specular.png, width, height, 0, SOIL_LOAD_RGB);glBindTexture(GL_TEXTURE_2D, specularMap);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);SOIL_free_image_data(image);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);glBindTexture(GL_TEXTURE_2D, 0);lightingShader.Use();glUniform1i(glGetUniformLocation(lightingShader.Program, material.diffuse), 0);glUniform1i(glGetUniformLocation(lightingShader.Program, material.specular), 1);// Game loopwhile (!glfwWindowShouldClose(window)){// Calculate deltatime of current frameGLfloat currentFrame glfwGetTime();deltaTime currentFrame - lastFrame;lastFrame currentFrame;// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functionsglfwPollEvents();do_movement();// Clear the colorbufferglClearColor(0.1f, 0.1f, 0.1f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Use cooresponding shader when setting uniforms/drawing objectslightingShader.Use(); glUniform3f(glGetUniformLocation(lightingShader.Program, viewPos), cameraPos.x, cameraPos.y, cameraPos.z);glUniform1f(glGetUniformLocation(lightingShader.Program, material.shininess), 64.0f); glUniform3f(glGetUniformLocation(lightingShader.Program, dirLight.direction), -0.2f, -1.0f, -0.3f);glUniform3f(glGetUniformLocation(lightingShader.Program, dirLight.ambient), 0.05f, 0.05f, 0.05f);glUniform3f(glGetUniformLocation(lightingShader.Program, dirLight.diffuse), 0.4f, 0.4f, 0.4f);glUniform3f(glGetUniformLocation(lightingShader.Program, dirLight.specular), 0.5f, 0.5f, 0.5f);// Point light 1glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[0].position), pointLightPositions[0].x, pointLightPositions[0].y, pointLightPositions[0].z);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[0].ambient), 0.05f, 0.05f, 0.05f);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[0].diffuse), 0.8f, 0.8f, 0.8f);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[0].specular), 1.0f, 1.0f, 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[0].constant), 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[0].linear), 0.09f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[0].quadratic), 0.032f);// Point light 2glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[1].position), pointLightPositions[1].x, pointLightPositions[1].y, pointLightPositions[1].z);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[1].ambient), 0.05f, 0.05f, 0.05f);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[1].diffuse), 0.8f, 0.8f, 0.8f);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[1].specular), 1.0f, 1.0f, 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[1].constant), 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[1].linear), 0.09f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[1].quadratic), 0.032f);// Point light 3glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[2].position), pointLightPositions[2].x, pointLightPositions[2].y, pointLightPositions[2].z);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[2].ambient), 0.05f, 0.05f, 0.05f);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[2].diffuse), 0.8f, 0.8f, 0.8f);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[2].specular), 1.0f, 1.0f, 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[2].constant), 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[2].linear), 0.09f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[2].quadratic), 0.032f);// Point light 4glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[3].position), pointLightPositions[3].x, pointLightPositions[3].y, pointLightPositions[3].z);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[3].ambient), 0.05f, 0.05f, 0.05f);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[3].diffuse), 0.8f, 0.8f, 0.8f);glUniform3f(glGetUniformLocation(lightingShader.Program, pointLights[3].specular), 1.0f, 1.0f, 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[3].constant), 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[3].linear), 0.09f);glUniform1f(glGetUniformLocation(lightingShader.Program, pointLights[3].quadratic), 0.032f);glUniform3f(glGetUniformLocation(lightingShader.Program, spotLight.ambient), 0.8f, 0.8f, 0.8f);glUniform3f(glGetUniformLocation(lightingShader.Program, spotLight.diffuse), 0.8f, 0.8f, 0.8f);glUniform3f(glGetUniformLocation(lightingShader.Program, spotLight.specular), 1.0f, 1.0f, 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, spotLight.constant), 1.0f);glUniform1f(glGetUniformLocation(lightingShader.Program, spotLight.linear), 0.09);glUniform1f(glGetUniformLocation(lightingShader.Program, spotLight.quadratic), 0.032);glUniform3f(glGetUniformLocation(lightingShader.Program, spotLight.position), cameraPos.x, cameraPos.y, cameraPos.z);glUniform3f(glGetUniformLocation(lightingShader.Program, spotLight.direction), cameraFront.x, cameraFront.y, cameraFront.z);glUniform1f(glGetUniformLocation(lightingShader.Program, spotLight.cutOff), glm::cos(glm::radians(12.5f)));glUniform1f(glGetUniformLocation(lightingShader.Program, spotLight.outerCutOff), glm::cos(glm::radians(17.5f)));// Create camera transformationsglm::mat4 view(1);glm::mat4 model(1);glm::mat4 projection(1); view glm::lookAt(cameraPos, cameraPos cameraFront, cameraUp);projection glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);// Get the uniform locationsGLint modelLoc glGetUniformLocation(lightingShader.Program, model);GLint viewLoc glGetUniformLocation(lightingShader.Program, view);GLint projLoc glGetUniformLocation(lightingShader.Program, projection);// Pass the matrices to the glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));// Bind diffuse mapglActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, diffuseMap);// Bind specular mapglActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, specularMap);// Draw the container (using containers vertex attributes)glBindVertexArray(containerVAO);for (GLuint i 0; i 10; i){model glm::mat4(1);model glm::translate(model, cubePositions[i]);GLfloat angle 20.0f * i;model glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f));glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));glDrawArrays(GL_TRIANGLES, 0, 36);}glBindVertexArray(0); lampShader.Use();// Get location objects for the matrices on the lamp shader (these could be different on a different shader)modelLoc glGetUniformLocation(lampShader.Program, model);viewLoc glGetUniformLocation(lampShader.Program, view);projLoc glGetUniformLocation(lampShader.Program, projection);// Set matricesglUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));// We now draw as many light bulbs as we have point lights.glBindVertexArray(lightVAO);for (GLuint i 0; i 4; i){model glm::mat4(1);model glm::translate(model, pointLightPositions[i]);model glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cubeglUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));glDrawArrays(GL_TRIANGLES, 0, 36);}glBindVertexArray(0);// Swap the screen buffersglfwSwapBuffers(window);}// Terminate GLFW, clearing any resources allocated by GLFW.glfwTerminate();return 0;
}// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{if (key GLFW_KEY_ESCAPE action GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);if (key 0 key 1024){if (action GLFW_PRESS)keys[key] true;else if (action GLFW_RELEASE)keys[key] false;}
}void do_movement()
{// Camera controlsGLfloat cameraSpeed 5.0f * deltaTime;if (keys[GLFW_KEY_W])cameraPos cameraSpeed * cameraFront;if (keys[GLFW_KEY_S])cameraPos - cameraSpeed * cameraFront;if (keys[GLFW_KEY_A])cameraPos - glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;if (keys[GLFW_KEY_D])cameraPos glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
}bool firstMouse true;
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{if (firstMouse){lastX xpos;lastY ypos;firstMouse false;}GLfloat xoffset xpos - lastX;GLfloat yoffset lastY - ypos; // Reversed since y-coordinates go from bottom to leftlastX xpos;lastY ypos;GLfloat sensitivity 0.05; // Change this value to your likingxoffset * sensitivity;yoffset * sensitivity;yaw xoffset;pitch yoffset;// Make sure that when pitch is out of bounds, screen doesnt get flippedif (pitch 89.0f)pitch 89.0f;if (pitch -89.0f)pitch -89.0f;glm::vec3 front;front.x cos(glm::radians(yaw)) * cos(glm::radians(pitch));front.y sin(glm::radians(pitch));front.z sin(glm::radians(yaw)) * cos(glm::radians(pitch));cameraFront glm::normalize(front);}void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{}参考链接https://www.yumefx.com/?p3006 参考链接https://learnopengl-cn.readthedocs.io/zh/latest/02%20Lighting/06%20Multiple%20lights/