DGL
https://delphigl.com/forum/

Per-Pixel-Lighting
https://delphigl.com/forum/viewtopic.php?f=20&t=7255
Seite 1 von 1

Autor:  Fabian W. [ Mo Feb 04, 2008 14:33 ]
Betreff des Beitrags:  Per-Pixel-Lighting

Hallo!

Entsprechend dem Tutorial glsl2 habe ich versucht Phong bzw Blinn-Phong Lighting zu realisieren. Allerdings ist das Resultat eher dürftig, da die ganze Szene jetzt nur noch grau / weiß gezeigt wird.
Ich hab keinen Plan was ich falsch mache - woran könnte das denn liegen?


// edit Lossy: Thema verschoben

Autor:  i0n0s [ Mo Feb 04, 2008 14:40 ]
Betreff des Beitrags: 

Tut mir leid. Schäuble hat mir leider den Zugriff auf den Bundestrojaner verweigert. Daher konnte ich mir den Quellcode nicht anschauen und habe somit keine Ahnung was falsch sein könnte...

Autor:  Fabian W. [ Mo Feb 04, 2008 15:33 ]
Betreff des Beitrags: 

Haha ;)

Da meine ersten Versuche genauso wenig funktioniert haben wie die jetzt habe ich inzwischen die entsprechenden Stellen durch den Code aus den Tutorials ersetzt, daher glaube ich dass der Code richtig ist.
Welche Teile soll ich denn schicken: Laden der Shader, Aktivieren des Lichts, Render-Prozedure, ...?

Kann das Problem damit zusammenhängen, dass ich gl3ds verwende und das evtl die Normalen nicht richtig berechnet?

mfg

Autor:  Lord Horazont [ Mo Feb 04, 2008 15:59 ]
Betreff des Beitrags: 

Fabian W. hat geschrieben:
Welche Teile soll ich denn schicken: Laden der Shader, Aktivieren des Lichts, Render-Prozedure, ...?


"Wie wärs mit allen drei?"

Gruß Lord Horazont

Autor:  Fabian W. [ Mo Feb 04, 2008 16:16 ]
Betreff des Beitrags: 

Okay :)

Zu Begin beim Laden der einstellungen:
Code:
  1. // Tiefentest aktivieren
  2.   glEnable(GL_DEPTH_TEST);
  3.   // Nur Fragmente mit niedrigerem Z-Wert (näher an Betrachter) "durchlassen"
  4.   glDepthFunc(GL_LESS);
  5.   // Backface Culling aktivieren
  6.   glEnable(GL_CULL_FACE);
  7.   // Hintergrundfarbe: leichtes Blau
  8.   glClearColor(0.3, 0.4, 0.7, 0.0);
  9.  
  10.   Form_Main.Light := true;
  11.   case Form_Main.Settings.ReadInteger('graphics', 'light', 0) of
  12.     0: Form_Main.Light := false;
  13.     1: InitLight;
  14.     2: begin SetupShaders; InitLight; glUseProgramObjectARB(Form_Main.shader_phong); end;
  15.     3: begin SetupShaders; InitLight; glUseProgramObjectARB(Form_Main.shader_blinn); end;
  16.   end;

Rendern:
Code:
  1. //==============================================================================
  2. // Render
  3. //==============================================================================
  4. procedure TForm_Main.Render;
  5. var
  6.   i: integer;
  7. begin
  8.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  9.  
  10.   glMatrixMode(GL_MODELVIEW);
  11.   glLoadIdentity;
  12.  
  13.   glInitNames;
  14.   glPushName(0);
  15.  
  16.   case GameState of
  17.   // === INGAME ===
  18.   st_InGame: begin
  19.     glTranslatef(0, 0, Zoom); // Zeichenstift nach hinten verschieben
  20.     glRotatef(XRot, 1, 0, 0); // Um x-Achse drehen
  21.     glRotatef(YRot, 0, 0, 1); // Um y-Achse drehen
  22.  
  23.     if Light then
  24.       SetLightPos;
  25.  
  26.     // rendern diverser gegenstände (TAll3dsMesh.Render)
  27.  
  28.  
  29.   end;
  30.   // === MENU ===
  31.   st_MainMenu: begin
  32.     BoardRotation := BoardRotation + 0.05 * DrawTime;
  33.     if BoardRotation > 360 then
  34.       BoardRotation := BoardRotation - 360;
  35.     glTranslatef(0, 0, Zoom); // Zeichenstift nach hinten verschieben
  36.     glRotatef(XRot, 1, 0, 0); // Um x-Achse drehen
  37.     glRotatef(BoardRotation, 0, 0, 1); // Um y-Achse drehen
  38.  
  39.     if Light then
  40.       SetLightPos;
  41.  
  42.   end;
  43.  
  44.   end; // case
  45.  
  46.  
  47.   // Rendern weiterer Gegensände
  48.  
  49.  
  50.   //SwapBuffers(DC); // Wegen AA hier rausgenommen
  51. end;

