Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Software rendering/ occlusion culling

Software rendering/ occlusion culling

Advanced: Тема повышенной сложности или важная.
Страницы: 1 2 3 Следующая »
BernsПостоялецwww30 июля 201822:29#0
Привет.
Решил опробовать и эту технику, ибо хардварный варинт с маппингом текстуры уж слишком медленный. Планирую рендерить куллбоксы и 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;
  }

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

WraithПостоялецwww31 июля 201810:53#1
innuendoПостоялецwww31 июля 201811:01#2
Berns

Intel SOQ

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

Правка: 31 июля 2018 11:57

g-contПостоялецwww31 июля 201811:55#4
Какое оптимальное разрешение софтварного depth-буффера? 32х32 пикселя хватит?
BernsПостоялецwww31 июля 201818:30#6
Ну по идее как-то так:
      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Д точек  треугольника в скринспейсе, а потом уже ковыряю и интерполирую в растеризаторе. Выходит вот такое вот фуфло:
Изображение

FordPerfectПостоялецwww31 июля 201819:41#7
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, т. е. после перспективного деления.
FordPerfectПостоялецwww31 июля 201820:06#8
> Формула выглядит внятно
В смысле с т. з. правильности результата.
С т. з. производительности - можно кучу констант наружу вынести.
"Вот я тупо так скобочки сейчас раскрою, меня в школе учили" (c) IronPeter.
BernsПостоялецwww31 июля 201822:47#9
Да, так получше:
Изображение

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

  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

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

SuslikМодераторwww1 авг. 20185:30#10
а потом эти же люди спрашивают, что плохого в покомпонентных операциях с векторами.
FordPerfectПостоялецwww1 авг. 201810:20#11
Если присмотреться, то в формуле только 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

Правка: 1 авг. 2018 10:25

FordPerfectПостоялецwww1 авг. 201810:22#12
Suslik
Вот и получается, что здесь один из тех случаев, когда работать в координатах может быть вполне внятно.
innuendoПостоялецwww1 авг. 201810:24#13
Suslik
> а потом эти же люди спрашивают, что плохого в покомпонентных операциях с
> векторами.

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

FordPerfectПостоялецwww1 авг. 201816:34#14
Suslik
Сюжетная зарисовка:
+ Показать

Правка: 1 авг. 2018 16:48

Страницы: 1 2 3 Следующая »

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

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