RTPS

RTPS (Rotate-Translate-Perspective Single) - инструкция GTE, которая осуществляет полный процесс проекции одной вершины из мирового в экранное пространство.

Входные данные:

Выходные данные:

Порядок вычислений:

1. Трансформация вершины матрицей поворота (R) и вектором смещения (TRX, TRY, TRZ):

MAC1 = TRX + R11*VX0 + R12*VY0 + R13*VZ0 -> IR1
MAC2 = TRY + R21*VX0 + R22*VY0 + R23*VZ0 -> IR2
MAC3 = TRZ + R31*VX0 + R32*VY0 + R33*VZ0 -> IR3

Матрица 3×3 размещается в регистрах R11R12, R13R21, R22R23, R31R32, R33 следующим образом:

R11+R12 R13
R21 R22+R23
R31+R32 R33

Результаты попадают в регистры IR1, IR2, IR3 и 32-битные аккумуляторы MAC1, MAC2, MAC3.

2. Нормированное значение MAC3 добавляется в FIFO глубины:

SZ3 = SZ2
SZ2 = SZ1
SZ1 = SZ0
SZ0 = clamp(MAC3 SAR 12)

SAR - это операция «арифметический сдвиг вправо» (битовый сдвиг с сохранением знака). Это масштабирование, которое сжимает диапазон глубины до ±524 287.

Новое значение Z попадает в SZ0, старые данные сдвигаются вверх по номерам.

3. Перспективное деление:

n = H / SZ3

GTE делит H (дистанцию проекции) на SZ3 (глубина вершины) с помощью аппроксимации Ньютона-Рафсона. Деление неточное - это аппаратное ограничение, которое и порождает характерное дрожание вершин в графике PlayStation. Если SZ3 = 0 или H >= 2*SZ3, деление переполняется (n = 0x1FFFF), и поднимаются флаги FLAG.Bit17 и FLAG.Bit31 (вершина за камерой или слишком близко).

Дистанция проекции (16 бит) обычно равна 0x0100.

3. Вычисление экранных координат:

SX2 = OFX + IR1 * n
SY2 = OFY + IR2 * n

Экранные координаты обрезаются в диапазон -1024..+1023.

OFX, OFY - экранный сдвиг (обычно центр экрана) в формате Q16.15:

OFX = 160 << 16
OFY = 120 << 16

IR1, IR2 - повернутые координаты из шага 1.

Результат добавляется в очередь SXY-FIFO:

SXY0 = SXY1
SXY1 = SXY2
SXY2 = {SX2, SY2}

Новое значение попадает в SXY2, старые данные сдвигаются вниз по номерам.

4. Depth cueing для интерполяции цвета по глубине:

MAC0 = ((H/SZ3) * DQA + DQB)
IR0  = MAC0 / 0x1000

DQA и DQB - коэффициенты затухания, IR0 - интерполяционный коэффициент, который потом используют команды DPCS, NCDT и др.