Licht:
Code:
  1. const
  2.   material_specular : Array[0..3] of GLfloat = (0, 0, 0, 1);
  3.   material_ambient  : Array[0..3] of GLfloat = (0.5, 0.5, 0.5, 1);
  4.   material_diffuse  : Array[0..3] of GLfloat = (0.5, 0.5, 0.5, 1);
  5.   material_shininess: Array[0..0] of GLfloat = (120);
  6.  
  7.   light_position    : Array[0..3] of GlFloat = (0.0, 0.0, 5.0, 1.0);
  8.   light_ambient     : Array[0..3] of GLfloat = (0.5, 0.5, 0.5, 1);
  9.   light_diffuse     : Array[0..3] of GLfloat = (1, 0, 0, 1);
  10.   light_specular    : Array[0..3] of GLfloat = (1, 1, 1, 1);
  11.  
  12.  
  13. //==============================================================================
  14. // InitLights;
  15. //==============================================================================
  16. procedure InitLight;
  17. begin
  18.   glEnable(GL_LIGHTING);
  19.   glEnable(GL_LIGHT0);
  20.  
  21.   glMaterialfv(GL_FRONT, GL_SPECULAR, @material_specular[0]);
  22.   glMaterialfv(GL_FRONT, GL_SHININESS, @material_shininess[0]);
  23.   glMaterialfv(GL_FRONT, GL_AMBIENT, @material_ambient[0]);
  24.   glMaterialfv(GL_FRONT, GL_DIFFUSE, @material_diffuse[0]);
  25.  
  26.   {glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0);
  27.   glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.001);
  28.   glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.004);}
  29.   glLightfv(GL_LIGHT0, GL_AMBIENT, @light_ambient[0]);
  30.   glLightfv(GL_LIGHT0, GL_DIFFUSE, @light_diffuse[0]);
  31.   glLightfv(GL_LIGHT0, GL_SPECULAR, @light_specular[0]);
  32.   SetLightPos;
  33. end;
  34.  
  35.  
  36. //==============================================================================
  37. // SetLightPos;
  38. //==============================================================================
  39. procedure SetLightPos;
  40. begin
  41.   glLightfv(GL_LIGHT0, GL_POSITION, @light_position[0]);
  42. end;

Shader: (Code und Dateien aus dem Tutorial übernommen)
Code:
  1. //==============================================================================
  2. // SetupShaders
  3. //==============================================================================
  4. procedure SetupShaders;
  5. begin
  6.   Form_Main.shader_phong := LoadFragmentAndVertexShader(
  7.     Form_Main.RootPath + 'Shader\lbphong.fp', Form_Main.RootPath + 'Shader\lbphong.vs');
  8.   Form_Main.shader_blinn := LoadFragmentAndVertexShader(
  9.     Form_Main.RootPath + 'Shader\lbblinn.fp', Form_Main.RootPath + 'Shader\lbblinn.vs');
  10.   glUseProgramObjectARB(0); // Zunächst keinen Shader verwenden
  11. end;
  12.  
  13.  
  14. //==============================================================================
  15. // LoadFragmentandVertexShader
  16. //==============================================================================
  17. function LoadFragmentandVertexShader(FFilename: string; VFilename: string): GLHandleARB;
  18. var
  19.   ProgramObject, FragmentShaderObject, VertexShaderObject: GLHandleARB;
  20.   FShader: TStringList;
  21.   FShaderText: String;
  22.   FShaderLength: Integer;
  23.   VShader: TStringList;
  24.   VShaderText: String;
  25.   VShaderLength: Integer;
  26. begin
  27. if (FileExists(FFilename) = True) AND (FileExists(VFilename)= True) then
  28. begin
  29.   ProgramObject:= glCreateProgramObjectARB;
  30.  
  31.   FragmentShaderObject:= glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
  32.   VertexShaderObject:= glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
  33.  
  34.   FShader:= TStringList.Create;
  35.   FShader.LoadFromFile(FFilename);
  36.   FShaderText:= FShader.Text;
  37.   FShaderLength:= Length(FShaderText);
  38.  
  39.   VShader:= TStringList.Create;
  40.   VShader.LoadFromFile(VFilename);
  41.   VShaderText:= VShader.Text;
  42.   VShaderLength:= Length(VShaderText);
  43.  
  44.   glShaderSourceARB(VertexShaderObject, 1, @VShaderText, @VShaderLength);
  45.   glShaderSourceARB(FragmentShaderObject, 1, @FShaderText, @FShaderLength);
  46.  
  47.   glCompileShaderARB(FragmentShaderObject);
  48.   glCompileShaderARB(VertexShaderObject);
  49.  
  50.   glAttachObjectARB(ProgramObject, FragmentShaderObject);
  51.   glAttachObjectARB(ProgramObject, VertexShaderObject);
  52.  
  53.  
  54.   glDeleteObjectARB(FragmentShaderObject);
  55.   glDeleteObjectARB(VertexShaderObject);
  56.   glLinkProgramARB(ProgramObject);
  57.  
  58.   Result:= ProgramObject;
  59. end
  60. else
  61.   Form_Main.Log(Form_Main.StartUpLog, 'LoadFragmentandVertexShader', 'Could not find shader-files!', true);
  62. end;

