Jump to content
Unity Insider Forum

Draw Calls - Static Batch funktioniert nicht?


Tiwaz

Recommended Posts

Hallo Leute.

 

Ich bin grade etwas verwirrt. Hab mir letztens ein Stadt Asset im Store gekauft.

Das Ding ist modular aufgebaut ist und ich hab jetzt mehrere 1000 einzelne Objekte in der Szene aus denen die Häuser und so weiter zusammengesetzt sind.

 

Doof ist nur, dass ich an einem bestimmten Punkt in der Map, bei ungünstigem Blickwinkel ca. 9000 Draw Calls habe.

 

Zur Szene selber:

Es werden 14 Materialien und 25 Texturen insgesamt benutzt wobei jedes Material Bumped Diffuse Shader verwendet und es sind 700k+ Poly insgesamt. Auch sind alle statischen Objekte als static geflagt.

Es werden außerdem 19 Lightmaps benutzt.

 

Was mich jetzt etwas verwirrst ist, dass "Saved by batching" einfach bei 0 bleibt.

 

Ich hab einfach mal ein paar in der Szene bestehenden Prefabs kopiert oder neue in die Szene eingefügt und bei den von mir neu eingebauten Prefabs wird auch tatsächlich gebatcht.

Jetzt weiß ich nicht mehr weiter wieso die vorhandenen nicht gebatcht werden.

 

Hab auch mal eben ein Script geschrieben das alle Lichter in der Szene löscht also wirds wohl nicht an denen liegen.

Dass die Lightmaps die potenziellen Batchsaves verringern ist mir klar aber, dass wirklich überhaupt gar nichts gebatcht wird find ich selbst mit Lightmaps ziemlich merkwürdig.

 

@edit: Hab mal die Lightmaps rausgenommen und es wird trotzdem nix gebatcht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich traue dieser ganzen Batchinggeschichte eh nicht übern weg. Die ist in Unity so herrlich sinnbefreit ineffizient. Von wegen dynamic Batching bis maximal 300 Vertices pro Mesh ...

 

Ich würde die Objekte die das gleiche Material haben einfach sinnvoll* zusammenfassen, als ein einziges Obj File exportieren, selbiges dann wieder importieren, und die Einzelteile deaktivieren. Das kannst du zum Beispiel mit dem Obj Script aus dem Unity Wiki machen

 

*Theoretisch könntest du das als ein einziges Objekt exportieren sofern du das 65 K Vertices Limit nicht erreichst. Es könnte aber Sinn machen das Ganze in Vier, Acht oder 16 Stücke zu unterteilen, je nach Levelaufbau und Zielplattform.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@LightYarn:

Yup, hab ich auch schon geschrieben ^^

[....]Auch sind alle statischen Objekte als static geflagt.[...]

 

@Mark:

Ne ich hab nur die Free aber soweit ich weiß bezieht sich das "for each Platform" lediglich auf mobile und kann auf PC verwendet werden.

Außerdem hab ich mal ne Testszene gemacht in der ich einfach mal ein paar von den Prefabs aus dem Asset reingepackt hab weil ich eigentlich n'Script für Frustum Culling schreiben wollte aber da hatte ich dann plötzlich 2 Draw Calls und Saved by batching 88 also denke ich kann ich das benutzen.

Und es wurden eben auch in der besagten Demo Scene kopierte Objekte gebatcht (wird da eigentlich die Lightmap mitkopiert?) bzw. wenn ich einfach welche neu eingefügt habe.

 

@Tiles:

Ich benutze dynamic batching eh nich für die Gebäude ^^ Außerdem sind in dem Asset auch z.B, einzelne Wandmodule mit hald 2 Tris.. wenigstens die sollten doch, selbst mit Dynamic, gebatcht werden oder?

Zielplattform ist nur der PC.

 

