Main Menu

Textur auf .obj-Objekten

Started by uwepost, April 23, 2013, 11:14:13 PM

Previous topic - Next topic

uwepost

Tagchen,

nachdem ich dreimal alles durchsucht habe und mir ziemlich sicher bin, dass ich es so mache, wie es hier steht (http://www.jpct.net/wiki/index.php/Loading_models), muss ich euch leider mit einer Wie-kriege-ich-das-denn-nun-hin-Frage belästigen.

Also, ich habe ein relativ einfaches .obj mit Blender fabriziert, ein Haus. Wand und Dach sind mit jeweils einer Textur beklebt, roof1.jpg und wall1.jpg, jeweils 256x128 Pixel groß. Beide werden vorab geladen:

TextureManager.getInstance().addTexture("roof1.jpg", new Texture(getAssets().open("3dobjects/roof1.jpg")));
TextureManager.getInstance().addTexture("wall1.jpg", new Texture(getAssets().open("3dobjects/wall1.jpg")));


Das Objekt wird geladen mit:
objects = Loader.loadOBJ(objStream, mtlStream, 1f);
Dabei sind die Streams natürlich die passenden zu den Files house_1.obj und house_1.mtl. Ich habe in der house_1.mtl nachgesehen, dort werden die beiden Texturen referenziert als:
map_Kd roof1.jpg
...
map_Kd wall1.jpg


Soweit funktioniert auch alles, es wirft keine Fehler, bloß in der 3D-Ansicht ist von den Texturen nichts zu sehen, das Haus hat ein einfarbig oranges Dach und graue Wände.

Verdächtig ist: Orange und grau sind zufälligerweise die "gemittelten" Farben von Dach bzw. Wand. Es schaut fast so aus, als wären die Texturen zwar da, aber... "unendlich unscharf". Denn wenn ich in Blender die Textur-Bilder entferne und einfach nur als Farben z.B. rot und weiß einstelle, wird das Objekt dementsprechend richtig eingefärbt. Das Orange kann nur aus der Texturdatei kommen, aber die hat eben nicht nur orange Pixel, sondern... Dachschindeln. Die Wand, eigentlich ein hübsches schwarz-weißes Fachwerk, wird zu grau.

Der Textur-Manager funktioniert mit anderen Texturen, die ich auf z.B. Primitives.getPlane lege, d.h. wird eine geladene Bodentextur wunschgemäß dargestellt.

Das verwendete Testgerät ist ein Nexus 7. Auf einem LG Optimus 3D derselbe Effekt.

Objekt als 3ds statt als obj exportiert und geladen mit Loader.load3DS() - derselbe Effekt.

Was übersehe ich?

Dreidimensionale Grüße

Uwe

EgonOlsen

#1
Ich habe keine Ahnung von Blender, aber ich meine dort gibt verschiedene Arten, die Texturen aufzukleben und eine davon produziert keine Textur-Koordinaten in der Export-Datei. Du könntest mal prüfen, ob in der OBJ-Datei wirklich u/v-Koordinates enthalten sind. Wenn du nicht sicher bist, poste kurz die verwendete Datei.

Edit: http://www.jpct.net/forum2/index.php/topic,3192.msg23313.html

Socke

Man muss bei Blender das UV Mapping benutzen. Einfach auf Youtube gucken.

uwepost

Danke für eure Antworten!
Leider habe ich es trotz diverser Fummelei noch nicht hinbekommen. Mein Haus hat jetzt in Blender UV-Mapping, und es wird dort korrekt gerendert.

Ich kopiere mal die beiden exportierten Dateien hier rein, vielleicht kann mir einer sagen, woran ich erkenne, ob UV-Koordinaten enthalten sind, und wenn nicht, wie ich sie hinein bekomme.

# Blender v2.65 (sub 0) OBJ File: ''
# www.blender.org
mtllib house_1.mtl
v -1.764480 -1.733434 1.882851
v 1.789923 -1.733434 1.882847
v -1.764481 0.043768 1.882851
v 1.789923 0.043768 1.882849
v 0.012722 -3.403152 1.882849
v -1.764480 -1.733434 -1.689803
v 1.789923 -1.733434 -1.689806
v 0.012721 -3.403152 -1.689805
v 1.789923 0.043768 -1.689805
v -1.764481 0.043768 -1.689803
vt 0.443690 0.228636
vt 0.658282 0.000231
vt 0.658282 0.457042
vt 0.886687 0.457042
vt 0.886688 0.000231
vt 0.919007 0.770902
vt 0.459850 0.770902
vt 0.459849 0.457503
vt 0.919006 0.457503
vt 0.459388 0.770902
vt 0.000231 0.770902
vt 0.000231 0.457503
vt 0.459388 0.457503
vt 0.214823 0.000231
vt 0.000231 0.228636
vt 0.214822 0.457042
vt 0.443228 0.457042
vt 0.443229 0.000231
vt 0.459388 0.771364
vt 0.459388 0.999769
vt 0.000231 0.999769
vt 0.000231 0.771364
vt 0.919006 0.771364
vt 0.919006 0.999769
vt 0.459849 0.999769
vt 0.459849 0.771364
vn -0.000001 0.000000 -1.000000
vn -0.000001 0.000001 -1.000000
vn 0.684725 -0.728802 -0.000000
vn -0.684725 -0.728802 0.000000
vn 0.000001 -0.000000 1.000000
vn 0.000001 -0.000001 1.000000
vn 0.000001 0.000001 1.000000
vn 1.000000 0.000000 -0.000000
vn -1.000000 -0.000000 0.000000
usemtl house_1
s off
f 8/1/1 6/2/1 7/3/1
f 6/2/2 9/4/2 7/3/2
f 6/2/1 10/5/1 9/4/1
f 5/6/3 8/7/3 7/8/3 2/9/3
f 1/10/4 6/11/4 8/12/4 5/13/4
f 1/14/5 5/15/5 2/16/5
f 4/17/6 1/14/6 2/16/6
f 3/18/7 1/14/7 4/17/7
f 4/19/8 2/20/8 7/21/8 9/22/8
f 1/23/9 3/24/9 10/25/9 6/26/9


# Blender MTL File: 'None'
# Material Count: 1

newmtl house_1
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 1
map_Kd house_1uv.jpg


Das Textur-File hänge ich mal an.

[attachment deleted by admin]

EgonOlsen

Sieht ok aus. Die Zeilen mit "vt" sind die Texturkoordinaten. Kannst du mal posten, wie du das Ding lädst und die Textur zuweist. Wenn es nicht zu groß, poste doch einfach die ganze Activity.

uwepost

Leute, Leute, ich hab meinen Fehler gefunden.
Folgende Zeile war vollkommen überflüssig und als ich sie auskommentiert habe, ging's:
object.calcTextureWrap();
Irgendwie logisch, oder?  ::)

