OpenGL 3.1照明混乱,使用Phong着色

aamkag61  于 2024-01-07  发布在  其他
关注(0)|答案(3)|浏览(203)

经过许多痛苦的小时试图弄清楚为什么我的照明是搞砸了,我仍然不知所措。
OpenGL法线是正确的(背面剔除不会导致我的任何三角形消失)
我计算我的法线,以插值照明,所有的三角形在同一面也有相同的法线。
如果任何人有任何想法,将不胜感激。
我绝对是OpenGL的新手,所以这在我的代码中有点明显。

以下是我的shader:

  • 顶点着色器
  1. #version 330 core
  2. layout(location = 0) in vec3 Position;
  3. layout(location = 1) in vec3 vertexColor;
  4. in vec3 vNormal;
  5. out vec3 fragmentColor; // Output data ; will be interpolated for each fragment.
  6. uniform mat4 MVP;
  7. uniform mat4 transformMatrix;
  8. uniform vec4 LightPosition;
  9. // output values that will be interpretated per-fragment
  10. out vec3 fN;
  11. out vec3 fE;
  12. out vec3 fL;
  13. void main()
  14. {
  15. fN = vNormal;
  16. fE = Position.xyz;
  17. fL = LightPosition.xyz;
  18. if( LightPosition.w != 0.0 ) {
  19. fL = LightPosition.xyz - Position.xyz;
  20. }
  21. // Output position of the vertex, in clip space : MVP * position
  22. vec4 v = vec4(Position,1); // Transform in homoneneous 4D vector
  23. gl_Position = MVP * v;
  24. //gl_Position = MVP * v;
  25. // The color of each vertex will be interpolated
  26. // to produce the color of each fragment
  27. //fragmentColor = vertexColor; // take out at some point
  28. }