Naja ich bin bei Recherche Zwecken nach "Wie könnte man ein Frustum Culling Script schreiben" auf ein ziemlich gutes Script gestoßen (Das der Verfasser einfach in ein Forum als Quelltext geschrieben hat ^^) und da sind an der kritischen Stelle nur noch 2800 Draw Calls (im Vergleich zu ~8950) gesunken ^^

Immerhin etwas :D

Aber wenn hier Batching funktionieren würde wären das nur noch ein Bruchteil davon ^^

Werd mich mal heute nochmal hinsetzen und versuchen zu optimieren.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Woops, sorry! Das muss ich dann wohl überlesen haben :D

 

Zum Thema Frustrum-Culling: Das macht Unity sowieso immer

 

Unity ensures that when rendering your objects those which are completely outside of this frustum are not displayed. This is called Frustum Culling. Frustum Culling happens irrespective of whether you use Occlusion Culling in your game.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Könnte mal bitte jemand, der richtig gut englisch kann diesen Absatz lesen und kommentieren?

Für mich liest sich das so, als ob sowohl Batching, als auch Geometrie zusammenfassen nix bringt.

Bin jetzt auch etwas verwirrt. :blink:

Draw Call Batching

 

 

To draw an object on the screen, the engine has to issue a draw call to the graphics API (e.g. OpenGL or Direct3D). The graphics API does significant work for every draw call, causing performance overhead on the CPU side.

Unity can combine a number of objects at runtime and draws them together with a single draw call. This operation is called “batchingâ€. The more objects Unity can batch together, the better rendering performance (on the CPU side) you can get.

Built-in batching support in Unity has significant benefit over simply combining geometry in the modeling tool (or using the CombineChildren script from the Standard Assets package). Batching in Unity happens after the visibility determination step. The engine does culling on each object individually, and the amount of rendered geometry is going to be the same as without batching. Combining geometry in the modeling tool, on the other hand, prevents efficient culling and results in a much greater amount of geometry being rendered.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Um ein Objekt zu zeichnen muss die Engine einen sogenannten DrawCall an die GrafikAPI (DX oder OpenGL) geben. Die GrafikAPI macht verdammt viel wenn ein DrawCall ankommt und das kostet viel Performance auf der CPU Seite.

 

Unity kann Objekte zusammenfassen um sie mit nur einem DrawCall zu zeichnen. Dies wird batching genannt.

 

Je mehr Unity zusammenfassen kann umso weniger DrawCalls und umso besser die Performance.

 

Das eingebaute batching in Unity hat diverse Vorteile gegenüber dem manuellen Batching mithilfe von Modellierungstools (Maya, Blender, etc) oder gegenüber dem Combine Script in den Standard Assets.

 

Batching in Unity passiert nachdem festgestellt wurde welche Objekte sichtbar sind. Unity checkt jedes Objekt einzeln um zu sehen ob es gezeichnet werden muss oder nicht. Dadurch bleibt auch die Menge an geometrie die gerendert wird mit oder ohne batching genau gleich.

 

Geometrie mithilfe von Modellierungstools wie Maya oder Blender zu kombinieren verhindert dass unity selbst unsichtbare geometrie cullen (vom Rendern ausschließen) kann. Was dazu führt dass viel mehr Geometrie gezeichnet wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Sänk ju weri matsch!

 

Wie gehe ich den jetzt damit um? (immer noch verwirrt - jetzt auf deutsch)

"Dadurch bleibt auch die Menge an Geometrie die gerendert wird mit oder ohne batching genau gleich."

"...Maya oder Blender zu kombinieren...Was dazu führt dass viel mehr Geometrie gezeichnet wird."

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, aber das Script verschiebt entsprechend der Sichtweite die Far Plane also wenn ich vor nem Haus stehe wird die Farplane hald so weit nach vorne gesetzt bis ich grade noch das Haus sehe ^^

Wenn ich natürlich ne riesen Weitsicht über ne Stadt hab is es nicht so effektiv weil die Far Plane bis ans Ende der Stadt versetzt wird und somit nix an Performance gewonnen wird ^^

 

