Jump to content
Unity Insider Forum

Viele Materialien ohne Texturen


SuperFranTV

Recommended Posts

Hallo liebe Community,

 

gibt es da eine Möglichkeit Speicher bzw. Performance zu sparen, weil in meinem Spiel sind alle Materialien ohne Texturen und da gibt es dann auch nur 5 Varianten (Metallisch, Glas usw..). Ich hatte mal irgendwo von einer Sache gelesen wo man die Materialien packen oder so ähnlich kann.

 

Danke schon mal.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Eigentlich packt man eher Texturen die das gleiche Material benutzen zusammen. Atlastexturen nennt man das, aber Atlasmaterialien gibt es nicht. Machbar wäre es natürlich, aber dann hättest du einen Megashader und das ist auch nicht gut für die Performance.

 

Überlege lieber ob du wirklich soviele Materialien brauchst, zB 2x das gleiche Metall mit unterschiedlichen Farben kann man gut durch 1 Material ersetzen was die Farben aus einer Textur liest. Auch andere Materialeigenschaften lassen sich in den Texturdaten verpacken.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie jetzt?

 

Ich kann ein Material als Basis nehmen und dann dieses Material bei Objekt A mit der Texture X und bei Objekt B mit der Texture Y und das gleichzeitig? wenn nicht wäre es genau das selbe wie 100 Materialien die alle eine andere Texture haben.

 

Das mit Textura Atlas hab ich mir mal angesehen, das ist nix anderes als das man alle Texturen zu einer Datei macht (eine Texture) und dann über die UV-Maps den jeweiligen Teil der Texture aussucht, jedoch ist das doch nicht sinnvoll wenn man nur reine Farben hat (keine Texturen, man könnte zwar für jede Farbe eine "Abteilung" in der Texture machen) z.b. 1 Objekt soll es in verschiedenen Farben geben da kann man ja schlecht bei 20 Farben, 20 mal das selbe Objekt in den Assets Ordner tun und bei jeden Objekt die UV-Map verändern das wäre mega sinnlos.

Link zu diesem Kommentar
Auf anderen Seiten teilen

... das wäre mega sinnlos.

 

Nicht unbedingt. Es gibt immer die Balance zwischen Arbeitsaufwand und Performance. 20 Objekte mit verschiedenen UVs, die ein Material verwenden werden sicher schneller gezeichnet, als 20 Objekte mit 20 Materialien. Musst Du Dir überlegen, ob es den höheren Arbeitsaufwand wert ist, oder ob es auch so funktionieren wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie jetzt?

 

Ich kann ein Material als Basis nehmen und dann dieses Material bei Objekt A mit der Texture X und bei Objekt B mit der Texture Y und das gleichzeitig? wenn nicht wäre es genau das selbe wie 100 Materialien die alle eine andere Texture haben.

 

Das mit Textura Atlas hab ich mir mal angesehen, das ist nix anderes als das man alle Texturen zu einer Datei macht (eine Texture) und dann über die UV-Maps den jeweiligen Teil der Texture aussucht, jedoch ist das doch nicht sinnvoll wenn man nur reine Farben hat (keine Texturen, man könnte zwar für jede Farbe eine "Abteilung" in der Texture machen) z.b. 1 Objekt soll es in verschiedenen Farben geben da kann man ja schlecht bei 20 Farben, 20 mal das selbe Objekt in den Assets Ordner tun und bei jeden Objekt die UV-Map verändern das wäre mega sinnlos.

 

Wenn dir was besseres einfällt, nur zu :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich möchte nur wissen ob es trotzdem sinnvoll wäre in meiner Situation: Ich habe jetzt 20 Farben (20 Materialien) und meine Objekte bestehen aus Würfeln und jeden Würfel wird eine Farbe zugewiesen so entstehen dann am Ende die Figuren mit Farben. (Mit bestehen aus Würfeln meine ich eigentlich sind sie nur eckig weil z.b. nur 3 Seiten von einen Würfel an manchen Stellen sichtbar und wirklich da sind)

 