Ich bedanke mich für eure Unterstützung!

EgonOlsen

Ja..."leider" benutze ich das in manchen Beispiele und es wird dann übernommen. Ich fand das eine einfache Möglichkeit, irgendwelche Texturkoordinaten für Beispiele zu erzeugen, aber mittlerweile bereue ich es...es führt einfach zu zuviel Verwirrung... ;)

uwepost

Schreib doch einen Kommentar über die Zeile in den Demo-Code.
Zugegeben: Im Javadoc steht ja, was die Funktion tut, und damit ist es offensichtlich, dass man sie in diesem Fall nicht verwenden darf... es dauerte halt 2 Tage, bis ich es geschafft habe, den eigenen Code mit größerem Abstand zu betrachten - dann erst wird einem so manches klar.

Unklar ist mir nach wie vor, warum bei einem anderen Objekt die Alpha-Transparenz der Textur nicht funktioniert (erscheint schwarz). Gibt es, abgesehen von dem Texture-Konstruktor mit useAlpha, der auch nicht hilft, noch einen heißen Tipp?

Gestern ist mir noch ein Problem aufgefallen: Eines meiner OBJ ist seitlich ein bisschen gegenüber den anderen verschoben. Konkret ist es so, dass ich in Blender mehrere Fahrzeuge gebastelt und einzeln exportiert habe (sie sind alle um die x-Achse zentriert), aber in der Engine ist eines nicht in der Flucht. Irgendeine Idee, woran das nun wieder liegen könnte? setCenter(0,0,0) habe ich versucht, und zwar HINTER build(), das laut Doku dieses Zentrum (falsch) setzen könnte.



EgonOlsen

Ein Alpha-Kanal alleine tut erstmal nichts, bevor du keine Transparenz aktiviert hast: http://www.jpct.net/doc/com/threed/jpct/Object3D.html#setTransparency(int)