Autor:  i0n0s [ Di Feb 05, 2008 14:17 ]
Betreff des Beitrags: 

Das Ganze sieht eher nach einem Licht-Problem als einem Shader Problem aus. Denn das Ergebnis ist identisch auch wenn man keinen Shader benutzt.
Nur habe ich keine Ahnung wie das Verhalten des Lichtes zustande kommt.

Autor:  Fabian W. [ Di Feb 05, 2008 14:28 ]
Betreff des Beitrags: 

Identisch solange bis ich
Code:
  1. glUseProgramObjectARB(Form_Main.shader_phong);
aufrufe, dann ist alles weiß...

Das OpenGL-Licht war mir schon immer unsympatisch :mrgreen: Was müsst ihr denn noch wissen, im Grund habe ich auch alles was mit Licht zu tun hat oben gepostet.

Ist es möglich, dass das Ganze mit meiner GraKa (bzw deren Treiber) oder mit gl3ds und nicht gesetzten Normalen zu tun hat?

Autor:  Philip [ Di Feb 05, 2008 15:49 ]
Betreff des Beitrags: 

Zitat:
nicht gesetzten Normalen zu tun hat?

Du setzt keine Normalen? Für Licht brauchst du die aber zwingend...

Autor:  Fabian W. [ Di Feb 05, 2008 16:14 ]
Betreff des Beitrags: 

Ich setze keine Normalen, nein wenn dann muss das gl3ds machen. Ich habe das noeska gefragt und der meinte
Zitat:
Normals are calculated with gl3ds (only it is bugged)
- Ich bin mir jetzt nur nicht sicher ob er meinte dass es nen bug gibt oder dass da einer sein könnte.
Wären fehlende Normalen also eine mögliche Erklärung?

