УДАЛЕНИЕ НЕВИДИМЫХ ЧАСТЕЙ
3.3. Z-буфер
Заведем буфер (собственно z-буфер) размером с экран, и забьем его каким-то
большим числом, настолько большим, что координаты z для точек сцены заведомо
меньше. Например, если z - fixedpoint 16:16, то можно использовать максимально
возможное значение, то есть 0x7FFFFFFF. Для каждой рисуемой точки считаем
значение z; если оно больше, чем значение в z-буфере (точка закрыта какой-то
другой точкой), или меньше, чем -dist (точка находится за камерой), то
переходим к следующей точке. Если меньше, то рисуем точку на экране (или в
видеобуфере), а в z-буфер записываем текущее значение z. Вот кусок кода для
лучшего понимания:
// ...
if (z > -dist && z < zbuffer[screenX][screenY]) {
screen[screenX][screenY] = color;
zbuffer[screenX][screenY] = z;
}
// ...
Имеет смысл считать значения не z, а z1 = 1/(z+dist), так как эта величина
изменяется по грани линейно, и линейная интерполяция дает точные результаты
(более подробно это описано в 4.3). Тогда условия чуть изменяются - точка
загорожена другой, если значение z1 *меньше* значения в z-буфере; и точка
находится за камерой, если z1 < 0. Буфер инициализируем нулями. Тогда
не нежна проверка на положительность z1 - точка попадает в z-буфер и на
экран, только если z1 больше текущего значения, и поэтому точки, для которых
z1 < 0 в буфер и без проверки никогда не попадут. Код тоже чуть изменится:
// ...
if (z1 > zbuffer[screenX][screenY]) {
screen[screenX][screenY] = color;
zbuffer[screenX][screenY] = z1;
}
// ...
Вот и все. Осталось упомянуть, что этот метод иногда называют w-буфером,
подчеркивая разницу между хранением z и какой-то обратной величины, w.
Это самый простой метод удаления невидимых частей, причем всегда дающий
полностью правильные результаты. Единственная проблема - скорость, z-буфер,
как самый простой, является и самым медленным методом.