Was den "Zusammenhalt" der Objekte angeht: Das kann verschiedene Ursachen haben. Es könnte am Exporter ebenso wie am Importer liegen (die Loader von jPCT unterstützen nicht jede Absurdität der Formate) oder am Rotationspivot. Wenn du die Modelle als 3DS vorliegen hast, kannst du jPCT anweisen, das Pivot aus der Datei zu verwenden: http://www.jpct.net/jpct-ae/doc/com/threed/jpct/Config.html#useRotationPivotFrom3DS
Vielleicht hilft das...

uwepost

Okay, ich setze also setTransparency(0x0f0f0f), wenn ich das richtig verstehe? Dadurch werden die alphatransparenten Flächen in der Tat durchsichtig, aber anscheinend auch alle schwarzen.
Heißt das, meine App muss wissen, bei welchem Objekt setTransparency() aufgerufen werden darf (da Alpha-Transp. in der Textur vorkommen) und bei welchem nicht? Das wäre aber unpraktisch. Ich habe zig mehr oder weniger generische Landschaftsobjekte, und die App sollte nicht extra eine Liste verwalten müssen, wo sie die Funktion aufrufen darf und wo nicht. Geht das irgendwie anders oder verstehe ich wieder was falsch?

Der Hinweis auf den Rotationspivot war genau richtig, vielen Dank dafür. Offenbar setzt build() ihn aus irgendeinem Grund auf einen Vektor "neben" der Mitte. Ich mache jetzt dies:
itemObject.build();
itemObject.setCenter(new SimpleVector(0,0,0));
itemObject.setRotationPivot(new SimpleVector(0,0,0));

Das wäre also schonmal geschafft  :D

EgonOlsen

Quote...setTransparency(0x0f0f0f)...
Nein. Das ist was völlig anderes. Transparenz bezieht sich auf das gesamte Objekt und zusätzlich den Alphakanal. Wenn man also das ganze Objekt etwas durchsichtig haben will, nimmt man sowas wie setTransparency(0). Wenn nur der Alphakanal zum Tragen kommen sollte, besser sowas wie setTransparency(100).

uwepost

Verstehe... d.h. nicht ganz. Bei 100 sind Flächen komplett durchsichtig, die es vorher nicht waren, und die auch keinen Alphakanal in der Textur haben, und es gibt ein unschönes Geflacker. Außer bei meinem Baum, dem mit Alpha in der Textur, der ist jetzt prima  ;D
Ich werde aus der Doku nicht ganz schlau. Welche Skala ist das? Ist 100 das Maximum? Was ist der Default? -1 vermutlich? Da ist allerdings wiederum mein Baum (bzw. der Alpha-transparente Bereich um seine Blätter herum) nicht transparent.

EgonOlsen

-1 ist default und bedeutet, dass nichts transparent ist und der Alphakanal niemanden interessiert. Werte ab 0 werden nach der hier beschriebenen Formel umgerechnet: http://www.jpct.net/doc/com/threed/jpct/Config.html#glTransparencyOffset. Dabei ist 0 die maximale Transparenz (also quasi unsichtbar) und >1 die höchste. Die Faktoren für die Formel lassen sich in Config anpassen.
Wenn Objekte nach dem Setzen der Transparenz "flackern", dann ist vermutlich ein Sortierproblem, welches sich meistens nur individuell lösen lässt. Dazu müsste ich genauer wissen, was da "flackert"...man muss immer bedenken, dass transparente Objekte pro Objekt sortiert werden. Es kann daher sein, dass bestimmte Objektteile mit anderen so ungünstig überlappen, dass es falsch aussieht. Das lässt sich nur durch Aufteilen der Objekte lösen.

uwepost

Hm. Sagen wir, ich habe zwei Objekte, A.obj und B.obj. A hat eine Textur mit Alpha-Transparenz, B nicht.

Bei A muss ich nach dem Laden setTransparency auf 100 setzen, bei B darf ich das nicht, sonst flackern schwarze Flächen.

Das ist nicht schön, weil ich beide Objekte mit dem gleichen Code laden will, bloß der Dateiname ist parametrisiert.

Ich habe mir jetzt so geholfen, dass ich Dateien von der Sorte A mit einem "atr" im Dateinamen kennzeichne, und in dem Fall setTransparency(100) aufrufe, sonst nicht.

Danke erstmal, dieses Forum ist eine große Hilfe!  :D