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

Aktuelle Zeit: Fr Jul 18, 2025 08:44

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Fläche von beiden Seiten beleuchten
BeitragVerfasst: Mi Jul 21, 2010 14:27 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Hallo,
hier ein Fahrrad-Unfall mit WebGl, wobei ich denke, dass es auch zu einem normalen OpenGL-Problem gezählt werden kann(?):

für die Oberfläche des Objektes habe ich die Normalenvektoren berechnet, die nun Bestandteil einer scheinbar korrekten Beleuchtung mit dem Punktlicht sind. Es werden alle Triangles mit ihrer entspechenden Färbung versehen und bewirken somit einen kleinen 3D-Effekt. Doch wenn ich das 3D Objekt um 180° drehe, also die Rückfläche betrachte, ist alles nur grau. Eigentlich ist das ja einleuchtend: Die Normalenvektoren wurden auf Basis einer bestimmten Orientierung berechnet. Somit zeigen sie auf der Rückseite von der Lichtquelle weg und bekommen kein Licht ab. Doch was tun, damit auch dort ein dreidimensionaler Effekt entsteht?


Die schönsten Sommergrüße aus dem heißesten Land der Welt. Deutschland.
:D


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 21, 2010 15:20 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Also wenn es dir nicht um Realismus geht sondern nur darum irgendwas erkennen zu können ist meine Lieblingslösung im Shader das Dot-Produkt nicht bei 0.0 abzuschneiden sondern den Absolutwert zu verwenden:

Normalerweise sieht das im Shader so aus:
Code:
float diffuseFactor = max(dot(normal, lightdir), 0.0);

So kriegst du dann auch auf der Rückseite Licht:
Code:
float diffuseFactor = abs(dot(normal, lightdir));


Eine weitere Alternative ist natürlich eine oder mehr weitere Lichtquellen, dann klappt es auch mit dem Realismus.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 21, 2010 17:13 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 11, 2009 08:02
Beiträge: 532
Programmiersprache: pascal (Delphi 7)
//edit: hab gerade gesehen, dass du noch recht neu bist. dann sind shader wohl keine alternative :(

Zitat:
Eine weitere Alternative ist natürlich eine oder mehr weitere Lichtquellen, dann klappt es auch mit dem Realismus.


das ändert aber nichts daran, dass die Normale von der Rückseite in die falsche Richtung zeigt.

Code:
float diffuseFactor = abs(dot(normal, lightdir));


das is auch nicht perfekt, weil es kann ja wirklich die Normale vom Licht wegzeigen.

Der einzige Weg, der mir jetzt einfallt ist, die Normale vorher umzudrehen, wenn sie vom Betrachter wegzeigt. Das ist nämlich genau dann so, wenn man die Rückseite sieht... oder wenn bei der Berechnung von der Normale irgendwas schief gegengen is.

Code:
if (normal.z < 0.0) {
  normal = -normal;
}


vielleicht muss da auch normal.z > 0.0 hin. je nachdem wo hinten ist. Aber so sollts gehen.

Das kann im Fragmentshader gemacht werden, ode wenns nötig ist auch im Geometrieshader. Aber auf jeden fall nach dem transformieren.

mfg

Sharkman


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 21, 2010 18:51 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 20, 2005 13:18
Beiträge: 1054
Wohnort: Dresden
Programmiersprache: C, C++, Pascal, OPL
Aber wichtig ist doch die Normale nach dem Reinarbeiten der ModellView-Matrix.
Sonst dreht man das Objekt per glRotatef um 180° und alles ist falsch. :?

Ich habe es ein mal so gelöst, dass ich BackFaceCulling aktiviert habe, also dass Rückseiten nicht gezeichnet werden, und ich diese dann explizit mit eigener Normale übergeben habe. Vorteil war bei mir, dass ich die "Hintergrundfarbe" explizit einstellen konnte.
Hier mal ein Beispiel, wie das aussah:
Dateianhang:
screenshot.png


LG Ziz


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

