Алгоритм пиксельного шейдера

Здравствуйте. Пытаюсь реализовать закраску полигонов с учетом нормалей.

Вот есть хорошая статья и внутри есть код шейдера.

Взял его к себе.
получилось такая штука:

Point3D VertexShader(Point3D vPosition, Point3D vNormal)
{
	Point3D mvPosition;
	//Transform the point
	mvPosition = Mul(mv, vPosition);  //mvPosition is used often
	//gl_Position = p * mvPosition;

	//Set up Normal, Light, Eye and Half vectors
	Point3D N = Normilize(Mul(mv, vNormal));
	Point3D L = Normilize(Sub(lightPosition, mvPosition));
	if (lightPosition.q == 0.0)
		L = Normilize(lightPosition);

	Point3D E = MulF3d(Normilize(mvPosition), -1);
	Point3D H = Normilize(Add(L, E));

	//Calculate diffuse coefficient
	float Kd = max(dotProduct(L, N), 0.0);

	//Calculate Blinn-Phong specular coefficient
	float Ks = pow(max(dotProduct(N, H), 0.0), shininess);

	//Calculate lit colour for this pixel
	Point3D color = Add(Add(Add(MulF3d(diffuseProduct, Kd), MulF3d(specularProduct, Ks)), ambientProduct), emission);
	Point3D mcl = MulF3d(color, 255);
	mcl.x = min(mcl.x, 255);
	mcl.y = min(mcl.y, 255);
	mcl.z = min(mcl.z, 255);
	return mcl;
}

НАстройки света взял из то го же примера:

mv = { 1,1,1,1 };   // так и не понял что это за переменная поэтому выставил 1 везде
	shininess = 125.0f;
	ambientProduct = { 0.0f, 0.0f, 0.1f, 1.0f };  // синий должен быть
	diffuseProduct = { 0.0f, 0.0f, 1.00f, 1.0f };
	specularProduct = { 0.1f,  0.1f,  0.1f, 1.0f };
	emission = { 1.0f, 1.0f, 1.0f, 1.0f };
	lightPosition = { 20,20,20,1 }; // уже ставил по всякому в разные точки

я так понял что ему надо передать точку и нормаль в ней.
Point3D VertexShader(Point3D vPosition, Point3D vNormal)

Подаю точки куба без проекций. как есть. Но почему то цвет всегда рассчитывается на ярко белый. Почему так то??
В качестве нормали подаю нормаль плоскости.

Если правильно понял то синий получится примерно так:

ambientProduct = { 0.0f, 0.0f, 1.0f, 1.0f };

Ну и последний параметр указывающий яркость, при 1.0f равен максимальной яркости. Или скорее всего 255.0f это максимум.

P. S.
Можно еще такой вариант попробовать, для получения прозрачного синего:

ambientProduct = { 0.0f, 0.0f, 255.0f, 0.3f };

ambient это цвет фонового освещения. Цвет объекта это диффузный.

4 компонента вообще не используется. А на 255 я умножаю последний результат.
Только после расчетов конечный цвет равен что то типа 1.0, 1.0, 1.6
вот и не понятно откуда такой баг

Итоговые результаты расчета значений RGB, где три значения практически равны, и дают белый.
Т. е. выходит:
R = 1.0
G = 1.0
B = 1.6
В итоге на выходе будет светлейший светло-голубой (практически белый).

Это значение вектора в размерности 0 - 1.
Для цвета ргб его надо умножить на 255. Но 1,6 даст компоненту больше чем 255. Если вектор нормализовать то вообще почему то желтый получается.