Lighting maps_练习二

添加一个叫做放射光贴图(Emission Map)的东西,它是一个储存了每个片段的发光值(Emission Value)的贴图。发光值是一个包含(假设)光源的物体发光(Emit)时可能显现的颜色,这样的话物体就能够忽略光照条件进行发光(Glow)。游戏中某个物体在发光的时候,你通常看到的就是放射光贴图(比如 机器人的眼,或是箱子上的灯带)。将这个纹理(作者为 creativesam)作为放射光贴图添加到箱子上,产生这些字母都在发光的效果

片段着色器代码:

 1 #version 330 core
 2 struct Material {
 3     sampler2D diffuse;
 4     sampler2D specular;
 5     sampler2D emission;
 6     float shininess;
 7 }; 
 8 
 9 struct Light {
10     vec3 position;
11 
12     vec3 ambient;
13     vec3 diffuse;
14     vec3 specular;
15 };
16 
17 in vec2 TexCoords;
18 in vec3 Normal;
19 in vec3 FragPos;
20 out vec4 FragColor;
21  
22 uniform Material material; 
23 uniform Light light;
24 uniform vec3 viewPos;
25 uniform sampler2D creativesam;
26 
27 void main()
28 {    
29     // 环境光
30     vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
31 
32     // 漫反射 
33     vec3 norm = normalize(Normal);
34     vec3 lightDir = normalize(light.position - FragPos);
35     float diff = max(dot(norm, lightDir), 0.0);
36     vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
37 
38     // 镜面光
39     vec3 viewDir = normalize(viewPos - FragPos);
40     vec3 reflectDir = reflect(-lightDir, norm);  
41     float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
42     vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
43 
44     // emission
45     vec3 emission = vec3(texture(material.emission, TexCoords));
46 
47     vec3 result = ambient + diffuse + specular + emission;
48     FragColor = vec4(result, 1.0);
49 }
View Code