Und um das mit dem Batching und Geometrie zu veranschaulichen:

Wenn du eine Stadt hast wo jedes Fenster, jede Wand, etc einzelne Objekte sind, kann Unity die nicht sichtbaren Teile (also z.B. die von anderen Häusern verdeckten Teile oder auch die Einzelteile auf der anderen Seite eines Hauses) einfach nicht rendern lassen.

Wenn deine Stadt allerdings aus einem riesengroßen Mesh besteht muss die komplette Stadt, zu jedem Zeitpunkt vollständig gerendert werden weil Unity eben nur die Stadt als Mesh überprüfen kann und die so ziemlich immer sichtbar ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Und um das mit dem Batching und Geometrie zu veranschaulichen:

Wenn du eine Stadt hast wo jedes Fenster, jede Wand, etc einzelne Objekte sind, kann Unity die nicht sichtbaren Teile (also z.B. die von anderen Häusern verdeckten Teile oder auch die Einzelteile auf der anderen Seite eines Hauses) einfach nicht rendern lassen.

Wenn deine Stadt allerdings aus einem riesengroßen Mesh besteht muss die komplette Stadt, zu jedem Zeitpunkt vollständig gerendert werden weil Unity eben nur die Stadt als Mesh überprüfen kann und die so ziemlich immer sichtbar ist.

 

Na, halt.....das was du da beschreibst ist das Occlusion Culling. Also, das Weglassen von Objekten, die sich gegenseitig verdecken. Das hat mit dem batching nichts zu tun.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Sänk ju weri matsch!

 

Wie gehe ich den jetzt damit um? (immer noch verwirrt - jetzt auf deutsch)

"Dadurch bleibt auch die Menge an Geometrie die gerendert wird mit oder ohne batching genau gleich."

"...Maya oder Blender zu kombinieren...Was dazu führt dass viel mehr Geometrie gezeichnet wird."

 

Das besagt im Grunde nur, dass du alles Unity überlassen sollst. Mehrere Meshs zu ein Mesh zusammen fassen ist laut unity keine gute Idee, Beispiel:

 

Du hast 2 Häuser:

 

Haus1             Haus2

(War mal ASCII Art aber die nutzlose Rotzforumssoftware hats versemmelt..)

 

Wenn die Cam effektiv nur das erste haus sieht dann würdest du folgendes dadurch erreichen:

 

Beide Häuser sind insgesammt 1 Mesh: Es werden beide Häuser gerendert auch wenn das rechte haus nicht sichtbar ist, es werden zuviele Geometriedaten (Vertexe, Triangles) an die Grafikkarte gesendet. 1 DrawCall

 

Beide Häuser sind separate Meshs: Es wird nur das linke Haus gerendert, es wird nur der Kram für das eine haus an die Grafikkarte gesendet. 1 DrawCall.

 

Wenn die Cam beide Häuser im Bild hat:

 

Beide Häuser sind insgesammt 1 Mesh: Es werden beide Häuser gerendert. 1 DrawCall.

 

Beide Häuser sind separate Meshs: Es werden beide Häuser gerendert. 1 DrawCall wenn Unity beide Häuser gebatcht hat. 2 DrawCalls wenn unity das nicht gemacht hat.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Absolut einleuchtend, so kenne ich das auch von anderen Programmen.

 

Ich kann es jetzt nicht belegen, aber ich schwöre ich hab schon ein Dutzend mal an verschiedenen Stellen gelesen, dass man im optimalsten Falle die ganze Szene als ein Objekt in Unity importieren, zumindest aber so viel wie möglich zusammenkloppen soll.

 

 

Als ich mit Unity angefangen habe gab es da auch so eine Beispiel Szene, die im Wesentlichen auch nur ein großes Teil war. Ich glaube Angry Robots oder so.

 

Bevor ich hier noch weiter das eigentliche Thema verfremde mach ich gleich mal ein Eigenes auf!!!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...