当前位置:网站首页>OpenGL Chapter 11 multiple light sources
OpenGL Chapter 11 multiple light sources
2022-06-11 03:34:00 【Carefree young heart】
This chapter is a summary of the light learned earlier
//MultipleLights
#include "Shader.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void processInput(GLFWwindow* window);
glm::vec3 camera(glm::vec3(0.0f, 0.0f, 3.0f));
// settings
const unsigned int SCR_WIDTH = 800; // Define the size of screen space
const unsigned int SCR_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);
bool firstMouse = true;
float yaw = -90.0f; // Yaw is initialized to -90.0 degree , Because the yaw is 0.0 Will result in a direction vector pointing to the right , So we initially rotated a little to the left .
float pitch = 0.0f; // Initialize pitch angle
float lastX = 800.0f / 2.0;// In order to set the initial position as the center of the screen, take half the size of the screen space
float lastY = 600.0 / 2.0;
float fov = 45.0f;// Initial field angle
// timing
float deltaTime = 0.0f; // time between current frame and last frame
float lastFrame = 0.0f;
glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
//glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
void processInput(GLFWwindow* window);
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)
};
float 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
};
// Define a vec3 Type array to store the displacement matrix
glm::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),
};
int main()
{
//Glfw: Initialization and configuration
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
//glfw Window creation
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);// Use the size of the defined screen space
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
// First we have to tell GLFW, It should hide the cursor , And capture (Capture) it .
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// Load all OpenGL A function pointer
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// Configure global opengl state
// -----------------------------
glEnable(GL_DEPTH_TEST);
// Build and compile our shader Program
// ------------------------------------
Shader ourShader("shaderSampler.vs", "shaderSampler.fs");
Shader modelShader("MultipleLights.vs", "MultipleLights.fs");
Shader lightShader("lightShader.vs", "lightShader.fs");
// Create and compile vertex data ( And buffer ), Configure vertex attributes
// ------------------------------------------------------------------
unsigned int VBO, VAO, VAO2;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(VAO);
// Location properties
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// Then in the vertex shader layout (location = 1) in vec3 aNormal;// tell GPU Location 1 Properties of
glGenVertexArrays(1, &VAO2);
glBindVertexArray(VAO2);
//glBindBuffer(GL_ARRAY_BUFFER, VBO);
// Location properties
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// Normal attributes
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
// Load and create a texture
// -------------------------
unsigned int texture1, texture2;
// texture 1
// ---------
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
// Set the texture wrapping Parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set the texture filtering Parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Load image , Create textures and generate mipmaps // Multi level principle texture
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true); // tell stb_image.h stay y Flip the loaded texture on the axis .
// Why do you need to flip Y The axis is because the starting position of the texture image is the upper right and the coordinates of our vertices (0,0) The point is lower left
unsigned char* data = stbi_load("container2.png", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
// texture 2
// ---------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
// Set the texture wrapping Parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set the texture filtering Parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// load image, create texture and generate mipmaps
//data = stbi_load(("aotu.jpg"), &width, &height, &nrChannels, 0);
//data = stbi_load(("shanshui.jpg"), &width, &height, &nrChannels, 0);
data = stbi_load(("container2_specular.png"), &width, &height, &nrChannels, 0);
if (data)
{
// If there is no map, please give priority to this RGBA Medium alpha(A) passageway If your map has alpha Please be sure to use RGBA Otherwise, the map cannot be displayed
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
// Tell... For each sampler opengl Which texture unit does it belong to ( Just do it once )
// -------------------------------------------------------------------------------------------
modelShader.use();
modelShader.setInt("material.diffuse", 0);
modelShader.setInt("material.specular", 1);
// ourShader.setVec3("lightPos", lightPos);
// Render loop
// -----------
while (!glfwWindowShouldClose(window))
{
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// -----
processInput(window);
// Rendering
// ------
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the color buffer of the previous frame as well as Depth test buffer
// Activate shader
float angle = 20.0f * 0 * (float)glfwGetTime();// Give me a glfwGetTime Let the model rotate
glm::mat4 projection = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 model = glm::mat4(1.0f);
//glm::vec3 lightPos = glm::vec3(cubePositions[10]);// Light source location
projection = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);// Projection matrix Parameters : Viewport size , Screen aspect ratio , as well as near and far
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);//lookAt matrix Parameters : Camera position , Observe the position of the target , A vertical upward direction
model = glm::translate(model, cubePositions[0]);// Pass in the array to each new model, which has different displacement in world coordinates
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
lightShader.use();
lightShader.setMat4("model", model);// Set the model transformation matrix
lightShader.setMat4("projection", projection);// Set the projection change matrix
lightShader.setMat4("view", view);// Set the view change matrix
for (unsigned int i = 0; i < 4; i++)
{
model = glm::mat4(1.0f);
model = glm::translate(model, pointLightPositions[i]);
model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube
lightShader.setMat4("model", model);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
modelShader.use();
//modelShader.use();
//lightPos.x = 1.0f + sin(glfwGetTime()) * 2.0f;
//lightPos.y = sin(glfwGetTime() / 2.0f) * 1.0f;
model = glm::mat4(1.0f);
model = glm::translate(model, cubePositions[0]);// Pass in the array to each new model, which has different displacement in world coordinates
angle = 20.0f * 1 * (float)glfwGetTime();// Give me a glfwGetTime Let the model rotate
model = glm::rotate(model, glm::radians(angle) * 0, glm::vec3(1.0f, 0.5f, 0.5f));//rotate Model location Rotation angle Rotation axis
modelShader.setMat4("model", model);// Set the model transformation matrix
modelShader.setMat4("projection", projection);// Set the projection change matrix
modelShader.setMat4("view", view);// Set the view change matrix
modelShader.setVec3("objectColor", 1, 0.5, 0.5);// Set the color of the object
modelShader.setVec3("lightColor", 0.3, 1, 0.52);// Set the color of the light source. Of course, you can also set a uniform To set variables
//modelShader.setVec3("lightPos", lightPos);// Set the light source position
modelShader.setVec3("viewPos", cameraPos);// Set the position of the camera to the viewing position
// Set each of the materials uniform component
modelShader.setFloat("material.shininess", 32.0f);
modelShader.setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f);
modelShader.setVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f);
modelShader.setVec3("dirLight.diffuse", 0.4f, 0.4f, 0.4f);
modelShader.setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
// point light 1
modelShader.setVec3("pointLights[0].position", pointLightPositions[0]);
modelShader.setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f);
modelShader.setVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f);
modelShader.setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f);
modelShader.setFloat("pointLights[0].constant", 1.0f);
modelShader.setFloat("pointLights[0].linear", 0.09f);
modelShader.setFloat("pointLights[0].quadratic", 0.032f);
// point light 2
modelShader.setVec3("pointLights[1].position", pointLightPositions[1]);
modelShader.setVec3("pointLights[1].ambient", 0.05f, 0.05f, 0.05f);
modelShader.setVec3("pointLights[1].diffuse", 0.8f, 0.8f, 0.8f);
modelShader.setVec3("pointLights[1].specular", 1.0f, 1.0f, 1.0f);
modelShader.setFloat("pointLights[1].constant", 1.0f);
modelShader.setFloat("pointLights[1].linear", 0.09f);
modelShader.setFloat("pointLights[1].quadratic", 0.032f);
// point light 3
modelShader.setVec3("pointLights[2].position", pointLightPositions[2]);
modelShader.setVec3("pointLights[2].ambient", 0.05f, 0.05f, 0.05f);
modelShader.setVec3("pointLights[2].diffuse", 0.8f, 0.8f, 0.8f);
modelShader.setVec3("pointLights[2].specular", 1.0f, 1.0f, 1.0f);
modelShader.setFloat("pointLights[2].constant", 1.0f);
modelShader.setFloat("pointLights[2].linear", 0.09f);
modelShader.setFloat("pointLights[2].quadratic", 0.032f);
// point light 4
modelShader.setVec3("pointLights[3].position", pointLightPositions[3]);
modelShader.setVec3("pointLights[3].ambient", 0.05f, 0.05f, 0.05f);
modelShader.setVec3("pointLights[3].diffuse", 0.8f, 0.8f, 0.8f);
modelShader.setVec3("pointLights[3].specular", 1.0f, 1.0f, 1.0f);
modelShader.setFloat("pointLights[3].constant", 1.0f);
modelShader.setFloat("pointLights[3].linear", 0.09f);
modelShader.setFloat("pointLights[3].quadratic", 0.032f);
modelShader.setVec3("spotLight.position", 0.0f, 0.0f, -1.0f);
modelShader.setVec3("spotLight.direction", 0.0f, 0.0f, 5.0f);
modelShader.setVec3("spotLight.ambient", 0.0f, 0.0f, 0.0f);
modelShader.setVec3("spotLight.diffuse", 1.0f, 1.0f, 1.0f);
modelShader.setVec3("spotLight.specular", 1.0f, 1.0f, 1.0f);
modelShader.setFloat("spotLight.constant", 1.0f);
modelShader.setFloat("spotLight.linear", 0.09f);
modelShader.setFloat("spotLight.quadratic", 0.032f);
modelShader.setFloat("spotLight.cutOff", glm::cos(glm::radians(12.5f)));
modelShader.setFloat("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));
// Activate texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
for (unsigned int i = 0; i < 10; i++)
{
glm::mat4 model;
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * i;
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
modelShader.setMat4("model", model);
glBindVertexArray(VAO2);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
float cameraSpeed = 5.5f * deltaTime;; // adjust accordingly
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
cameraPos += cameraSpeed * cameraFront;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
cameraPos -= cameraSpeed * cameraFront;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)// Here is a space bar so that we can Y Move on the axis
cameraPos += cameraUp * cameraSpeed;
//cameraPos.y = 0.0f;
// You can do this by Y The vector in the direction is set to 0 Make him FPS This type of camera can only be used in XZ Move on the plane
}
void mouse_callback(GLFWwindow* window, double xposIn, double yposIn)
{
float xpos = static_cast<float>(xposIn);
float ypos = static_cast<float>(yposIn);
// This bool The variable is initially set to true Of
// We need to set it as the center of the screen at the beginning
// If you don't do this At the beginning of the program, it will call the callback function to point to the position of the screen when you enter the mouse
// So it's far from the center
if (firstMouse)
{
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
// Then, in the mouse callback function, we calculate the offset of the mouse position between the current frame and the previous frame :
float xoffset = xpos - lastX;
float yoffset = lastY - ypos; // y The coordinates are from bottom to top
lastX = xpos;
lastY = ypos;
float sensitivity = 0.1f; // sensitivity This value can be set arbitrarily
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
// To make sure the camera doesn't roll over
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
// stay xz Look at... On the plane Y Axis
// Here we only update y value , Observe carefully x and z The component is also affected . From the triangles, we can see that their value is equal to :
//direction.x = cos(glm::radians(pitch));
//direction.y = sin(glm::radians(pitch)); // Notice that we first turn the angle into radians
//direction.z = cos(glm::radians(pitch));// here Y Axis updates do affect Z But I don't quite understand why it's directly equal to cos(pitch)
//
//
//
// Here we only update y value , Observe carefully x and z The component is also affected . From the triangles, we can see that their value is equal to :
//direction.x = cos(glm::radians(yaw));
//direction.y =1 // Y unchanged
//direction.z = sin(glm::radians(yaw));
//
// The following equation is equivalent to first completing the rotation transformation of the pitch angle and then multiplying it by the yaw angle
// Combine the above two steps
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);
}
// glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
//yoffset Is the direction in which our roller rolls vertically
if (fov >= 1.0f && fov <= 45.0f)
fov -= yoffset;
// Set a boundary for him stay 1 To 45 Between
if (fov < 1.0f)
fov = 1.0f;
if (fov > 45.0f)
fov = 45.0f;
}
//MultipleLights.fs
#version 330 core
out vec4 FragColor;
struct Material {
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 position;
vec3 direction;
float cutOff;
float outerCutOff;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
#define NR_POINT_LIGHTS 4
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;
uniform vec3 viewPos;
uniform DirLight dirLight;
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform SpotLight spotLight;
uniform Material material;
// function prototypes
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
void main()
{
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos);
// == =====================================================
// Our lighting is set up in 3 phases: directional, point lights and an optional flashlight
// For each phase, a calculate function is defined that calculates the corresponding color
// per lamp. In the main() function we take all the calculated colors and sum them up for
// this fragment's final color.
// == =====================================================
// phase 1: directional lighting
vec3 result = CalcDirLight(dirLight, norm, viewDir);
// phase 2: point lights
for(int i = 0; i < NR_POINT_LIGHTS; i++)
result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
// phase 3: spot light
result += CalcSpotLight(spotLight, norm, FragPos, viewDir);
FragColor = vec4(result, 1.0);
}
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
vec3 lightDir = normalize(-light.direction);
// Diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// Specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// Consolidated results
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 lightDir = normalize(light.position - fragPos);
// Diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// Specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance +
light.quadratic * (distance * distance));
// Consolidated results
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 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// spotlight intensity
float theta = dot(lightDir, normalize(-light.direction));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
// combine results
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 * intensity;
diffuse *= attenuation * intensity;
specular *= attenuation * intensity;
return (ambient + diffuse + specular);
}
//MultipleLights.vs
#version 330 core
layout (location = 0) in vec3 aPos;// The initial position is 0 The attribute of is vertex position
layout (location = 1) in vec3 aNormal;// The initial position is 1 The attribute of is normal position
layout (location = 2) in vec2 aTexCoords;// The initial position is 2 The attribute of is mapping coordinates
out vec3 FragPos;// Output the position of the object
out vec3 Normal;// Output normals
out vec2 TexCoords;// Output map
uniform mat4 model;// Define global variables model Set... In the main function
uniform mat4 view;// Define global variables view Set... In the main function
uniform mat4 projection;// Define global variables projection Set... In the main function
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
// The position of an object in world coordinates after model transformation
Normal = mat3(transpose(inverse(model))) * aNormal;
// Normal transformation matrix = Transpose of inverse matrix * Normal matrix
TexCoords = aTexCoords;
// UVW Map
gl_Position = projection * view * vec4(FragPos, 1.0);// The last position you see in the cone
}
//lightShader.fs
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0);
}
//lightShader.vs
#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}

