Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Jul 17, 2025 12:17

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Stencil verschachteln
BeitragVerfasst: Di Apr 20, 2010 23:10 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Hi,

ich hab ein kleines problem mit dem Stencil Buffer.. dabei geht es aber nicht unbedingt um probleme mit den befehlen, sondern um eine Idee wie ich ein gewünschtes ergebnis erreiche.

Ich hab im Attachment ein Bild angehängt was das ganze etwas verdeutlichen soll.
Die Schraffierten, rot umrandeten flächen im Bild sind Quads die ich in den StencilBuffer zeichne, in der reihenfolge 1, 2, 3 und dann das 4te.

Dateianhang:
stencil.png


Wenn ich das tue habe ich logischerweise am ende einen komplett weißen StencilBuffer, denn schon bei dem Quad von '1.' wird der komplette Bildschirm ausgefüllt.

Was ich aber gerne hätte ist ein ergebnis wie im Bild unter 'Result'.. sprich es soll von allen vorherigen Quads immer das kleinste den Stencil Bilden..


Im grunde müsste ich den Stencil komplett auf 0 leeren vor jedem Quad, aber dann das neue Quad nur da zeichnen wo der Stencil vor dem leeren 1 war - oder anders gesagt: Ich möchte nur dort in den StencilBuffer zeichnen wo er 1 ist, aber dannach alles wo ich nichts gezeichnet habe automatisch auf 0 setzen :)

Bei simplen Rechtecken könnte ich natürlich einfach 4 Rechtecke zeichnen welche den Stencil rings um mein Quad auf 0 setzen, aber bei mir geht es um recht komplexe Polygon Formen..

Hat irgendjemand eine Idee?

Aya~


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 08:16 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Was ich aber gerne hätte ist ein ergebnis wie im Bild unter 'Result'.. sprich es soll von allen vorherigen Quads immer das kleinste den Stencil Bilden..

Was verstehst du unter dem "kleinsten"? Bezüglich Fläche oder Umfang? In dem Fall würde dir der Stencilbuffer wahrscheinlich nicht weiter helfen. Die Fläche könnte man aber z.B. durch die Anzahl der Pixel approximieren. Die Anzahl der gerenderten Pixel kann man mit einem Occlusion Query zählen.

Mit dem Stencilbuffer wäre z.B. die Schnittmenge aller Polygone möglich. Also die Pixel die von allen Polygonen angefasst werden. Das geht ganz einfach: Der Stencilbuffer kann nicht nur 0 und 1, sondern der kann zählen (*). Mit jedem Polygon inkrementierst du den Stencilbuffer, am Ende zeichnest du alle Pixel bei denen der Wert im Stencil gleich der Anzahl der Polygone ist.



(*) auf modernen Grafikkarten üblicherweise von -128 bis 127. Ältere Karten können ggf. einen kleineren Bereich oder keine negativen Zahlen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 09:39 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Perfekt, das mit dem incrementieren war genau was ich brauche :)
Wusste nich das dass geht ^^

Danke~~
Aya


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 09:59 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Es ist ganz nützlich zu wissen was man mit dem Stencilbuffer so anstellen kann, ich empfehle dir mal Stencil-Volumen-Schatten anzuschauen, z.B. hier Kapitel 3:
http://www-users.rwth-aachen.de/martin. ... 8_1350.pdf

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 10:07 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Coolcat hat geschrieben:
Es ist ganz nützlich zu wissen was man mit dem Stencilbuffer so anstellen kann, ich empfehle dir mal Stencil-Volumen-Schatten anzuschauen, z.B. hier Kapitel 3:
http://www-users.rwth-aachen.de/martin. ... 8_1350.pdf


Die kenn ich.. hatte ich früher auch mal implementiert :)
Aber das ist so lange schonwieder her, das mir das mit dem Incremental kram absolut nichmehr geläufig war ^^