_________________
Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut.
Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’.
Und du schaust mich an und fragst ob ich das kann.
Und ich denk, ich werd' mich ändern irgendwann.

_________________Farin Urlaub - Bewegungslos


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 21, 2010 19:27 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Coolcat hat geschrieben:

So kriegst du dann auch auf der Rückseite Licht:
Code:
float diffuseFactor = abs(dot(normal, lightdir));



cool, es funktioniert..ich muss nur noch verstehen, warum das funktioniert.

sharkman hat geschrieben:
Der einzige Weg, der mir jetzt einfallt ist, die Normale vorher umzudrehen, wenn sie vom Betrachter wegzeigt. Das ist nämlich genau dann so, wenn man die Rückseite sieht... oder wenn bei der Berechnung von der Normale irgendwas schief gegengen is.

Code:
if (normal.z < 0.0) {
  normal = -normal;
}


vielleicht muss da auch normal.z > 0.0 hin. je nachdem wo hinten ist. Aber so sollts gehen.

Das kann im Fragmentshader gemacht werden, ode wenns nötig ist auch im Geometrieshader. Aber auf jeden fall nach dem transformieren.

sehr cool, damit klappt es ebenfalls. Die Lösung gefällt mir :)


danke euch!


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 21, 2010 20:13 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
sharkman hat geschrieben:
//edit: hab gerade gesehen, dass du noch recht neu bist. dann sind shader wohl keine alternative :(

Er benutzt WebGL, da geht nichts ohne Shader.

Zitat:
cool, es funktioniert..ich muss nur noch verstehen, warum das funktioniert.

Das dot-Produkt zweier Vektoren A und B ist so definiert:
A.x*B.x + A.y*B.y + A.z*B.z
Wenn du nun A = -A setzt ist das nichts anderes als
-A.x*B.x - A.y*B.y - A.z*B.z
es ändert sich also nur das Vorzeichen des dot-Produktes. Die abs-Funktion ist der Betrag einer Zahl das Ergebnis ist der positive Wert der Zahl. Die Funktion ist natürlich vordefiniert, aber im Code sähe das ca. so aus:
Code:
float abs(float zahl) {
    if (zahl < 0) { return -zahl; }
    else { return zahl; }
}

=> Die Variante von sharkman macht also eigentlich das gleiche. Zumindest sofern man das wirklich nach dem transformieren der Normale durch gl_NormalMatrix macht, weil dann die Z-Achse der Blickrichtung der Kamera entspricht. :)
[ Edit: Sorry, in WebGL gibt es natürlich kein vordefiniertes Uniform gl_NormalMatrix. Gemeint ist jedenfalls dein äquivalent dieser 3x3 Matrix, welches du in jedem Fall benötigst. Falls du die noch nicht eingebaut hast, die Berechnung dafür ist nicht so unglaublich kompliziert, kann ich dir gerne geben, einfach fragen :)]

Ziz hat geschrieben:
Vorteil war bei mir, dass ich die "Hintergrundfarbe" explizit einstellen konnte.

Im Fragmentshader kannst du mit der Variable gl_FrontFacing (Typ bool, nur lesbar) feststellen ob der gerenderte Pixel zur Vorder- oder Rückseite gehört und entsprechend die Farbe setzen. So lässt sich das auch ohne BackFaceCulling und zweimaliges Rendern realisieren. Die Variante von Ziz hat aber natürlich den Vorteil, dass sie ohne Shader funktioniert.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 21, 2010 22:12 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 20, 2005 13:18
Beiträge: 1054
Wohnort: Dresden
Programmiersprache: C, C++, Pascal, OPL
Das es um webGL geht und zudem das "normal.z<0" innerhalb eines Shaders war, habe ich nicht mitbekommen, sorry. Hoffe, meine Lösung ist vielleicht trotzdem für die Nichtshaderfraktion von Interesse.

_________________
Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut.
Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’.
Und du schaust mich an und fragst ob ich das kann.
Und ich denk, ich werd' mich ändern irgendwann.

_________________Farin Urlaub - Bewegungslos


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 15 Queries | GZIP : On ]