[opengl/glut]falsche schattierung



  • 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:

    http://www.manueldewald.de/fehler2.jpg



  • 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--3

    Deinem 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--3

    was 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.5
    

    kann ja eigentlich nur normalenvektor nr 0 sein oder?

    also berechne ich wohl was falsch... fällt jemand was auf?



  • keiner eine idee???



    1. Normalenvektoren sollten die Länge 1 haben! -> Normalisiere zum Schluss!(OBJV)
    2. 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 ?



  • DaHunger schrieb:

    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() *vec!!2!!.getX())-(vec1.getX() * vec2.getZ());
    	normalenVektor[2]=(vec1.getX() * vec2.getY())-(vec1.getY() * vec!!2!!.getX());
    	                                   
    	ObjektVektor erg(normalenVektor[0],normalenVektor[1],normalenVektor[2]);
    	return erg;
    }
    

    meiner meinung nach absolut richtig...

    weiß da jemand nen fehler ?

    Ich hab mal Ausrufezeichen um deinen C&P Fehler gemacht! 😉



  • ui wie doof

    da steht ein paar mal vec1 wo vec2 hingehört ^^

    richtig gehört die funktion also so:

    ObjektVektor Objekt::kreuzProdukt(ObjektVektor vec1, ObjektVektor vec2){
    	GLfloat normalenVektor[3];
    	normalenVektor[0]=vec1.getY() * vec2.getZ()-vec1.getZ() * vec2.getY();
    	normalenVektor[1]=vec1.getZ() * vec2.getX()-vec1.getX() * vec2.getZ();
    	normalenVektor[2]=vec1.getX() * vec2.getY()-vec1.getY() * vec2.getX();
    
    	ObjektVektor erg(normalenVektor[0],normalenVektor[1],normalenVektor[2]);
    	return erg;
    }
    

    falls es jemand interessiert 😉

    EDIT:
    oh hab die 3. seite nich entdeckt und auch den fehler gefunden danke ^^



  • jetzt is alles richtig schattiert

    Person ich;
    ich.swear("Ich werde nie wieder copy und paste benutzen.");
    

Anmelden zum Antworten