[opengl/glut]falsche schattierung
-
hi,
ich habe mir eine funktion geschrieben die automatisiert normalenvektoren zu einem haufen vertizen(in dreiecken gruppiert) berechnet. es scheint auch teilweise gut zu laufen aber irgendwas ist da falschrum...ich habe der funktion 2 dreiecke als rechteck gegeben (im uhrzeigersinn definiert).
allerdings ist das eine dreieck irgendwie spiegelverkehrt schattiert...
kann mir jemand einen tipp geben was ich falsch gemacht haben könnte?
so schaut der fehler aus: (orange eingerahmt)
-
ich vermute mal, dass du aufgrund deiner berechnung für den gleichen vertex 2 unterschiedliche normalenvektoren bekommst.
du musst natürlich den normalenvektor für jedes vertex immer gleich berechnen bzw. du berechnest ihn nur einmal für jedes vertex.
-
visualisier doch mal die normalen mit linien, dann kann man viel eher sehen was los ist, das sie kaputt sind scheint eindeutig zu sein, nur wie, hmm... geflippt, rechenfehler, dreiecke geneigt zueinander usw.
-
also
es sind 2 getrennte 3ecke
jeder vertex hat also sein eigenen normalenvektor
wie soll ich die sichtbar machen?
-
1.Wie berechnest du deine Normalenvektoren, wenn das zwei getrennte dreiecke sind?
2.Visualisieren der Normalen (ein bissl Pseudocode):
glBegin(GL_LINES); glVertex3fv(vertex[i]); glVertex3fv(vertex[i]+normal[i]); glEnd();
-
ok ich probiers mal aus
-
das ergebnis sieht in der tat sehr interessant aus:
ein vektor geht in die andere Richtung, die anderen scheinen orthogonal zu sein
wieder ein bild:
-
gut dieses problem hab ich behoben jetzt stehen die normalenvektoren alle senkrecht zu meinem viereck.
aber geshadet is immernoch nich richtig:
http://www.manueldewald.de/fehler3.jpg
achso mein fehler war:
i+1%3
is nich (i+1)%3
dummer fehler....
ncoh jemand ne idee was ich falsch machen könnte?
EDIT:
die normalenvektoren berechne ich folgendermaßen:
ich habe ein array von dreiecken...
für jedes vertex i
(vertex[i] - nächsten vertex im uhrzeigersinn) KREUZ (vertex[i] - nächsten vertex GEGEN den uhrzeigersinn)jeweils im dreieck herum halt
-
Die Normalen an den gemeinsamen Knoten können nich identisch sein.... Wenn sie identisch wären hättest du keine scharfe kante zwischen beiden dreiecken.
zeig mal den code, wo die dreiecksknoten gesetzt/gezeichnet und die normalen berechnet/gezeichnet werden.
-
wie die können nicht identisch sein, müssen sie nicht identisch sein?
und was willst du haben?
EDIT:
hier die koordinaten von den Dreiecken:
vertices[0] =ObjektVektor(-1.0, -1.0, 1.0 ); vertices[1] =ObjektVektor(-1.0, 1.0, 1.0 ); vertices[2] =ObjektVektor(1.0, 1.0, 1.0 ); vertices[3] =ObjektVektor(-1.0, -1.0, 1.0 ); vertices[4] =ObjektVektor(1.0, 1.0, 1.0 ); vertices[5] =ObjektVektor(1.0, -1.0, 1.0 );
-
Du möchtest doch bestimmt, dass man die kante zwischen den beiden dreiecken nicht
sieht:0--1
|\ |
| \|
2--3Deinem Screenshot nach definierst du aber bei Vertex "0", den du ja zweimal zeichnen musst, nicht die gleiche normale.
(Gleiche Normale = Gleiche Farbe)
-
erm,
jetzt bin ich etwas überfordert....an vertex 0 geht doch nur eine linie ab,
also scheint der normalenvektor doch gleich zu sein oder?megaweber schrieb:
0--1
|\ |
| \|
2--3was meinst du damit?
und nunja die berechnung erfolgt automatisch und ich weiß nich warum der normalenvektor nicht gleich ist... vielleicht mach ich was falsch aber was??
hier der algorithmus der dies tun sollte:
for(int i=0;i<numNormalVertices;i++){ ObjektVektor objV,vec1,vec2,vec3; if(i%3!=0 && i!=0 && (i+1)%3!=0){ vec1=normalisiere(vertices[i]); vec2=normalisiere(vertices[i+1]); vec3=normalisiere(vertices[i-1]); }else if(i==0 || i%3==0){ vec1=normalisiere(vertices[i]); vec2=normalisiere(vertices[i+1]); vec3=normalisiere(vertices[i+2]); }else if((i+1)%3==0){ vec1=normalisiere(vertices[i]); vec2=normalisiere(vertices[i-2]); vec3=normalisiere(vertices[i-1]); } objV=kreuzProdukt(substrahiereVektoren(vec1,vec2),substrahiereVektoren(vec1,vec3)); //GLfloat laenge=sqrt(pow(objV.getX(),2)+pow(objV.getY(),2)+pow(objV.getZ(),2)); //ObjektVektor normalisiertObjV(objV.getX()/laenge,objV.getY()/laenge,objV.getZ()/laenge); normalVertices[i]=objV; }hab ich mir selbst zusammengebastelt, aber eigentlich sollte es stimmen...
-
for(int i=0;i<numNormalVertices;i++){ ObjektVektor objV,vec1,vec2,vec3; if(i%3!=0 && i!=0 && (i+1)%3!=0){ vec1=vertices[i]; //<--- vec2=vertices[i+1];//<--- vec3=vertices[i-1];//<--- }else if(i==0 || i%3==0){ vec1=vertices[i]);//<--- vec2=vertices[i+1];//<--- vec3=vertices[i+2];//<--- }else if((i+1)%3==0){ vec1=vertices[i];//<--- vec2=vertices[i-2];//<--- vec3=vertices[i-1];//<--- } vec4 = subtrahiere(vec1,vec2);//<--- vec5 = subtrahiere(vec1,vec3);//<--- objV=kreuzprodukt(vec4,vec5);//<--- //objV=kreuzProdukt(substrahiereVektoren(vec1,vec2),substrahiereVektoren(vec1,vec3)); //GLfloat laenge=sqrt(pow(objV.getX(),2)+pow(objV.getY(),2)+pow(objV.getZ(),2)); //ObjektVektor normalisiertObjV(objV.getX()/laenge,objV.getY()/laenge,objV.getZ()/laenge); normalVertices[i]=objV; }Du darfst natürlich erst die Vektoren von vec1 zu vec2 bzw vec1 zu vec3 normalisieren!!!!!
Probier das mal aus!
-
omg wird gemacht, komm heut aber nimmer dazu
danke wenns hilft
-
also jetzt hab ich das getan,
jetzt sind die normalenvektoren offenbar unterschiedlich lang...aber falsch schattiert ist das ganze immernoch...
hier wieder ein bild:
http://www.manueldewald.de/fehler4.jpg
der jetzige quelltext zum berechnen:
ObjektVektor Objekt::normalisiere(ObjektVektor objV){ GLfloat laenge=sqrt(pow(objV.getX(),2)+pow(objV.getY(),2)+pow(objV.getZ(),2)); ObjektVektor normalisiertObjV(objV.getX()/laenge,objV.getY()/laenge,objV.getZ()/laenge); return normalisiertObjV; } void Objekt::calcNormalVertices(){ normalVertices=new ObjektVektor[numNormalVertices]; for(int i=0;i<numNormalVertices;i++){ ObjektVektor objV,vec1,vec2,vec3; if(i%3!=0 && i!=0 && (i+1)%3!=0){ vec1=vertices[i]; vec2=vertices[i+1]; vec3=vertices[i-1]; }else if(i==0 || i%3==0){ vec1=vertices[i]; vec2=vertices[i+1]; vec3=vertices[i+2]; }else{ //(i+1)%3==0 um warnings zu vermeiden ohne else if(); vec1=vertices[i]; vec2=vertices[i-2]; vec3=vertices[i-1]; } ObjektVektor vec4=normalisiere(substrahiereVektoren(vec1,vec2)); ObjektVektor vec5=normalisiere(substrahiereVektoren(vec1,vec3)); objV=kreuzProdukt(vec4,vec5); //GLfloat laenge=sqrt(pow(objV.getX(),2)+pow(objV.getY(),2)+pow(objV.getZ(),2)); //ObjektVektor normalisiertObjV(objV.getX()/laenge,objV.getY()/laenge,objV.getZ()/laenge); normalVertices[i]=objV; } int x=0; cout << "Errechnen der Vertices: " << endl; cout << x << ": " << normalVertices[x].getX(); cout << ", " << normalVertices[x].getY(); cout << "," << normalVertices[x].getZ() ; cout << endl; gibAusNormalenvektor(0); }hier die koordinaten der errechneten Normalenvektoren, vllt fällt jemand da ein fehler auf:
Normalenvektor Nr 0: 0, 0,0 Normalenvektor Nr 1: 0, 0,-1 Normalenvektor Nr 2: 0, 0,-0.5 Normalenvektor Nr 3: -0, 0,-0.5 Normalenvektor Nr 4: 0, 0,0 Normalenvektor Nr 5: 0, 0,-1
-
ok, folgende neue erkenntnis:
http://www.manueldewald.de/fehler5.jpg
ich hab mal ein einzelnes Dreieck losgeschickt.
Die schwarze ecke davon (schwer zu erkennen im bild)
hat offenbar keinen normalenvektor.
es wird zumindest keiner gezeichnet.Normalenvektor Nr 0: 0, 0,0 Normalenvektor Nr 1: 0, 0,-1 Normalenvektor Nr 2: 0, 0,-0.5kann ja eigentlich nur normalenvektor nr 0 sein oder?
also berechne ich wohl was falsch... fällt jemand was auf?
-
keiner eine idee???
-
- Normalenvektoren sollten die Länge 1 haben! -> Normalisiere zum Schluss!(OBJV)
- Ein Nullvektor entsteht bei einem Kreuzprodukt zwischen zwei Vektoren die linear abhängig sind! Das sollte bei einem Dreieck, dass nicht zu einer Linie degeneriert ist, nie der Fall sein! -> Überprüfe deine Berechnung von Vec1-5 (Debugger)!!!
Für dein(e) Dreieck(e) sollten alle Normalenvektoren identisch sein!!!!
-
wie alle identisch sein...
hmm was mach ich denn dann falsch?die dreiecke (siehe oben) sind dreieckig und nicht zu geraden abgestiegen...
-
also ich hab gerade herausgefunden, dass mein kreuzprodukt nicht richtig funktioniert.
hier der code
ObjektVektor Objekt::kreuzProdukt(ObjektVektor vec1, ObjektVektor vec2){ GLfloat normalenVektor[3]; normalenVektor[0]=(vec1.getY() * vec2.getZ())-(vec1.getZ() * vec2.getY()); normalenVektor[1]=(vec1.getZ() *vec1.getX())-(vec1.getX() * vec2.getZ()); normalenVektor[2]=(vec1.getX() * vec2.getY())-(vec1.getY() * vec1.getX()); ObjektVektor erg(normalenVektor[0],normalenVektor[1],normalenVektor[2]); return erg; }meiner meinung nach absolut richtig...
weiß da jemand nen fehler ?