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

Aktuelle Zeit: Fr Jul 18, 2025 11:15

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



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Per-Pixel Lighting
BeitragVerfasst: Do Sep 18, 2003 12:48 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Tach,

ich bin momentan dabei meine engine mit Per-Pixel Licht und später Diffuse/Specular Bumpmapping auszuschatten.
Als ersten Schritt möchte ich erstmal nur das licht ohne bumpmapping.

Das hatte ich schon auch schon teilweise hingekriegt, teilweise deshalb weil es beim lars (ATI Radeon 9800 pro) funktioniert und bei mir nicht (GeForce1/GeForce4 Ti 4200).

Ich benutze aber keinerlei Extensions die über der GeForce1 liegen.
Es werden nur diese extensions benutzt:
GL_ARB_multitexture
GL_ARB_texture_env_combine
GL_ARB_texture_cube_map

Aber jetzt erstmal erklär ich mal wie Per-Pixel licht funktioniert, so wie ichs verstanden habe *g*:::

Erstmal die Formel:

Code:
  1.  
  2. Ambient + [ Attenuation * Decal ]
  3.  
  4. Umgebungsfarbe (meistens schwarz) + Für Jedes Licht[ Lichtintensität * Standardtexture ]
  5.  


- Ambient = Welt mit Umgebungsfarbe zeichnen (0,0,0)
- Attentuation = Lichtintensität, setzt sich zusammen aus einer 3D Texture, bzw 1D+2D Texture, wird einmal vorberechnet am anfang.
- Decal = Welt mit basistexture zeichnen

In Jedem pass muss die gesamte Welt gezeichnet werden, natürlich kann man optimieren beim licht, das man nicht belichtete polys auslässt oder über Occlusion Culling optimieren, aber das ist zum testen nicht wichtig.

hier jetzt mal code zum richtigen verständnis aus meiner engine:

