Texturen nicht dehnen

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Midimaster

Betreff: Texturen nicht dehnen

BeitragDo, Okt 20, 2011 14:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab da mal ne ganz blöde Anfängerfrage:

Wenn ich eine Haus direkt in B3D als Mesh aus Vertices, Triangles und Surfaces erstelle, dann kann ich doch den Surfaces Texturen zuweisen.

Stellt Euch vor das Haus ist im Erdgeschoss 1 Höheneinheit hoch und je 2 Einheiten breit. Oben drauf ist ein Dachgeschoss auch noch mal 2 Höheneinheiten hoch, aber halt wie ein Spitzboden.

Nun möchte ich den Wänden die immer gleiche Mauertextur zuweisen. Wenn ich es von der Vorderseite, (wo normalerweise die Regenrinnen zu sehen sind) anschaue sieht man eine Wand von 2x1 Einheiten. Wenn man es von der Giebelseite anschaut, dann sieht man eine Wand von 2x2 Einheiten:


Code: [AUSKLAPPEN]

Vorderansicht (nur Mauer):
 ----------------
 |              |
 |              |
 ----------------
 

Giebelseite:
        /\
      /    \
    /        \   
  /            \
 ----------------
 |              |
 |              |
 ----------------



Diese Giebelseite ist eine einzige Surface. Wende ich nun meine Mauertextur auf beide Seiten an, so sind die einzelnen Steine nicht gleich groß.

Gibt es hier eine Möglichkeit, dies zu "normalisieren"?

Bitte keine Antworten ala "Mach es mit einem 3D-Zeichenprgramm". Es soll ja eben in B3D erstellt werden.
Die Lösung sollte auch dann funktionieren, wenn der User z.b. das Haus in die Länge zieht. In einem solchen Fall sollen dann nachher "mehr" Steine zu sehen sein statt längere Steine.

Auch keine Lösung: verschiedene Texturen nachladen. Der User soll nur eine Textur "Mauerwerk" auswählen und das soll sich dann sinvoll um das Haus beliebeiger Größe herumschlingen.

Meine Idee wäre, Kopien der Orignal-Textur zu erzeugen und die abhängig von den Ausmaßen des Mesh zu skalieren...

Aber sicher gibt es da einen wesentlich eleganteren Weg, oder?


### Nachtrag ###

Upps, es gibt gar keine Kopierbefehl für Texturen, oder?
  • Zuletzt bearbeitet von Midimaster am Do, Okt 20, 2011 14:32, insgesamt einmal bearbeitet

Jan_

Ehemaliger Admin

BeitragDo, Okt 20, 2011 14:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Du solltest die UV-coordinaten vom Vertex anpassen.
between angels and insects

Xeres

Moderator

BeitragDo, Okt 20, 2011 15:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Texturen könntest du mit CopyRect von einem Texturbuffer in den anderen kopieren. Sollte relativ fix gehen.
Edit: Die Lösung für das Problem ist das aber nicht - richtige UV Koordinaten sind das Mittel der Wahl.
Edit2: Nach einer Gedächtniserfrischung von Jan_ in Sachen UV ein Beispiel:
BlitzBasic: [AUSKLAPPEN]
Graphics3D(800,600,0,2)
SetBuffer BackBuffer()
Local camera = CreateCamera()
Local light = CreateLight()
PositionEntity camera, 0, 0, - 5
RotateEntity light, 90, 0, 0

Local mesh = CreateMesh()
Local surface = CreateSurface(mesh)
Local v0 = AddVertex(surface, 0, 3, 0, 3, 0) ;* Oben
Local v1 = AddVertex(surface, 3, -3, 0, 6,6) ;* Rechts
Local v2 = AddVertex(surface, -3, -3, 0, 0,6) ;* Links
AddTriangle(surface, v0, v1, v2)
UpdateNormals mesh

Local tex = GetMeATexture()
Local cube = CreateCube()
EntityTexture(cube, tex): PositionEntity(cube,-3,3,+2): ;PointEntity(cube,camera)
EntityTexture(mesh, tex)