完整代码:

  1 #include <glad/glad.h>
  2 #include <GLFW/glfw3.h>
  3 #define STB_IMAGE_IMPLEMENTATION
  4 #include <stb/stb_image.h>
  5 
  6 #include <glm/glm.hpp>
  7 #include <glm/gtc/matrix_transform.hpp>
  8 #include <glm/gtc/type_ptr.hpp>
  9 
 10 #include <Shader/shader.h>
 11 #include <Camera/camera.h>
 12 
 13 #include <iostream>
 14 
 15 void framebuffer_size_callback(GLFWwindow* window, int width, int height);
 16 void mouse_callback(GLFWwindow* window, double xpos, double ypos);
 17 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
 18 void processInput(GLFWwindow *window);
 19 unsigned int loadTexture(const char *path);
 20 
 21 // settings
 22 const unsigned int SCR_WIDTH = 800;
 23 const unsigned int SCR_HEIGHT = 600;
 24 
 25 // camera
 26 Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
 27 float lastX = SCR_WIDTH / 2.0f;
 28 float lastY = SCR_HEIGHT / 2.0f;
 29 bool firstMouse = true;
 30 
 31 //timeing
 32 float deltaTime = 0.0f; // 当前帧与上一帧的时间差
 33 float lastFrame = 0.0f; // 上一帧的时间
 34 
 35 // lighting
 36 glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
 37 
 38 int main()
 39 {
 40     // glfw: initialize and configure
 41     // ------------------------------
 42     glfwInit();
 43     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
 44     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 45     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 46 
 47 #ifdef __APPLE__
 48     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
 49 #endif
 50 
 51     // glfw window creation
 52     // --------------------
 53     GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
 54     if (window == NULL)
 55     {
 56         std::cout << "Failed to create GLFW window" << std::endl;
 57         glfwTerminate();
 58         return -1;
 59     }
 60     glfwMakeContextCurrent(window);
 61     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
 62     glfwSetCursorPosCallback(window, mouse_callback);
 63     glfwSetScrollCallback(window, scroll_callback);
 64 
 65     // tell GLFW to capture our mouse
 66     glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
 67 
 68     // glad: load all OpenGL function pointers
 69     // ---------------------------------------
 70     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
 71     {
 72         std::cout << "Failed to initialize GLAD" << std::endl;
 73         return -1;
 74     }
 75 
 76     // configure global opengl state
 77     // -----------------------------
 78     glEnable(GL_DEPTH_TEST);
 79 
 80     // build and compile our shader zprogram
 81     // ------------------------------------
 82     Shader lightingShader("colors.vs", "colors.fs");
 83     Shader lampShader("lamp.vs", "lamp.fs");
 84 
 85     // set up vertex data (and buffer(s)) and configure vertex attributes
 86     // ------------------------------------------------------------------
 87     float vertices[] = {
 88         // positions          // normals           // texture coords
 89         -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
 90         0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
 91         0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
 92         0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
 93         -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
 94         -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
 95 
 96         -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
 97         0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
 98         0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
 99         0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
100         -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
101         -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
102 
103         -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
104         -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
105         -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
106         -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
107         -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
108         -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
109 
110         0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
111         0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
112         0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
113         0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
114         0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
115         0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
116 
117         -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
118         0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
119         0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
120         0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
121         -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
122         -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
123 
124         -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
125         0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
126         0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
127         0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
128         -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
129         -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
130     };
131 
132     unsigned int VBO, cubeVAO;
133     glGenVertexArrays(1, &cubeVAO);
134     glGenBuffers(1, &VBO);
135 
136     glBindVertexArray(cubeVAO);
137 
138     glBindBuffer(GL_ARRAY_BUFFER, VBO);
139     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
140 
141     // position attribute
142     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
143     glEnableVertexAttribArray(0);
144     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
145     glEnableVertexAttribArray(1);
146     glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
147     glEnableVertexAttribArray(2);
148 
149     unsigned int diffuseMap = loadTexture("container2.png");
150     unsigned int specularMap = loadTexture("container2_specular.png");
151     unsigned int emissionMap = loadTexture("matrix.jpg");
152     //unsigned int specularMap = loadTexture("matrix.jpg");
153 
154     lightingShader.use();
155     lightingShader.setInt("material.diffuse", 0);
156     lightingShader.setInt("material.specular", 1);
157     lightingShader.setInt("material.emission", 2);
158 
159     unsigned int lightVAO;
160     glGenVertexArrays(1, &lightVAO);
161     glBindVertexArray(lightVAO);
162     // 只需要绑定VBO不用再次设置VBO的数据,因为箱子的VBO数据中已经包含了正确的立方体顶点数据
163     glBindBuffer(GL_ARRAY_BUFFER, VBO);
164     // 设置灯立方体的顶点属性(对我们的灯来说仅仅只有位置数据)
165     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
166     glEnableVertexAttribArray(0);
167 
168 
169     // render loop
170     // -----------
171     while (!glfwWindowShouldClose(window))
172     {
173         float currentFrame = glfwGetTime();
174         deltaTime = currentFrame - lastFrame;
175         lastFrame = currentFrame;
176 
177         // input
178         // -----
179         processInput(window);
180 
181         // render
182         // ------
183         glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
184         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
185 
186         // bind textures on corresponding texture units
187         glActiveTexture(GL_TEXTURE0);
188         glBindTexture(GL_TEXTURE_2D, diffuseMap);
189         glActiveTexture(GL_TEXTURE1);
190         glBindTexture(GL_TEXTURE_2D, specularMap);
191         glActiveTexture(GL_TEXTURE2);
192         glBindTexture(GL_TEXTURE_2D, emissionMap);
193 
194         // activate shader
195         lightingShader.use();
196 
197         lightingShader.setVec3("viewPos", camera.Position);
198 
199         //lightingShader.setVec3("material.specular", 0.5f, 0.5f, 0.5f);
200         lightingShader.setFloat("material.shininess", 64.0f);
201 
202         lightingShader.setVec3("light.position", lightPos);
203         lightingShader.setVec3("light.ambient", 0.2f, 0.2f, 0.2f);
204         lightingShader.setVec3("light.diffuse", 0.5f, 0.5f, 0.5f); // 将光照调暗了一些以搭配场景
205         lightingShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f);
206 
207         // pass projection matrix to shader (note that in this case it could change every frame)
208         glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
209         lightingShader.setMat4("projection", projection);
210 
211         // camera/view transformation
212         glm::mat4 view = camera.GetViewMatrix();
213         lightingShader.setMat4("view", view);
214 
215         glm::mat4 model = glm::mat4(1.0);
216         lightingShader.setMat4("model", model);
217 
218         // render boxes
219         glBindVertexArray(cubeVAO);
220         glDrawArrays(GL_TRIANGLES, 0, 36);
221 
222         lampShader.use();
223         lampShader.setMat4("projection", projection);
224         lampShader.setMat4("view", view);
225         model = glm::mat4(1.0f);
226         float r = 5.0f;
227         float x = sin(glfwGetTime())*r;
228         float z = cos(glfwGetTime())*r;
229         lightPos.x = x; lightPos.z = z;
230         model = glm::translate(model, lightPos);
231         model = glm::scale(model, glm::vec3(0.2f));
232         lampShader.setMat4("model", model);
233 
234         glBindVertexArray(lightVAO);
235         glDrawArrays(GL_TRIANGLES, 0, 36);
236 
237         // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
238         // -------------------------------------------------------------------------------
239         glfwSwapBuffers(window);
240         glfwPollEvents();
241     }
242 
243     // optional: de-allocate all resources once they've outlived their purpose:
244     // ------------------------------------------------------------------------
245     glDeleteVertexArrays(1, &cubeVAO);
246     glDeleteVertexArrays(1, &lightVAO);
247     glDeleteBuffers(1, &VBO);
248 
249     // glfw: terminate, clearing all previously allocated GLFW resources.
250     // ------------------------------------------------------------------
251     glfwTerminate();
252     return 0;
253 }
254 
255 // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
256 // ---------------------------------------------------------------------------------------------------------
257 void processInput(GLFWwindow *window)
258 {
259     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
260         glfwSetWindowShouldClose(window, true);
261 
262     if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
263         camera.ProcessKeyboard(FORWARD, deltaTime);
264     if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
265         camera.ProcessKeyboard(BACKWARD, deltaTime);
266     if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
267         camera.ProcessKeyboard(LEFT, deltaTime);
268     if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
269         camera.ProcessKeyboard(RIGHT, deltaTime);
270 }
271 
272 // glfw: whenever the window size changed (by OS or user resize) this callback function executes
273 // ---------------------------------------------------------------------------------------------
274 void framebuffer_size_callback(GLFWwindow* window, int width, int height)
275 {
276     // make sure the viewport matches the new window dimensions; note that width and 
277     // height will be significantly larger than specified on retina displays.
278     glViewport(0, 0, width, height);
279 }
280 
281 void mouse_callback(GLFWwindow* window, double xpos, double ypos){
282     if (firstMouse)
283     {
284         lastX = xpos;
285         lastY = ypos;
286         firstMouse = false;
287     }
288 
289     float xoffset = xpos - lastX;
290     float yoffset = lastY - ypos;
291     //std::cout << ypos << std::endl;
292     lastX = xpos;
293     lastY = ypos;
294 
295     camera.ProcessMouseMovement(xoffset, yoffset);
296 }
297 
298 // glfw: whenever the mouse scroll wheel scrolls, this callback is called
299 // ----------------------------------------------------------------------
300 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
301 {
302     camera.ProcessMouseScroll(yoffset);
303 }
304 
305 // utility function for loading a 2D texture from file
306 // ---------------------------------------------------
307 unsigned int loadTexture(char const * path)
308 {
309     unsigned int textureID;
310     glGenTextures(1, &textureID);
311 
312     int width, height, nrComponents;
313     unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
314     if (data)
315     {
316         GLenum format;
317         if (nrComponents == 1)
318             format = GL_RED;
319         else if (nrComponents == 3)
320             format = GL_RGB;
321         else if (nrComponents == 4)
322             format = GL_RGBA;
323 
324         glBindTexture(GL_TEXTURE_2D, textureID);
325         glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
326         glGenerateMipmap(GL_TEXTURE_2D);
327 
328         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
329         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
330         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
331         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
332 
333         stbi_image_free(data);
334     }
335     else
336     {
337         std::cout << "Texture failed to load at path: " << path << std::endl;
338         stbi_image_free(data);
339     }
340 
341     return textureID;
342 }
View Code

效果图:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2019/11/30

posted @ 2019-11-30 22:39  ljy3268  阅读(260)  评论(0编辑  收藏  举报