r3d_world.pas
Code:
  1.  
  2. // Hier wird alles gerendert,
  3. procedure TR3DWorld.Render;
  4. var
  5.   I : Integer;
  6. begin
  7.   // Ambiente und Tiefe zechnen
  8.   DrawAmbientLightAndDepth;
  9.  
  10.   // Lichter Zeichnen
  11.   if (fDrawPointLights) then
  12.     For I := 0 to High(fPointLights) do
  13.       DrawLight(r3d_PointLightIntoLight(fPointLights[I]));
  14.  
  15.   {
  16.   if (fDrawSpotLights) then
  17.     For I := 0 to High(fSpotLights) do
  18.       DrawLight(r3d_SpotLightIntoLight(fSpotLights[I]));
  19.   }
  20.  
  21.   //reset polygon mode to fill
  22.   glPolygonMode(GL_FRONT, GL_FILL);
  23.  
  24.   glDepthFunc(GL_LESS);
  25.   glDisable(GL_STENCIL_TEST);
  26. end;
  27.  
  28. procedure TR3DWorld.DrawAmbientLightAndDepth;
  29. begin
  30.   // Stencil Deaktivieren
  31.   glDisable(GL_STENCIL_TEST);
  32.  
  33.   // Tiefentest einstellen
  34.   glDepthFunc(GL_LESS);
  35.   glEnable(GL_DEPTH_TEST);
  36.  
  37.   // Alpha Kanal ersetzten
  38.   glBlendFunc(GL_ONE, GL_ZERO);
  39.   glEnable(GL_BLEND);
  40.  
  41.   glClearColor(0, 0, 0, 1);
  42.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  43.  
  44.   // Umgebungsfarbe
  45.   if (fAmbientEnable) then
  46.     glColor4f(fAmbient, fAmbient, fAmbient, 1)
  47.   else
  48.     glColor4f(0,0,0,1);
  49.  
  50.   // Welt mit Basis texturen zeichnen
  51.   DrawWorld(cWLM_Base);
  52. end;
  53.  
  54. procedure TR3DWorld.DrawLight(const _Light : TR3DLight);
  55. begin
  56.   gActiveLight := _Light;
  57.  
  58.   // Light und HalfAngle Vector berechnen
  59.   //UpdatePolygons;
  60.  
  61.   if (fShadowsEnable) then
  62.   begin
  63.   end;
  64.  
  65.   glDepthFunc(GL_EQUAL);
  66.   glDepthMask(False);
  67.  
  68.   // add diffues lighting if enabled
  69.   if (fDiffuseEnable) then
  70.   begin
  71.     gActiveLight.beginAlphaDiffuseIntensity;
  72.       DrawWorld(cWLM_AlphaDiffuseIntensity);
  73.     gActiveLight.endAlphaDiffuseIntensity;
  74.  
  75.     gActiveLight.beginDiffuse;
  76.       DrawWorld(cWLM_Diffuse);
  77.     gActiveLight.endDiffuse;
  78.   end;
  79.  
  80.   glDepthFunc(GL_LESS);
  81.   glDepthMask(True);
  82. end;
  83.  
  84. procedure TR3DWorld.DrawPolygon(const _FaceIndex, _ObjIndex : Integer; _LightMode : Integer);
  85. var
  86.   Face         : TR3DFace;
  87.   Obj          : TR3DObject;
  88.   Poly         : TR3DPolygon;
  89.   Plane        : TR3DPlane;
  90.   Shader       : TR3DShader;
  91.   Vertice      : TR3DVertex;
  92.   PolyCoord    : TR3DTexcoordArray;
  93.  
  94.   I,
  95.   VecIndex     : Integer;
  96.   HasNoTexture : Boolean;
  97.  
  98.   procedure BindTextureFromShaderProg(const _ShaderProg : TR3DShaderProg; const _MultiTexIndex : Integer);
  99.   var
  100.     ShaderStage,
  101.     TexIdx       : Integer;
  102.  
  103.     procedure SetNoTexture(const _TexName : String);
  104.     begin
  105.       PolyCoord := r3d_TexcoordCalculate(Poly, Poly.Normal, 0, False, False, 1, 1);
  106.       TexIdx := fTextures.IndexOf(_TexName);
  107.       if (TexIdx > -1) then
  108.         fTextures.Textures[TexIdx].BindMultiTexture(_MultiTexIndex)
  109.       else
  110.         glBindTexture(GL_TEXTURE_2D, 0);
  111.       HasNoTexture := True;
  112.     end;
  113.  
  114.   begin
  115.     ShaderStage := r3d_IndexFromProgInShader(_ShaderProg, Shader);
  116.     if (ShaderStage > -1) then
  117.     begin
  118.       TexIdx := Shader.Stages[ShaderStage].TextureIDX;
  119.       if (TexIdx > -1) then
  120.         fTextures.Textures[TexIdx].BindMultiTexture(_MultiTexIndex)
  121.       else
  122.         SetNoTexture('common\texnotfound');
  123.     end
  124.     else
  125.       SetNoTexture('common\shadernotfound');
  126.   end;
  127. begin
  128.   Face := fFaces[_FaceIndex];
  129.   Obj := fObjects[_ObjIndex];
  130.   Poly := GetPolyFromFace(Face, Obj);
  131.   Plane := r3d_PlaneConstruct(Poly);
  132.   Shader := GetShaderFromFace(Face);
  133.   HasNoTexture := False;
  134.  
  135.   case _LightMode of
  136.     cWLM_Base: BindTextureFromShaderProg(r3d_shaderprog_decal, 0);
  137.     cWLM_AlphaDiffuse: BindTextureFromShaderProg(r3d_shaderprog_diffuse, 0);
  138.     cWLM_Diffuse: BindTextureFromShaderProg(r3d_shaderprog_decal, 0);
  139.   end;
  140.  
  141.   // draw the surface
  142.   glBegin(GL_TRIANGLE_STRIP);
  143.     VecIndex := 0;
  144.     For I := Face.VerticeIndex to Face.VerticeIndex + 2 do
  145.     begin
  146.       Vertice := fVertices[I];
  147.  
  148.       case _LightMode of
  149.  
  150.         cWLM_Base: // Decal
  151.         begin
  152.           // Vertex Normale
  153.           Vertice.Normal.SetNormal;
  154.  
  155.           // Texture Koordinaten
  156.           if HasNoTexture then PolyCoord[VecIndex].SetMultiTexcoord(0)
  157.           else Vertice.Texcoords[0].SetMultiTexcoord(0);
  158.  
  159.           // Vertex
  160.           Vertice.Position.SetVertex;
  161.         end;
  162.  
  163.         cWLM_AlphaDiffuseIntensity: // Lichtintensität 3D Texture
  164.         begin
  165.           gActiveLight.processAlphaDiffuseIntensityVertex(Vertice.Position, Vertice.Light);
  166.         end;
  167.  
  168.         cWLM_AlphaDiffuse: // AlphaDiffuse,  Diffuse Bumpmapping (unwichtig)
  169.         begin
  170.           gActiveLight.processAlphaDiffuseVertex(Vertice.Position, Vertice.Texcoords[0], Vertice.Light);
  171.         end;
  172.  
  173.         cWLM_Diffuse: // Standard Texture
  174.         begin
  175.           gActiveLight.processDiffuseVertex(Vertice.Position, Vertice.Texcoords[0]);
  176.         end;
  177.  
  178.       end;
  179.       Inc(VecIndex);
  180.     end;
  181.   glEnd;
  182. end;
  183.  
  184. procedure TR3DWorld.DrawWorld(_Lightmode : Integer);
  185. var
  186.   I, J    : Integer;
  187.   ObjAABB : TR3DAxisAlignBoundingBox;
  188. begin
  189.   For I := 0 to High(fObjects) do
  190.   begin
  191.     if (fFrustumCulling) then
  192.     begin
  193.       if (fObjects[I].AABBIndex > -1) then
  194.       begin
  195.         ObjAABB := fAABBs[fObjects[I].AABBIndex];
  196.         if (not fFrustum.IsAABBWithin(ObjAABB)) then Continue;
  197.       end;
  198.     end;
  199.  
  200.     if (fCameraClipping) then
  201.     begin
  202.       if (fObjects[I].AABBIndex > -1) then
  203.       begin
  204.         ObjAABB := fAABBs[fObjects[I].AABBIndex];
  205.         if (not r3d_AABBInAABBIntersection(CameraAABB, ObjAABB)) then Continue;
  206.       end;
  207.     end;
  208.  
  209.     For J := fObjects[I].StartFaceIndex to fObjects[I].EndFaceIndex do
  210.       DrawPolygon(J, I, _Lightmode);
  211.   end;
  212. end;
  213.  


