Efecte de contur în OpenGL (Programare, Opengl, Grafică, 3D, Glsl)

dupersuper a intrebat.

În OpenGL, pot contura obiectele desenând obiectul în mod normal, apoi desenându-l din nou ca un wireframe, folosind bufferul stencil pentru ca obiectul original să nu fie desenat peste. Totuși, acest lucru are ca rezultat contururi cu o singură culoare solidă.

În această imagine, pixelii conturului creaturii par să devină mai transparenți cu cât se îndepărtează mai mult de creatura pe care o conturează. Cum pot obține un efect similar cu OpenGL?

4 răspunsuri
weltensturm

Nu au folosit wireframe pentru acest lucru. Cred că este puternic legat de shader și necesită acest lucru:

  1. Renderizarea obiectului într-un buffer stencil
  2. Renderizarea buffer-ului stencil cu culoarea aleasă în timp ce se aplică blur
  3. Renderizarea modelului peste acesta

Comentarii

  • Deci, desenăm obiectul cu o culoare solidă într-o textură, apoi desenăm acea textură pe ecran cu un shader de estompare? –  > Por dupersuper.
  • Da, dar probabil că nu este singurul mod de a face acest lucru. –  > Por weltensturm.
  • Acesta este în esență modul în care a fost făcut pe titlul la care am lucrat, deși a fost problematic de lent pentru noi. Luați în considerare cât de mult din ecran va conține conturul dvs. înainte de a vă angaja în această abordare – există efecte mai ieftine disponibile pentru a comunica faptul că „acest model este evidențiat”. Pe un titlu modern, probabil că nu aveți rată de umplere de prisos. –  > Por Philip Guin.
  • De ce nu o faceți printr-un vertex shader care împinge vertexul cu un decalaj în direcția normală și folosiți-l ca și contur (redare plată), apoi redați culoarea de sus după aceea –  > Por Spider.
EmericBeaufays

Am întârziat cu un răspuns, dar încercam să realizez același lucru și m-am gândit să împărtășesc soluția pe care o folosesc.

Un efect similar poate fi obținut într-o singură operațiune de desenare cu un shader nu foarte complex.

În fragment shader, vei calcula culoarea fragmentului pe baza fulgerului și a texturii, oferindu-ți culoarea ne-iluminată „colorA”.

A doua culoare este culoarea conturului, „colorB”.

Ar trebui să obțineți vectorul fragment-cameră, să îl normalizați, apoi să obțineți produsul punct al acestui vector cu normalul fragmentului.

Vectorul fragmentului față de cameră este pur și simplu inversul poziției fragmentului în spațiul vizual.

Culoarea fragmentului este atunci:

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

Aceasta este ideea de bază, dar va trebui să vă jucați cu ea pentru a avea mai multă sau mai puțină culoare de contur. De asemenea, părțile concave ale modelului dvs. vor fi de asemenea evidențiate, dar acesta este și cazul în imaginea postată în întrebare.

ChatCloud

Detectați marginile în shaderul GLSL folosind dotprod(view,normal)

http://en.wikibooks.org/wiki/GLSL_Programming/Unity/Toon_Shading#Outlines

Comentarii

  • Rețineți că această tehnică va evidenția toate „marginile” vizibile, nu doar conturul. Ar putea fi sau nu de dorit. –  > Por Calvin1602.
rioki

Din câte văd eu efectul pe ecran scurt și multe efecte de „margine” nu sunt margini pure, ca în conturul benzii desenate. Ceea ce se face de cele mai multe ori, ai o trecere în care faci o randare normală a obiectului, apoi o trecere cu doar geometria (fără texturi) și un shader GLSL. În shaderul de fragmente se ia normala, iar această normală este perpendiculară pe vectorul camerei pe care se colorează obiectul. Efectul este apoi netezit prin includerea unei zone apropiate de perpendicularitatea perfectă.

Ar trebui să caut matematica exactă, dar cred că dacă luați produsul punctual al vectorului camerei și al normalului obțineți cantitatea de „perpendicularitate”. Pe care îl poți trece apoi printr-o funcție precum exp pentru a obține o polarizare spre 1.

Deci (fără a garanta că este corect):

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

(Notă: totul este în spațiul ecranului.)