Licht/Normals
Übersicht

NoxBetreff: Licht/Normals |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Tag zusammen.
Habe folgendes Problem: Ich baue mir mein Levelmesh selbst zusammen und richte danach auch die Normalen neu aus (UpdateNormals()). Doch einige Triangles werden absolut falsch beleuchtet. Muss ich bei der Reihenfolge der Vertices eines Triangles denn noch was beachten? (außer natürlich, dass sie im Uhrzeigersinn angeordnet sein müssen) Für eine Veranschaulichung hier klicken. Ein Punktlicht ist an die Kamera angehängt. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das sieht für mich aus, als ob du die Wand aus einzelnen Quads gemacht hast.
In diesem Falle wären die Vertexnormalen auch nur für 1 Quad aufgestellt und nicht für die gesamte Wand, weswegen es so falsch aussieht. Um das zu beheben, musst du dafür sorgen, das Vertices, die in 2 Quads vorkommen auch in beiden Quads (also den zugehörigen Triangles) genutzt werden und nicht für jedes Quad neue Vertices erzeugt werden. Dann sollte das auch mit UpdateNormals klappen ![]() |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das ist sch... ![]() Wenn's keinen Weg um deine genannte Methode drumherum gibt, wird das ne ziemlich mühselige Arbeit. ![]() Edit: Und nochwas: Wieso wird die Wand ganz "hinten" beleuchtet, doch der Vorsprung ganz rechts garnicht? Das ist mir irgendwie ganz unlogisch, denn die Normalen zeigen in dieselbe Richtung. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Da bin ich überfragt.
Eigentlich sollten die normalen stimmen, auch bei einzelteilen, da hast du recht. Kannst dir ja sonst mal "Debugobjekte" überall ankleben und dir die Daten ausgeben lassen ... vielleicht läuft auch sonstwas schief. Alternativ gibts auch die Möglichkeit, dass du die Normalen angibst. Da du ja scheinbar nur die 3 Axenrichtungen zulässt, sind das 6 möglichkeiten für die vertexnormalen, du könntest die also bei der Generierung ganz einfach selbst mit rein schreiben. Weisst ja in welche richtung die Wand schaut. *nur für den Fall das UpdateNormals sich nicht mit dem Konstrukt vertragen würde* Alternativ wäre vielleicht ein Code der das Problem zeigt nicht schlecht, für den Fall das da was bogus wäre. (wie meshFX auf double sided geschaltet und so dinge) |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bei Ecken solltest du die Vertices nicht doppelt benutzen .
Also wie in deinem Level Decke,Wand links und Wand hinten etc. trennen weil die Normalen ja je Punkt gelten . |
||
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Dreamora hat Folgendes geschrieben: Alternativ gibts auch die Möglichkeit, dass du die Normalen angibst.
Das müsste ich dann mal ausprobieren, jepp. Falls es daran liegen sollte, kann man UpdateNormals() also getrost in die Tonne kloppen.. ![]() Zitat: Alternativ wäre vielleicht ein Code der das Problem zeigt nicht schlecht, für den Fall das da was bogus wäre. (wie meshFX auf double sided geschaltet und so dinge)
Kann ich gerne hier pasten. Was genau ist gewünscht? Vorab kann ich jedoch schonmal sagen, dass ich kein MeshFX oder sonstiges genutzt habe. Erstelle lediglich die einzelnen Vertices und verbinde sie zu jeweils zwei Dreiecken, das war's. Markus2 hat Folgendes geschrieben: Bei Ecken solltest du die Vertices nicht doppelt benutzen .
Also wie in deinem Level Decke,Wand links und Wand hinten etc. trennen weil die Normalen ja je Punkt gelten. Wenn ich dich jetzt richtig verstanden habe, dann lautet die Antwort "Mach ich nich". ![]() Vielleicht macht's das Bild hier ein bisschen klarer (jedes Quad ist einzeln, deutlich durch versch. Farben) ![]() Was mich ja total daran wundert ist, dass die ganze Wand nach demselben Prinzip aufgebaut wird. Und sofern die Textur übereinstimmt, wird das alles auch in ein Surface gepresst, d.h. völlig identische Quads..aber falsche Beleuchtung. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Naja das UpdateNormals nicht die hellste Funktion ist, ist bekannt.
Fredborg musste für Gile[s] eine eigene Funktion schreiben, weil die von Blitz zuviele Dinge einfach "vergisst" beim erzeugen der Normalen ... |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
UpdateNormals ist nur für runde Objekte geeignet. Für eckige Sachen kannste folgende Funktion benutzen(geht noch ein bisschen einfacher, da man auch direkt das Kreuzprodukt von v1-2 und v1-3 bilden könnte):
Code: [AUSKLAPPEN] Function UpdateNormalsFlat(mesh) Local surface, mesh_surface, faktor# Local v1, v2, v3 Local ax#, ay#, az# Local lx#, ly#, lz# Local nx#, ny#, nz# For mesh_surface = 0 To CountSurfaces(mesh) surface=GetSurface(mesh,mesh_surface) For triangle = 0 To CountTriangles(surface)-1 v1 = TriangleVertex(surface, triangle, 0) v2 = TriangleVertex(surface, triangle, 1) v3 = TriangleVertex(surface, triangle, 2) ;Achse durch v1 als Vektor lx# = -((VertexX#(surface,v3) + VertexX#(surface,v2))/2-VertexX#(surface,v1)) ly# = -((VertexY#(surface,v3) + VertexY#(surface,v2))/2-VertexY#(surface,v1)) lz# = -((VertexZ#(surface,v3) + VertexZ#(surface,v2))/2-VertexZ#(surface,v1)) ;Kante von v2 zu v3 als Vektor ax# = VertexX#(surface,v2) - VertexX#(surface,v3) ay# = VertexY#(surface,v2) - VertexY#(surface,v3) az# = VertexZ#(surface,v2) - VertexZ#(surface,v3) ;Kreuzprodukt beider Vektoren nx# = (ly# * az#)-(lz# * ay#) ny# = (lz# * ax#)-(lx# * az#) nz# = (lx# * ay#)-(ly# * ax#) ;Ergebnisvektor auf Laenge 1 bringen faktor# = Sqr((nx# * nx#)+(ny# * ny#)+(nz# * nz#)) nx# = nx# / faktor# ny# = ny# / faktor# nz# = nz# / faktor# VertexNormal surface, v1, nx#, ny#, nz# Next Next End Function |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
@Nox
Jup das hört sich gut an , da die Normalen ja berechnet sind ,laß sie dir mal mit einer 3D Linien Funk. am besten anzeigen . Wenn deine Entitys nicht gedreht wurden geht das relativ einfach . ansonsten einfach erstmal versuchen die Eckpunkte anzeigen zu lassen an der richtigen Stelle . |
||
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@BIG BUG:
Erstmal vielen Dank für den Codeschnippsel. Allerdings habe ich - wie du sagtest - direkt das Kreuzprodukt angewandt. Nun aber die Frage: Ist es wirklich notwendig, das Kreuzprodukt von v0*v1 und v0*v2 anzuwenden, oder reicht nicht schon ein v0*v1? Mein Gedanke dabei ist, dass die ganzen Triangles immer gleich ausgerichtet sind. D.h. die Normale zwischen v0 und v1 ist auch die Normale von v2 - rechnerisch...mein ich. ![]() Ich zeig einfach mal, wie ich's probiert habe zu lösen (klappt natürlich nicht ![]() Code: [AUSKLAPPEN] Function UpdateNormalsFlat( mesh% ) Local srfMesh% Local srfnum%, trinum% Local v0%, v1%, v2% Local nx#, ny#, nz#, norm# Local v0x#, v0y#, v0z#, v1x#, v1y#, v1z# For srfnum% = 1 To CountSurfaces( mesh% ) srfMesh% = GetSurface( mesh%, srfnum% ) For trinum% = 0 To CountTriangles( srfMesh% ) - 1 v0% = TriangleVertex( srfMesh%, trinum%, 0 ) v1% = TriangleVertex( srfMesh%, trinum%, 1 ) v2% = TriangleVertex( srfMesh%, trinum%, 2 ) v0x# = VertexX( srfMesh%, v0% ) ; Nur zur besseren Lesbarkeit.. v0y# = VertexY( srfMesh%, v0% ) v0z# = VertexZ( srfMesh%, v0% ) v1x# = VertexX( srfMesh%, v1% ) v1y# = VertexY( srfMesh%, v1% ) v1z# = VertexZ( srfMesh%, v1% ) nx# = v0y# * v1z# - v0z# * v1y# ; Kreuzprodukt zwischen v0 und v1. ny# = v0x# * v1z# - v0z# * v1x# nz# = v0x# * v1y# - v0y# * v1x# ; Normalisierungsfaktor bestimmen. norm# = Sqr( nx# * nx# + ny# * ny# + nz# * nz# ) nx# = nx# / norm# ; ...und normalisieren. ny# = ny# / norm# nz# = nz# / norm# ; Normale auf alle Vertices anwenden. VertexNormal( srfMesh%, v0%, nx#, ny#, nz# ) VertexNormal( srfMesh%, v1%, nx#, ny#, nz# ) VertexNormal( srfMesh%, v2%, nx#, ny#, nz# ) Next Next End Function |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Es gibt keine normale zwischen v0 und v1
Was du machen musst ist: (v0-v1) X (v0-v2) (oder sonstwie, da das immer aufs gleiche raus kommt da kommutativ) Damit erhälst du die Normale des Triangles, was ja bei etwas flachem auch den VertexNormalen entspricht. Das entspricht auch dem was BigBug schrieb. Das Kreuzprodukt der Vertexpositionen macht dabei keinen Sinn, da diese rein garnichts mit dem Triangle zu tun haben, da keiner der beiden Vektoren überhaupt in der Triangle Ebene zu liegen braucht (und normalerweise auch nicht wird) |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Dreamora hat Folgendes geschrieben: Das Kreuzprodukt der Vertexpositionen macht dabei keinen Sinn, da diese rein garnichts mit dem Triangle zu tun haben, da keiner der beiden Vektoren überhaupt in der Triangle Ebene zu liegen braucht (und normalerweise auch nicht wird)
Okay das leuchtet mir ein, danke. Gesagt, getan: Die Normalen sind korrekt ausgerichtet, allerdings nicht von allen Triangles. Wie im o.g. Code zu sehen, iteriere ich durch sämtliche Triangles aller Surfaces. Doch komischerweise wird immer nur ein Triangle eines Quads berücksichtigt. Ob das nun an meiner Rechnung liegt oder an der Iteration, kann ich mir nicht beantworten. Zuerst ein Bildchen: ![]() Sehr gut zu sehen auf dem Bild ist der Effekt an den Decken- und Wandquads. Ich nehme mir mal die Freiheit, einfach nochmal die Funktion zu pasten. Vielleicht findet ihr meinen Fehler.. Code: [AUSKLAPPEN] Function UpdateNormalsFlat( mesh% ) Local srfMesh% Local srfnum%, trinum% Local v0%, v1%, v2% Local nx#, ny#, nz#, norm# Local v0x#, v0y#, v0z#, v1x#, v1y#, v1z# Local v01x#, v01y#, v01z#, v02x#, v02y#, v02z# For srfnum% = 1 To CountSurfaces( mesh% ) srfMesh% = GetSurface( mesh%, srfnum% ) For trinum% = 0 To CountTriangles( srfMesh% ) - 1 v0% = TriangleVertex( srfMesh%, trinum%, 0 ) v1% = TriangleVertex( srfMesh%, trinum%, 1 ) v2% = TriangleVertex( srfMesh%, trinum%, 2 ) v0x# = VertexX( srfMesh%, v0% ) ; Nur zur besseren Lesbarkeit.. v0y# = VertexY( srfMesh%, v0% ) v0z# = VertexZ( srfMesh%, v0% ) v1x# = VertexX( srfMesh%, v1% ) v1y# = VertexY( srfMesh%, v1% ) v1z# = VertexZ( srfMesh%, v1% ) v01x# = v0x# - v1x# v01y# = v0y# - v1y# v01z# = v0z# - v1z# v02x# = v0x# - v2x# v02y# = v0y# - v2y# v02z# = v0z# - v2z# ; Kreuzprodukt zwischen (v0 - v1) und (v0 - v2). nx# = v01y# * v02z# - v01z# * v02y# ny# = v01x# * v02z# - v01z# * v02x# nz# = v01x# * v02y# - v01y# * v02x# ; Normalisierungsfaktor bestimmen. norm# = Sqr( nx# * nx# + ny# * ny# + nz# * nz# ) nx# = nx# / norm# ; ...und normalisieren. ny# = ny# / norm# nz# = nz# / norm# ; Normale auf alle Vertices anwenden. VertexNormal( srfMesh%, v0%, nx#, ny#, nz# ) VertexNormal( srfMesh%, v1%, nx#, ny#, nz# ) VertexNormal( srfMesh%, v2%, nx#, ny#, nz# ) Next Next End Function |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das ist einer der Fälle bei dem ich weiss warum BM >>>> B3D
BM würde dir jetzt nämlich sagen: V2x/y/z existieren nicht ![]() Sprich dort kommt immer 0 womit die gesamte Rechnung schief kommt, weswegen die Triangles so komisch aussehen. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
- Zuletzt bearbeitet von Dreamora am Mi, Jul 19, 2006 12:23, insgesamt einmal bearbeitet
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Verdammte §$%&=("&. Ich geb dir ja sowas von Recht. Ne Art Option Explicit wäre verdammt angebracht. ![]() |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nö ... wird jetzt aber gleichmässig falsch sein ![]() NY ist noch falsch. Dort müsste das negative des jetzigen stehen (also v1z*v2x - v1x*v2z ). Dann müsste es eigentlich stimmen ![]() |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
![]() Jap, das ist mir auch aufgefallen, als ich sah, dass zwar alle Wände korrekt beleuchtet werden, aber Boden und Decke nicht, da die Normalen immer genau in die entgegengesetzte Richtung zeigten. =) Vielen Dank euch für die Hilfe, hat mir super weitergeholfen - und schließlich klappt jetzt auch alles. Merci. =) |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group