• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

3D - billboards

m1au

New member
Hallo :)

Wisst ihr zufällig, wie man für die 3D-Welt billboards programmiert? Ich habe mir jetzt mal so ein kleines Progrämmchen zu "world oriented billboards" (oder "viewpoint oriented billboards") geschrieben. Da richtet sich das billboard der Kamera aus. Ist also wie ein Plakat, das der Betrachter immer von vorne sieht, egal wohin er sich bewegt. Siehe z. B. http://www.flipcode.com/archives/clouds.jpg

Ich habe mir hier 2 kleine Klassen programmiert:

- Billboard: dort definiere ich Position, Breite und Höhe
- BillboardGeometry: für die Vertizes

Eine Billboard-Instanz liefert mir dann eine BillboardGeometry-Instanz.

Die Idee war folgende: Normalerweise habe ich für alle Objekte (Kugel, Pyramide, ...) immer nur ein einziges Objekt. Das wird dann irgendwie beliebig transformiert, bis es an der richtigen Stelle im world-space ist. Das kann ich aber bei billboards nur mit der zentralen Position machen, nicht jedoch mit den Vertizes (die das Plakat definieren). Denn die Vertizes müssen dann so ausgerichtet sein, dass die Normale des Plakats immer in Richtung Betrachter geht.

Habe ich das so richtig gemacht? Mir kommt das nämlich fürchterlich kompliziert vor.

Falls sich das wer anschauen will, was ich versucht habe: 'Untitled Post' | TextUploader.com
Wird erst ab Zeile 1194 interessant.
Und die index.html-Datei:
Code:
<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title>Title of the document</title>
      <script src="js.js"></script>
   </head>
   <body onload="start()">
      <canvas id="glcanvas" width="640" height="480">
         Your browser doesn't appear to support the <code><canvas></code> element.
      </canvas>
   </body>
</html>
 
Zuletzt bearbeitet:
Ja, stimmt. Die zentrale Position kann ich frei tansformieren, die Vertizes vom billboard (also die Eckpunkte vom Plakat) kann ich nicht frei transformieren, sondern muss sie immer genau so transformieren, sodass die Normale aus das billboard genau richtig Kamera zeigt.

Ich habe mir das jetzt mal in einem Java-package angeschaut: https://docs.oracle.com/cd/E17802_0...elopers/j3dapi/javax/media/j3d/Billboard.html

Und dazu ein kleines Demo-Programm: How to use a billboard node - Java Tips

Der dort aufgebaute Szenen-Graph schaut folgendermaßen aus (wenn ich das richtig verstanden habe)
Code:
         contentBranch
         |           |
         |           |
myBillBoard     bothGroup
                     |
                     |
                   rightGroup
                     |
                     |
                   billboardGroup
                     |
                     |
                   rightCube
Die leftGroup habe ich hier mal weggelassen. Ich habe den Eindruck, die spielt in Verbindung mit dem billboards keine Rolle.

rightCube ist die Geometrie, d. h. dort sind scheinbar die Vertizes definiert: ColorCube (Java 3D 1.3.2)

myBillboard hat eine Beziehung zu rightCube:
Code:
Billboard myBillboard = new Billboard(billBoardGroup,
        Billboard.ROTATE_ABOUT_AXIS, new Vector3f(0.0f, 1.0f, 0.0f));
myBillboard kennt via billbordGroup rightCube.

D. h. da gibt es einen Unterschied zu meiner Programmierung. Während im Java-Programm die Geometrie extern definiert und dann dem Billboard übergeben wird, erzeuge ich in meinem JS-Programm die Geometrie in meiner Billboard-Klasse und übergebe dann die Geometrie dem Hauptprogramm.

Irgendwie habe ich die Vermutung, dass die Java-Programmierung flexibler ist. Ich vermute, man kann diversen Geometrie-Objekten ein Billboard machen. Währenddessen ist bei mir das Billboard immer ein Rechteck.

Die Vererbung schaut aber ähnlich aus. ColorCube erbt von Shape, erbt von Leaf. Billboard erbt von Behavior, erbt von Leaf. Ich glaube, ich mache das so ähnlich. Also zumindest diese Trennung in 2 Klassen scheint OK zu sein.

Allerdings scheint es ein Blödsinn zu sein, dass ich die Transformation der 4 Vertizes im JS mache. Ich glaube, das sollte extern geschehen, oder? Ich definiere in meiner BillboardGeometry-Klasse zwar mal grundsätzlich die 4 Vertizes basierend auf width und height, die Transformation mache ich dann aber in einem Vertex-Shader. Die Matrix, die er dafür benötigt, erstelle ich dann .... wo??? Im JS-Hauptprogramm oder in meiner Billboard-Klasse?
 
Zuletzt bearbeitet:
Es wäre auf jeden Fall flexibler, wenn du das Billboard als Metaklasse definieren würdest. Also ihm irgendein beliebiges Geometrieobjekt und einen Vektor, der bei deisem Objekt Vorne definiert, übergeben und die Metaklasse dreht dann das Objekt immer so, dass der "Vorne"-Vektor zur Kammera zeigt. Wenn du diese Transformation nicht in JS, sondern auf der GPU machen kannst, ist das wahrscheinlich performanter.
 
Flexibler ist es dann sicher, allerdings frage ich mich, wofür ich das dann benötigen könnte.

Angenommen, ich komme auf die Idee, eine Statue zu modellieren, die immer in Richtung Kamera blicken soll. Wenn ich mich mit der Kamera nun in die Höhe bewege, also in y-Richtung, dann dreht sich die Statue ebenfalls mit. D. h. sie steht dann nicht mehr mit dem Sockel auf dem Boden, sondern hängt verdreht in der Luft.

Darum frage ich mich, ob es überhaupt sinnvoll ist, normale Geometrieobjekt einem Billboard-Objekt zu übergeben.

---

THREE.js macht das interessanterweise wieder ganz anders. Dort arbeitet man mit http://threejs.org/docs/#Reference/Objects/Sprite. Dem Sprite wird ein SpriteMaterial übergeben, dem man eine Textur übergibt. SpriteMatrial erbt von Material, ist also gar keine Geometry. Also man übergibt kein Geometrie-Objekt, sondern ein Matrial-Objekt.
 
Zuletzt bearbeitet:
Man könnte ja die Billboard Metaklasse auch noch soweit erweitern, dass der "Vorne"-Vektor nur horizontal drehen darf... mit Geometrieobjekten bist du einfach flexibler.
 
Hm, nur ein Drehen um die vertikale Achse des local space. Als Option. Ist ganz sicher keine schlechte Idee. Ich werde das im Hinterkopf behalten. Vielleicht mache ich das wirklich. Danke :)
 
Zurück
Oben