Войти
ПрограммированиеФорумГрафика

Software rendering/ occlusion culling

Advanced: Тема повышенной сложности или важная.

Страницы: 1 2 3 Следующая »
#0
22:29, 30 июля 2018

Привет.
Решил опробовать и эту технику, ибо хардварный варинт с маппингом текстуры уж слишком медленный. Планирую рендерить куллбоксы и low-poly, в частности для стен, домов, больших ящиков, бочек. Разрешение наверное 256x128 + буфер глубины, из дополнительных оптимизаций - frustum culling и отрисовка от ближнего к дальнему.
Код скопипастил отсюда http://grafika.me/node/67 , добавил загрузку моделей и Depth-тест. На данный застрял на интерполяции данных для получения корректной карты глубины, не могу корректно получить массы вершин. Даже не знаю, что тут нужно. Первое, что пришло в голову - найти барицентрические координаты, пробить дистанцию до угла как нормализатор, и поделить на него расстояние от позиции записи до точек треугольника для получения веса в диапазоне от 0.0 - 1.0. Только мой вариант - липа:

// растеризуем верхний полутреугольник
  for (int i = y1; i < y2; i++)
  {  
    float tx =  (x1 + x2 + x3) / 3.f;
    float ty =  (y1 + y2 + y3) / 3.f;

    // рисуем горизонтальную линию между рабочими точками
    for (int j = fixed_to_int(wx1); j <= fixed_to_int(wx2); j++)
    {

      float norm1grrg = sqrt((tx - x1)*(tx - x1) + (ty - y1)*(ty - y1));

      float corr = 255;
      float bias = norm1grrg * 2;
      int tl1 = corr - (255 * sqrt((x1 - j)*(x1 - j) + (y1 - i)*(y1 - i)) / bias );
      int tl2 = corr - (255 * sqrt((x2 - j)*(x2 - j) + (y2 - i)*(y2 - i)) / bias);
      int tl3 = corr - (255 * sqrt((x3 - j)*(x3 - j) + (y3 - i)*(y3 - i)) / bias);


      color.x = tl1;
      color.y = tl2;
      color.z = tl3;

      WritePixel(j, i, color);
    }
    wx1 += dx13;
    wx2 += dx12;
  }

куда копать? Как это делается?


#1
10:53, 31 июля 2018

https://gamedev.ru/code/articles/Software_occlusion

#2
11:01, 31 июля 2018

Berns

Intel SOQ

#3
(Правка: 11:57) 11:54, 31 июля 2018

Berns
Та глубина, которая пишется в Z-буфер (zNDC линейно отмапленная в depth range) - линейно меняется в screen-space. Соответственно тупо вычисляешь её в 3-х вершинах, а между ними - интерполируешь с помощью барицентрических координат.
https://gamedev.ru/code/forum/?id=217881&page=17#m244
Как барицентрические координаты считаются, надеюсь, в курсе.

+ Показать
#4
11:55, 31 июля 2018

Какое оптимальное разрешение софтварного depth-буффера? 32х32 пикселя хватит?

#5
12:06, 31 июля 2018

https://software.intel.com/en-us/articles/software-occlusion-culling

#6
18:30, 31 июля 2018

Ну по идее как-то так:

      float norm = 1.f / ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3));
      float l1 = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) * norm;
      float l2 = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) * norm;
      float l3 = (1.0F) - l1 - l2;

      float depth = (l1 * zp1) + (l2 * zp2) + (l3 * zp3);
  

Только вот начинаю путаться, ибо сперва я получаю расположение 2Д точек  треугольника в скринспейсе, а потом уже ковыряю и интерполирую в растеризаторе. Выходит вот такое вот фуфло:
Изображение

#7
19:41, 31 июля 2018

Berns

      float norm = 1.f / ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3));
      float l1 = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) * norm;
      float l2 = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) * norm;
      float l3 = (1.0F) - l1 - l2;

      float depth = (l1 * zp1) + (l2 * zp2) + (l3 * zp3);
Как говорил наш преподаватель по теоретической механике - научатся не путаться в знаках "только когда у них ружьё в руках не той стороной выстрелит".
Ну можешь подставить треугольник (0,0), (5,0), (0,5) и точку (1,1) и посмотреть какие значения получатся.
+ подсказка
      float norm = 1.f / ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3)); // 1/(2*Atri)
      float l1 = ((y2 - y3) * (x - x2) + (x3 - x2) * (y - y2)) * norm; // A1/Atri
      float l2 = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) * norm; // A2/Atri
      float l3 = (1.0F) - l1 - l2; // =A3/Atri

      float depth = (l1 * zp1) + (l2 * zp2) + (l3 * zp3);
Так вроде правильно.
Формула выглядит внятно, если x,y - это экранные координаты, а zp1, zp2, zp3 - в NDC, т. е. после перспективного деления.
#8
20:06, 31 июля 2018

> Формула выглядит внятно
В смысле с т. з. правильности результата.
С т. з. производительности - можно кучу констант наружу вынести.
"Вот я тупо так скобочки сейчас раскрою, меня в школе учили" (c) IronPeter.

#9
22:47, 31 июля 2018

Да, так получше:
Изображение

однако, после таких махинаций для нижнего триангла:

  if (y1 == y2)
  {
    wx1 = int_to_fixed(x1);
    wx2 = int_to_fixed(x2);
  }
  // упорядочиваем приращения
  if (_dx13 < dx23)
  {
    swap(_dx13, dx23);
  }  
  // растеризуем нижний полутреугольник
  for (int y = y2; y <= y3; y++)
  {

не то. пробовал менять стороны, не меняя нормализатора - тоже не то:

float l1 = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) * norm; // A1/Atri
float l2 = ((y1 - y2) * (x - x1) + (x2 - x1) * (y - y1)) * norm; // A2/Atri

не умею я учить математику в общих традициях

#10
5:30, 1 авг. 2018

а потом эти же люди спрашивают, что плохого в покомпонентных операциях с векторами.

#11
(Правка: 10:25) 10:20, 1 авг. 2018

Если присмотреться, то в формуле только x и y - не являются константами.
В смысле глубина - это линейная функция от x, y:

depth=A*x+B*y+C
Мы можем вычислить A, B, C для треугольника изначально ("тупо так скобочки сейчас раскрою"). И после этого - бам, у нас есть функция перевода экранных координат в глубину. Которая не зависит от того, как мы треугольник разбиваем, и в каком порядке мы его обходим.

Разбивать, кстати, его не обязательно. И обходить можно не по сканлиниям. А заюзать half-space:
https://gamedev.ru/projects/forum/?id=215799&page=55#m823

#12
10:22, 1 авг. 2018

Suslik
Вот и получается, что здесь один из тех случаев, когда работать в координатах может быть вполне внятно.

#13
10:24, 1 авг. 2018

Suslik
> а потом эти же люди спрашивают, что плохого в покомпонентных операциях с
> векторами.

это что, бывает что хотят работать без матриц :)

#14
(Правка: 16:48) 16:34, 1 авг. 2018

Suslik
Сюжетная зарисовка:

+ Показать
Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика