• OpenGL_Learn12(光照)


     续OpenGL_Learn11(光照)-CSDN博客

    1. 镜面高光

    和漫反射光照一样,镜面光照也决定于光的方向向量和物体的法向量,但是它也决定于观察方向,例如玩家是从什么方向看向这个片段的。镜面光照决定于表面的反射特性。

    我们通过根据法向量翻折入射光的方向来计算反射向量(对称就是R那条线)。然后我们计算反射向量与观察方向的角度差,它们之间夹角越小,镜面光的作用就越大。由此产生的效果就是,我们看向在入射光在表面的反射方向时,会看到一点高光。

    只需要修改

    cube.vs

    增加翻折后的法向量

    1. #version 330 core
    2. layout (location = 0) in vec3 aPos;
    3. layout (location =0 ) in vec3 aNormal;
    4. out vec3 FragPos;
    5. out vec3 Normal;
    6. uniform mat4 model;
    7. uniform mat4 view;
    8. uniform mat4 projection;
    9. void main()
    10. {
    11. FragPos=vec3(model*vec4(aPos,1.0));
    12. Normal=mat3(transpose(inverse(model)))*aNormal;
    13. gl_Position = projection * view * vec4(FragPos, 1.0);
    14. }

    cube.fs

     增加一个高光因子

    1. #version 330 core
    2. out vec4 FragColor;
    3. in vec3 Normal;
    4. in vec3 FragPos;
    5. uniform vec3 objectColor;
    6. uniform vec3 lightColor;
    7. uniform vec3 lightPos;
    8. uniform vec3 viewPos;
    9. void main()
    10. {
    11. //ambient
    12. float ambientStrength=0.1;
    13. vec3 ambient=ambientStrength*lightColor;
    14. //diffuse
    15. vec3 norm=normalize(Normal);
    16. vec3 lightDir=normalize(lightPos-FragPos);//光的方向向量是光源位置向量与片段位置向量之间的向量差。
    17. //对norm和lightDir向量进行点乘,计算光源对当前片段实际的漫反射影响
    18. //两个向量之间的角度越大,漫反射分量就会越小,点乘的几何意义也如此
    19. float diff=max(dot(norm,lightDir),0.0);
    20. vec3 diffuse=diff*lightColor;
    21. //specular
    22. float specularStrength=0.5;//高光强度
    23. //漫反射是光源指向片段位置。现在这个是摄像机指向片段位置
    24. vec3 viewDir=normalize(viewPos-FragPos);
    25. vec3 reflectDir=reflect(-lightDir,norm);//reflect第一个参数就是要片段指向摄像机位置
    26. float spec=pow(max(dot(viewDir,reflectDir),0.0),32);
    27. vec3 specular=specularStrength*spec*lightColor;
    28. vec3 result=(ambient+diffuse+specular)*objectColor;
    29. FragColor = vec4(result, 1.0);
    30. }

     main.cpp

    1. #include
    2. #include
    3. #include
    4. #include "stb_image.h"
    5. #include
    6. #include "shader.h"
    7. #include "camera.h"
    8. #include
    9. #include
    10. #include
    11. void framebuffer_size_callback(GLFWwindow* window, int width, int height);
    12. void processInput(GLFWwindow* window);
    13. void mouse_callback(GLFWwindow* window, double xpos, double ypos);
    14. void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
    15. // settings
    16. const unsigned int SCR_WIDTH = 1800;
    17. const unsigned int SCR_HEIGHT = 1200;
    18. //camera
    19. Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
    20. float lastX = SCR_WIDTH / 2.0f;
    21. float lastY = SCR_HEIGHT / 2.0f;
    22. bool firstMouse = true;
    23. //timing
    24. float deltaTime = 0.0f;//不同配置绘制速度不同,所以需要这个属性
    25. float lastFrame = 0.0f;
    26. //lighting
    27. glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
    28. int main() {
    29. //glfw:initialize and configure
    30. //=============================
    31. glfwInit();
    32. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    33. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    34. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    35. #ifdef __APPLE__
    36. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    37. #endif
    38. //glfw window creation
    39. //=============================
    40. GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Learn", NULL, NULL);
    41. if (window == NULL) {
    42. std::cout << "Failed to create GLFW window" << std::endl;
    43. glfwTerminate();
    44. return -1;
    45. }
    46. glfwMakeContextCurrent(window);
    47. glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    48. glfwSetCursorPosCallback(window, mouse_callback);
    49. glfwSetScrollCallback(window, scroll_callback);
    50. //tell GLFW to capture our mouse
    51. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
    52. //glad::load all OPenGL function pointers
    53. //=============================
    54. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
    55. std::cout << "Failed to initialize GLAD" << std::endl;
    56. return -1;
    57. }
    58. //configure gloabl opengl state
    59. //=============================
    60. glEnable(GL_DEPTH_TEST);
    61. //build and compile our shader zprogram
    62. //=============================
    63. Shader lightingShader("./cube.vs", "./cube.fs");
    64. Shader lightingCubeShader("./light_cube.vs", "./light_cube.fs");
    65. //set up vertex data
    66. float vertices[] = {
    67. -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
    68. 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
    69. 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
    70. 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
    71. -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
    72. -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
    73. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
    74. 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
    75. 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
    76. 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
    77. -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
    78. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
    79. -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
    80. -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
    81. -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
    82. -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
    83. -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
    84. -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
    85. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
    86. 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
    87. 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
    88. 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
    89. 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
    90. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
    91. -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
    92. 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
    93. 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
    94. 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
    95. -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
    96. -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
    97. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
    98. 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
    99. 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
    100. 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
    101. -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
    102. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f
    103. };
    104. //第一个
    105. unsigned int VBO, cubeVAO;
    106. glGenVertexArrays(1, &cubeVAO);
    107. glGenBuffers(1, &VBO);
    108. glBindBuffer(GL_ARRAY_BUFFER, VBO);
    109. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    110. glBindVertexArray(cubeVAO);
    111. //position attribute
    112. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    113. glEnableVertexAttribArray(0);
    114. //normal attribute
    115. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    116. glEnableVertexAttribArray(1);
    117. //第二个
    118. unsigned int lightCubeVAO;
    119. glGenVertexArrays(1, &lightCubeVAO);
    120. glBindVertexArray(lightCubeVAO);
    121. glBindBuffer(GL_ARRAY_BUFFER, VBO);
    122. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    123. glEnableVertexAttribArray(0);
    124. // render loop
    125. // -----------
    126. while (!glfwWindowShouldClose(window))
    127. {
    128. // per-frame time logic
    129. // --------------------
    130. float currentFrame = static_cast<float>(glfwGetTime());
    131. deltaTime = currentFrame - lastFrame;
    132. lastFrame = currentFrame;
    133. // input
    134. // -----
    135. processInput(window);
    136. // render
    137. // ------
    138. glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    139. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    140. // be sure to activate shader when setting uniforms/drawing objects
    141. lightingShader.use();
    142. lightingShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
    143. lightingShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
    144. lightingShader.setVec3("lightPos", lightPos);
    145. lightingShader.setVec3("viewPos", camera.Position);
    146. // view/projection transformations
    147. glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
    148. glm::mat4 view = camera.GetViewMatrix();
    149. lightingShader.setMat4("projection", projection);
    150. lightingShader.setMat4("view", view);
    151. // world transformation
    152. glm::mat4 model = glm::mat4(1.0f);
    153. lightingShader.setMat4("model", model);
    154. // render the cube
    155. glBindVertexArray(cubeVAO);
    156. glDrawArrays(GL_TRIANGLES, 0, 36);
    157. // also draw the lamp object
    158. lightingCubeShader.use();
    159. lightingCubeShader.setMat4("projection", projection);
    160. lightingCubeShader.setMat4("view", view);
    161. model = glm::mat4(1.0f);
    162. model = glm::translate(model, lightPos);
    163. model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    164. lightingCubeShader.setMat4("model", model);
    165. glBindVertexArray(lightCubeVAO);
    166. glDrawArrays(GL_TRIANGLES, 0, 36);
    167. // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
    168. // -------------------------------------------------------------------------------
    169. glfwSwapBuffers(window);
    170. glfwPollEvents();
    171. }
    172. glDeleteVertexArrays(1, &cubeVAO);
    173. glDeleteVertexArrays(1, &lightCubeVAO);
    174. glDeleteBuffers(1, &VBO);
    175. glfwTerminate();
    176. return 0;
    177. }
    178. void processInput(GLFWwindow* window)
    179. {
    180. if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    181. glfwSetWindowShouldClose(window, true);
    182. if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
    183. camera.ProcessKeyboard(FORWARD, deltaTime);
    184. if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
    185. camera.ProcessKeyboard(BACKWARD, deltaTime);
    186. if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
    187. camera.ProcessKeyboard(LEFT, deltaTime);
    188. if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
    189. camera.ProcessKeyboard(RIGHT, deltaTime);
    190. }
    191. void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    192. {
    193. // make sure the viewport matches the new window dimensions; note that width and
    194. // height will be significantly larger than specified on retina displays.
    195. glViewport(0, 0, width, height);
    196. }
    197. // glfw: whenever the mouse moves, this callback is called
    198. // -------------------------------------------------------
    199. void mouse_callback(GLFWwindow* window, double xposIn, double yposIn)
    200. {
    201. float xpos = static_cast<float>(xposIn);
    202. float ypos = static_cast<float>(yposIn);
    203. if (firstMouse)
    204. {
    205. lastX = xpos;
    206. lastY = ypos;
    207. firstMouse = false;
    208. }
    209. float xoffset = xpos - lastX;
    210. float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
    211. lastX = xpos;
    212. lastY = ypos;
    213. camera.ProcessMouseMovement(xoffset, yoffset);
    214. }
    215. // glfw: whenever the mouse scroll wheel scrolls, this callback is called
    216. // ----------------------------------------------------------------------
    217. void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
    218. {
    219. camera.ProcessMouseScroll(static_cast<float>(yoffset));
    220. }

    2. 动态光源位置

    目前,我们的光源是静止的,尝试使用sin或cos函数让光源在场景中来回移动。观察光照随时间的改变能让你更容易理解冯氏光照模型。

    1. //动态修改 光源位置
    2. lightPos.x = 1.0f + sin(glfwGetTime()) * 2.0f;
    3. lightPos.y = sin(glfwGetTime() / 2.0f) * 1.0f;
    4. lightingShader.setVec3("lightPos", lightPos);

     

     基础光照 - LearnOpenGL CN (learnopengl-cn.github.io)

  • 相关阅读:
    Navicat平替工具,一款免费开源的通用数据库工具
    SSTI服务器模板注入漏洞
    配置两个网关之间通过IPSec VPN互联并通过总部IPSec网关进行NAT后上网
    6个tips缓解第三方访问风险
    Ubuntu20.04.4 LTS正确安装方案及问题解决
    如何打造适用的MES管理系统解决方案
    Oracle(2-5)Usage and Configuration of the Oracle Shared Server
    Vue项目 配置项设置
    使用mac自带服务器(一行命令即可启动)
    Huggingface transformers 里的模型加载的两种方式的写法
  • 原文地址:https://blog.csdn.net/qq_59068750/article/details/134431482