(Siehe auch http://www.delphigl.com/forum/viewtopic.php?t=7212&highlight=)

Autor:  MatReno [ Di Feb 05, 2008 20:15 ]
Betreff des Beitrags: 

Probier' das ganze mal an ner gluSphere aus.
Oder nimm die Sphere-Prozedur aus dem Wiki.
Dann haste ordentliche Normalen und kannst dies als mögliche Fehlerquelle ausschließen.

Autor:  Fabian W. [ Mi Feb 06, 2008 09:42 ]
Betreff des Beitrags: 

Ich hab jetzt mal die erste Funktion genommen - allerdings sieht die so erzeugte Kugel "hohl" aus -> also die Flächen werden so gezeichnet, dass nur diejenigen von der Kamera "abgewandten" sichtbar sind. Es sieht also von jeder Kameraposition so aus als ob ich in eine Schale sähe.

Die Kugel (bzw das was man davon sieht) wird genauso weiß / grau / rot gezeichnet wie der Rest auch :(

Autor:  MatReno [ Mi Feb 06, 2008 10:19 ]
Betreff des Beitrags: 

Fabian W. hat geschrieben:
Ich hab jetzt mal die erste Funktion genommen - allerdings sieht die so erzeugte Kugel "hohl" aus -> also die Flächen werden so gezeichnet, dass nur diejenigen von der Kamera "abgewandten" sichtbar sind.

Ändert sich an der Beleuchtung etwas, wenn du nach OpenGL-Initialisierung glDisable(GL_CULL_FACE) schreibst?
Dann ist die Kugel nicht mehr als "Schale".

EDIT:
Übergib' mal die Shininess des Materials mit glMaterialf(...) statt glMaterialfv().
Also:
Code:
  1. material_shininess: GLfloat = 64.0;
  2. ...
  3. glMaterialf(GL_FRONT, GL_SHININESS, material_shininess);

Autor:  Fabian W. [ Mi Feb 06, 2008 10:25 ]
Betreff des Beitrags: 

Nein auch deaktiviertes Backface Culling ändert an der Schale nix. :(

EDIT: Auch das geänderte Übergeben mit glMaterialf bewirkt keine sichtbare Veränderung - weder mit noch ohne Shader.

Autor:  Sellmann [ So Feb 10, 2008 11:44 ]
Betreff des Beitrags: 

Ich hab ein ähnliches Problem gehabt, als ich den shader aus dem Tutorial versucht habe nach zu schreiben.
Der erste große Fehler war, davon auszugehen, dass sich die normalen von alleine setzen. Hab sie mit der Hand gesetzt und danach sah es schon besser aus.

das ist mein vertex shader für phonglight, recht unspektakulär:
Code:
  1.  
  2. varying vec3 normal;
  3. varying vec3 v;
  4. varying vec3 lightvec;
  5.  
  6. void main(void)
  7. {
  8.   normal          = normalize(gl_NormalMatrix * gl_Normal);
  9.   v               = vec3(gl_ModelViewMatrix * gl_Vertex);
  10.   lightvec        = normalize(gl_LightSource[0].position.xyz - v);
  11.  
  12.   gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
  13.  
  14.   gl_TexCoord[0]  = gl_MultiTexCoord0;
  15. }
  16.  


das ist der dazu gehörige fragmentshader
(ich benutze allerdings nur diffuse material anteile, keine weiteren materialeigenschaften):
Code:
  1.  
  2. uniform sampler2D diffspec;
  3.  
  4. varying vec3 normal;
  5. varying vec3 v;
  6. varying vec3 lightvec;
  7.  
  8. void main(void)
  9. {
  10.  vec3 Eye             = normalize(-v);
  11.  vec3 Reflected       = normalize( 2.0 * dot(normal, lightvec) * normal - lightvec);
  12.  vec3 base        = texture2D(diffspec,vec2(gl_TexCoord[0])).xyz;
  13.  
  14.  vec4 IAmbient        = gl_LightSource[0].ambient;
  15.  
  16.  vec4 IDiffuse        = gl_LightSource[0].diffuse * max(dot(normal, lightvec), 0.0);
  17.  
  18.  float lambertTerm    = dot(normal,lightvec);
  19.  
  20.  vec4 finalcolor      = gl_LightSource[0].ambient * vec4(base,1.0) * (1.0-lambertTerm);
  21.  
  22.     if (lambertTerm > 0.0)
  23.     {
  24.         finalcolor += gl_LightSource[0].diffuse * vec4(base,1.0) * lambertTerm;
  25.        
  26.         vec3 E = normalize(-v);
  27.         vec3 R = reflect(-lightvec, normal);
  28.         float specular = pow( max(dot(R, E), 0.0), 120.0 );
  29.         finalcolor += gl_LightSource[0].diffuse * texture2D(diffspec,vec2(gl_TexCoord[0])).a * (specular*3.0); 
  30.     }
  31.  
  32.  gl_FragColor         = vec4(finalcolor.xyz,1.0);
  33. }
  34.  


der Lösungsansatz ist von Ozone3d und hat bei mir sehr gut funktioniert, nachdem ich meine normalen von Hand gesetzt habe.
diffspe heißt meine Textur, weil ich in den rgb wertn halt den diffusen anteil habe und im alpha den faktor für das Specular. Man kann die Textur also auch durch diffuse und spekulare anteile der materialien ersetzen.

Probiers einfach mal aus. Ich könnte mir vorstellen, dass du evtl. mit deinem Lightvektor irgendwas nicht richtig gemacht hast.

Autor:  Fabian W. [ Mo Feb 11, 2008 18:52 ]
Betreff des Beitrags: 

Ah, fein - der Shader funktioniert prächtig :) Thx

Ja, ich glaube ich habe oben schon angedeutet, dass ich gl3ds verwende. Mit den Normalen kann ich atm also nichts machen, außer hoffen dass die nächste gl3ds-version sie richtig setzt.^^

mfg

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/