Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Z-интерполяция (2 стр)

Z-интерполяция (2 стр)

Поделиться

Страницы: 1 2

FordPerfectПостоялецwww5 ноя. 201722:15#15
}:+()___ [Smile]
>Скорее всего, выполняется на общем железе для float/double (а возможно и для целых), непонятно откуда там дополнительная задержка.
Совсем не очевидно. Перемножить 2x24 бита или 2x53 - довольно большая разница.
Я хз, что в Core i7, но, возможно, характеристики асимптотики те же, что и для https://en.wikipedia.org/wiki/Wallace_tree , https://en.wikipedia.org/wiki/Adder_%28electronics%29#Adders_supp… multiple_bits .

>Кстати, хорошо видно, что "скалярные" операции на самом деле векторные с отключенной записью результата.
Несколько неочевидно. Т. е. это даст те же значения, что и в таблице, но их можно достичь и по-другому же. Джоули экономить.

Правка: 5 ноя. 2017 22:16

FordPerfectПостоялецwww5 ноя. 201722:52#16
}:+()___ [Smile]
В смысле, если у тебя есть источники/детали - делись, что-ли.
}:+()___ [Smile]Постоялецwww5 ноя. 201723:48#17
FordPerfect
> Совсем не очевидно. Перемножить 2x24 бита или 2x53 - довольно большая разница.
Вообще-то 4x24 и 2x53, что достаточно близко.

> возможно, характеристики асимптотики те же, что и для
Для того, чтобы из Wallace tree для перемножения 64x64 бита сделать 2 32x32 или 4 16x16, достаточно просто "перерезать" некоторые проводки, даже финальный сумматор трогать не надо.
Соответственно, логично использовать для этого общее железо, максимально переиспользуя железную логику.
В случае плавающей точки все сложнее, однако ядро — все тот же целочисленный умножитель.

> Несколько неочевидно. Т. е. это даст те же значения, что и в таблице, но их можно достичь и по-другому же. Джоули экономить.
Не, понятно, что можно аппаратно отключить другую половину ALU для экономии энергии (хотя я сомневаюсь, что это возможно с потактовой гранулярностью).
Важно, что с практической точки зрения другая половина по-любому простаивает, т. е. от режима условного исполнения по маске в AVX-512 или на GPU ничем принципиально не отличается.

thevladПостоялецwww6 ноя. 20171:18#18
}:+()___ [Smile]
> Для того, чтобы из Wallace tree для перемножения 64x64 бита сделать 2 32x32 или
> 4 16x16, достаточно просто "перерезать" некоторые проводки, даже финальный
> сумматор трогать не надо.
> Соответственно, логично использовать для этого общее железо, максимально
> переиспользуя железную логику.
обычно на современном железе, умножение делают через рекурсивный алгоритм деления пополам, (A_high*2^(N/2) + A_low)*(B_high*2^(N/2) + B_low)
в результате получаетcя схема с высоким темпом(за счет конвееризации каждого шага) и относительно небольшой задержкой.
соответсвенно посчитать более узкий результат - просто забрать его на предыдущем шаге пайплайна.

Правка: 6 ноя. 2017 1:48

eDmkПользовательwww6 ноя. 20173:59#19
В общем без деления единицы никак не обойтись.
Шаг нелинейный получается.
}:+()___ [Smile]Постоялецwww6 ноя. 20176:59#20
thevlad
> обычно на современном железе, умножение делают через рекурсивный алгоритм деления пополам
Пруфы есть? А то я что-то сильно сомневаюсь, что в одном ALU сразу несколько умножителей.

eDmk
> В общем без деления единицы никак не обойтись.
Да, одно перспективное деление на пиксель необходимо для корректных текстурных координат.

> Шаг нелинейный получается.
А вот Z-буфферу на это параллельно, на настоящих GPU он нелинейный.

eDmkПользовательwww6 ноя. 201712:10#21
>на настоящих GPU он нелинейный
Так он везде нелинейный из-за перспективной матрицы.
Хотя в ортогональной проекции он скорее всего линейный.
1 frag / 2 deathsУчастникwww6 ноя. 201713:23#22
Не знаю, что у тебя за компилятор, но Дельфи-7 ужасно оптимизирует вещественные операции, но неплохо оптимизирует целочисленные. Поэтому советую фиксированную запятую.
И да, тебе уже сказали, что величина 1/z меняется линейно, это значит, что тебе надо просто вычислить rev_z0 и d_rev_z.
И достаточно писать в з-буфер только 1/z, делать деление нафиг не надо.
Деление нужно лишь для перспективной коррекции текстур, но и там можно считерить, например, сб3д забил на перспективную коррекцию, сделал мелкие полигоны и на них не видно, как текстура "едет".
1 frag / 2 deathsУчастникwww6 ноя. 201713:36#23
> Z := 1.0 / (Pt.X * Z.X + Pt.Y * Z.Y + Pt.Z * Z.Z);
Тут барицентрические координаты не реальной точки реального треугольника, а проекции точки на экране относительно проекции треугольника на экране. Это значит, что при движении вдоль линии пикселей знаменатель меняется линейно.
Тебе перед началом движения по линии нужно узнать Pt0 - координаты начальной точки и dPt - на сколько меняются все координаты при смещении на соседний пиксель.
Того имеем формулу:
Z := 1.0 / (Pt.X * Z.X + Pt.Y * Z.Y + Pt.Z * Z.Z);
W := Pt.X * Z.X + Pt.Y * Z.Y + Pt.Z * Z.Z;
W0 := Pt0.X * Z.X + Pt0.Y * Z.Y + Pt0.Z * Z.Z;
dW := dPt.X * Z.X + dPt.Y * Z.Y + dPt.Z * Z.Z;
Этих данных достаточно, чтоб интерполировать W одним сложением при движении по полосе пикселей.
eDmkПользовательwww6 ноя. 201713:54#24
>Не знаю, что у тебя за компилятор, но Дельфи-7 ужасно оптимизирует вещественные операции
RAD Delphi XE6 Prof. Оптимизация жуткая. Почти бесполезная. Масимум 0.5-1% добавляет по скорости.
Я выравнивание никак не могу включить в Delphi. Из-за этого команды movaps или movdqa в ассемблере недоступны.
Везде невыровненные данные через movdqu. Может и от этого тормозит.
1 frag / 2 deathsУчастникwww6 ноя. 201714:25#25
eDmk
В Дельфи-7 фигач))) Только всё в целые числа 16:16 перегоняй перед сложными вещами по формуле round(x*65536.0). Например было 1.5 вещественное, будет 0x18000 целое.
И во внутреннем цикле чтоб никаких round() и вообще вызовов других функций. Внутренний цикл должен быть простой, как лопата.
  procedure LoopNoDith (
    Px : PScreenColor; w, dw :integer; Pixels : PAColor; cnt : integer;
    tx,dtx,ty,dty,mx,my,sx : integer);
  var
    i : integer;
  begin
    for i := 0 to cnt-1 do begin
      Px^ := FogTable[w shr 16,
        Pixels[
          ((tx shr 16)and mx) +
          ((ty shr 16)and my) shl sx
        ]
      ];
      Inc(tx,dtx);
      Inc(ty,dty);
      Inc(w, dw);
      Inc(Px);
    end;
  end;

Px^ - экранный буфер, Pixels - текстура, w - величина, обратная глубине. В этом цикле записи в z-буфер нету, глубина используется лишь для тумана.

Правка: 6 ноя. 2017 14:32

Страницы: 1 2

/ Форум / Программирование игр / Графика

2001—2017 © GameDev.ru — Разработка игр