2.5D Renderer

Stage 2: Отрисовка секторов

Нормализация высот секторов

На прошлом шаге стена симметрично росла вверх и вниз относительно линии горизонта, что выглядят не совсем корректно для нашего восприятия. Отсюда очевидно, что добавления одной только высоты для сектора это недостаточно.

Cекторам нужны разные уровни пола или потолка:


  interface Sector {
    segs: Seg[];
    ceilHeight: number;
    floorHeight: number;
  }

Теперь при расчете проекции будем учитывать эти уровни:

Исходная проекция

Исправленная проекция

Слева показана исходная модель с одной высотой: стены центрируются по линии горизонта независимо от того, где должен находиться пол. Справа верхняя и нижняя экранные координаты вычисляются раздельно из ceilHeight и floorHeight.

И если до этого мы считали высоту сектора и только потом вычисляли Y-координаты четырехугольника, то сейчас будем считать Y-координаты для проекции сразу:


  function projectLinedef(
    camera: Camera, 
    sector: Sector,
    linedef: Linedef
  ): LinedefProjection | null {
    // ..
    return {
      start: {
        // ..
        topY: horizontalCenter - (sector.ceilHeight! * startScale / distanceToCamera),
        bottomY: horizontalCenter + (sector.floorHeight! * startScale / distanceToCamera)
      },
      end: {
        // ..
        topY: horizontalCenter - (sector.ceilHeight! * endScale / distanceToCamera),
        bottomY: horizontalCenter + (sector.floorHeight! * endScale / distanceToCamera)
      }
    };
  }

Реализация шага на github