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

Aktuelle Zeit: Sa Jun 08, 2024 17:19

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



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Lighting (Verständnis)
BeitragVerfasst: Do Aug 23, 2012 23:08 
Offline
DGL Member

Registriert: Di Aug 21, 2012 19:31
Beiträge: 173
Programmiersprache: C#
Ich möchte meine Scene mit etwas Licht versehen.
Denn aus licht folgt Schatten und ohne Schatten is 3D ja irgendwie nicht ganz 3D ;)
Nur was wenn zwar der Lichtschalter auf an steht, aber der Schatten sich nicht blicken lässt?
Hat wohl Angst der Feigling... :D

Spass bei Seite:
Ich habe versucht anhand des Tutorials im Wiki meine Scene mit Licht zu versehen.
Also:
Code:
  1. Gl.glEnable(Gl.GL_LIGHTING);
Huch, alles ist Grau... Naja, nicht ganz unerwartet.
Die Lichtquellen fehlen ja noch.
Code:
  1. Gl.glEnable(Gl.GL_LIGHT0);
  2.             //Gl.glEnable(Gl.GL_LIGHT1);
  3.             Gl.glEnable(Gl.GL_COLOR_MATERIAL);
  4.             Gl.glEnable(Gl.GL_NORMALIZE);
  5.  
  6.             float[] mat_specular = { 0.0f, 0.0f, 0.0f, 1.0f };
  7.             float[] mat_shininess = { 50.0f };
  8.             float[] mat_ambient = { 0.4f, 0.4f, 0.4f, 1.0f };
  9.             float[] mat_diffuse = { 0.4f, 0.8f, 0.4f, 1.0f };
  10.  
  11.             float[] light_position = { -20.0f, 60.0f, -20.0f, 1.0f };
  12.             float[] light_ambient = { 0.8f, 0.8f, 0.8f, 1.0f };
  13.             float[] light_diffuse = { 0.2f, 0.2f, 0.2f, 1.0f };
  14.  
  15.             Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular);
  16.             Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, mat_shininess);
  17.             Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient);
  18.             Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse);
  19.  
  20.             Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, light_ambient);
  21.             Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, light_diffuse);
  22.             Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, light_position);
Im Grunde das Gleiche wie im Tutorial.

Schwups ist alles wieder Hell. Sehr schön.
Aber: kein Unterschied zu vorher. oO
Seltsam... ich hätte Schatten erwartet dort, wo ich extra 2 Flächen übereinander gelegt hatte.
Es gibt aber keinerlei Schatten.

Nun zu mir: Ich gebe zu, dass ich keinerlei Ahnung hab was da passiert. (Kann das aus dem Tutorial nicht so ganz herauslesen. Sorry)
Wie schaffe ich Licht UND Schatten in meiner Scene? Es soll im Grunde dem Licht einer Sonne weit über der Scene ähneln.

Grüße!

_________________
ack nack nack nack nack


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Do Aug 23, 2012 23:43 
Offline
DGL Member

Registriert: Sa Mär 31, 2012 23:14
Beiträge: 26
Programmiersprache: PASCAL
Das Problem ist dass Schattenberechnung einfach VIEL zu aufwänding ist als dass die GraKa das mal eben so nebenbei machen könnte; Schatten musst du trotz aktivierten Licht selber programmieren.
Dafür gibt es eine Reihe bewährter Methoden wie Shadowvolumes (die Schatten werden mit echter Geometrie erzeugt und sind 100% pixelgenau)
Volumetrische_Stencilschatten (kostet 'ne Menge Performance) oder gefühlt 100 Varianten von Schadowmapping (die Schatten werden erzeugt indem man den Abstand zur Lichtquelle jedes Pixels mit dem Abstand des der Lichtquelle am nächsten gelegenen Pixels verglichen wird (so grob); bessere Performance als Shadow Volumes, dafür nicht pixelgenau; z.B.
GLSL_Licht_und_Schatten oder
http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html).

Stencilshadows kann man einfach einbauen so im Prinzip (ist jetzt nicht sooo kompliziert), für Shadowmapping sollte man schon 'ne ordentliche Portion Zeit mit Shadern verbracht haben.
Hoffe ich konnte helfen

_________________
The force, strong it is in OpenGL.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Fr Aug 24, 2012 00:16 
Offline
DGL Member

