PostMortem - HDR-Implementation in der Splitterwelten-Engine

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2254
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von Zudomon »

Vielleicht war meine Reaktion etwas impulsiv, falls ja, entschuldige ich mich dafür.
Aber dennoch ist meine Aussage nicht falsch.
Hab nun nochmal genau nachgeschaut. Es geht um folgende Tonemapfunktion:

1-exp(color * key)

Wobei color für die Farbe des Pixels steht, der setzt sich aus z.B. 3 Lichtquellen zusammen:

1-exp((l1+l2+l3) * key)

http://de.wikipedia.org/wiki/Exponentialfunktion
unter Rechenregeln steht die Formel, die ich die ganze Zeit meinte, allerdings falsch ausgedrückt habe.
Aber durch Anwendung dieser Regel kommt man zu:

1-(exp(l1*key)*exp(l2*key)*exp(l3*key))

Das bedeutet, wenn ich die Exponentialfunktion auf jedes einzelne Licht anwende, dann muss ich die Lichtquellen MULTIPLIZIEREN statt zu ADDIEREN. Das komplette Bild muss dann nur noch invertiert werden.
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von Krishty »

Der Vollständigkeit halber hier nochmal die Einführung in die HDR-Funktionalität der Source-Engine.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Stefan Zerbst
Moderator
Beiträge: 189
Registriert: 25.02.2009, 19:54

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von Stefan Zerbst »

Hi,

habe ich diesen Thread doch heute erst gesehen. Also nochmal herzlichen Dank an Schrompf, die Screenshots rocken und sich die Zeit zu nehmen seine Erfahrungen mitzuteilen ist das was wir hier brauchen :)

Zufälligerweise habe ich vor ein paar Tagen selbst eine HDR Pipeline in meine Spielengine eingebaut um es auch endlich mal gemacht zu haben als bisher ewige LDR Jungfrau :D

Allerdings habe ich mir den Luxus gegönnt SM3.0 vorauszusetzen und gebe mit die volle R32FG32FB32FA32F Dröhnung. Für alle die sich auch für HDR interessieren gibt es im DX SDK ein nettes Beispiel: Post Processing Pipeline schimpft sich das glaube ich. Das ist recht ordentlich kommentiert so dass man schnell sehen kann wie das alles läuft. Als Ausgabe zeigt es auch die einzelnen Zwischenschritte an was die Lernkurve für Nichtwisser so wie mich sehr schön steil macht.

Fazit @Schrompf:
Mehr Postmortems bitte :)

Ciao,
Stefan
MadMax
Beiträge: 59
Registriert: 24.01.2003, 13:31
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von MadMax »

Hi,

habe da auch mal eine kurze Frage zu diesem Thema. Ich möchte unter Directx10 HDR screenshots machen. Was ist das die einfachste Möglichkeit das zu ereichen. Atm rendere ich in einen 32Bit folat Surface die frage ist nur wie bekomme ich die Daten dan in ein HDR taugliches Fileformat ? Bze. gibt es ein einfaches Format in das man fließkomma Bilder schreiben kann ?
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von Aramis »

EXR über OpenEXR. Das Schreiben ist einfach, die Bibliothek aber eine riesige Abhängigkeit. DDS natürlich auch, wird aber nur von wenigen Programmen wieder ordentlich gelesen. D3DX unterstützt auch noch '.HDR', das Format in dem einige HDR-Cubemaps aus dem DX SDK sind. Wie es da mit Unterstützung durch gängige Bildbearbeitungsprogramme/Imageviewer aussieht bin ich aber überfragt. Eher schlecht, würde ich tippen.
MadMax
Beiträge: 59
Registriert: 24.01.2003, 13:31
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von MadMax »

Hmm ich weiß das es die Möglichkeit gibt ein Rendertrarget im tiff format zu speichern allerdings bin ich mir nicht sicher welche Bit Tiefe dan verwendet wird.
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von Krishty »

PFM (Portable FloatMap). Der Code ist bei mir keine zehn Zeilen lang (falls du was brauchst, sag bescheid) und mit HDRShop kann man es perfekt verarbeiten.

Zum rumschicken im Internet ist es natürlich zu unpraktisch, aber die Simplizität steht ja im Vordergrund. Wenn es darauf ankommt, kann man es ja mittels HDRShop in jedem anderen gängigen Format abspeichern.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
MadMax
Beiträge: 59
Registriert: 24.01.2003, 13:31
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von MadMax »

Danke ich denke das ist das richtige Format. Kannst du mir mal ein Beispiel schicken wie so ein Bild aufgebaut ist werde aus der beschreibung da net so ganz schlau.
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von Krishty »

