Fragen zu Multitexturing/ Lightmaps und Texture-Baking



  • Hallo Leute,

    Ich habe mich schon oft gefragt wie man in 3D Anwendungen mit OpenGL helle und dunke Stellen einbauen könnte.
    Das könnte man z.B. mit Multitexturing machen aber leider ist die Textur, die den Schatten darstellen soll, dann auf der gesammten Fläche verteilt.

    Auf diesem Bild aus "Counter-Strike 1.irgendwas" sind die Schattenflächen sehr schön gemacht und auch das Licht der Taschenlampe aus Half-Life 1 ist mit dieser Methode gemacht ebenso die Einschusslöcher an den Wänden.

    Beispielbild: http://www.verdammtermist.de/cs1.jpg

    Was ich mir nicht vorstellen kann ist, dass man die zweite Textur als extra Model auf das andere legt denn dann würde die Grafikakrte die Modelle ineinander verschmelzen und diesen hässlichen Effekt kennt sicher jeder.

    Wisst ihr wie man sowas macht??



  • Google: Lightmaps und Texture-Baking
    Effektiv hast Du eine zusaetzliche Textur auf der fuer jedes Polygon Deiner Szene ein kleines Stueck Platz (zusaetzliche Texturkoordinaten) reserviert ist (hierbei Vorsicht mit Mipmaps) und dessen Helligkeitsinformationen enthaellt.
    Entweder renderst Du in zwei Durchgaengen (erst "normale" Textur, dann "Lightmap" mit Blending (multiplizieren) und Z-Compare auf Equal) oder eben per Multi-Texturing.
    Die Lightmap selbst kannst Du entweder mit Deiner Lieblings-3D-Software erzeugen oder selbst berechnen in dem Du zb jeden Texel der Lightmap auf die Oberflaeche des zugehoerigen Polygons projezierst und von dort aus raytrace'st.



  • Genau, für jede extra texture sind für jedes Vertex zusatz Informationen abgespeichert.
    Aber ich weiß nicht wie ich das machen soll das z.B. die Lightmap in der Mitte des Objektes ist und nicht komplett über das Mesh gezogen.

    // -> Texture 1
    ++ -> Texture 2
    ~~ -> Texture 3
    
      Objekt (Quader)
    *-----------------*
    |/////////////////|
    |/~~~~////////////|
    |/~~~~////+++++///|
    |/~~~~////+++++///|
    |/~~~~////+++++///|
    |/////////+++++///|
    |/////////////////|
    *-----------------*
    


  • Die Lightmap soll ja schon das gesamte Mesh abdecken.
    Du erzeugst also sinnvolle Texturkoodinaten und faerbst die jeweiligen Bereiche der Textur entsprechend ein.

    Geeignete Texturkoordinaten erhaelst Du zb indem Du Deinen Quader "einfach" ausklappst:

    +---------------------------------+
    |           +---------+           |
    |           |         |           |
    |           |         |           |
    |           |  oben   |           |
    |           |         |           |
    | +---------+---------+---------+ |
    | |         |         |         | |
    | |         |         |         | |
    | | links   |  vorne  | rechts  | |
    | |         |         |         | |
    | +---------+---------+---------+ |
    |           |         |           |
    |           |         |           |
    |           |  unten  |           |
    |           |         |           |
    |           +---------+           |
    |           |         |           |
    |           |         |           |
    |           |  hinten |           |
    |           |         |           |
    |           +---------+           |
    +---------------------------------+
    


  • Nagut, also für relativ leichte Schatten Effekte wie in HalfLife 1 geht das wohl ganz gut.

    Aber wie macht man das dann mit z.B. den EinschussLöchern?
    Das habe die in HalfLife 1 auch gut gemeistert aber da kann man ja keine Riesige Texture nehmen die hauptsächlich transparent ist und irgendwo in der Mitte ist das eigentliche Bild.
    In einem solchen fall darf das Bidl nicht auf das gesammte Mesh verteilt sein sondern eben nur auf den Punkt an dem das Loch zu sehen sein soll



  • Was das denn keine? 😞
    Ich bin Ratlos, das kann doch nicht einfach mit Multitexturing klappen oder?!



  • AFAIK ist es zumindest bei Half-Life so gewesen, dass das Einschussloch ein eigenes Quad ist, was ganz knapp vor der Wand platziert wird und so den Eindruck erweckt, draufzuliegen. Was man - je nach Qualität der Graka und des Treibers - auch oft am Z-Fighting sah.



  • Genau, wenn das nämlich zu nah anliegt sieht das ziemlich blöd aus, weil sich die Dreiecke überlappen.
    Aber wenn man in Half-Life 1 an eine Kante schießt legt sich das 'Loch' bzw. 'Quad' um die Ecke herum 😮
    Wie soll man das mit einem Quad machen? 😕



  • Das Quad als Pyramide mit quadratischer Grundflaeche betrachten (die Spitze entspricht der "Schussposition") und mit der Geometrie schneiden.
    Entspricht Sutherland/Hodgman 3D-Clipping im View-Frustum.



  • ZEIT SPRUNG ^^

    Ich hab mich jetzt schon ziehmlich lange nicht mehr mit dem Thema Lightmaps auseinander gesetzt, aber dafür wurde mir eben gerade das mit dem Tiefen-Test erst wirklich richtig klar (Geistesblitz ^^)

    Für mein aktuelles Projekt habe ich diesmal mit dem Editor angefangen, damit ich damit auch die Test-Level gestalten kann um die Engine zu testen.
    Es soll natürlich ein EgoShooter werden 🙂 und dafür will ich unbedingt einen LightmapGenerator integrieren.

    Was ich dazu bisher in Erfahrung bringen konnte war, dass es was mit dem "Radiosity" Algorithmus zu tun hat der schon in Quake3 und sehr wahrscheinlich auch in Half-Life 1 genutzt wurde.

    Allerdings habe ich dazu bisher nur ein Tutorial gefunden, und weil das recht "schwere Kost" ist, wollte ich euch fragen, ob ihr noch ein paar andere kennt, vielleicht auch gleich welche mit C++ oder OpenGL Code Beispielen?

    Hier ist der Link den ich bisher dazu gefunden habe:
    http://www.flipcode.com/archives/Light_Mapping_Theory_and_Implementation.shtml



  • Google mal nach "global illumination".


  • Mod

    quake2 hatte radiosity, in quake 3 sind es wieder simple lightmaps geworden weil sie schneller zu berechnen sind und die artist lieber mit lichtquellen kontrolle darueber haben.
    HL1 basierend auf Q1 hat wohl keine radiosity maps, HL2 hat wieder radiosity maps.

    ich finde es immerwieder erstaunlich wieviel du zusammenhackst ohne die grundlagen zu verstehen 😉
    software rasterizer schreiben aber tiefentest erst jetzt verstehen? respekt *hehe*



  • Naja das Grundkonzept vom Tiefentest war mir schon klar - zugegebener Weise allerdings wirklich nicht zu Beginn der Arbeit an meiner 3D Engine XD - jedoch funktioniert mein Versuch, mit OpenGL glDepthFunc(GL_EQUAL) doch nicht so wie ich mir das vorgestellt hatte.
    Die Pixel werden zwar nur dann angezeigt wenn sie gleich groß sind wie die des hintergrundes, aber dafür flackert das ganze immer noch so wie im normal Fall, weil die Dreiecke Überlappen. Vermutlich weil die Berechnung nicht genau genug ist.
    Genau weiß ich es aber nicht.

    Noch mal zu den Lightmaps, wenn HL1 keine Radiosity maps hat, was hat es dann? Die arbeiten doch auch mit Multitexturing und Lightmaps, oder?! Oder gibt es dafür noch eine andere Methode zum generieren der Lightmaps?


  • Mod

    LukasBanana schrieb:

    Naja das Grundkonzept vom Tiefentest war mir schon klar - zugegebener Weise allerdings wirklich nicht zu Beginn der Arbeit an meiner 3D Engine XD - jedoch funktioniert mein Versuch, mit OpenGL glDepthFunc(GL_EQUAL) doch nicht so wie ich mir das vorgestellt hatte.
    Die Pixel werden zwar nur dann angezeigt wenn sie gleich groß sind wie die des hintergrundes, aber dafür flackert das ganze immer noch so wie im normal Fall, weil die Dreiecke Überlappen. Vermutlich weil die Berechnung nicht genau genug ist.
    Genau weiß ich es aber nicht.

    ja, da haste recht (natuerlich kann es nen anderen grund geben, aber dieser ist wahrscheinlich).
    du musst EXACT die selbe geometrie und die selben shader (falls du shader benutzt) ausfuehren, damit auch das selbe resultat rauskommt, dann wird es kein z-fighting geben.

    Noch mal zu den Lightmaps, wenn HL1 keine Radiosity maps hat, was hat es dann? Die arbeiten doch auch mit Multitexturing und Lightmaps, oder?! Oder gibt es dafür noch eine andere Methode zum generieren der Lightmaps?

    die haben nur simple shadows in ihre lightmaps gerechnet.

    deine arbeit besteht im grund aus 2 wichtigen schritten.
    1. jedes dreieck das eine lightmap bekommen soll muss eine einzigartige stelle auf der lightmap-textur bekommen,also: es duerfen keine zwei dreiecke den selben pixel nutzen (wenn auch man spaeter ein wenig optimieren kann, waere es wichtig es erstmal so einfach hinzubekommen).

    2. die lightmaps berechnen. im simpelsten fall kannst du bei jedem dreieck, fuer jedes pixel der lightmap die kamera an diese stelle setzen (richtung normale schauend) und renderst ein bild.
    dann nimmst du die durchschnittshelligkeit aller pixel und setzt diese in die lightmap.
    wichtig ist:
    -alle lightmaps sind zu begin schwarz initializiert
    -die lightquelle muss mit eingezeichnet werden beim rendern, weil sie das einzige helle objekt ist.

    wenn du nun radiosity willst, berechnest du das ganze nochmal mit den schon neuen lightmaps.



  • Alles klar, das mit den Lightmaps generieren habe ich jetzt glaube ich einiger maßen verstanden. Allersings kann ich mir noch nicht ganz vorstellen, wie ich die Kamera auf dem Dreiecke für jeden Pixel positionieren muss. Normale ist klar, aber wie viel Pixel brauche ich wohl für das jeweilige Dreiecke?!
    Oberfläche / 100 = Anzahl Pixel ?!?

    Und noch mal wegen dem Tiefen Test:
    wenn man das mit der selben Geometrie verwendet sieht das gut aus.
    Aber wie muss man das machen, um es für beispielsweise die Einschusslöcher in einer Wand zu nutzen
    (http://www.hlportal.de/images/images/original/2040.jpg,
    http://img163.imageshack.us/img163/4884/parallaxmappingfearkleinxb9.jpg)
    Das frage ich mich auch schon seit Ewigkeiten. Das kann doch gar nicht über mutitexturing gehen, oder?!
    Ich habe mir sowas in einigen Spielen genau angesehen, selbst ich alten Spielen wie HL1 liegen diese Pixel genau auf der Oberfläche und nicht mit einem minimalen Abstand von 0.0001, das würde dann nämlich auch sehr schnell zu Grafikfehlern füren.

    Kann mir das vielleicht auch mal jemand gleich dazu erklären?



  • Wie werden denn diese Einschusslöcher dargestellt?
    Ich gehe mal davon aus, dass es sich um Quads (also zwei Dreiecke) handelt, aber wie funktioniert das, dass diese Pixelgenau auf dem Untergrund liegen. In HL1 ist mir das schon oft aufgefallen, diese Einschusslöcher haben nicht den geringsten Abstand zum Untegrund (Wand, Boden etc.).
    Wie macht man das?? Und wie bekommt man es hin, dass diese auch noch mit dem Hintergrund-Pixeln Multipliziert werden?
    Sieht man hier recht gut:
    http://img163.imageshack.us/img163/4884/parallaxmappingfearkleinxb9.jpg
    Kann mir das jemand erklären?? 😕



  • wie funktioniert das, dass diese Pixelgenau auf dem Untergrund liegen.

    Theoretisch pappst Du ein Quad an die Wand und setzt den Z-Test auf "Equal" - funktioniert in der Praxis wegen Rundungsabweichungen aber nicht.
    Stattdessen schiebst Du die Geometrie minimal nach vorne (Normale) und zeichnest mit "Less/Equal".
    Genanntes "Quad" ist in der Realitaet ein Ausschnitt der getroffenen Geometrie.

    LukasBanana schrieb:

    wie bekommt man es hin, dass diese auch noch mit dem Hintergrund-Pixeln Multipliziert werden?

    Blending aktivieren.


Log in to reply