RenderWorld
Flip

WaitKey()
End

Function GetMeATexture()
Local tex = CreateTexture(64,64),x,y
LockBuffer(TextureBuffer(tex))
SetBuffer(TextureBuffer(tex))
For x=0 To 63
For y=0 To 63
WritePixelFast(x,y,$FF*$1000000 + $F0*$10000 + ((4*x) Mod 255)*$100 + ((4*y) Mod 255))
Next
Next
UnlockBuffer(TextureBuffer(tex))
SetBuffer BackBuffer()
Return tex
End Function
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

BIG BUG

BeitragDo, Okt 20, 2011 18:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Genau, eine UV-Koordinate kann auch größer als 1 sein, die Textur wird dann entsprechend oft wiederholt.
z.B. Auf einer 2x1 Fläche müssten die UV koordinaten also auch von 0-2 auf der langen(2 Tiles) bzw von 0-1(1 Tile) auf der kurzen Seite gehen um die Textur gleichmäßig zu skalieren...
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)

Jan_

Ehemaliger Admin

BeitragDo, Okt 20, 2011 20:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke Xeres für die Erwähnung.

in meinen Tilecreator mache ich es so:
BlitzMax: [AUSKLAPPEN]
			Case MCUBE%
If (v[0].y=v[1].y) And (v[2].y=v[1].y) Then
For Local i%=0 To 2
v[i].uv(v[i].x-0.5,v[i].z-0.5)
Next
Else
For Local i%=0 To 2
v[i].uv(v[i].x+v[i].z,v[i].y+0.5)
Next
EndIf


beim if, sind alle auf der gleichen Y-Ebene, darum ein UV-set, welches planar von oben gesehen ist.
beim else, alle anderen Flächen.
Wie man sieht,
Code: [AUSKLAPPEN]
u=x+z
v=y

das klappt sehr gut.
between angels and insects
 

PhillipK

BeitragDo, Okt 20, 2011 20:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie schon erwähnt, können U/V koordinaten auch größer als 1 sein.

Dir bleibt nichts anderes übrig, als mit Zettel und stift die genauen größen auszurechnen, falls es kein "simples" Haus ist.

Danach kannst du ein wenig rumspielen - wichtig ist allerdings, das deine Mauer eine eigene Textur ist! Andernfalls muss eine andere lösung her.

Lösung 1: Eine Textur ist nur Mauer
Ansatz: Zb Vertexposition / 50 als U/V koords nehmen. Z muss entsprechend anders eingepflegt werden (Aber ich nehme nicht an, das dein Haus schräge aussenmauern hat!)

Lösung 2: Dein Haus hat eine einzige Textur, wo dachziegel, regenrinne, steinmauer, fenster etc drauf sind.
Ansatz: Hier musst du wohl oder übel ein paar mehr vertices spendieren.
Dazu musst du deine mauer in Triangles oder Quads unterteilen und die passenden UV's zuweisen - die position musst du allerdings nochmals genauer bestimmen.
Ist ein "Teil" deiner mauer kleiner als deine wunschgröße, so muss die UV koordinate einer seite entsprechend angepasst werden. Ansonsten kannst du zb 1x1 Mauerstücke mit der Textur bekleistern.
Ist das mauerstück aber nur 0.5x1 groß, so musst du die UV Koordinaten der Linken/Rechten seite um (breite des Texturausschnittes) *0.5 verschieben.

Ein genaues beispiel kann ich dir leider grade nicht geben, hoffentlich hast du es auch so verstanden :3

Zum 3d Programm:
es ist löblich, das du das ganze Hardcoded im Programm schreiben möchtest, allerdings sind die dinger nicht nur zum Mesh erstellen gut.
Ich finde, man lernt sehr gut, wenn man zb in Blender einfach mal versucht, einen Würfel zu UVMappen.

Mit ein wenig eigeninitiative (nicht böse gemeint, aber das braucht man bei blender, um reinzukommen *g*) lernt man dann ziemlich schnell, wie sich ein Mesh verhält.
Also - mit einem solchen 3d-Modeller rumspielen ist nicht zu verachten - solltest du eins vorrätig haben, versuch doch einfach mal deine Mauer darin nachzustellen.

