2012-10-16 13 views
16

W OpenGL mogę szkicować obiekty, normalnie rysując obiekt, a następnie rysując go ponownie jako szkielet, używając bufora szablonu, aby oryginalny obiekt nie został narysowany. Powoduje to jednak kontury o jednolitym kolorze.Efekty zewnętrzne w OpenGL

enter image description here

W tym obrazie piksele zarysie stwora wydają się bardziej przejrzyste dalsze są one od istoty ich zarys. Jak mogę osiągnąć podobny efekt w OpenGL?

Odpowiedz

6

W tym celu nie użyto szkieletu. Myślę, że jest ciężko shader powiązane i wymaga to:

  1. Rendering obiektu do bufor szablonowy
  2. renderowania bufor szablonowy kolorem wyboru przy zastosowaniu rozmycia
  3. modelu rendering na wierzchu
+0

Rysujemy obiekt z jednolitym kolorem na fakturze, a następnie narysujemy tę teksturę na ekranie za pomocą zacienionego shadera? – dupersuper

+0

Tak, ale prawdopodobnie nie jest to jedyny sposób, aby to zrobić. – weltensturm

+1

Zasadniczo to zostało zrobione na tytule, nad którym pracowałem, chociaż dla nas było problematycznie wolne. Zastanów się, jak duża część ekranu będzie zawierała Twój zarys, zanim podejmiesz się tego podejścia - dostępne są tańsze efekty, które informują, że "ten model jest podświetlony". W przypadku nowoczesnego tytułu prawdopodobnie nie masz do dyspozycji współczynnika wypełnienia. – Philip

1

O ile widzę, efekt na ekranie krótki, a wiele efektów "krawędziowych" nie jest czystymi krawędziami, jak w zarysie komiksu. W większości przypadków wystarczy jedno przejście, aby renderować obiekt normalnie, a następnie przejść tylko z geometrią (bez tekstur) i modułem cieniowania GLSL. W cieniującym ciele normalna jest pobierana, a normalna jest prostopadła do wektora kamery, którą kolorujesz obiekt. Efekt jest następnie wygładzany przez włączenie obszaru bliskiego idealnej prostopadłości.

Musiałbym sprawdzić dokładną matematykę, ale myślę, że jeśli weźmiesz kropkę iloczynu wektora kamery i normalnego, otrzymasz wartość "prostopadłości". Że można wtedy uruchomić za pomocą funkcji takich jak exp dostać nastawienie wobec 1.

SO (bez gwarancji, że są poprawne):

exp(dot(vec3(0, 0, 1), normal)); 

(Uwaga:. Wszystko jest w screenspace)

4

Spóźniłem się na odpowiedź, ale próbowałem osiągnąć to samo i pomyślałem, że podzielę się rozwiązaniem, którego używam.

Podobny efekt można uzyskać w operacji pojedynczego wyciągnięcia z niezbyt skomplikowanym modułem cieniującym.

W module cieniującym obliczysz kolor fragmentu na podstawie pioruna i tekstury, podając nie wyróżniony kolor "colorA".

Twój drugi kolor to kolor obrysu, "colorB".

Powinieneś otrzymać fragment do wektora kamery, znormalizować go, a następnie otrzymać iloczyn iloczynowy tego wektora z normalnym fragmentem.

Fragment do wektora kamery jest po prostu odwrotnością położenia fragmentu w przestrzeni oczu.

kolor fragmentu wynosi:

float CameraFacingPercentage = dot(v_fragmentToCamera, v_Normal); 
gl_FragColor = ColorA * CameraFacingPercentage + ColorB * (1 - FacingCameraPercentage); 

Jest to podstawowa idea, ale będziesz musiał bawić się mieć bardziej lub mniej koloru konturu. Ponadto podświetlone zostaną wklęsłe części modelu, ale tak samo jest w przypadku obrazu zamieszczonego w pytaniu.