Registriert: Di Aug 21, 2012 19:31
Beiträge: 173
Programmiersprache: C#
breakdancingYoda hat geschrieben:
Hoffe ich konnte helfen
Allein schon mit der Aussage!

Wo Licht, muss in OpenGL also noch längst kein Schatten sein.
Dann brauch ich damit gar nicht weiter rumprobieren.

Vielen danke ;)

_________________
ack nack nack nack nack


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Fr Aug 24, 2012 10:57 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich werf mal nochwas ein: Flächen sollten aber unterschiedlich hell sein je nach dem wie sie zum Licht gerichtet sind. Dafür musst du aber die Normalen ordentlich setzen: glNormal.

grüße & viel spaß

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Fr Aug 24, 2012 11:44 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Richtig, das hier zum Beispiel nur lokale Beleuchtung, allerdings pro Pixel im Shader, nicht pro Vertex wie das OpenGL-Licht welches zu benutzt. Ist ziemlich simpel zu bauen und erzeugt zunächst mal akzeptabel Ergebnisse.
Bild
(klicken zum vergrößern)


Echter Schatten ist das aber nicht. Es wird nur für jeden Pixel abhängig von der Normale (=Neigung der Fläche) entschieden wie er beleuchtet wird. Bei echtem Schatten wird geprüft ob sich ein anderes Objekt zwischen der aktuellen Pixel und der Lichtquelle befindet. Das ist offensichtlich nicht ganz einfach. ;)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Mo Aug 27, 2012 22:41 
Offline
DGL Member

Registriert: Di Aug 21, 2012 19:31
Beiträge: 173
Programmiersprache: C#
Ich habe das Thema Schatten erst mal nach hinten geschoben.
Allerdangs wollte ich schon gern das letzgenannte umsetzen. Sprich die unterschiedlich hellen Flächen.
Ich habe einen Berg, der im grunde aus zwei multiplizierten Cosinus-Funktionen besteht. Dreicke draus machen und fertig ist der Hügel.
Nun würde ich eben gern, dass die dem Licht zugewandte Seite heller erscheint als die dem Licht abgewandte Seite.
Dazu habe ich die Normalen berechnet (Kreuzprodukt usw... ) und Teile sie durch glNormal3d(); mit.

Ich sehe auch, dass sich was tut an dem Gebilde. Jedoch nicht wie erwartet.
Die Helligkeit der Fläche scheint viel mehr von der Blickrichtung der Kamera als von der Position der Lichtquelle abzuhängen

Siehe Anhang: die helleren Flächen sind die der Kamera zugewandten. Die Positionsangabe für das Licht ist jedoch 0, 0, 10. Also praktisch hinter dem Berg am Ursprung des Koordinatensystems.

Was mache ich da falsch?


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

_________________
ack nack nack nack nack


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Mo Aug 27, 2012 23:19 
Offline
DGL Member

Registriert: Di Aug 21, 2012 19:31
Beiträge: 173
Programmiersprache: C#
Ok, ich muss die Positionsangabe nach glu.lookat(...);
Machen... das hat zumindest diesen Fehler behoben ^^

_________________
ack nack nack nack nack


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Di Aug 28, 2012 12:44 
Offline
DGL Member

Registriert: Di Aug 21, 2012 19:31
Beiträge: 173
Programmiersprache: C#
erneutes Problem mit dem Licht -.-

Ich habe im Grunde die Parameter aus dem Wiki-Tutorial übernommen und sehe auch erste Erfolge (siehe Anhang)

Auf dem Bild ist zu erkennen, dass die dem Berg zugewandte Seite heller ist, als die andere.
Die übrige Fläche, der Kreis drumherum ist jedoch heller als die Grundfläche des Berges.
Ich habe auch hier die Normalen berechnet und zeichne auch alles in der selben Funktion. Also mit den gleichen Eigenschaften. (So hoffe ich):

