title: How to interpolate normals for Phong shading in OpenGL?
body: <p>Currently, I am implementing good old Phong shading. Overall it looks quite right but there is a pattern in the normals emerging, that I cannot explain.</p>
  
  <p>Without a closer look, the <a href="http://www.prinmath.com/csci5229/OBJ/bunny.zip" rel="nofollow noreferrer">Stanford Bunny</a> looks quite correct, I think.
  <a href="https://i.stack.imgur.com/gAxRa.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/gAxRa.png" alt="enter image description here"></a></p>
  
  <p>But on the ears for example there is a strange pattern:
  <a href="https://i.stack.imgur.com/3DuLt.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3DuLt.jpg" alt="enter image description here"></a></p>
  
  <p>In this picture I visualized the normals and boosted the saturation to make the problem more visible.
  <a href="https://i.stack.imgur.com/0Az6x.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/0Az6x.jpg" alt="enter image description here"></a></p>
  
  <p>This is my vertex shader:</p>
  
  <pre><code>#version 330 core
  
  layout (location = 0) in vec4 vPosition;
  layout (location = 1) in vec3 vNormal;
  
  out vec4 fWorldPosition;
  smooth out vec3 fWorldNormalSmooth;
  
  ...    
  
  void main() {
      fWorldNormalSmooth = normalize(NormalMatrix*vNormal);
      fWorldPosition = WorldMatrix*vPosition;
      gl_Position = ProjectionMatrix*ViewMatrix*WorldMatrix*vPosition;
  }
  </code></pre>
  
  <p>This is my fragment shader:</p>
  
  <pre><code>#version 330 core
  
  smooth in vec3 fWorldNormalSmooth;
  in vec4 fWorldPosition;
  
  out vec4 color;
  
  ...    
  
  vec4 shadePointLight(Material material, PointLight pointLight, vec3 worldPosition, vec3 worldNormal) {
      vec3 cameraPosition = wdiv(inverse(ViewMatrix)*vec4(0, 0, 0, 1));
      vec3 cameraDirection = normalize(cameraPosition - worldPosition);
      vec3 lightDirection = normalize(pointLight.position - worldPosition);
      vec3 reflectionDirection = reflect(-lightDirection, worldNormal);
  
      vec4 i_amb  = material.ambientReflection*pointLight.ambientColor;
      vec4 i_diff = max(0, dot(worldNormal, lightDirection))*material.diffuseReflection*pointLight.diffuseColor;
      vec4 i_spec = pow(max(0, dot(reflectionDirection, cameraDirection)), material.shininess)*material.specularReflection*pointLight.specularColor;
  
      float distance = length(pointLight.position - worldPosition);
      float d  = 1.0 / (pointLight.falloff.constant + pointLight.falloff.linear*distance + pointLight.falloff.quadratic*distance*distance);
  
      return i_amb + d*(i_diff + i_spec);
  }
  
  void main() {
      ...
  
      color = shadePointLight(material, pointLight, wdiv(fWorldPosition), normalize(fWorldNormalSmooth));
  }
  </code></pre>
  
  <p><strong>Can someone explain this behaviour?</strong></p>