light->getPos())) color += light -> getLightAt ( sample, poly ->
getNormal () );
}
}
// clamp each component to [0,1] color.clamp ( 0, 1 );
// now we have our light value in this // point write it to buffer buf [j] = rgbToInt ( (int)(255*color.z),
(int)(255*color.y), (int)(255*color.x) );
}
// now put buf as a line in lightmap texture lightmap -> writeLine ( height - 1 - i, buf );
}
// write lightmap to file int size = width * height * 3; MutableData data ( "lightmap", size + 1024 ); TgaEncoder encoder;
А. В. Боресков. Графики трехмерной компьютерной игры
encoder.encode ( lightmap, &data ) ;
data. saveToFile ( lightmapName );
// free allocated resources
delete buf; delete lightmap;
return true;
}
Для определения точки на грани, соответствующей данному люмелю, можно использовать метод шгтар класса Mapping, представляющий собой просто обращение метода тар и проекцию полученной точки на плоскость грани.
Однако данный подход несет в себе определенную проблему - во многих случаях текстура будет содержать люме-ли, которым не соответствует ни одной точки на грани (рис. 10.4). Так, соответствующая точке А точка на плоскости просто не принадлежит грани и приведенная реализация запишет в соответствующий люмель нулевое значение.
Поскольку при выводе карты освещенности обычно применяется билинейная интерполяция (в связи с ее небольшим размером), то значения освещенности для точек, лежащих рядом с границей грани, окажется заметно темнее. Это связано с тем, что как минимум одно значение, используемое при интерполяции, соответствует точке, прообраз которой лежит вне грани, - для таких точек значением люмеля является черный цвет (0, 0, 0).
Обратите внимание, что недостаточно просто в этом случае использовать значение фоновой освещенности 1тЛ, поскольку грань может быть
достаточно ярко освещена и освещенность вблизи границы все равно уменьшится.
Один из достаточно простых способов борьбы с этим явлением заключается в том, что в случае, когда построенная точка на плоскости лежит вне грани, она просто слегка "сдвигается" по направлению к грани (достаточно просто сдвигать по направлению в центру грани в.силу ее выпуклости). Тогда, если точка лежит достаточно близко к границе (и поэтому может влиять на значение освещенности), небольшое ее "шевеление" переводит ее на грань и, следовательно, получается осмысленное значение освещенности. Данный подход взят из игры Quake II и его реализация выглядит следующим образом: