diffuse_value в первом случае вычисляется в вершинном шейдере. Так что это делается только для каждой вершины.
После того, как вершинный шейдер выдает значения, растеризатор принимает эти значения (3 на треугольник для каждого вектора) и интерполирует (в правильной перспективе) их, чтобы обеспечить разные значения для каждого пикселя. Как это случается, интерполирующие векторы как это (векторы нормали и направления света) не являются правильными, потому что это теряет их нормализованное свойство. Многие реализации фактически нормализуют векторы в шейдерном фрагменте.
Но хуже интерполировать точку двух векторов (что эффективно делает векторное освещение). Скажем, например, что ваше есть N = + Z для всех ваших вершин и L = норма (Z-X) в одной и L = норма (Z + X) в другой.
N.L = 1/sqrt(2) for both vertices.
Интерполяция, которая даст вам ровное освещение, тогда как на самом деле интерполяция N и L по отдельности и перенормировка даст вам ожидаемый результат - освещение, которое достигает максимума точно в середине многоугольника. (потому что интерполяция нормы (Z-X) и нормы (Z + X) даст ровно Z после нормализации).