Gibt es mittlerweile eigentlich schönere Methoden um die Geometrie des StencilSchattens zu berechnen?
So vonwegen GeometryShader oder so..? Hab das damals recht schnell wieder verworfen gehabt, weil es mir einfach viel zu viel aufwand war diese Silhouetten-Geometry ständig zu berechnen etc..

Aya~


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 10:35 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Gibt es mittlerweile eigentlich schönere Methoden um die Geometrie des StencilSchattens zu berechnen?

Also das gängige Verfahren braucht nur den Vertexshader. Jede Kante wird aufgespalten und es werden zwei degenerierte Dreiecke eingefügt. Die beiden roten Kanten befinden sich also eigentlich übereinander. Wichtig: Die Vertices müssen aber wirklich mehrfach vorhanden sein, also nicht einfach via Indexbuffer machen!
Dateianhang:
stencil-shadow.png

Jeder Vertex erhält zudem die Normale des zugehörigen Dreiecks im Original-Mesh, also Face-Normalen statt Vertex-Normalen, aber pro Vertex gespeichert. Dadurch kannst du im Vertexshader für jeden Vertex entscheiden ob er nach hinten geschoben werden soll oder nicht. Da Stencil-Shadows sowieso sehr Füllratenlastig sind, fällt die Verarbeitung der zusätzlichen Dreiecke nicht ins Gewicht. Degenerierte Dreiecke werden von der Grafikkarte erkannt und nicht gezeichnet.

Mit dem Geometrieshader ist es möglich die notwendigen Dreiecke live zu erzeugen. Dafür werden aber Adjazenzinformationen benötigt, also zumindest ein spezieller Indexbuffer. Also 6 Vertices pro Dreieck die man dann im Geoemetryshader auch alle gleichzeitig angucken kann:
Dateianhang:
stencil-shadow2.png

Man überprüft also für jedes der 4 Dreiecke ob es Front- oder Backfacing ist. Wenn sich ein adjazentes Dreieck vom mittleren Dreieck unterscheidet wird ein Dreieck an der entsprechenden Kante eingefügt. Das zweite Dreieck wird generiert, wenn das entsprechende Nachbardreieck verarbeitet wird. Man muss sich natürlich eine Konvention ausdenken damit sich alles nahtlos zusammenfügt.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 15:24 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Mhh.. ganz so wie gedacht klappt das irgendwie doch nich, aber evtl hab ich da auch nen fehler drin :/

Code:
   glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   glDepthMask(GL_FALSE);

   glClear(GL_STENCIL_BUFFER_BIT);
   glEnable(GL_STENCIL_TEST);
   glStencilFunc(GL_ALWAYS, 1, 1);
   glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);

   // 1. Rechteck Zeichnen: [0, 0, 100, 100] // X, Y, Width, Height

   // 2. Rechteck Zeichnen: [0, 0, 200, 100] // X, Y, Width, Height
   
   glDepthMask(GL_TRUE);
   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);


So, jetzt müßte rein theoretisch doch der StencilBuffer links oben den wert 1 haben, und rechts daneben den wert 2.
Denn das erste Quad erhöht den Stencil wert im Bereich von (0, 0, 100, 100) um 1 auf 1, und das zweite dann im bereich von (0, 0, 200, 100) wiederrum um 1.. die linken 100px dann von 1 auf 2, und die rechten 100px von 0 auf 1 - richtig?

Wenn ich jetzt dann aber hiermit etwas zeichne:

Code:
   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
   glStencilFunc(GL_EQUAL, 1, 2);
   // Irgendwas zeichnen...
   glDisable(GL_STENCIL_TEST);


scheint es so als würde der Stencil Buffer komplett ignoriert werden... es wird nicht nur dort gezeichnet wo der wert 2 im StencilBuffer steht, sondern überall.

Hab ich irgendnen fehler drin?

Aya~


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 16:05 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Test wird bestanden wenn ( ref & mask) = ( stencil & mask).