Gibt es da irgend eine Color Tabelle oder ähnliches wo man am Ende nur 1 Material oder wenigstens etwas begrenzt das ganze hat?

 

Danke trotzdem für eure Hilfe :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Eventuell gibt es eine Lösung mit:

1 Material

1 Textur mit vielen Farbfeldern

1 UVW Set

Dazu müsstest Du dieses Script so umbauen, dass es nicht automatisch durch alle Bereiche der Textur läuft.

Stattdessen sollte es eine öffentliche Variable geben, also einen Wert, der im Editor angezeigt wird und an dem Du den UV Index eingeben kannst. Du hättest dann auf jedem Objekt dieses Script und somit die Möglichkeit an jedem Objekt einzustellen, welchen Bereich der Textur es nutzen soll.

 

Hier das Script: http://wiki.unity3d.com/index.php?title=Animating_Tiled_texture

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also folgendes:

 

1 Material mit einer Texture (Bei dieser Texture ist jeder Pixel = 1 Farbe)

Wie muss ich einen Shader schreiben das ich für jedes Objekt das, das Material trägt einen anderen Pixel auswählen kann bzw. wie schreibe ich es so das für jedes Material eines Mesh Renderers ich den Pixel angeben kann?

 

Danke

 

Edit:

 

public Color32[] colorsx;
void Start() {
 colorsx = GetComponent<MeshFilter>().mesh.colors32;
 Color32 colorWhite = Color.red;
 Color32 colorBlack = Color.black;
 Mesh mesh = GetComponent<MeshFilter>().mesh;
 Vector3[] vertices = mesh.vertices;
 Color32[] colors = new Color32[vertices.Length];
 int i = 0;
 while (i < vertices.Length) {
colors[i] = Color32.Lerp(colorWhite, colorBlack, vertices[i].y);
  i++;
 }
 mesh.colors32 = colors;
}

 