r3d_light.pas
Code:
  1.  
  2. procedure SetTextureStageRGB(param1, op, param2 : Integer);
  3. begin
  4.   glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT);
  5.   glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT,op);
  6.  
  7.   glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,param1);
  8.   glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR);
  9.  
  10.   glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,param2);
  11.   glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR);
  12.  
  13.   glTexEnvi(GL_TEXTURE_ENV,GL_RGB_SCALE_EXT,1);
  14. end;
  15.  
  16. procedure SetTextureStageAlpha(param1, op, param2 : Integer);
  17. begin
  18.   glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT);
  19.   glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,op);
  20.  
  21.   glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,param1);
  22.   glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_ARB,GL_SRC_ALPHA);
  23.  
  24.   glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB,param2);
  25.   glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_ALPHA_ARB,GL_SRC_ALPHA);
  26.  
  27.   glTexEnvi(GL_TEXTURE_ENV,GL_ALPHA_SCALE,1);
  28. end;
  29.  
  30. procedure ResetTextureStage(mode : Integer);
  31. begin
  32.   glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,mode);
  33.   glTexEnvi(GL_TEXTURE_ENV,GL_RGB_SCALE_EXT,1);
  34.   glTexEnvi(GL_TEXTURE_ENV,GL_ALPHA_SCALE,1);
  35. end;
  36.  
  37. procedure TR3DLight.beginAlphaDiffuseIntensity;
  38. begin
  39.   // Nur Alpha Kanal nehmen
  40.   glColorMask(False,False,False,True);
  41.  
  42.   // Alpha Kanal überschreiben
  43.   glBlendFunc(GL_ONE, GL_ZERO);
  44.   glDisable(GL_BLEND);
  45.  
  46.   //active texture 1 (the 1D radial ramp texture)
  47.   gTextureAtt1D.BindMultiTexture(1);
  48.   glDisable(GL_TEXTURE_CUBE_MAP_ARB);
  49.   glDisable(GL_TEXTURE_2D);
  50.  
  51.   //active texture 0 (the 2D radial map texture)
  52.   gTextureAtt2D.BindMultiTexture(0);
  53.  
  54.   glActiveTextureARB(GL_TEXTURE0_ARB);
  55.   SetTextureStageAlpha(GL_PRIMARY_COLOR_EXT,GL_SUBTRACT,GL_TEXTURE);
  56.  
  57.   glActiveTextureARB(GL_TEXTURE1_ARB);
  58.   SetTextureStageAlpha(GL_PREVIOUS_EXT,GL_SUBTRACT,GL_TEXTURE);
  59. end;
  60.  
  61. procedure TR3DLight.processAlphaDiffuseIntensityVertex(const _Vertex : TR3DVector; const _Light : TR3DVector);
  62. var
  63.   texCoords   : TR3DVector;
  64.   versuborig  : TR3DVector;
  65. begin
  66.   //adjust tex coords according to brightness (this could also be moved into the texture matricies)
  67.   versuborig := r3d_VectorSub(_Vertex, Position);
  68.   texCoords := r3d_VectorDiv(versuborig, Radius * 2.0);
  69.   texCoords.Add(0.5);
  70.  
  71.   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texCoords.x, texCoords.y);
  72.   glMultiTexCoord1fARB(GL_TEXTURE1_ARB, texCoords.z);
  73.   glVertex3fv(@_Vertex);
  74. end;
  75.  
  76. procedure TR3DLight.endAlphaDiffuseIntensity;
  77. begin
  78.   //turn texture unit 1 off
  79.   glActiveTextureARB(GL_TEXTURE1_ARB);
  80.   glDisable(GL_TEXTURE_1D);
  81.   glActiveTextureARB(GL_TEXTURE0_ARB);
  82.  
  83.   glActiveTextureARB(GL_TEXTURE1_ARB);
  84.   ResetTextureStage(GL_MODULATE);
  85.  
  86.   glActiveTextureARB(GL_TEXTURE0_ARB);
  87.   ResetTextureStage(GL_MODULATE);
  88.  
  89.   //remove the write masks
  90.   glColorMask(True,True,True,True);
  91. end;
  92.  
  93. procedure TR3DLight.beginDiffuse;
  94. begin
  95.   glBlendFunc(GL_DST_ALPHA, GL_one);
  96.   glEnable(GL_BLEND);
  97.  
  98.   glActiveTextureARB(GL_TEXTURE1_ARB);
  99.   glDisable(GL_TEXTURE_2D);
  100.  
  101.   glActiveTextureARB(GL_TEXTURE0_ARB);
  102.   glEnable(GL_TEXTURE_2D);
  103.  
  104.   Color.SetColor;
  105. end;
  106.  
  107. procedure TR3DLight.processDiffuseVertex(const _Vertex : TR3DVector; const _Texcoord : TR3DTexcoord);
  108. begin
  109.   glMultiTexCoord2fvARB(GL_TEXTURE0_ARB, @_Texcoord);
  110.   glVertex3fv(@_Vertex);
  111. end;
  112.  
  113. procedure TR3DLight.endDiffuse;
  114. begin
  115.   glActiveTextureARB(GL_TEXTURE0_ARB);
  116.   glColor3f(1,1,1);
  117. end;
  118.  


