14.5.2. Полный трассировщик лучей для сцен с излучающей сферой Вон совершенно круглая луна Кружит божественно сквозь синие глубины, И под ее немеркнущим лучом Пустынный круг раскинулся, как будто Круг океана опоясан небом.
Прекрасна ночь!
Роберт Саути (Robert Southey)
Мы располагаем достаточными средствами, чтобы создать простой трассировщик лучей для сцен, составленных из сфер (и, конечно, эллипсоидов). Очень полезно выполнить эту довольно значительную работу до усложнения ситуации, чтобы увидеть, как собрать вместе все уже рассмотренные нами ингредиенты. Главное - ничего не упустить, поскольку все эти инструменты понадобятся нам в дальнейшем.
На данный момент мы можем создавать объект, светящийся некоторым светом, только путем присвоения его эмиссионному компоненту в SDL-файле некоторого ненулевого значения, например командой emissive 0.3 0.6 0.2. Нетрудно скорректировать метод Scene: :shade() из листинга 14.4 так, чтобы в нем
Введение в трассировку лучей
поддерживался только излучаемый (эмиссионный) свет: нужно просто удалить те строки color.addO, в которых определяются другие составляющие света. Результат будет следующим:
Color3 Scene :: shade(Ray& ray) {
СоТогЗ color:
Intersection best:
getFirstHit(ray. best):
if(best.numHits - 0) return background:
Shape* myObj = (Shape*)best.hit[0].hitObject: // the hit object // объект соударения
color.set(myObj->mtrl.emissive):
return color:
}
Направление луча в каждом пиксельном блоке вычисляется только в тех частях метода Camera :: raytraceO из листинга 14.3, которые требуют конкретизации1:
forCint row - 0: row < nRows: row += blockSize) for(int col - 0; col < nCols: col +=* blockSize) {
float x - -W + col * 2 * w / (float)nCols:
float у - -H + row * 2 * H / (float)nRows;
theRay.setDir( -nearDist * n.x + x * u.x + у * v.x. -nearDist * n.y + x * u.y + у * v.у. -nearDist * n.z + x * u.z + у * v.z):
Color3 clr - scn.shade(theRay): // color of this ray // цвет данного луча
glColor3f(clr.red. clr.green, clr.blue);
glRectKcol. row, col + blockSize. row + blockSize):