Midimaster

BeitragFr, Okt 21, 2011 10:07
Antworten mit Zitat
Benutzer-Profile anzeigen
@Xeres

ja, so mach ich auch schon. Das bedeutet aber, dass bei jedem "Ziehen" des Users am Objekt alle diese UV-Koordinaten "von Hand" neu berechnet werden müssen.

Es gibt also scheinbar kein Flag, dass die UV-Koordinaten synchron mit den Vertext-Koordinaten anwachsen lässt?

user posted image

BlitzBasic: [AUSKLAPPEN]
Graphics3D(800,600,0,2)
SetBuffer BackBuffer()
Local camera = CreateCamera()
Local light = CreateLight()
PositionEntity camera, 0, 0, - 5
RotateEntity light, 90, 0, 0
AmbientLight 255,2552,255
Local mesh = CreateMesh()
Local surface = CreateSurface(mesh)
Local v0 = AddVertex(surface, -1, 1, 0, 0, 2) ;* Oben Links
Local v2 = AddVertex(surface, -1, -1, 0, 0,0) ;* Links
Local v1 = AddVertex(surface, 1, -1, 0, 2,0) ;* Rechts
Local v3 = AddVertex(surface, 1, 1, 0, 2, 2) ;* Oben rechts

AddTriangle(surface, v0, v1, v2)
AddTriangle(surface, v3, v1, v0)
UpdateNormals mesh

Local tex = LoadTexture("wand.png")

EntityTexture(mesh, tex)
MoveEntity mesh,0,-2,0

add#=0.01
Repeat
;DebugLog VertexX(Surface,0) + " " + VertexU(Surface,0) + " " + VertexV(Surface,0)
;DebugLog VertexX(Surface,0) + " " + VertexU(Surface,3) + " " + VertexV(Surface,3)
RenderWorld
Flip 1
VertexCoords Surface ,0 , VertexX(Surface,0) ,VertexY(Surface,0)+add,VertexZ(Surface,0)
VertexTexCoords Surface ,0 , 0 ,1+VertexY(Surface,0)

VertexCoords Surface ,3 , VertexX(Surface,3) ,VertexY(Surface,0),VertexZ(Surface,3)
VertexTexCoords Surface ,3 , 2 ,1+VertexY(Surface,3)

;WaitKey()

Until KeyHit(1)

End



@PhillipK
ich habe Blender und TrueSpace sowie Sketchup. Das sit nicht das Problem Ich würde aber gerne ein "Hauserstellungsprogramm" schreiben, das massenweise ähnliche Häuser herstellen kann.

@alle
was genau bewirkt eigentlich der Befehl:

BlitzBasic: [AUSKLAPPEN]
UpdateNormals mesh


???
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Jan_

Ehemaliger Admin

BeitragFr, Okt 21, 2011 10:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Update normals macht ein update aller Vertices im Mesh. Es berechnet die Normelen so, dass sie im 90 Grad Winkel auf dem Vertice stehen zur Eben die den Durchschnitt aller angrenzenden Ebenen Bildet.
Durch die Normalen kann dann ein softshading erfolgen.

user posted image
bei Fast oben, sieht man z.B. eine kante über den scheinwerfern.

Hier mal eine falsche Normal Setzung:
user posted image
(Rechts, normale senkrecht zur eben, des Polygon; Links, nur ebenen in Reihe beachtet.)

Lg. Jan
between angels and insects

Midimaster

BeitragFr, Okt 21, 2011 12:12
Antworten mit Zitat
Benutzer-Profile anzeigen
ah! danke! dann hat das mehr mit Licht zu tun!

Das ist dann auch einer der Gründe, warum ein BB-Cube 24 Vertices und nicht wie zu erwarten wäre 8 hat?

So existieren an jeder Ecke 3 Vertices, wo jeder für die dazugehörende Seitenfläche die richtige Ausrichtung hat.

