Skip to main content
1 of 2

Correct way to interpolate 1/z?

I have doubts on 1/z depth buffer interpolation. According to this website, the correct 1/z interpolation formula is

$\dfrac{1}{P.z} = \dfrac{1}{V0.z} * \lambda_0 + \dfrac{1}{V1.z} * \lambda_1 + \dfrac{1}{V2.z} * \lambda_2. $

Here is my 1/z interpolation implementation in my barycentric triangle rendering algorithm for my software renderer

    void DrawFilledTriangleBarycentric(const vec3f& v1, const vec3f& v2, const vec3f& v3, const Colour& colour) {
        ...
                // Barycentric weights
                float w1 = ((px - v2[0]) * (v3[1] - v2[1]) - (py - v2[1]) * (v3[0] - v2[0])) / area;
                float w2 = ((px - v3[0]) * (v1[1] - v3[1]) - (py - v3[1]) * (v1[0] - v3[0])) / area;
                float w3 = ((px - v1[0]) * (v2[1] - v1[1]) - (py - v1[1]) * (v2[0] - v1[0])) / area;

                if ((w1 >= 0.0f) & (w2 >= 0.0f) & (w3 >= 0.0f))
                {
                    float z = w1 * v1[2] + w2 * v2[2] + w3 * v3[2];
                    float depth = 1.0f / z;

                    PutPixel(x, y, depth, colour.argb);
                }
        ...
    }

especially this part

float z = w1 * v1[2] + w2 * v2[2] + w3 * v3[2];
float depth = 1.0f / z;

v1[2], v2[2], and v3[2] are z values. I am wondering whether I should change it to

float z = w1 * (1.0 / v1[2]) + w2 * (1.0 / v2[2]) + w3 * (1.0 / v3[2]);
float depth = z;

But if I do I got the following output

1

which is different from what I expect (using depth=1.0f/(w1 * v1[2] + w2 * v2[2] + w3 * v3[2]))

2

These are the triangles I am trying to render

DrawFilledTriangleBarycentric(vec3f(10, 50, 10), vec3f(400, 100, 10), vec3f(290, 380, 10), RED);
DrawFilledTriangleBarycentric(vec3f(50, 350, 2), vec3f(130, 40, 20), vec3f(380, 200, 5), GREEN);