Blending und Licht



  • Kann ich dann die Helligkeit der Texturen einfach mit den normalen angeben?
    (Das klappt irgendwie nicht)
    Oder muß ich aus den normalen und der Position und Richtung der Lichtquelle die Helligkeit selbst berechnen?

    Hier mal der Code mit dem ich zeichne (Nicht lachen, ich mache das nur als Hobby)
    Hinweis.
    Eine Kachel steht für die Kleinste zu zeichnende Einheit und beinhaltet die Angaben um 2 Dreiecke zeichnen zu können(Koordinaten , Textur , normale,...)

    void zeichne(Vector3D position,long sichtweite)
    	{
    
    		//Durchlaufe alle Kacheln
    		for (long x=linker_rand;x<rechter_rand;x++){
    			for (long y=unterer_rand;y<oberer_rand;y++) {
    
    				glEnable(GL_LIGHTING);
    				int a=1;
    				int b=1;
    				int c=1;
    
    				//berechne, welche Kante welcher Kachel mit anderen Texturen einen
    				//weichen übergang bilden sollen(Für das 1. Teildreieck)
    				if (x>0 && y>0 && x< breite-2 && y< laenge-2)
    				if (kachel[x][y].get_textur()!=kachel[x-1][y-1].get_textur() ||kachel[x][y].get_textur()!=kachel[x-1][y].get_textur() ||kachel[x][y].get_textur()!=kachel[x][y-1].get_textur() ) 
    				{
    					a=0;
    
    				}
    
    				//berechne, welche Kante welcher Kachel mit anderen Texturen einen
    				//weichen übergang bilden sollen(Für das 1. Teildreieck)
    
    				if (x>0 && y>0 && x< breite-2 && y< laenge-2)
    				if (kachel[x][y].get_textur()!=kachel[x][y-1].get_textur() ||kachel[x][y].get_textur()!=kachel[x+1][y-1].get_textur() ||kachel[x][y].get_textur()!=kachel[x+1][y].get_textur() ) 
    				{
    					b=0;
    
    				}
    
    				//berechne, welche Kante welcher Kachel mit anderen Texturen einen
    				//weichen übergang bilden sollen(Für das 1. Teildreieck)
    
    				if (x>0 && y>0 && x< breite-2 && y< laenge-2)
    				if (kachel[x][y].get_textur()!=kachel[x-1][y].get_textur() ||kachel[x][y].get_textur()!=kachel[x-1][y+1].get_textur() ||kachel[x][y].get_textur()!=kachel[x][y+1].get_textur() ) 
    				{
    				c=0;	
    				}
    
    				if (a==0 || b==0 || c==0) {
    			//	glDisable(GL_LIGHTING);
    				}
    
    				//Textureinheit 0 aktivieren
    				glActiveTextureARB(GL_TEXTURE0_ARB);
    				//2D Texturing aktivieren
    				glEnable(GL_TEXTURE_2D);
    				//?? Keine Ahnung, stand so im Tutorial :)
    				glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    
    				//Passende Textur laden
    				glBindTexture(GL_TEXTURE_2D, textur[kachel[x][y].get_textur()].get_texture());
    
    				//Wenn die Kachel im Frustum liegt
    				if ((kachel[x][y].get_Frustum()) || (kachel[x+1][y].get_Frustum()) || (kachel[x][y+1].get_Frustum()))
    				{	
    					//Zeichne das erste Dreieck der Kachel
    					glBegin(GL_TRIANGLES);
    					//Auswaehlen ob die erste Ecke duch die andere Textur überlagert werden soll
    					glColor4f(1,1,1,a);
    					//Normale zur Lichtberechnung angeben
    					glNormal3f(kachel[x][y].get_normale1().get_x(),kachel[x][y].get_normale1().get_y(),kachel[x][y].get_normale1().get_z());
    					//Koordinaten innerhalb der Textur angeben. Koordinaten des Dreiecks angeben
    					glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f, 0.0f); glVertex3d(x,      y,     kachel[x][y].get_hoehe());
    
    					//genauso für 2. Kante
    					glColor4f(1,1,1,b);
    					glNormal3f(kachel[x][y].get_normale2().get_x(),kachel[x][y].get_normale2().get_y(),kachel[x][y].get_normale2().get_z());
    					glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f, 0.0f); glVertex3d(x+1,    y,     kachel[x+1][y].get_hoehe());
    
    					//genauso für 3. Kante
    					glColor4f(1,1,1,c);
    					glNormal3f(kachel[x][y].get_normale3().get_x(),kachel[x][y].get_normale3().get_y(),kachel[x][y].get_normale3().get_z());
    					glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f, 1.0f); glVertex3d(x,    y+1,     kachel[x][y+1].get_hoehe());					
    					glEnd();
    				}
    
    				glDisable(GL_TEXTURE_2D);
    
    				//Wenn eine Kante zu einer anderen Textur weich gezeicnet werden soll,
    				//Blending aktivieren
    				if (a==0 || b==0 || c==0) {
    				blending1(x,y,a,b,c);
    				}
    ///////Analog für das 2. Dreieck der Kachel
    }
    

    Hier der Code mit dem ich das Blending versuche 😃

    void blending1(long x, long y,int d,int e,int f,float helligkeit )
    	{
    		if (d==1){d=0;} else {d=1;}
    		if (e==1){e=0;} else {e=1;}
    		if (f==1){f=0;} else {f=1;}
    
    		//Textureinheit 1 aktivieren
    		glActiveTextureARB(GL_TEXTURE1_ARB);
    		//Licht abschalen )Ist nötig, da das Blending anscheinend sonst nicht funktioniert)
    		glDisable(GL_LIGHTING);
    		//2D Texturing aktivieren
    		glEnable(GL_TEXTURE_2D);
    		//?? Keine Ahnung, stand so im Tutorial :)
    		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    		//Blending einschalten
    		glEnable(GL_BLEND);
    
    		//Blending funktion aktivieren
    		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    
    		//gegenteilige Textur aktivieren
    		if (kachel[x][y].get_textur()==0)
    		{
    			glBindTexture(GL_TEXTURE_2D, textur[1].get_texture());			//Textur 2 laden
    		}
    
    		if (kachel[x][y].get_textur()==1)
    		{
    			glBindTexture(GL_TEXTURE_2D, textur[1].get_texture());			//Textur 2 laden
    		}
    
    		//Dreieck zeichnen, bei dem Blending angewendet werden soll
    		glBegin(GL_TRIANGLES);
    
    			glColor4f(1.0f,1.0f,1.0f,d);
    			glNormal3f(kachel[x][y].get_normale1().get_x(),kachel[x][y].get_normale1().get_y(),kachel[x][y].get_normale1().get_z());
    			glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f, 0.0f); glVertex3d(x,      y,     kachel[x][y].get_hoehe());
    
    			glColor4f(1.0f,1.0f,1.0f,e);
    			glNormal3f(kachel[x][y].get_normale2().get_x(),kachel[x][y].get_normale2().get_y(),kachel[x][y].get_normale2().get_z());
    			glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f, 0.0f); glVertex3d(x+1,    y,     kachel[x+1][y].get_hoehe());
    
    			glColor4f(1.0f,1.0f,1.0f,f);		
    			glNormal3f(kachel[x][y].get_normale3().get_x(),kachel[x][y].get_normale3().get_y(),kachel[x][y].get_normale3().get_z());
    			glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f, 1.0f); glVertex3d(x,    y+1,     kachel[x][y+1].get_hoehe());					
    
    		glEnd();
    		//Einstellungen wieder rückgängig machen
    		glDisable(GL_TEXTURE_2D);
    		glDisable(GL_BLEND);
    		glEnable(GL_LIGHTING);
    	}
    

    So sieht es aus ohne blending (scharfe Kanten):
    http://www.pictureupload.de/pictures/070807152333_Beispiel.JPG

    Etwas genauer:
    Link: http://www.pictureupload.de/pictures/070807152452_1Beispiel.JPG

    Nun mit Blending (Textur ist zu hell bei den Übergängen, da wo Schatten ist)
    Link: http://www.pictureupload.de/pictures/070807152634_2Beispiel.JPG

    Was muß ich anders machen?



  • generell scheint mir das problem nicht beim blending selbst su liegen, sondern vielmer scheint der fehlende schatten das problem zu sein, wie wird der denn berechnet? wenn du schadowmapping verwendest, wo ja öfters mal blending verwendet wird 😉 , kann es ja sein, dass sich das irgendwie überlagert.


  • Mod

    mir schein auch so als ob an den betreffenden stellen einfach der schatten fehlt, an der wand links scheint auch ploetzlich kein schatten mehr zu sein.



  • Ne die Schattenberechnung ist unabhängig davon. Ich berechne von jeder kachel ne gerade zur sonne (Lichtquelle) und prüfe, ob die irgenwo niedriger ist als der Boden an der selben Stelle. Wenn ja dann setze ich die normale der Kachel senkrecht zu den "Strahlen" der Lichtquelle.

    Links das große ist kein Haus, sondern Boden, den ich dort steil ansteigen lasse. Da dann dort auch ein Übergang von Fels zu Gras ist, wird auch an dieser "Wand" das blending angewendet und auch diese Stelle wird zu hell, genau wie der Streifen im Schatten den man sieht.

    Wenn ich die blending1 Methode ausklammere stimmt der Schatten ja.
    (Und die methode list ja nur und verändert an den normalen zur Schattenberechnung nichts.)

    Wenn ich das normale Dreieck und das darüber geblendete beide mit Licht zeichne, funktioniert das Blending überhaupt nicht mehr und es sieht wieder aus wie ohne.Zeichne ich eins mit Licht, wird der Schatten nicht berücksichtigt.

    Habt iht sonst noch eine Idee? (Ich bastle hier schon seit ner Woche an dem §%&/(E&/&%&/%$ Blending)


  • Mod

    wenn du mit

    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    

    zwei layer blendest die schatten haben, ist es unmoeglich dass dadurch der schatten verschwindet.



  • rapso schrieb:

    wenn du mit

    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    

    zwei layer blendest die schatten haben, ist es unmoeglich dass dadurch der schatten verschwindet.

    Wenn ich beide layer mitSchatten berechne, verschwindet der komplette blending effekt und es ist wieder die Rauhe kante da ohne blending. Vieleicht hebt sich das irgenwie auf....

    Ist denn die Reihenfolge richtig in der ich die Befehle fürs blendig aufrufe?
    Und was macht eigentlich dieser Komische Befehl?

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    

    Der stand in nem Tutorial. Da stand aber nicht WAS der Befehl macht, sondern nur das er da hin soll.


  • Mod

    die zeile gibt an, dass die vertexfarbe mit der textur multipliziert werden soll.
    ich glaube auch dass sich die beiden sachen gegenseitig aufheben, da du beim blenden weiss als vertexfarbe uebergibst.



  • Also mir sind 7 Dinge aufgefallen,die helfen könnten das Problem zu finden.

    1. Wenn ich beide layer mit Licht berechne, verschwindet der komplette blending Effekt. (So als ob ich den 2. Layer überhaupt nicht zeichnen würde)
    Und der 1. Layer wird mit allen Schatten richtig dargestellt.

    2. Zeichne ich den 2. Layer ohne Licht und den 1. mit Licht, zählen als Helligkeit nur noch die ersten drei Werte von glColor4f(1,1,1,a); und die Angabe der normalen wird komplett ignoriert.

    3. Zeichne ich den 2. Layer überhaupt nicht, so wird der 1. Layer mit allen Schatten richtig dargestellt.

    4. Zeiche ich den ersten Layer ohne Licht und den 2. mit Licht, werden die Stellen die Schatten haben sollen und blending erfahren sollen richtig Schattiert, es findet jedoch wieder Blending statt.

    Also ist 1. wie 3.

    5. Ob ich die Zeilen

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    

    einfüge oder Ausklammere scheint keinerlei Änderungen zu bringen.

    In allen Fällen (Fall 1 bis 5) zeigt der Debugger keine Fehler an.
    (Ich habe es jetzt schon auf 2 ganz verschiedenen Computern getestet)

    Dann wollte ich mir die beiden Layer einzeln ansehen mit Licht:
    6. Nehme ich als blendig Funktion glBlendFunc(GL_ONE,GL_ZERO); wird alles mit Schatten wie ohne Blending richtig dargestellt

    7. Nehme ich als blendig Funktion glBlendFunc(GL_ZERO,GL_ONE); wird alles mit Schatten wie ohne Blending richtig dargestellt lediglich die Stellen an denen Blending erfolgen soll haben wie gewünscht die jeweils andere Textur

    Also wird jeder Layer für sich richtig dargestellt.

    Jede Idee kann hilfreich sein! (Ich probiere hier nur zufällig verschiedene Funktionen zu ändern und erziele bisher keinen Erfolg)


  • Mod

    kann es sein dass dein schatten per vertex im alpha gespeichert wird? oder ist die shadowmap in einer extra texture?



  • Bei mir gibt es die Klasse Kachel.

    pragma once
    class Kachel{
    	float hoehe;
    	Vector3D normale1;
    	Vector3D normale2;
    	Vector3D normale3;
    	Vector3D normale4;
    	Vector3D normale5;
    	Vector3D normale6;
    
    	int textur;
    
    	bool in_Frustum;
    
    public: 
    	Kachel(float hoehe_):hoehe(hoehe_) {}
    	Kachel():hoehe(0) {}
    
    	void set_hoehe (float hoehe_) {
    		hoehe=hoehe_;
    	}
    
    	void set_normale1(Vector3D vec) {
    		normale1=vec;
    	}
    
    	void set_normale2(Vector3D vec) {
    		normale2=vec;
    	}
    
    	void set_normale3(Vector3D vec) {
    		normale3=vec;
    	}
    
    	void set_normale4(Vector3D vec) {
    		normale4=vec;
    	}
    
    	void set_normale5(Vector3D vec) {
    		normale5=vec;
    	}
    
    	void set_normale6(Vector3D vec) {
    		normale6=vec;
    	}
    
    	Vector3D get_normale1() {
    		return normale1;
    	}
    
    	Vector3D get_normale2() {
    		return normale2;
    	}
    
    	Vector3D get_normale3() {
    		return normale3;
    	}
    
    	Vector3D get_normale4() {
    		return normale4;
    	}
    
    	Vector3D get_normale5() {
    		return normale5;
    	}
    
    	Vector3D get_normale6() {
    		return normale6;
    	}
    
    	void set_Frustum(bool frustum)
    	{
    		in_Frustum=frustum;
    	}
    
    	bool get_Frustum() 
    	{
    		return in_Frustum;
    	}
    
    	float get_hoehe() 
    	{
    		return hoehe;
    	}
    
    	void set_textur(float textur_){textur=textur_;}
    
    	int get_textur() {return textur;}
    
    };
    

    Ich Stelle die Landschaft jeweils als 2 Dreiecke pro Kachel dar.
    Dazu berechne und speichere ich auch noch die zugehörige Textur und 6 normale. Eine normale für jede Ecke der Dreiecke.

    Diese normale benutze ich dann um in der Zeichenfunktion mit Hilfe von

    glNormal3f(kachel[x][y].get_normale2().get_x(),kachel[x][y].get_normale2().get_y(),kachel[x][y].get_normale2().get_z());
    

    die normalen für den Schatten anzugeben.
    (Siehe zeichenfunktion in den vorherigen Beiträgen)

    Dies funktioniert auch super, solange ich kein blending verwende.

    Sobald ich Licht für beide Layer beim Blending einschalte verschwindet der blendig Effekt. (Das Licht wird aber komischerweise richtig dargestellt)


Anmelden zum Antworten