kategoria: ANSI C
[#91] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@Umpal, post #90

no coś mi zamula z tymi texturami, potem to ogarnę, te sufity i podlogi najpierw bo to straszne marnotrastwo jest.. dzieki za testy!
[#92] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #91

Nie ma sprawy, działaj! OK
[#93] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@kiero, post #63

@Rendering 32bit vs 8bit

W sumie naszła mnie jeszcze jedna taka myśl która wypadła kompletnie wcześniej. Wersja 32bit ma sens i jest jak najbardziej możliwa jeżeli zmienisz nieco podejście. Otóż zamiast liczyć oświetlenie dla każdego piksela poczytaj o czymś takim jak surface cache. Tego używał Quake do realizowania oświetlenia za pomocą lightmap. Tam lightmapy miały jedynie jasność (w oryginalnym quake), ale koncept można rozszerzyć na w pełni kolorowe. Trik polega na tym, że teksturę z oświetleniem łączy się poza renderowaniem ekranu. Wszystko kosztem pamięci na cache i skomplikowania całości + pewnej zmiany podejścia. Brak cieniowania w dal, a to dlatego że wymusza to zmianę oświetlenia w każdej klatce, a w zamian oświetlenie wypalone do tekstur, bardziej statyczne.

Taka dygresja.
[#94] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@kiero, post #93

Dzięki za info..
Czy przez oświetlenie masz na myśli wlasnie to cieniowanie w dal? Bo to jest w tym momencie w aktualnym progresie. Nie ma nic innego. Tzn. Jest jeszcze cieniowanie boczne zależne od strony w którą zwrócona jest ściana. To cieniowanie odległości chyba nie jest aż tak zasobożerne, ono polega na dystansie który I tak musi być obliczony, a wartość intensity pobieram na podstawie dystansu z tablicy.

O wypaleniu mapy intensywności tez myślałem, można w ten sposób uzyskać fajne realistyczne efekty. Przy czym taka textura moze byc znacznie mniejsza.

Generalnie teraz bez textur bardzo ładnie śmiga, na v4 ma ok. 80fps w 640x480.. na razie nie wiem czemu textury zabierają 90% wydajności, być może chodzi o kolejność odczytu z tablicy. Mam kilka rzeczy do poprawy i parę pomysłów na optymalizację algorytmów, więc na razie tym się zajmę. Na vampirach i warpach jest widoczny potencjał. Na NG, morphosach i tych mocniejszych platformach chyba jeszcze nie było testowane, przy następnej okazji postaram się dorobić jeszcze tryb 24 i okienkowy.
[#95] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #91

Z tego co pamiętam to podłogi i sufity da się zrobić kodem podobnym jak w zoom-rotator. Czyli tak jak pisał Kiero, dodawanie i przesuwanie bitów wystarcza do obliczenia współrzędnej w teksturze.
[#96] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@Kefir_Union, post #95

Zastanawiam się, czy można jakoś zoptymalizować algorytm albo samą przstrzeńm którą musi przebyć promień aby dobić się do ściany. Na zasadzie, że może jakoś połączyć ze sobą sąsiadujące puste komórki w jedną dużą czy coś w ten deseń.. do BSP typu Doom to raczej nie bede podchodził.. szukam jakiś pomysłów na poprawę algorytmu przechodzenia promienia przez siatkę,
[#97] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #96

Ile takich promieni obliczasz na klatkę?
[#98] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@Kefir_Union, post #97

Pewnie tyle ile szerokość ekranu. Ale serio, algorytm jest banalny. Tego używał Wolfenstein i działał wystarczająco szybko.
[#99] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@Kefir_Union, post #97

Tak jak mówi @kiero, jeden promień na 1 pixel szerokości ekranu, generalnie im większa pusta przestrzeń tym więcej obliczeń musi wykonać.. fakt nie jest bardzo zasobożerne, ale zawsze warto poszukać jakiś optymalizacji
[#100] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #99

Znalazłem jakiś ciekawy algorytm w Graphic Gems I, jak tak patrzę to albo jestem ślepy albo nie ma tam ani jednego mnożenia ani dzielenia.. no ciekawe jak by to zadziałało..
[#101] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #100

Bo nie powinno być, przynajmniej jeżeli chodzi o przechodzenie po promieniu. To jest DDA, tam są tylko dodawania + instrukcje warunkowe. Jedyne bardziej skomplikowane operacje są już po dojściu do końca.

link
[#102] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@kiero, post #101

testowałem dwa do tej pory, każdy miał tam jakieś dzielenia i mnożenia.. chyba ze temu z GGI czegoś brakuje,
ale znajduje punkt przecięcia, wiec to co jest potrzebne, w dodatku można go obliczać jedynie gdy dana komórka nie jest pusta.. no ciekawy jestem, jak mi sie go uda zaimplementować to podrzucę wyniki..

trzeba z tego podstawowego rdzenia, który teraz mam, czyli proste scianki, podlogi + textury wycisnać ile się da póki kod jest mały..

w ogóle to to do pierwszego postu, zacznę wrzucać ciekawe linki dla zainteresowanych tematem..

Ostatnia aktualizacja: 17.03.2021 18:20:20 przez mateusz_s
[#103] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #102

********************
mały UPDATE


do pierwszego postu (na jego końcu)
dodałem pierwsze materiały edukacyjne związane z tematem raycastingu
i grafiki komputerowej dla zainteresowanych

**************************

Ostatnia aktualizacja: 17.03.2021 21:04:51 przez mateusz_s

Ostatnia aktualizacja: 17.03.2021 21:05:10 przez mateusz_s
[#104] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #103

Lamerska sugestio-porada od nie-programisty: robisz to na "nowoczesne" maszyny, więc nie ma problemu z ilością pamięci. Zrób sobie prekalkulacje współrzędnych wszystkich możliwych przecięć siatki przez każdy z promieni dla każdej możliwej pozycji bohatera w kratce. Potem przy rysowaniu tylko odczyt współrzędnych z tablicy i sprawdzanie czy trafiło na ścianę. Wtedy nie będzie żadnego mnożenia, dzielenia, ani nawet dodawania czy odejmowania :) Jaki rozmiar ma jedna kratka na mapie?
[#105] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mastaszek, post #104

Tak się raczej nie da, bo rzucasz promienie stojąc e dowolnym miejscu i przy dowolnym obrocie. Każda komórką jest jednostkowa czyli ma długość i szerokość 1.0, a ja mogę być np. W pozycji 0.34,0.87 a aktualny mój kierunek to np. 56.7 stopnia także nie wiem co by tu można przekalkulować.
[#106] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #105

Myślałem o prekalkulowaniu przecięć siatki dla KAŻDEJ pozycji bohatera w komórce dla WSZYSTKICH 360 promieni (czyli "dookoła"). No ale jeśli bohater przesuwa się o 0.01, czyli masz 100 pozycji bohatera w komórce w pionie i tyle samo w poziomie, no to faktycznie jakby to wszystko prekalkulować to wyjdzie wielgachna tablica.

PS Teraz skumałem, że Ty tych promieni nie rzucasz 360, tylko znacznie więcej, bo nie zmieniasz promienia co stopień, tylko częściej. Sorry za zaśmiecenie wątku.
[#107] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #103

Kurczę, generalnie znalazłem zdaję się w końcu przyczynę całego złaaaa... kierunek rysowania ścian,
czyli kolumnami..

Same podłogi i sufity które wypełniają cały ekran dają ponad 350 fps ze wszytkimi obliczeniami,
ale one rysowane są per scanline, czyli "cache friendly"..

a tym czasem "wykastrowana" z obliczeń funkcja rysujaca ściany, która rysuje je kolumna po kolumnie oscyluje gdzieś ok. 120 fps, ale wystarczy, dodac pare obliczen albo podobny dostep do innej tablicy i momentalnie dropuje o duże wartości.. nie mówiąc już o texturach..

hmm czy można to jakoś zamienić zeby rysowac w poziomie.. ciezko teraz powiedziec..
[#108] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #107

Jeżeli trzymasz tekstury 'normalnie', poziomo, to robisz to baaardzo źle... Rysować możesz sobie w pionie, ale przynajmniej nie kalecz sztuki i trzymaj tekstury odwrócone;)
[#109] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #107

Problemem nie jest rysowanie ale pobieranie danych. Jeśli pobierasz z kolumn to zmuszasz cache do zapamiętywania niepotrzebnych danych. Przekonwertuj tekstury zamieniając współrzędne x i y, na pewno będzie szybciej. Obawiam się że to jednak nie jest największy problem wydajnościowy.

Ostatnia aktualizacja: 19.03.2021 10:22:55 przez Kefir_Union
[#110] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@Kefir_Union, post #109

Rysowanie też, bo żeby zapisać 1 lub 4 bajty procesor odczyta z pamięci całą linie cache (16), zmodyfikuje i zapisze. Troche słabe, ale popełnianie tego błędu też dla czytania jest słabe 2x:) Plus 060 (nie wiem jak 040) ma 4 bufory do zapisu i z tego co pamiętam odbywa się to 'w tle', więc koszt mniejszy. Z zapisem można sobie od biedy też jakoś poradzić ale imo na tym etapie nie jest to warte zachodu i tylko zamiesza u mateusza_s, tym bardziej że nie ma prawdziwego sprzętu na którym mógłby potestować.

Ostatnia aktualizacja: 19.03.2021 10:51:18 przez kiero
[#111] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@kiero, post #110

Tak z tymi texturami to wiem..
Tylko ze teraz je wyłączyłem i tylko rysuje beż textur czyli umieszczam dane w tablicy po kolumnie.
Do tego momentu jest jeszcze Ok.. Można żyć.. ale wystarczy dodać np. Kolejny odczyt z tablicy nie mówiąc o pobieraniu texteli to dostaje w kość mocno..

Szukam sposobu zeby to jakoś zoptymalizowac. Na początku myślałem żeby obracać bufor o 90 stopni,
Ale to też zajmuje czas, chyba żeby za pomocą jakiś lookup tablet, ale nie doszedłem jeszcze do tego.
[#112] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #111

Po pierwsze, to że funkcja rysuje wierszami wcale nie oznacza że jest cache-friendly. Bardzo daleko od tego. Wystarczy że czytasz z tekstury podłogi kolumnami (obrót widoku o 90 stopni).

Po drugie, jeżeli wydaje ci się, że rysowanie kolumnami zabija ci wydajność to fatalnie oceniasz sytuację. Stawiam, że wszystkie amigowe 'doomy' rysują kolumnami i działają świetnie/w miarę. To nie rysowanie kolumnami jest twoim problemem a obliczenia przy rysowaniu.
[#113] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #111

Licz co drugi promień i zapisuj w tablicy T współrzędne ściany w którą trafia. Przy takich mapach jakich używasz gdzie najmniejszy obiekt to cztery ścianki tworzące kwadrat złączone ze sobą i przy takim DOF, można zrobić następujące założenie:

Jeśli dla promienia x oraz x+2 jest widoczna ta sama ściana to dla x+1 również będzie widoczna ta sama ściana.

Chodzi o to że nie ma tak małego obiektu żeby renderował się jako jedno pikselowa kolumna na ekranie.

Od biedy można nawet wtedy współrzędną tekstury zrobić jako średnią z x, x+2 ale to nie będzie zgodne z perspektywą i z bardzo bliska może "pływać".

Ostatnia aktualizacja: 19.03.2021 14:35:51 przez Kefir_Union
[#114] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@kiero, post #112

@kiero

Wyrzuciłem wszystkie obliczenia,
została tylko funkcja rysująca ściany,
tzn. nawet nie rysuje ścian tylko wypełniam cały ekran,
oto rezultaty:


W tej postaci (kolumna po kolumnie) - mam 270 fps

inline void RC_Raycast_Walls()
{
    for (u_int16 rx = 0; rx < RC_render_width_i; ++rx)
    {
                int16 pp_wall_start = 0;
                int16  intensity_value = 100;
                int16 pp_wall_end = 240;

                for (u_int16 ry = pp_wall_start; ry < pp_wall_end; ++ry)
                {
                    u_int32 output_pixel_index = rx + ry * RC_render_width_i;
                    RC_output_dbuffer[output_pixel_index] = (intensity_value) << 16 | intensity_value << 8 | intensity_value;
                }
    }
}


Natomiast w tej postaci (linia po lini) - mam ok. 410 fps.

inline void RC_Raycast_Walls()
{
    for (u_int16 ry = 0; ry < RC_render_height_i; ++ry)
    {
                int16 pp_wall_start = 0;
                int16  intensity_value = 100;
                int16 pp_wall_end = 340;

                for (u_int16 rx = pp_wall_start; rx < pp_wall_end; ++rx)
                {
                    u_int32 output_pixel_index = rx + ry * RC_render_width_i;
                    RC_output_dbuffer[output_pixel_index] = (intensity_value) << 16 | intensity_value << 8 | intensity_value;
                }
    }
}


W obu przypadkach wypełniam cały ekran, różnica tkwi w kolejności, i daje to dużą róznicę..
[#115] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #114

Sprawdź w asemblerze jak to optymalizuje kompilator. W drugim przypadku może wyrzucać mnożenie ry przed pętlę.
[#116] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@Kefir_Union, post #115

dodaje flage "-save-temps" ale nic mi nie zapisuje,

zorbiłem to na kompilatorze online Bebbo tu są różnice:
https://www.diffchecker.com/n5NRH1oT
[#117] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #114

35% to nie jest duża różnica. Robisz bardzo duży błąd zakładając że to co widzisz na emulatorze będzie zachowywać się tak samo na Amidze. Do tego wyrzucając pozostały kod z pętli dodatkowo fałszujesz wyniki. Jeżeli dodasz wszystko do środka to z tych 35% robi się dużo mniej, dlatego że same zapisy będą stanowić coraz mniejszą jej część. Kolejny aspekt to to, że nie widać czy renderujesz nawet taką samą ilość pikseli. Nie widać tutaj jakie wartośći ma width i height. Widać tylko że wewnętrzna pętla wykonuje się inną ilość razy .. To jest ostatni raz kiedy odpisuję w tej kwestii. Twój kod nie jest powolny dlatego że rysujesz ściany pionowo zamiast poziomo.

Ostatnia aktualizacja: 19.03.2021 15:30:47 przez kiero
[#118] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@kiero, post #117


@kiero

ok, dzięki za pomoc..

Testowaliśmy na Vampie i efekty były podobne...

Ostatnia aktualizacja: 19.03.2021 15:38:14 przez mateusz_s
[#119] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@mateusz_s, post #116

Kompilator rozwija pętlę na 8 iteracji. Różnica w szybkości wynika z inkrementowania wskaźnika operatorem '+' gdy zapisywanie jest w wierszu zamiast instrukcji lea dodającej offset gdy zapisujesz kolumnę. Dodatkowo kompilator z braku rejestrów adresowych jeszcze żongluje trochę rejestrami w pierwszej wersji. Na 060 to chyba bez znaczenia ale na niższych procesorach szybsze będzie wpisywanie do pamięci zawartości rejestru zamiast stałej tzn.

Dla cpu 020/030

move.l d0, (a0)+ ; 4 cykle
będzie szybsze niż
move.l #6579300,(a0)+ ; 8 cykli

więc warto przed pętlą zrobić
move.l #6579300 ,d0

Na 060 też chyba warto bo krótsza w pamięci będzie ta pętla.

Ostatnia aktualizacja: 19.03.2021 15:36:22 przez Kefir_Union
[#120] Re: [C, RTG] Moje Raycasterowe zabawy, progresy, testy..

@Kefir_Union, post #115

Kompilator sobie poradzil bardzo dobrze, wewnetrzna petla w pierwszym przypadku:

.L3:
        move.l #6579300,(a0)+
        dbra d0,.L3


W drugim:
move.l #6579300,(a0)
        add.l d1,a0
        dbra d0,.L3


Czyli pierwsza wersja powinna byc szybsza. A nie jest. Znowu trafil na problem z optymalizacja zmiennych globalnych? Ten kod co pokazalem to po zmianie funkcji na:

void RC_Raycast_Walls(int RC_render_width_i, unsigned int *RC_output_dbuffer)


Po zmianie RC_render_width_i na zmienna globalna, wewnetrzna petla:

.L10:
        move.l _RC_render_width_i,-(sp)
        move.l d2,-(sp)
        jsr (a3)
        add.l a2,d0
        lsl.l #2,d0
        addq.l #8,sp
        move.l #6579300,(0,a4,d0.l)
        addq.l #1,d2
        subq.w #1,d3
        cmp.w #-1,d3
        jne .L10


Wniosek: nie uzywaj zmiennych globalnych. Przekaz je do funkcji jako parametry, zrob lokalna kopie jak juz chcesz koniecznie miec globalne.
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem