Skip to main content
1 of 3
jpaver
  • 2.2k
  • 13
  • 11

dot(CameraViewInv.at, SurfaceNormal) can return > 0.0 even if the the surface is visible. Think of a box whose right side normal is slightly away from the camera - as it's moved to the left of the frustum, it can become visible.

What avoids this phenomenon is dot(VecFromCameraToSurface, SurfaceNormal).

Another way is to check the winding of your screen-space vertices (ie. vertices after model, view and projection transform). This is done by checking the sign of the z component of the cross product of two edges on the screen space triangle (or quad). Code is here (not OpenGL specific):

// culls CW verts, passes CCW verts. Invert the condition for opposite behavior.
bool shouldCullTriangleScreenSpace(vec2 points[3])
{
edgeA = points[1] - points[0];
edgeB = points[2] - points[0];
return (edgeA.x * edgeB.y - edgeA.y * edgeB.x) < 0.0;
}

jpaver
  • 2.2k
  • 13
  • 11