Damit sollte das verständnis wesentlich klarer sein ;)
TR3DLight ist nen record, gActiveLight ist immer das aktuelle licht was zwischengespeichert wird.

Hier jetzt mal nen paar screens:

So siehts ohne Licht aus (mit Umgebungsfarbe 1,1,1):
Bild

So siehts mit Licht bei mir aus (GeForce 256):
Bild

So siehts mit Licht bei Lars Middendorf aus (ATI Radeon 9800 Pro):
Bild


Ich kann nun nicht verstehen, wieso es bei lars funktioniert und bei mir alles gelb wird obwohl ich keine Nvidia oder ATI spezifischen Extensions benutzt habe :(



Und das Program selbst gibts hier:
http://www.xenorate.com/Template.zip



Bitte testet es mal bei wem das Licht funktioniert, und bei wem alles gelb ist, postet auch bitte die grafikkarte dazu !




Ich danke schonmal fürs mühselige durchlesen und natürlich für antworten ;)

Mfg,
Final[/b]


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Sep 18, 2003 13:24 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 26, 2002 22:12
Beiträge: 259
Wohnort: Dresden
Also auf meiner Geforce2MX 400 ist ebenfalls alles gelb.
Woran das allerdings liegt, kann ich nicht sagen, da ich mich mit dem Thema noch nicht weiter auseinander gesetzt habe.