字符串

  • 和fragmentShader,使用phong着色
  1. #version 330
  2. //out vec3 color;
  3. // per-fragment interpolated values from the vertex shader
  4. in vec3 fN;
  5. in vec3 fL;
  6. in vec3 fE;
  7. out vec4 fColor;
  8. uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
  9. uniform mat4 ModelView;
  10. uniform vec4 LightPosition;
  11. uniform float Shininess;
  12. in vec3 fragmentColor; // Interpolated values from the vertex shaders
  13. void main()
  14. {
  15. // Normalize the input lighting vectors
  16. vec3 N = normalize(fN);
  17. vec3 E = normalize(fE);
  18. vec3 L = normalize(fL);
  19. vec3 H = normalize( L + E );
  20. vec4 ambient = AmbientProduct;
  21. float Kd = max(dot(L, N), 0.0);
  22. vec4 diffuse = Kd*DiffuseProduct;
  23. float Ks = pow(max(dot(N, H), 0.0), Shininess);
  24. vec4 specular = Ks*SpecularProduct;
  25. // discard the specular highlight if the light's behind the vertex
  26. if( dot(L, N) < 0.0 ) {
  27. specular = vec4(0.0, 0.0, 0.0, 1.0);
  28. }
  29. fColor = ambient + diffuse + specular;
  30. fColor.a = 1.0;
  31. //color = vec3(1,0,0);
  32. // Output color = color specified in the vertex shader,
  33. // interpolated between all 3 surrounding vertices
  34. //color = fragmentColor;
  35. }
  36. void setMatrices()
  37. {
  38. GLfloat FoV = 45; // the zoom of the camera
  39. glm::vec3 cameraPosition(4,3,3), // the position of your camera, in world space // change to see what happends
  40. cameraTarget(0,0,0), // where you want to look at, in world space
  41. upVector(0,-1,0);
  42. // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
  43. glm::mat4 Projection = glm::perspective(FoV, 3.0f / 3.0f, 0.001f, 100.0f); // ratio needs to change here when the screen size/ratio changes
  44. // Camera matrix
  45. glm::mat4 View = glm::lookAt(
  46. cameraPosition, // Camera is at (4,3,3), in World Space
  47. cameraTarget, // and looks at the origin
  48. upVector // Head is up (set to 0,-1,0 to look upside-down)
  49. );
  50. // Model matrix : an identity matrix (model will be at the origin)
  51. glm::mat4 Model = glm::mat4(1.0f); // Changes for each model !
  52. // Our ModelViewProjection : multiplication of our 3 matrices
  53. glm::mat4 MVP = Projection * View * Model * transformMatrix; //matrix multiplication is the other way around
  54. // Get a handle for our "MVP" uniform.
  55. // Only at initialisation time.
  56. GLuint MatrixID = glGetUniformLocation(programID, "MVP");
  57. // Send our transformation to the currently bound shader,
  58. // in the "MVP" uniform
  59. // For each model you render, since the MVP will be different (at least the M part)
  60. glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
  61. RotationID = glGetUniformLocation(programID,"transformMatrix");
  62. //lighting
  63. cubeNormal = glGetAttribLocation( programID, "vNormal" );
  64. }
  65. void setBuffers()
  66. {
  67. // Get a vertex array object
  68. GLuint VAO;
  69. glGenVertexArrays(1, &VAO);
  70. glBindVertexArray(VAO);
  71. glUseProgram(programID);
  72. // cube buffer objects
  73. glGenBuffers(1, &CubeVertexbuffer); // Generate 1 buffer, put the resulting identifier in vertexbuffer
  74. glBindBuffer(GL_ARRAY_BUFFER, CubeVertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer
  75. glBufferData(GL_ARRAY_BUFFER, sizeof(CubeBufferData), CubeBufferData, GL_STATIC_DRAW); // Give our vertices to OpenGL.
  76. // cube normal objects
  77. glGenBuffers(1, &CubeNormalbuffer); // Generate 1 buffer, put the resulting identifier in vertexbuffer
  78. glBindBuffer(GL_ARRAY_BUFFER, CubeNormalbuffer); // The following commands will talk about our 'vertexbuffer' buffer
  79. glBufferData(GL_ARRAY_BUFFER, sizeof(CubeNormalBufferData), CubeNormalBufferData, GL_STATIC_DRAW); // Give our vertices to OpenGL.
  80. //octahedron buffer objects
  81. glGenBuffers(1, &OctaVertexbuffer); // Generate 1 buffer, put the resulting identifier in vertexbuffer
  82. glBindBuffer(GL_ARRAY_BUFFER, OctaVertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer
  83. glBufferData(GL_ARRAY_BUFFER, sizeof(octahedronBufData), octahedronBufData, GL_STATIC_DRAW); // Give our vertices to OpenGL.
  84. //tetrahedron buffer objects
  85. glGenBuffers(1, &TetraVertexbuffer); // Generate 1 buffer, put the resulting identifier in vertexbuffer
  86. glBindBuffer(GL_ARRAY_BUFFER, TetraVertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer
  87. glBufferData(GL_ARRAY_BUFFER, sizeof(tetrahedronBufData), tetrahedronBufData, GL_STATIC_DRAW); // Give our vertices to OpenGL.
  88. //dodecahedron buffer objects
  89. glGenBuffers(1, &DodecaVertexbuffer); // Generate 1 buffer, put the resulting identifier in vertexbuffer
  90. glBindBuffer(GL_ARRAY_BUFFER, DodecaVertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer
  91. glBufferData(GL_ARRAY_BUFFER, sizeof(dodecahedronBufData), dodecahedronBufData, GL_STATIC_DRAW); // Give our vertices to OpenGL.
  92. //icosahedron buffer objects
  93. glGenBuffers(1, &icosaVertexbuffer); // Generate 1 buffer, put the resulting identifier in vertexbuffer
  94. glBindBuffer(GL_ARRAY_BUFFER, icosaVertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer
  95. glBufferData(GL_ARRAY_BUFFER, sizeof(icosahedronBufData), icosahedronBufData, GL_STATIC_DRAW); // Give our vertices to OpenGL.
  96. //sphere buffer objects
  97. glGenBuffers(1, &sphereVertexbuffer); // Generate 1 buffer, put the resulting identifier in vertexbuffer
  98. glBindBuffer(GL_ARRAY_BUFFER, sphereVertexbuffer); // The following commands will talk about our 'vertexbuffer' buffer
  99. glBufferData(GL_ARRAY_BUFFER, sizeof(sphereBufData), sphereBufData, GL_STATIC_DRAW); // Give our vertices to OpenGL.
  100. glGenBuffers(1, &colorbuffer);
  101. glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
  102. glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
  103. // lighting stuff
  104. // Initialize shader lighting parameters
  105. point4 light_position= { 0.0, 20.0, -10.0, 0.0 };
  106. color4 light_ambient ={ 0.2, 0.2, 0.2, 1.0 };
  107. color4 light_diffuse ={ 1.0, 1.0, 1.0, 1.0 };
  108. color4 light_specular ={ 1.0, 1.0, 1.0, 1.0 };
  109. color4 material_ambient ={ 1.0, 0.0, 1.0, 1.0 };
  110. color4 material_diffuse ={ 1.0, 0.8, 0.0, 1.0 };
  111. color4 material_specular ={ 1.0, 0.8, 0.0, 1.0 };
  112. float material_shininess = 20.0;
  113. color4 ambient_product;
  114. color4 diffuse_product;
  115. color4 specular_product;
  116. int i;
  117. for (i = 0; i < 3; i++) {
  118. ambient_product[i] = light_ambient[i] * material_ambient[i];
  119. diffuse_product[i] = light_diffuse[i] * material_diffuse[i];
  120. specular_product[i] = light_specular[i] * material_specular[i];
  121. }
  122. //printColor("diffuse", diffuse_product);
  123. //printColor("specular", specular_product);
  124. glUniform4fv( glGetUniformLocation(programID, "AmbientProduct"),
  125. 1, ambient_product );
  126. glUniform4fv( glGetUniformLocation(programID, "DiffuseProduct"),
  127. 1, diffuse_product );
  128. glUniform4fv( glGetUniformLocation(programID, "SpecularProduct"),
  129. 1, specular_product );
  130. glUniform4fv( glGetUniformLocation(programID, "LightPosition"),
  131. 1, light_position );
  132. glUniform1f( glGetUniformLocation(programID, "Shininess"),
  133. material_shininess );
  134. }


还有更多...

  1. void display()
  2. {
  3. setMatrices(); // initilize Matrices
  4. // Use our shader
  5. //glUseProgram(programID);
  6. glClearColor(0.0f, 0.0f, 0.3f, 0.0f);
  7. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  8. // 2nd attribute buffer : colors
  9. glEnableVertexAttribArray(1);
  10. glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
  11. glVertexAttribPointer(
  12. 1, // attribute. No particular reason for 1, but must match the layout in the shader.
  13. 3, // size
  14. GL_FLOAT, // type
  15. GL_FALSE, // normalized?
  16. 0, // stride
  17. (void*)0 // array buffer offset
  18. );
  19. glEnableVertexAttribArray(0); // 1rst attribute buffer : vertices
  20. // enum platosShapes{tet, cube, octah, dodec, icos};
  21. switch(shapeInUse)
  22. {
  23. case tet:
  24. {
  25. glBindBuffer(GL_ARRAY_BUFFER, TetraVertexbuffer);
  26. glVertexAttribPointer(
  27. 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
  28. 3, // size
  29. GL_FLOAT, // type
  30. GL_FALSE, // normalized?
  31. 0, // stride
  32. (void*)0 // array buffer offset
  33. );
  34. glDrawArrays(GL_TRIANGLES, 0, 4*3); // Starting from vertex 0; 3 vertices total -> 1 triangle // need to know amount of vertices here // and change to triangle strips accordingly
  35. }
  36. break;
  37. case cube:
  38. {
  39. //GLuint cubeNormal = glGetAttribLocation( programID, "vNormal" );
  40. glEnableVertexAttribArray( cubeNormal );
  41. glVertexAttribPointer( cubeNormal, 3, GL_FLOAT, GL_FALSE, 0,
  42. (const GLvoid *) (sizeof(CubeNormalBufferData)) );
  43. //glDisableVertexAttribArray( cubeNormal );
  44. glBindBuffer(GL_ARRAY_BUFFER, CubeVertexbuffer);
  45. glVertexAttribPointer(
  46. 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
  47. 3, // size
  48. GL_FLOAT, // type
  49. GL_FALSE, // normalized?
  50. 0, // stride
  51. (void*)0 // array buffer offset
  52. );
  53. glDrawArrays(GL_TRIANGLES, 0, 12*3); // Starting from vertex 0; 3 vertices total -> 1 triangle // need to know amount of vertices here // and change to triangle strips accordingly
  54. }
  55. break;
  56. case octah:
  57. {
  58. glBindBuffer(GL_ARRAY_BUFFER, OctaVertexbuffer);
  59. glVertexAttribPointer(
  60. 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
  61. 3, // size
  62. GL_FLOAT, // type
  63. GL_FALSE, // normalized?
  64. 0, // stride
  65. (void*)0 // array buffer offset
  66. );
  67. glDrawArrays(GL_TRIANGLES, 0, 8*3); // Starting from vertex 0; 3 vertices total -> 1 triangle // need to know amount of vertices here // and change to triangle strips accordingly
  68. }
  69. break;
  70. case dodec:
  71. {
  72. glBindBuffer(GL_ARRAY_BUFFER, DodecaVertexbuffer);
  73. glVertexAttribPointer(
  74. 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
  75. 3, // size
  76. GL_FLOAT, // type
  77. GL_FALSE, // normalized?
  78. 0, // stride
  79. (void*)0 // array buffer offset
  80. );
  81. glDrawArrays(GL_TRIANGLE_FAN, 0, 5 * 6); // Starting from vertex 0; 3 vertices total -> 1 triangle // need to know amount of vertices here // and change to triangle strips accordingly
  82. glDrawArrays(GL_TRIANGLE_FAN, (5 * 6) + 1, 30);
  83. //glutSolidDodecahedron();
  84. //glDrawArrays(GL_TRIANGLE_STRIP,0,5*12);
  85. }
  86. break;
  87. case icos:
  88. {
  89. glBindBuffer(GL_ARRAY_BUFFER, icosaVertexbuffer);
  90. glVertexAttribPointer(
  91. 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
  92. 3, // size
  93. GL_FLOAT, // type
  94. GL_FALSE, // normalized?
  95. 0, // stride
  96. (void*)0 // array buffer offset
  97. );
  98. glDrawArrays(GL_TRIANGLES, 0, 3*20); // Starting from vertex 0; 3 vertices total -> 1 triangle // need to know amount of vertices here // and change to triangle strips accordingly
  99. }
  100. break;
  101. case sphere:
  102. {
  103. glBindBuffer(GL_ARRAY_BUFFER, sphereVertexbuffer);
  104. glVertexAttribPointer(
  105. 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
  106. 3, // size
  107. GL_FLOAT, // type
  108. GL_FALSE, // normalized?
  109. 0, // stride
  110. (void*)0 // array buffer offset
  111. );
  112. //glDrawElements(GL_TRIANGLES, cnt2, GL_UNSIGNED_INT, 0)
  113. glDrawArrays(GL_TRIANGLE_FAN, 0, 100);
  114. }
  115. }
  116. glDisableVertexAttribArray(0);
  117. glFlush();
  118. }


还有一些........

  1. void calculateNormals(GLfloat bufData[], GLfloat normBufData[], int size) // probalby works
  2. {
  3. int count = 0;
  4. GLfloat temp[9];
  5. for(int i = 0; i < size; i++)
  6. {
  7. temp[count] = bufData[i];
  8. count++;
  9. if((i+1) % 9 == 0)
  10. {
  11. count = 0;
  12. //for(int i = 0; i < 9; i++)
  13. //{
  14. // cout << temp[i] << "!,";
  15. // if((i + 1) % 3 == 0)
  16. // cout << "\n";
  17. //}
  18. calculateCross(temp, normBufData);
  19. }
  20. }
  21. printNormals(normBufData, size);
  22. }
  23. void calculateCross(GLfloat bufData[], GLfloat normBufData[]) // probably works
  24. {
  25. static int counter = 0; // need to reset in bettween new buffers
  26. glm::vec3 C1;
  27. glm::vec3 C2;
  28. glm::vec3 normal;
  29. //cout << bufData[0] << "," << bufData[1] << "," << bufData[2] << " buf 1 \n";
  30. //cout << bufData[3] << "," << bufData[4] << "," << bufData[5] << " buf 2 \n";
  31. //cout << bufData[6] << "," << bufData[7] << "," << bufData[8] << " buf 3 \n\n";
  32. //C1.x = bufData[3] - bufData[0];
  33. //C1.y = bufData[4] - bufData[1];
  34. //C1.z = bufData[5] - bufData[2];
  35. //C2.x = bufData[6] - bufData[0];
  36. //C2.y = bufData[7] - bufData[1];
  37. //C2.z = bufData[8] - bufData[2];
  38. C1.x = bufData[0] - bufData[3];
  39. C1.y = bufData[1] - bufData[4];
  40. C1.z = bufData[2] - bufData[5];
  41. C2.x = bufData[0] - bufData[6];
  42. C2.y = bufData[1] - bufData[7];
  43. C2.z = bufData[2] - bufData[8];
  44. //C2.x = bufData[6] - bufData[0];
  45. //C2.y = bufData[7] - bufData[1];
  46. //C2.z = bufData[8] - bufData[2];
  47. //cout << C1.x << " 1x \n";
  48. //cout << C1.y << " 1y \n";
  49. //cout << C1.z << " 1z \n";
  50. //cout << C2.x << " 2x \n";
  51. //cout << C2.y << " 2y \n";
  52. //cout << C2.z << " 2z \n";
  53. normal = glm::cross(C1, C2);
  54. //cout << "\nNORMAL : " << normal.x << "," << normal.y << "," << normal.z << " counter = " << counter << "\n";
  55. for(int j = 0; j < 3; j++)
  56. {
  57. for(int i = 0; i < 3; i++)
  58. {
  59. normBufData[counter] = normal.x;
  60. normBufData[counter + 1] = normal.y;
  61. normBufData[counter + 2] = normal.z;
  62. }
  63. counter+=3;
  64. }
  65. }


和主.....

  1. int main(int argc, char **argv)
  2. {
  3. glutInit(&argc, argv);
  4. glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  5. glutInitWindowSize(700, 700); // Window Size
  6. glutCreateWindow("Michael - Lab 3");
  7. glutDisplayFunc(display);
  8. glutTimerFunc(10, timeFucn, 10);
  9. glutIdleFunc(Idle);
  10. glutKeyboardFunc(keyboard);
  11. glewExperimental = GL_TRUE;
  12. glewInit();
  13. glEnable(GL_CULL_FACE);
  14. glEnable(GL_DEPTH_TEST); // Enable depth test
  15. glDepthFunc(GL_LESS); // Accept fragment if it closer to the camera than the former one
  16. GenerateSphere(); // this function generates points for the sphere
  17. programID = LoadShader( "VertexShader.glsl", "FragmentShader.glsl" ); // Create and compile our GLSL program from the shaders
  18. setBuffers(); // initilize buffers
  19. calculateNormals(CubeBufferData,CubeNormalBufferData,108); // calculate norms
  20. //printNormals(CubeNormalBufferData);
  21. glutMainLoop();
  22. }

nkkqxpd9

nkkqxpd91#

在调用glVertexAttribPointer( cubeNormal, 3,....);之前,您忘记将缓冲区对象与法线绑定。因此,法线的实际数据来自颜色缓冲区,这会导致最奇怪的Phong评估结果。
顺便说一句,很好的编码风格:)

k0pti3hp

k0pti3hp2#

Phong和Gouraud着色不适用于所有平面的对象,例如立方体。

33qvvth1

33qvvth13#

我在这个立方体中出现了问题,当我发送它的正常值时,我注意到我发送的偏移值不正确,并修复了这个问题。

相关问题