ДР13/средни/Т1 - Adaptive resolution

Adaptive resolution

В лекция 13 демонстрирахме realtime рейтрейсинг на наистина лека сцена, simple.hexray. Но дори за не особено високата разделителна способност от 960х540 пиксела, се наложи да сменим шейдъра на винената чаша от стъклен към Lambert, за да може сцената да се рендерира с интерактивна скорост.

По принцип бихме могли да намаляваме разделителната способност надолу, докато постигнем приличен фреймрейт, примерно поне 15 FPS. Идеята на тази задача е това намаляване да става автоматично, като gameloop() през цялото време адаптира render resolution-а, за да поддържа добър FPS. За целта ще имаме променлив decimation factor, който указва реалната render resolution.

Например, при зададен размер на екрана 960х540 от сценовия файл, и decimation factor = 10.0, реално render() функцията би следвало да изренди кадъра 96х54 пиксела, и след което displayVFB да скалира това изображение по 10, преди да го покаже в 960х540 прозорец.

Имайте предвид, че въпросния фийчър ще се ползва единствено в interactive режим. Няма смисъл да пипате coarseRender, markAApixels, ... и т.н. процедури, които не се ползват в interactive режима.

Ползвайте следната примерна схема:

  1. Поддържайте списък с възможни decimation factors, примерно 1.0, 1.25, 1.66, 2.0, ... някаква такава геометрична прогресия до максимум 50;
  2. Ако сцената ще се ренди в interactive режим, започнете с максималния decimation;
  3. Променете renderWithMonteCarlo(), detectAApixels, getBucketsList(), и Camera::beginFrame() да ползват реалната render resolution (тя е frameWidth()/decimation, frameHeight()/decimation). Например може да си направите нови функции renderWidth()/renderHeight();
  4. Подавайте по-малък размер на bucket-ите на getBucketsList() (най-добре и този размер да се децимира);
  5. Реализирате upscaling-a на умаления кадър към пълния размер на SDL window-а в displayVFB(). В публикуваното примерно видео, това се прави с билинейно филтриране, но не сте длъжни да го правите така. Nearest neighbour е напълно ОК (т.е. full_frame(x, y) = decimated_frame(x/decimation, y/decimation));
  6. в gameloop следете за текущия фреймрейт: примерно времето за рендерирането на последните 10 кадъра, или за последните 0.5 секунди. Ако фреймрейта падне под примерно 12 FPS: увеличете decimation factor-а. Ако се качи над 35: намалете го. Тунинговайте метода и константите по ваш вкус;
  7. след всяко пипане на decimation factor-а, списъка buckets следва да се преизчисли

Резултатът ще изглежда примерно така: adaptive resolution demo.