Code:
  1.  
  2. private void storeMapList() {
  3.             double texX = 0, texZ = 0;
  4.  
  5.             for (int y = 0; y < objects.getIslandCount(); y++) {
  6.                 Gl.glEnable(Gl.GL_NORMALIZE);
  7.                 Island island = objects.getIsland(y);
  8.                 island.setID(Gl.glGenLists(1));
  9.                 Gl.glNewList(island.getID(), Gl.GL_COMPILE);
  10.  
  11.                 Gl.glEnable(Gl.GL_TEXTURE_2D);
  12.                 Gl.glBindTexture(Gl.GL_TEXTURE_2D, textures[0]);
  13.  
  14.                 Gl.glBegin(Gl.GL_TRIANGLES);
  15.                
  16.                 for (int i = 0; i < island.getCount(); i++) {
  17.                     Triangle tri = (Triangle)island.getTriangle(i);
  18.                     Point A = tri.getA();
  19.                     Point B = tri.getB();
  20.                     Point C = tri.getC();
  21.                     Vector normal = tri.getNormal();
  22.                     double xPos = island.getPosition().getX();
  23.                     double zPos = island.getPosition().getZ();
  24.                     double radian = island.Radian;
  25.  
  26.                     Gl.glNormal3d(normal.getX(), normal.getY(), normal.getZ());
  27.  
  28.                     texX = ((A.getX() - (xPos - radian)) / (radian * 2)) * 6;
  29.                     texZ = ((A.getZ() - (zPos - radian)) / (radian * 2)) * 6;
  30.                     Gl.glTexCoord2d(texX, texZ);
  31.                     Gl.glVertex3d(A.getX(), A.getY(), A.getZ());
  32.  
  33.                     texX = ((B.getX() - (xPos - radian)) / (radian * 2)) * 6;
  34.                     texZ = ((B.getZ() - (zPos - radian)) / (radian * 2)) * 6;
  35.                     Gl.glTexCoord2d(texX, texZ);
  36.                     Gl.glVertex3d(B.getX(), B.getY(), B.getZ());
  37.  
  38.                     texX = ((C.getX() - (xPos - radian)) / (radian * 2)) * 6;
  39.                     texZ = ((C.getZ() - (zPos - radian)) / (radian * 2)) * 6;
  40.                     Gl.glTexCoord2d(texX, texZ);
  41.                     Gl.glVertex3d(C.getX(), C.getY(), C.getZ());
  42.                 }
  43.                
  44.                 for (int i = 0; i < island.getHillCount(); i++) {
  45.                     Hill h = island.getHill(i);
  46.                     Console.WriteLine(island.getHillCount());
  47.                     for (int l = 0; l < h.getCount(); l++) {
  48.                         Triangle tri = h.getTriangle(l);
  49.                         Point A = tri.getA();
  50.                         Point B = tri.getB();
  51.                         Point C = tri.getC();
  52.                         Vector normal = tri.getNormal();
  53.                         Vector parentPosition = h.getParentPosition();
  54.                         double parentX = parentPosition.getX();
  55.                         double parentY = parentPosition.getY();
  56.                         double parentZ = parentPosition.getZ();
  57.  
  58.                         Gl.glNormal3d(normal.getX(), normal.getY(), normal.getZ());
  59.  
  60.                         texX = (parentX + A.getX()) % mapMultiplier / 10;
  61.                         texZ = (parentZ + A.getZ()) % mapMultiplier / 10;
  62.                         Gl.glTexCoord2d(texX, texZ);
  63.                         Gl.glVertex3d(parentX + A.getX(), parentY + A.getY(), parentZ + A.getZ());
  64.  
  65.                         texX = (parentX + B.getX()) % mapMultiplier / 10;
  66.                         texZ = (parentZ + B.getZ()) % mapMultiplier / 10;
  67.                         Gl.glTexCoord2d(texX, texZ);
  68.                         Gl.glVertex3d(parentX + B.getX(), parentY + B.getY(), parentZ + B.getZ());
  69.  
  70.                         texX = (parentX + C.getX()) % mapMultiplier / 10;
  71.                         texZ = (parentZ + C.getZ()) % mapMultiplier / 10;
  72.                         Gl.glTexCoord2d(texX, texZ);
  73.                         Gl.glVertex3d(parentX + C.getX(), parentY + C.getY(), parentZ + C.getZ());
  74.                     }
  75.  
  76.  
  77.                 }
  78.                 Gl.glEnd();
  79.                 Gl.glDisable(Gl.GL_TEXTURE_2D);
  80.                 Gl.glDisable(Gl.GL_NORMALIZE);
  81.                 Gl.glEndList();
  82.             }
  83.  
  84.         }
  85.  

