Let's suppose we have an object consisting of only 3d points, and triangle faces that each take a subset of these 3d points. How can I interpolate the normal vectors to get that Phong smooth shading? The actual algorithm seems impossible to find yet everybody is doing it.

There is one post on here, but I still have no idea how to implement it: Normal Interpolation for Phong shading

Also, it seems wrong to me that this supposed formula only takes in account two normals. What if you have a triangle surrounded by 3 other triangles? Then how do you blend the normals?

  • 2
    $\begingroup$ Refer to: "Weights for Computing Vertex Normals from Facet Normals". Generally you walk over all triangles that share a vertex and use all of the adjacent triangle normals to compute the normal at that vertex. To achieve this you can walk over all triangles and add their normals to their 3 adjacent vertices (with a weight). More generally you can create a structure which for each vertex lets you iterate over the triangles that share it. $\endgroup$
    – lightxbulb
    Sep 30, 2019 at 9:23
  • $\begingroup$ @lightxbulb exactly what I was looking for, thank you! I can't upvote comments yet but otherwise I would have. $\endgroup$
    – AnnoyinC
    Sep 30, 2019 at 16:07
  • $\begingroup$ Also worth pointing out the interpolated normals need renormalising per pixel. $\endgroup$
    – PaulHK
    Feb 28, 2020 at 4:44

1 Answer 1


EDIT: I misunderstood your question, so please disregard this answer.

The Phong shading model assumes a surface normal $\mathbf{n}$ at the shading point $\mathbf{x}$ but it is independent of its type, so either the shading normal or the geometric normal will work. Moreover, this reflectance model requires an incoming and outgoing directions. In that sense, you can't just "interpolate the normals" to get the desired effect since you need to take into account the positions of the camera and the light, as well as the roughness parameters.

The (normalized) Phong BRDF is a sum of a diffuse and specular term:

$$ f_r(\mathbf{x},\omega_i,\omega_o) = \frac{\rho_d}{\pi} + \rho_s \frac{n+2}{2\pi}\max(0,\cos^n\alpha), $$ where

  • $\rho_d$ is the diffuse albedo, i.e. the fraction of the incoming energy that is reflected diffusely,
  • $\rho_s$ is the specular albedo, i.e. the fraction of the incoming energy that is reflected specularly,
  • $n$ is the Phong exponent; higher values yield more mirror-like specular reflection, and
  • $\alpha$ is the angle between the perfect specular reflection direction $\omega_r$ and the outgoing direction $\omega_o$.

You can compute $\omega_r$ from the surface normal $\mathbf{n}$ and the lighting direction $\omega_i$, which is just

$$ \omega_r = 2\mathbf{n}(\mathbf{n}\cdot\omega_i) - \omega_i. $$

Typically you pick the albedos such that $\rho_d + \rho_s \leqslant 1$ to conserve energy.

  • $\begingroup$ I don't see how this formula makes creased edges appear to smoothly blend into its neighbours, aka phong normal interpolation (I'm not confused with gouraud interpolation) $\endgroup$
    – AnnoyinC
    Sep 30, 2019 at 8:05
  • 2
    $\begingroup$ He is talking about Phon shading, not the Phong brdf: en.m.wikipedia.org/wiki/Phong_shading Consider editing your answer as it is currently misleading. $\endgroup$
    – lightxbulb
    Sep 30, 2019 at 9:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.