Code: Alles auswählen

void WriteImageToFile(
	const Image<R32G32B32_Float> &	p_Image, // Deine Bilddaten als float-RGB
	File &				p_File, // Meine Klasse, kannst stattdessen fwrite() o.ä. benutzen
	const float				p_Exposure = 1.0f
) {
	// Create the file header string.
	::std::stringstream l_sFileHeader(::std::stringstream::out);
		// It consists of the magic number "PF" (color PFM), followed by a newline character, …
		l_sFileHeader << "PF" << ::std::endl
		// … the decimal width and height of the image, in pixels, followed by another newline character, …
			<< ::std::setbase(10) << p_Image.WidthInPixels() << " " << p_Image.HeightInPixels() << ::std::endl
		// … and an exposure value, which also determines the file's Endian (negative means little Endian),
		//	terminated by a final newline character to seperate the header from the pixel data.
			<< -p_Exposure << std::endl;

	// When writing the header string to the file, ensure to exclude the terminating null character!
	p_File.WriteBinaryData(l_sFileHeader.str().c_str(), l_sFileHeader.str().length());

	// The file data is flipped vertically. We can, however, write to the file sequentially by writing the last
	//	line first.
	for(size_t l_CurrentLine = 0; l_CurrentLine < p_Image.HeightInPixels(); ++l_CurrentLine)
		p_File.WriteBinaryData(
			p_Image.Line(p_Image.HeightInPixels() - 1 - l_CurrentLine), // Gibt einen Zeiger auf die Zeile zurück …
			p_Image.WidthInPixels() * sizeof(R32G32B32_Float)
		);

	return;
}
Edit: Ach, durch generische Programmierung vergessen/verdrängt: Musst natürlich den Alphakanal entfernen.

Kann es sein, dass das & nicht richtig (als &) dargestellt wird?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
MadMax
Beiträge: 59
Registriert: 24.01.2003, 13:31
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von MadMax »

Ich mache folgendes und da kommt nur murgs raus.

Code: Alles auswählen

	fstream f;
	itos << this->screen_shot;   
	string path = "Test" + itos.str() + ".pfm";
	itos.str("");
	itos.clear(); 

	f.open(path.c_str(), ios::out );
    f << "PF" << endl;
	f << Texture->texture_resX << " ";
	f << Texture->texture_resY << endl;
	f << "-1.000000"  << endl;

	FLOAT* pTexels = (FLOAT*)tex.pData;
    for( UINT row = 0; row <Texture->texture_resY; row++ )
    {
      UINT rowStart = row * tex.RowPitch/4;
      for( UINT col = 0; col < Texture->texture_resX; col++ )
      {
		f << pTexels[rowStart + col*4 + 0] << " ";
		f << pTexels[rowStart + col*4 + 1] << " ";
		f << pTexels[rowStart + col*4 + 2] << " ";  
      }
	  f << endl;
    }
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von Krishty »

Ist klar – du hast keine Binärdatei geöffnet, schreibst also die ASCII-Darstellung der Zahlen in die Datei statt den binären Daten. Nur der Header hat ein ASCII-String zu sein, der Rest sollen schlichte Binärdaten sein.

Edit: f.write() sollte sein, was du brauchst.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
MadMax
Beiträge: 59
Registriert: 24.01.2003, 13:31
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von MadMax »

Ich glaube langsam ich bin zu blöd für binär Datein kommt nach wie vor nur schrott raus.

Code: Alles auswählen

f.open(path.c_str(), ios::out);
    f << "PF" << endl;
	f << Texture->texture_resX << " ";
	f << Texture->texture_resY << endl;
	f << "-1.000000"  << endl;

   FLOAT* pTexels = (FLOAT*)tex.pData;
    for( UINT row = 0; row <Texture->texture_resY; row++ )
    {
      UINT rowStart = row * tex.RowPitch/4;
      for( UINT col = 0; col < Texture->texture_resX; col++ )
      {
		f.write((const char*)&(pTexels[rowStart + col*4 + 0]),sizeof(float));
		f.write((const char*)&(pTexels[rowStart + col*4 + 1]),sizeof(float));
		f.write((const char*)&(pTexels[rowStart + col*4 + 2]),sizeof(float));
	  }
	}

	f.close();     
	Texture->texture_2D->Unmap(0);
MadMax
Beiträge: 59
Registriert: 24.01.2003, 13:31
Kontaktdaten:

Re: PostMortem - HDR-Implementation in der Splitterwelten-Engine

Beitrag von MadMax »

Ok sorry hat sich erledigt ich muss die datei natürlich auch noch binär öffnen. Danke für deine hilfe
Antworten