Ich habe den Vertex Shader drauf, nun es ändert zwar den kompletten Mesh zu schwarz aber es soll ja nur den halben (Mein Objekt hat 2 Polygon Selektions und somit kann man 2 Materialien zuweisen wenn ich nur 1 Material zuweise ist die Hälfte des Meshs unsichtbar, wie kann ich jetzt nur die Hälfte färben? colorsx bleibt übrigends leer was für mich kein Sinn ergibt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi, Du möchtest wissen ob es sinnvoll ist?

Ja: Wenn Du 20 Materialien brauchst, nutze 20 Materialien. Ist in dem Fall denke auch mal der einfachste und schnellste Weg.

 

Wenn Du wissen willst was mehr Performance braucht: Teste es. So aufwändig ist das in dem Fall nicht.

 

 

PS: Seit einiger Zeit steht das Wort Performance ganz weit hinten, da man erst einmal was braucht bzw erstellen oder entwickeln muss was die Engine oder deine HW an die Grenzen bringt. Sicher kann man sich schon vorher einen Kopf machen und auf verschiedene Dinge achten bzw Planen. Jedoch sollte man sich nicht dabei den Kopf zerbrechen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ändern der UVW über Script. Ist vielleicht nicht elegant das in Update zu machen, aber so in der Art könnte man das lösen. Jemand der im Gegensatz zu mir wirklich programmieren kann ist sicher in der Lage das zu optimieren.

var uvAnimationTileX = 4;
var uvAnimationTileY = 4;
var index = 0;

function Update () {

// Size of every tile
var size = Vector2 (1.0 / uvAnimationTileX, 1.0 / uvAnimationTileY);

// split into horizontal and vertical index
var uIndex = index % uvAnimationTileX;
var vIndex = index / uvAnimationTileX;

// build offset
// v coordinate is the bottom of the image in opengl so we need to invert.
var offset = Vector2 (uIndex * size.x, 1.0 - size.y - vIndex * size.y);

renderer.material.SetTextureOffset ("_MainTex", offset);
renderer.material.SetTextureScale ("_MainTex", size);
}

post-4421-0-09727900-1444589811.png

post-4421-0-32847200-1444589817_thumb.png

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ändern der UVW über Script. Ist vielleicht nicht elegant das in Update zu machen, aber so in der Art könnte man das lösen. Jemand der im Gegensatz zu mir wirklich programmieren kann ist sicher in der Lage das zu optimieren.

var uvAnimationTileX = 4;
var uvAnimationTileY = 4;
var index = 0;

function Update () {

// Size of every tile
var size = Vector2 (1.0 / uvAnimationTileX, 1.0 / uvAnimationTileY);

// split into horizontal and vertical index
var uIndex = index % uvAnimationTileX;
var vIndex = index / uvAnimationTileX;

// build offset
// v coordinate is the bottom of the image in opengl so we need to invert.
var offset = Vector2 (uIndex * size.x, 1.0 - size.y - vIndex * size.y);

renderer.material.SetTextureOffset ("_MainTex", offset);
renderer.material.SetTextureScale ("_MainTex", size);
}

 

Nice, vielen Dank :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah just so you know:

 

Das gibt allen Objekten die das gleiche Material benutzen genau das gleiche aussehen, denn es wird das Material geändert, nicht das Mesh oder so.

 

Was du bräuchtest wäre ne Art Baking der gewünschten Farbe in separate Meshs.

 

Leider kann meines Wissens nach Unity kein echtes HW Instancing, dann wäre es möglich zusätzliche Daten zu halten ohne das Batching zu verhindern.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Mark:

Ähh..wie? Falls Du mein Script meinst, das gibt allen Objekten einen anderen Textur Bereich und somit einen andere Farbe.

Daher benötigt man für 20 Objekte, welche sich nur in der Farbe unterscheiden sollen nur ein Material. Erkennst Du da einen Fehler, den ich übersehen habe?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Script gibt dem Material andere UV Offsets und Scale Werte. Nicht dem GameObject und auch nicht dem Mesh. Wenn es das gleiche Material ist wird am Ende des gesamten Update Zyklus das Material die UV Werte vom letzten gemachten Update bekommen.

 

Wenn du dem GO eigene UV Koordinaten geben willst dann brauchst du sowas hier:

 

var mesh = myRenderer.sharedMesh = (Mesh) Instantiate( myRenderer.sharedMesh );
var uv = mesh.uv;
// uv verändern
mesh.uv =uv;

 

oder besser ändert mesh.colors

 

http://docs.unity3d....esh-colors.html

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mhhh ich müsste raten, aber renderer.material erstellt ein einzigartiges neues Material, renderer.sharedMaterial nutzt das gemeinsame. Ich glaube das ganze müsste sich in den DrawCalls niederschlagen.

 

Korrigiere mich wenn ich mich da irre, hab nun schon eine ganze Weile nichts mehr mit Unity gemacht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

3 Mesh, jedes das Material mir der bunten Textur und jedes das Script mit einem anderen Wert für Index.

4 DrawCalls

 

3 Mesh, jedes mit einem einfachen Material mit der selben Textur.

4 DrawCalls

 

4 Mesh, jedes das Material mir der bunten Textur und jedes das Script mit einem anderen Wert für Index.

5 DrawCalls

 

Macht es weder besser noch schlechter.

Unity 4.5.2. Kostenfreie Version, kein Batching.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Script gibt dem Material andere UV Offsets und Scale Werte. Nicht dem GameObject und auch nicht dem Mesh. Wenn es das gleiche Material ist wird am Ende des gesamten Update Zyklus das Material die UV Werte vom letzten gemachten Update bekommen.

 

Wenn du dem GO eigene UV Koordinaten geben willst dann brauchst du sowas hier:

 

var mesh = myRenderer.sharedMesh = (Mesh) Instantiate( myRenderer.sharedMesh );
var uv = mesh.uv;
// uv verändern
mesh.uv =uv;

 

oder besser ändert mesh.colors

 

http://docs.unity3d....esh-colors.html

 

 

Wegen den Mesh.colors kann man jetzt wenn mein Mesh aus 1 Mesh besteht auch nur einen bestimmten Teil färben?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...