经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
多光源(定向光、点光源、聚光灯)
来源:cnblogs  作者:茶飘香~  时间:2019/10/8 9:15:30  对本文有异议

 

  前篇学习了单个的光源,现在在一个场景中放置多个不同的光源,包括一个定向光源、4个点光源、一个聚光灯。

  

  GLSL代码如下(片段着色器):

  1. #version 430 core
  2. out vec4 color;
  3. in VS_OUT{
  4. vec3 FragPos;
  5. vec3 Normal;
  6. vec2 TexCoords;
  7. }vs_in;
  8. struct Material{
  9. sampler2D diffuse;
  10. sampler2D specular;
  11. float shininess;
  12. };
  13. struct DirLight{
  14. vec3 ambient;
  15. vec3 diffuse;
  16. vec3 specular;
  17. vec3 direction;
  18. };
  19. struct PointLight{
  20. vec3 ambient;
  21. vec3 diffuse;
  22. vec3 specular;
  23. float constant;
  24. float linear;
  25. float quadratic;
  26. vec3 position;
  27. };
  28. struct SpotLight{
  29. vec3 ambient;
  30. vec3 diffuse;
  31. vec3 specular;
  32. float constant;
  33. float linear;
  34. float quadratic;
  35. vec3 position;
  36. vec3 direction;
  37. float cutOff;
  38. float outerCutOff;
  39. };
  40. #define NR_POINT_LIGHTS 4
  41. uniform Material material;
  42. uniform DirLight dirLight;
  43. uniform PointLight pointLights[NR_POINT_LIGHTS];
  44. uniform SpotLight spotLight;
  45. uniform vec3 viewPos;
  46. vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
  47. {
  48. vec3 lightDir=normalize(-light.direction);
  49. vec3 ambient=light.ambient * vec3(texture(material.diffuse, vs_in.TexCoords));
  50. float diff=max(dot(normal,lightDir),0.0f);
  51. vec3 diffuse=light.diffuse * diff * vec3(texture(material.diffuse, vs_in.TexCoords));
  52. vec3 reflectDir=reflect(-lightDir,normal);
  53. float spec=pow(max(dot(viewDir,reflectDir),0.0f),material.shininess);
  54. vec3 specular=light.specular * spec * vec3(texture(material.specular, vs_in.TexCoords));
  55. return (ambient+diffuse+specular);
  56. }
  57. vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
  58. {
  59. vec3 lightDir = normalize(light.position - fragPos);
  60. // 漫反射着色
  61. float diff = max(dot(normal, lightDir), 0.0);
  62. // 镜面光着色
  63. vec3 reflectDir = reflect(-lightDir, normal);
  64. float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
  65. // 衰减
  66. float distance = length(light.position - fragPos);
  67. float attenuation = 1.0 / (light.constant + light.linear * distance +
  68. light.quadratic * (distance * distance));
  69. // 合并结果
  70. vec3 ambient = light.ambient * vec3(texture(material.diffuse, vs_in.TexCoords));
  71. vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, vs_in.TexCoords));
  72. vec3 specular = light.specular * spec * vec3(texture(material.specular, vs_in.TexCoords));
  73. ambient *= attenuation;
  74. diffuse *= attenuation;
  75. specular *= attenuation;
  76. return (ambient + diffuse + specular);
  77. }
  78. vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
  79. {
  80. vec3 lightDir = normalize(light.position - fragPos);
  81. // 漫反射着色
  82. float diff = max(dot(normal, lightDir), 0.0);
  83. // 镜面光着色
  84. vec3 reflectDir = reflect(-lightDir, normal);
  85. float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
  86. // 衰减
  87. float distance = length(light.position - fragPos);
  88. float attenuation = 1.0 / (light.constant + light.linear * distance +
  89. light.quadratic * (distance * distance));
  90. // 合并结果
  91. vec3 ambient = light.ambient * vec3(texture(material.diffuse, vs_in.TexCoords));
  92. vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, vs_in.TexCoords));
  93. vec3 specular = light.specular * spec * vec3(texture(material.specular, vs_in.TexCoords));
  94. //ambient *= attenuation;
  95. //diffuse *= attenuation;
  96. //specular *= attenuation;
  97.  
  98. float theta=dot(lightDir,normalize(-light.direction));
  99. float epsilon=light.cutOff-light.outerCutOff;
  100. float intensity=clamp((theta-light.outerCutOff)/epsilon,0.0,1.0);
  101. ambient*=intensity;
  102. diffuse*=intensity;
  103. specular*=intensity;
  104. return (ambient + diffuse + specular);
  105. }
  106. void main()
  107. {
  108. vec3 norm=normalize(vs_in.Normal);
  109. vec3 viewDir=normalize(viewPos-vs_in.FragPos);
  110. //定向光
  111. vec3 result=CalcDirLight(dirLight, norm, viewDir);
  112. //点光源
  113. for(int i=0;i<NR_POINT_LIGHTS;i++){
  114. result+=CalcPointLight(pointLights[i], norm, vs_in.FragPos, viewDir);
  115. }
  116. //聚光灯
  117. result+=CalcSpotLight(spotLight, norm, vs_in.FragPos, viewDir);
  118. color=vec4(result,1.0f);
  119. }

  

  渲染代码如下:

  1. void SceneRendering::CubeRendering() {
  2. //update uniform buffer
  3. cube->setViewMat(phc->getViewMatrix());
  4. cube->setProjectionMat(phc->getProjectionMatrix());
  5. shader_multiLights->use();
  6. shader_multiLights->setInt("material.diffuse", 0);
  7. glActiveTexture(GL_TEXTURE0);
  8. glBindTexture(GL_TEXTURE_2D, container);
  9. shader_multiLights->setInt("material.specular", 1);
  10. glActiveTexture(GL_TEXTURE1);
  11. glBindTexture(GL_TEXTURE_2D, container_specular);
  12. shader_multiLights->setFloat("material.shininess", 500);
  13. shader_multiLights->setVec3("viewPos", phc->getPos());
  14. glm::vec3 pointLightPositions[] = {
  15. glm::vec3(0.7f, 0.2f, 2.0f),
  16. glm::vec3(2.3f, -3.3f, -4.0f),
  17. glm::vec3(-4.0f, 2.0f, -12.0f),
  18. glm::vec3(0.0f, 0.0f, -3.0f)
  19. };
  20. glm::vec3 pointLightColors[] = {
  21. glm::vec3(1.0f, 0.6f, 0.0f),
  22. glm::vec3(1.0f, 0.0f, 0.0f),
  23. glm::vec3(0.0f, 1.0, 0.0),
  24. glm::vec3(0.2f, 0.2f, 1.0f)
  25. };
  26. // Directional light
  27. shader_multiLights->setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f);
  28. shader_multiLights->setVec3("dirLight.ambient", 0.3f, 0.24f, 0.14f);
  29. shader_multiLights->setVec3("dirLight.diffuse", 0.7f, 0.42f, 0.26f);
  30. shader_multiLights->setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
  31. // Point light 1
  32. shader_multiLights->setVec3("pointLights[0].position", pointLightPositions[0].x, pointLightPositions[0].y, pointLightPositions[0].z);
  33. shader_multiLights->setVec3("pointLights[0].ambient", pointLightColors[0].x * 0.1, pointLightColors[0].y * 0.1, pointLightColors[0].z * 0.1);
  34. shader_multiLights->setVec3("pointLights[0].diffuse", pointLightColors[0].x, pointLightColors[0].y, pointLightColors[0].z);
  35. shader_multiLights->setVec3("pointLights[0].specular", pointLightColors[0].x, pointLightColors[0].y, pointLightColors[0].z);
  36. shader_multiLights->setFloat("pointLights[0].constant", 1.0f);
  37. shader_multiLights->setFloat("pointLights[0].linear", 0.09f);
  38. shader_multiLights->setFloat("pointLights[0].quadratic", 0.032f);
  39. // Point light 2
  40. shader_multiLights->setVec3("pointLights[1].position", pointLightPositions[1].x, pointLightPositions[1].y, pointLightPositions[1].z);
  41. shader_multiLights->setVec3("pointLights[1].ambient", pointLightColors[1].x * 0.1, pointLightColors[1].y * 0.1, pointLightColors[1].z * 0.1);
  42. shader_multiLights->setVec3("pointLights[1].diffuse", pointLightColors[1].x, pointLightColors[1].y, pointLightColors[1].z);
  43. shader_multiLights->setVec3("pointLights[1].specular", pointLightColors[1].x, pointLightColors[1].y, pointLightColors[1].z);
  44. shader_multiLights->setFloat("pointLights[1].constant", 1.0f);
  45. shader_multiLights->setFloat("pointLights[1].linear", 0.09f);
  46. shader_multiLights->setFloat("pointLights[1].quadratic", 0.032f);
  47. // Point light 3
  48. shader_multiLights->setVec3("pointLights[2].position", pointLightPositions[2].x, pointLightPositions[2].y, pointLightPositions[2].z);
  49. shader_multiLights->setVec3("pointLights[2].ambient", pointLightColors[2].x * 0.1, pointLightColors[2].y * 0.1, pointLightColors[2].z * 0.1);
  50. shader_multiLights->setVec3("pointLights[2].diffuse", pointLightColors[2].x, pointLightColors[2].y, pointLightColors[2].z);
  51. shader_multiLights->setVec3("pointLights[2].specular", pointLightColors[2].x, pointLightColors[2].y, pointLightColors[2].z);
  52. shader_multiLights->setFloat("pointLights[2].constant", 1.0f);
  53. shader_multiLights->setFloat("pointLights[2].linear", 0.09f);
  54. shader_multiLights->setFloat("pointLights[2].quadratic", 0.032f);
  55. // Point light 4
  56. shader_multiLights->setVec3("pointLights[3].position", pointLightPositions[3].x, pointLightPositions[3].y, pointLightPositions[3].z);
  57. shader_multiLights->setVec3("pointLights[3].ambient", pointLightColors[3].x * 0.1, pointLightColors[3].y * 0.1, pointLightColors[3].z * 0.1);
  58. shader_multiLights->setVec3("pointLights[3].diffuse", pointLightColors[3].x, pointLightColors[3].y, pointLightColors[3].z);
  59. shader_multiLights->setVec3("pointLights[3].specular", pointLightColors[3].x, pointLightColors[3].y, pointLightColors[3].z);
  60. shader_multiLights->setFloat("pointLights[3].constant", 1.0f);
  61. shader_multiLights->setFloat("pointLights[3].linear", 0.9f);
  62. shader_multiLights->setFloat("pointLights[3].quadratic", 0.032f);
  63. // Spot light
  64. shader_multiLights->setVec3("spotLight.position", phc->getPos());
  65. shader_multiLights->setVec3("spotLight.direction", phc->GetForwardVec());
  66. shader_multiLights->setVec3("spotLight.ambient", 0.0f, 0.0f, 0.0f);
  67. shader_multiLights->setVec3("spotLight.diffuse", 1.0f, 1.0f, 0.0f);
  68. shader_multiLights->setVec3("spotLight.specular", 1.0f, 1.0f, 0.0f);
  69. shader_multiLights->setFloat("spotLight.constant", 1.0f);
  70. shader_multiLights->setFloat("spotLight.linear", 0.9f);
  71. shader_multiLights->setFloat("spotLight.quadratic", 0.032f);
  72. shader_multiLights->setFloat("spotLight.cutOff", glm::cos(glm::radians(12.5f)));
  73. shader_multiLights->setFloat("spotLight.outerCutOff", glm::cos(glm::radians(14.5f)));
  74. // draw cubes
  75. for (unsigned int i = 0; i < 10; i++)
  76. {
  77. glm::mat4 model;
  78. model = glm::scale(model, glm::vec3(5));
  79. model = glm::translate(model, cube->cubePositions[i]);
  80. float angle = 20.0f * i;
  81. model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
  82. shader_multiLights->setMat4("model", model);
  83. cube->DrawCube();
  84. }
  85. }

  

  效果图:

  1、定向光+点光源

  

  2、定向光+点光源+聚光灯(软影)

  

  

  

原文链接:http://www.cnblogs.com/chen9510/p/11625464.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号