Przeważnie udało mi się przenieść implementację Marching Cubes z CPU do shaderów obliczeniowych OpenGL, ale jeszcze nie poradziłem sobie z normami i zastanawiam się, jak to zrobić.
Moja implementacja zajmuje się konkretnie polami o wartości binarnej (próbuję modelować funkcje fraktalne 3D, które nie mają jeszcze estymatora odległości), więc metody różnic i gradientów do przodu nie będą działać. Dzielę działające wierzchołki, a moja implementacja procesora wykorzystuje opisaną tutaj metodę Quilez do gromadzenia normalnych twarzy na każdym sąsiednim wierzchołku.
Mógłbym po prostu przenieść tę implementację na inny moduł cieniujący, ale widzę problem z ogromną liczbą potrzebnych atomów. Ponieważ możemy używać atomów tylko na skalarnych typach liczb całkowitych, i nie mogę wymyślić sposobu na spakowanie 3 podpisanych liczb całkowitych w 1 w sposób sumowalny, oznacza to, że 3 osie * 3 wierzchołki = 9 dodatków atomowych na wywołanie modułu cieniującego. Będą one oczywiście rozrzucone w całej pamięci, więc nie jest to 9-krotne uderzenie w pojedynczy licznik atomowy, ale nadal wydaje się, że to cholernie dużo.
Inną alternatywą jest uruchomienie wywołania modułu cieniującego dla wielokąta i zbudowanie listy normalnych twarzy (prawdopodobnie mógłbym spakować do x10y10z10 w ten sposób), a następnie modułu cieniującego na wierzchołek, aby zgromadzić wszystkie normalne sąsiednie twarze. Byłby to jednak olbrzymi świnia pamięci, miejsce do przechowywania indeksów twarzy wymagałoby 12 int na wierzchołek, aby poradzić sobie z najgorszym przypadkiem. Istnieje również problem z tym, jak zapisać w tym magazynie, bez uciekania się do atomów, aby dowiedzieć się, ile twarzy zostało już zapisanych w danym wierzchołku.
Czy ktoś ma lepsze pomysły, jak to zrobić?