Also sollte ich bei dem Haus-Modell auch lieber jede Wand mit "eigenen" Ecken versehen. Ist es dann vielleicht sogar sinnvoll gleich mit Cubes für die Wänden zu arbeiten? Dann hätte man auch gleich immer eine "Wandstärke". Ab wieviel Tausend Cubes ist hier mit Performance-Einbrüchen zu rechnen?

Ah! Mein Uralt-Notebook stößt bei 5.000 Cubes und 10FPS bereits an seine Grenze (100% Auslastung):
BlitzBasic: [AUSKLAPPEN]
Graphics3D(800,600,0,2)
SetBuffer BackBuffer()
Local camera = CreateCamera()
AmbientLight 255,2552,255

For i=0 To 5000
cube=CreateCube()
;cube=CreateQuad()
MoveEntity cube, Rand(-100,100), Rand(-100,100),Rand(0,1000)
EntityColor cube,Rand(0,255),Rand(0,255),Rand(0,255)
ScaleEntity cube, Rand(5),Rand(5),Rand(5)
Next
fps=CreateTimer(10)
Repeat
RenderWorld
Flip 0
WaitTimer fps
Until KeyHit(1)

End

;Alternative:
Function CreateQuad()
Local mesh=CreateMesh()
Local surface = CreateSurface(mesh)
Local v0 = AddVertex(surface, -1, 1, 0, 0, 2) ;* Oben Links
Local v2 = AddVertex(surface, -1, -1, 0, 0,0) ;* Links
Local v1 = AddVertex(surface, 1, -1, 0, 2,0) ;* Rechts
Local v3 = AddVertex(surface, 1, 1, 0, 2, 2) ;* Oben rechts

AddTriangle(surface, v0, v1, v2)
AddTriangle(surface, v3, v1, v0)
UpdateNormals mesh
Return mesh
End Function


Wenn also pro Haus 50 Cubes verbaut wären, dann wäre schon bei 100 Häusern Schluß!
Aber auch mit selbsthergestellten Quads bin ich bei 5.000 schon bei 70% Auslastung. Das bringt auch nicht viel!

Was frißt denn am meisten Leistung? Vertices, Triangles oder Surfaces?


Erstelle ich 5.000 Surfaces auf einem Mesh dann habe ich wieder volle Auslastung. Mache ich 1 Surface mit 5000 Quads bin ich bei nur 17%. Das würde heißen "so wenig Surfaces wie möglich"?

Bis jetzt zeigen meine Tests, dass es gut läuft bei:

600 Häuser (1 Mesh, 1 Surface) mit je 100 Quads
oder
3000 Häuser (1Mesh, 1 Surface) mit je 10 Quads

Also zwei verschiedene Häuser? eines für die Ferne, eines für die Nähe?
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Jan_

Ehemaliger Admin

BeitragFr, Okt 21, 2011 12:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm, die geschwindigkeit hängt nicht an den Vertices sondern an den Surfaces. Wenn du create cube machst, kommt ein neues Surface. eub Surface darf bis zu 32000 Tris haben.
32000 / 14 = 2280 Häuser.
die 2280 Häuser mit 1nen Surface sind warscheinlich kaum langsamer als 200 mit jedes einen eigenen surface.
between angels and insects
 

bjh

BeitragFr, Okt 21, 2011 18:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Jan_ ein surface kann 65536 triangles haben, glaub ich. Wink

Jan_

Ehemaliger Admin

BeitragSa, Okt 22, 2011 9:20
Antworten mit Zitat
Benutzer-Profile anzeigen
bjh, nein 65524 /2 nur.

Jedenfalls bei B3D.
between angels and insects
 

bjh

BeitragSa, Okt 22, 2011 15:54
Antworten mit Zitat
Benutzer-Profile anzeigen
ich mein bei b3d.
jadenfalls funktioniert es bei mir.
das größte meshterrain hat bei mir 181*181=32761 vertexe.
die triangles sind dann 180*180*2=64800.
und das funktioniert.
probiers doch mal aus Wink

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group