Form v - - ray.dir: // direction to viewer // направление на наблюдателя

v.normalize():

Shape* myObj - (Shape*)h.hitObject; // point to the hit object // указатель на объект соударения

Color3 color(myObj->mtrl.emissive)* : //start with emissive part // начинаем с эмиссионной части

color.add(d/7!D7'ent contribution): II compute ambient color // вычисляем фоновый цвет

Vector3 normal; // transform the generic normal to the world normal // преобразуем нормаль из базовых координат в мировые

xfrmNormal(normal. myObj->invTransf. h.hitNormal);

normal, norma lizeO: // normalize it // нормируем ее

for(each light source. L) // sum over all sources // суммируем все источники

if(isInShadow(…)) continue: // skip L if it's in shadow // пропускаем точку L. если она в тени

Form s - L.pos - hitPoint: // vector from hit point to source // вектор от точки соударения до источника

s.normalizeO:

float mDotS - s.dot(normal); // the Lambert term // член Ламберта

if(mDotS > 0.0) // hit point is turned toward the light // точка соударения повернута к свету

Form diffuseColor = mDotS * myObj->mtrl.diffuse * L.color; color.add(diffuseColor): // add the diffuse part

Предполагается, что к классам УесЬогЗ и СоТогЗ добавлены некоторые удобные конструкторы: УесЬогЗ 5(А, В) вычисляет вектор как разность двух точек А и В, а СоТогЗ со1ог(с) создает цвет, имеющий те же компоненты, что и цвет с.

Введение в трассировку лучей

Листинг 14.10 (продолжение)

// добавляем диффузную часть

Form h = v + s: // the halfway vector // промежуточный вектор

h.normalizeO:

float mDotH - h.dot(normal): // part of phong term // часть члена Фонга

if (mDotH <- 0) continue: // no specular contribution // зеркального отражения нет

float phong = pow(mDotH. myObj->mtrl.specularExponent):
specColor - phong * myObj->mtrl.specular * L.col or:
color.add(specColor):
}
return color:
}

Нетрудно добавить в трассировщик луча вычисления фоновой, диффузной и зеркальной составляющих света. В листинге 14.10 показан скелет кода, который требуется добавить в метод shadeO из листинга 14.4. Запись наилучшего пересечения best, формируемая в подпрограмме getFirstHitO, исследуется с целью сбора данных о первом соударении луча с объектом. Копию best. hit[0] удобно помещать в Hitinfo, запись п. Положение точки соударения hitPoint вычисляется при помощи луча и h.hitTime. Нормаль в точке соударения, хранящаяся в h.hitNormal в базовых координатах, преобразуется с помощью уравнения (14.24) в мировые координаты. Различные составляющие суммарного цвета, возвращающиеся обратно по лучу, вычисляются и помещаются в color. Определяются эмиссионная и фоновая составляющие света и для каждого источника света исходящие из него диффузная и зеркальная составляющие; все они вычисляются и добавляются ко все растущему color. Если в точке соударения на данный источник света падает тень от другого объекта, то от такого источника не добавляется ничего. (Мы будем рассматривать тени в разделе «Добавление теней для большей реалистичности»; пока же просто опустим строку кода


⇐ Предыдущая| |Следующая ⇒