Ich habe versucht die Normale zu negieren um zu sehen ob sie einfach in die falsche Richtung zeigen. dies jedoch ohne Erfolg. Der Boden wird einfach nur dunkler. Was nach meinem Verständnis heißt, das die Normalen JETZT in die falsche Richtung zeigen. Hab's also wieder umgedreht.

Mehr Lösungsversuche sind mir bisher nicht eingefallen.
Jemand ne Idee, was ich da falsch mache?


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

_________________
ack nack nack nack nack


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Di Aug 28, 2012 17:26 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Du setzt pro Dreieck eine Normale. Dadurch hat natürlich jeder Pixel eines Dreiecks die gleiche Beleuchtung. Daher entsteht wohl der harte Übergang auf deinem Screenshot.

Besser ist es die Normalen pro Vertex zu setzen. Dazu addierst du jeweils die Normalen der umliegenden Dreiecke auf und normalisierst das ganze. Vom Prinzip also arithmetisches Mittel. Das OpenGL-Licht wird nun für jeden Vertex eine Lichtfarbe berechnen und diese über das Dreieck interpolieren.

Hier ein wenig Code zur Verdeutlichung. Es handelt sich hier um einen Ausschnitt aus einem Vertexshader (dieser), aber es geht ja nur ums Prinzip. Mittels texelFetch2DOffset wird jeweils die Höhe der umgebenden 6 Vertices ausgelesen und damit jeweils ein Richtungsvektor vom zentralen Vertex zum jeweiligen Nachbar aufgestellt. Mittels Kreuzprodukt (cross) werden die 6 Normalen berechnet und aufsummiert. Dadurch das die 6 Normalen nicht normalisiert werden findet hier noch eine Gewichtung anhand der Dreiecksfläche statt.
Code:
  1.         //retrieve height
  2.         height = terrainscale * texelFetch2DOffset(heightmap, coords, 0, ivec2(0,0)).a;
  3.  
  4.         //compute normal
  5.         vec3 vector[6];
  6.         vector[0] = vec3( 0.0, texelFetch2DOffset(heightmap, coords, 0, ivec2( 0, -1)).a, -1.0);
  7.         vector[1] = vec3(-1.0, texelFetch2DOffset(heightmap, coords, 0, ivec2(-1, -1)).a, -1.0);
  8.         vector[2] = vec3(-1.0, texelFetch2DOffset(heightmap, coords, 0, ivec2(-1,  0)).a,  0.0);
  9.         vector[3] = vec3( 0.0, texelFetch2DOffset(heightmap, coords, 0, ivec2( 0,  1)).a,  1.0);
  10.         vector[4] = vec3( 1.0, texelFetch2DOffset(heightmap, coords, 0, ivec2( 1,  1)).a,  1.0);
  11.         vector[5] = vec3( 1.0, texelFetch2DOffset(heightmap, coords, 0, ivec2( 1,  0)).a,  0.0);
  12.         for (int i=0; i<6; ++i) {
  13.             vector[i].y = terrainscale * vector[i].y - height;
  14.         }
  15.         normal = cross(vector[5], vector[0]);
  16.         for (int i=1; i<6; ++i) {
  17.             normal += cross(vector[i-1], vector[i]);
  18.         }
  19.         normal = normalize(normal);





P.S. Ein besseres Ergebnis erhältst du natürlich wenn du mittels Shader stattdessen die Normale über das Dreieck interpolierst und pro Pixel eine Lichtfarbe berechnest. Stichwort: Per-Pixel-Lightning, hier wirst du sicher massig Beispielshader finden.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Lighting (Verständnis)
BeitragVerfasst: Di Aug 28, 2012 18:10 
Offline
DGL Member

Registriert: Di Aug 21, 2012 19:31
Beiträge: 173
Programmiersprache: C#
Hmmm... also irgendwas hatte mit der Normierung der Normalen nicht funktioniert.
Jetzt mache ich das manuell bzw. anders und es funktioniert... mit schön weichen Übergängen.

Übrigens ich hasse es, dass ich Stundenlang an einem Problem hänge, selbiges aus Verzweiflung poste und es dann kurz darauf oftmals gelöst bekomme.
Sorry dafür.

_________________
ack nack nack nack nack


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 20 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.011s | 16 Queries | GZIP : On ]