Tworzę własny silnik 3D w JavaScript i używam tylko rysunku na płótnie, bez WebGL. To kolejny klon Minecrafta; Uwielbiam pudełka, nie oceniaj mnie.
Jak dotąd wszystko działa wspaniale, z wyjątkiem jednej rzeczy: w 3D, gdy niektóre wierzchołki wychodzą za bliską płaszczyznę tnącą, ich rzut na ekran wychodzi dziwnie (zakładając, że inne wierzchołki używane do śledzenia płaszczyzny znajdują się z przodu).
Próbowałem wyciąć te punkty, ale potem widzę koryta powierzchni wykorzystujących te wierzchołki. W WebGL / OpenGL karta graficzna zajmuje się tymi punktami, a płaszczyzna jest renderowana poprawnie, ale nie mam dostępu do sprzętu, więc sam muszę to kodować.
Nie jestem do końca pewien, co z tym zrobić, obecnie ostatnią rzeczą, jaka przyszła mi do głowy, jest odwrócenie projekcji punktów za zbliżającą się płaszczyzną tnącą gracza, co wydaje się logiczne, ponieważ muszę rzutować punkt na ekran przed nim wierzchołka.
Oto moje przemyślenia:
Oto kilka zdjęć ilustrujących to, co się dzieje:
Z daleka niebieskie pudełko renderuje się doskonale.
Kiedy niektóre wierzchołki znajdują się za płaszczyzną przycinania odtwarzacza, odwracam projekcję, ale nie wygląda to dobrze:
focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;
Zauważ, że szare pole z tyłu zostało całkowicie usunięte, ponieważ wszystkie wierzchołki użyte do narysowania jego twarzy znajdują się za graczem.
Tak dzieje się, gdy patrzysz w górę lub w dół.
Nie wiem, co sądzić o matematyce, mam nadzieję, że ktoś już napotkał ten sam problem i może mi pomóc.
źródło
lineTo(x,y)
można było wywołać tę funkcję, ale nie wiem, jak się zachowuje ... to dziwny wymiar, zgadzam się.Odpowiedzi:
Celem bliskiej płaszczyzny tnącej jest to, że jest to płaszczyzna tnąca . Trójkąty znajdujące się poza płaszczyzną przycinania są przycinane : pocięte na kawałki, aby każdy pozostały kawałek znalazł się w obszarze przycinania.
Jeśli chcesz, możesz zignorować klip w pobliżu. Rzeczywiście OpenGL i D3D mogą całkowicie wyłączyć obcinanie w pobliżu płaszczyzny (chociaż bufor głębokości nadal ma minimalną wartość bliską). Problemem nie jest bliski klip.
Problem dotyczy wierzchołków znajdujących się za kamerą.
Nie można renderować trójkątów znajdujących się za kamerą. Nie z rzutowaniem perspektywicznym. Takie trójkąty nie mają sensu pod matematyką za rzutami perspektywicznymi. Co więcej, są one również poza otoczką.
Wyłączenie w pobliżu przycinania zmienia frustum w piramidę. Powodem, dla którego piramida zatrzymuje się w tym punkcie, jest to, że punkty nad piramidą znajdują się za wszystkimi czterema bokami piramidy. Tak więc każdy punkt za kamerą (czubek piramidy) znajduje się powyżej, poniżej, po lewej i po prawej stronie widocznego obszaru ekranu. Wszystko w tym samym czasie.
Jak powiedziałem: wierzchołki pod rzutowaniem perspektywicznym, które znajdują się za kamerą, nie mają sensu.
Musisz wdrożyć obcinanie. Musisz wykryć, kiedy jakikolwiek wierzchołek trójkąta w przestrzeni klipu ( przed podziałem perspektywy) znajduje się za kamerą. Jeśli tak, musisz przyciąć ten trójkąt, generując tylko trójkąty znajdujące się przed kamerą.
To nie jest prosty proces. Będzie to wymagało matematyki, która ma sens tylko wtedy, gdy masz pełne zrozumienie jednorodnych układów współrzędnych. Alternatywnie, możesz po prostu wyprostować dowolny trójkąt, jeśli jakikolwiek jego wierzchołek znajduje się za kamerą.
źródło
Jeśli część trójkąta znajdująca się za bliską płaszczyzną mogłabyś sprawdzić, czy piksel znajduje się za płaszczyzną przycinającą?
Możesz traktować bliski samolot jak każdą inną płaszczyznę tnącą. Na przykład płaszczyzny obcinania są używane do takich rzeczy, jak płaszczyzny wodne (do odbić i załamań). Sądzę, że ta płaszczyzna odcinania będzie działać tak samo, jak płaszczyzna zbliżenia przycinania, i będzie przycinana na piksel.
Wiem, jak obsługiwać płaszczyzny obcinania w HLSL za pomocą DirectX, ale ich implementacja może być zastrzeżona. Jeśli możesz uzyskać informacje na ten temat, może to być pomocne.
Dodatkowo tutaj jest link, który może ci pomóc: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html
źródło