_________________
Nichts auf der Welt ist so gerecht verteilt wie der Verstand. Denn jederman ist überzeugt, dass er genug davon habe.
Rene Descartes, frz. Mathematiker u. Philosoph, 1596-1650


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Sep 18, 2003 15:23 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Ich habs grad mal auf meinen beiden Rechnern ausprobiert, und wie zu erwarten war hat auf meiner Radeon9700 alles ohne Probleme funktioniert, während es auf der GeForce4-Ti4400 so aussieht wie auf deiner GeForce256.

Ich hab allerdings noch nie was mit Cubemaps gemacht, weshalb ich nur mal vermuten kann das NVidia-Karten Probleme beim Lookup haben und dir irgendwie nen falschen Wert zurückgeben.
Alternativ könnte dein Problem auch daher rühren, das die NVidia-Karten bestimmte Kombinationsoperationen (von denen du ja reichlich Gebrauch machst) nicht unterstüzten und das Bild deshalb so fehlerhaft aussieht.
Auf mich machts allerdings den Eindruck das ersteres der Fall ist, und du evtl. mal ein kleines Beispiel zusammenschrauben solltest (ohne den Engine-Kram runderum).Das könnt ich dann bei mir zu Hause bequem auf beiden Rechnern testen und auch debuggen.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Sep 18, 2003 15:25 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Okt 26, 2002 17:14
Beiträge: 188
Wohnort: Hannover/Lüneburg
Also ich habe eine Radeon 8500, und auf dieser läuft das Programm einwandfrei (etwa 32 FPS).

_________________
Thunderman
Bei schwierigen Problemen entscheiden wir uns einfach für die richtige Lösung. Klar?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Sep 18, 2003 17:40 
Offline
DGL Member

Registriert: Sa Aug 30, 2003 22:23
Beiträge: 36
Wohnort: Hamburg
bei mir läufts gar nicht.. bekomm permanent zugriffsverletzungen.

Ich hab aber keine ahnung ob meine kyroII überhaupt die GL_ARB... extrension unterstützt..

_________________
<< Ich werde Ewig leben oder beim Versuch dies zu erreichen, sterben! >>


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Sep 19, 2003 09:45 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Cubemaps werden gar nicht benutzt, das ist es ja.
Es werden für die Lichtintensität nur 1D+2D = 3D Texture benutzt.
Die Cubemap hab ich nur mal vor initialisiert wenn ich später die Normalization Cubemap brauch für Diffuse/Specular Bumpmapping.

Und die Spotlight Cubemap wird auch nicht benutzt, da ich spotlights momentan eh deaktiviert habe.

Das Sample werd ich aber mal schnell machen ;)

matane,
Final


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


Wer ist online?

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