边栏推荐
- UML series articles (28) architecture modeling - collaboration
- svg实现纸飞机自由的飞翔动画
- jlink最新版本下载
- Multi thread alternate output ab
- RequestContextHolder
- {dataSource-1} closing ... {dataSource-1} closed
- postgresql 捕获函数中的异常
- Canvas+svg line particle animation web page background
- Instructor add function_ Enable auto fill_ Instructor modification function
- 名不副实的雅迪高端品牌VFLY,为何“不高端”?
猜你喜欢

three.js炫酷科技感背景h5动画

If the source code of the home page module is not separated ----- > nanny level source code analysis (1)

/10个值得推荐的学习编程的网站 世界已经进入了互联网的时代。据最近发布的一篇《2016年互联网趋势》报告显示,中国已成为互联网市场的领导者,中国互联网用户的数量达到了6.68亿。可以预见,有

Dépannage du problème de retard des données de communication du micro - ordinateur à puce unique

PostgreSQL source code learning (22) - fault recovery ③ - transaction log registration

用Fragment实现图片简易浏览

Understand single chip microcomputer drive 8080lcd

PostgreSQL source code learning (XX) -- fault recovery ① - transaction log format

If no separation ----- > > login module nanny level source code analysis (0)

單片機通信數據延遲問題排查
随机推荐
Azure Kubernates Service 更新|提升开发体验和效率
Mazhiqiang: research progress and application of speech recognition technology -- RTC dev Meetup
【ELT.ZIP】OpenHarmony啃论文俱乐部——快速随机访问字符串压缩
Troubleshooting of single chip microcomputer communication data delay
PostgreSQL source code learning (21) -- fault recovery ② - transaction log initialization
Oppo reno6 turned sour by "inner roll"
R分析可视化实用数据(航班_教育_餐厅_租户_变迁_寿命_安全)
Right click PowerShell here function add
SQL查询连续三天登录的用户
canvas绘图——如何把图形放置画布中心
摘桃子(双指针)
RT thread test
PostgreSQL source code learning (17) -- mvcc ② - Introduction to snapshot and isolation level
Arm development board scheme and manufacturer analysis
R生物信息学统计分析
【安全科普】今天你被社工了吗?
Simple image browsing with fragment
canvas交互式星星动画背景js特效
Mavros controls UAV to conduct binocular slam in gazebo environment
/The world of 10 recommended websites for learning programming has entered the era of the Internet. According to a recently released Internet trends 2016 report, China has become a leader in the Inter