Vielleicht solltest du mask lieber auf 255 statt auf 2 setzen. Die Maske wird bitweise UND verknüpft. Im Augenblick dürfte er eigentlich nur dort rendern wo der Stencil 0 ist, da 1 & 2 nun mal 0 ist.

Edit:
Eine mögliche Fehlerquelle wäre der Z-Buffer. Ist es richtig das du diesen nicht löscht?

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 16:11 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Mhh.. 255 anstatt 2..?

Was genau macht denn das GL_INCR..?
Dachte das sei so vonwegen nach dem ersten Zeichenn ist der StencilWert 1, dann 2.. 3, 4.. etc.. wohl nicht?

Bzw wie sag ich ihm dann das er NUR da zeichnen soll, wo vorher 2 Quads im stencil gezeichnet wurden?

@DepthTest: Der ist die ganze zeit sowieso deaktiviert, sorry.. hab ich im beispiel nich mit angegeben.

EDIT: Aaahh! ich habe "mask" und "ref" vertauscht.. :) Ganz klappen tut es zwar noch nicht, aber das kann jetzt grad auch daran liegen das ich zum fehler finden soviel umgebastelt habe :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 16:40 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Was genau macht denn das GL_INCR..?

Das nimmt das was im Stencil drin ist und addiert 1 drauf.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 16:48 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Mhh.. auch nach meinem EDIT von oben klappt es noch nich ganz..

Code:
   glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   glDepthMask(GL_FALSE);

   glClear(GL_STENCIL_BUFFER_BIT);
   glEnable(GL_STENCIL_TEST);
   glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
   glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);

   // 1. Rechteck Zeichnen: [0, 0, 100, 100] // X, Y, Width, Height

   // 2. Rechteck Zeichnen: [0, 0, 200, 100] // X, Y, Width, Height
   
   glDepthMask(GL_TRUE);
   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

   [...]

   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
   glStencilFunc(GL_EQUAL, 2, 0xFFFFFFFF);
      // 'ref' und 'mask' waren vertauscht
      // Wenn ich als 'ref' 0 angebe, wird alles gezeichnet ausser links oben die fläche beider Rechtecke.
      // Wenn ich als 'ref' 1 angebe, wird nur die linke oberer fläche beider Rechtecke gezeichnet
      // Wenn ich als 'ref' 2 angebe, wird garnichts gezeichnet...
      
   // Irgendwas zeichnen...

   glDisable(GL_STENCIL_TEST);


Hab im Code unten ein paar kommentare hingeschrieben.
Kann es evtl sein das mein Wert im Stencil beim GL_INCR bei 1 geclampt ist?

Aya


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 16:59 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Du kannst via GL_STENCIL_BITS abfragen wie groß sein Stencibuffer ist. (Das gibt dir die Anzahl der Bits, also 2^bits)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 17:01 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Coolcat hat geschrieben:
Du kannst via GL_STENCIL_BITS abfragen wie groß sein Stencibuffer ist. (Das gibt dir die Anzahl der Bits, also 2^bits)

Da kommt 8 raus.. also scheint das richtig zu sein.

Mhh.. irgendne idee was da sonst das Problem sein kann? :/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 17:08 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Hm, versuch mal eine kleinere Maske...vielleicht 255 oder 127.

Mit glClearStencil hast du nicht gespielt, oder?

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil verschachteln
BeitragVerfasst: Mi Apr 21, 2010 17:12 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Coolcat hat geschrieben:
Hm, versuch mal eine kleinere Maske...vielleicht 255 oder 127.

hilft leider auch nix.. bzw, ist kein unterschied.

Coolcat hat geschrieben:
Mit glClearStencil hast du nicht gespielt, oder?

Ne.. nur halt einmal beim Initialisieren glClearStencil(0); aufgerufen.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 16 Queries | GZIP : On ]