PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : OpenGL: Render to Texture, Fake Motion Blur


aths
2003-12-16, 23:35:37
Folgendes Problem: Ich möchte Max-Payne-like in einer Animation Motion Trail zuschalten können. Das geht wohl am besten via Render to Texture. Wie funzt das? (Anlegen einer solchen Textur, wählen der Textur als Ziel, pixelgenaue Positionierung der Textur...) Wie kriegt man hin, dass das Zuschalten vom Fake Motion Blur nicht weiter auffällt (außer dass die bewegten Objekte halt eine Spur hinterlassen)?

Chris Lux
2003-12-17, 10:58:06
hi,
unter OpenGL kann ich dir folgende extensions sagen:

WGL_ARB_pbuffer (das rendertarget)
WGL_ARB_render_texture (erweiterung für den pbuffer)

das ist das wenigste was man dafür braucht. man legt eben einen pbuffer an, welcher die render_texture fähigkeit besitzt. diesem muss man dann auch die ganzen texturparameter mitgeben. so ein pbuffer kennt dann zwei modi, render_to und read_as_texture und er kann jeweils nur in einem der beiden modi sein.

zusätzlich würde ich dir noch empfehlen die GL_NV_texture_rectangle zu nutzen (da sollte schon lange eine allgemeine extension da sein) als texturformat, denn diese kann dimensionen ungleich power of 2 haben und muss nicht mit normierten texturcoordinaten behandelt werden, somit macht sich das pixelgenaue mappen auf dem viewport sehr einfach.

wenn du dir so wenig arbeit wie möglich machen möchtest: http://www.cs.unc.edu/~harrism/misc/rendertexture.html#ggviewer-offsite-nav-8992464 mark harris hat da eine render2texture klasse.

über das motion blur kann ich dir leider nix sagen, nur soweit über die render2texture grundlagen.

HTH

p.s. is leider mit ein wenig arbeit verbunden, aber wenn du magst schick ich dir beispielcode oder kann noch was erklären, aber die pbuffer und render_texture specs sind eigentlich sehr aufschlussreich.

Matti
2003-12-17, 14:14:08
ich könnte dir mal ein Bsp-Prog von mir zuschicken, aber ich bin jetzt in der Hochschule und das Prog ist aufm Rechner zu Hause. Wird also frühestens morgen...

Dieses Prog nutzt Render-to-Texture:
1. Szene normal rendern
2. Szene in Textur rendern (quadratischen Viewport setzen und dann glCopyTexImage2d)
...nach jedem Rendern der Szene muß natürlich noch die Blur-Textur drübergeblendet werden.

Wenn man die beiden Schritte vertauscht, entsteht auch an der Vorderseite der Bewegung etwas Unschärfe, was für Feuer-Effekte gut ist.

EDIT:
Hab grad Hans Post gelesen. Wenn es eine Extension gibt, die auch nicht-quadratische Texturen zuläßt, würde das natürlich die Performance fast verdoppeln, weil die Szene dann nur 1x gerendert werden muß.

KiBa
2003-12-17, 17:00:35
mal so als bemerkung/frage: ist jetzt speziell der effekt in max payne 2 nicht mit dem multisample-buffer realisiert? (wie z.b. in motogp auch)

Xmas
2003-12-17, 18:12:43
KiBa,
von den Screenshots die ich bisher gesehen habe würde ich sagen, nein. Denn dafür sind zu viele Abstufungen drin.

Natürlich ist Motion Trail mit Multisample Buffer am einfachsten und frisst auch am wenigsten Performance. Aber die Zahl der Samples limitiert doch zu stark, gerade mal maximal 6 bei aktueller Hardware.

Das dumme bei Render-to-Texture Motion Trail ist, dass man zweimal Kopieren muss, weil man nicht kurzfristig auf Single Buffering umschalten kann. Und im Backbuffer hat man ja nun mal nicht sicher den Inhalt des vorherigen Frames.

edit: Mal ganz davon abgesehen dass die beiden Varianten (R2T, MS-Buffer) ganz andere Resultate bringen...

zeckensack
2003-12-17, 18:32:15
Es müsste es auch so gehen:
a)altes Zeug in den Backbuffer kopieren
b)aktuellen Frame drüberrendern
c)Backbuffer in "altes Zeug"-Textur kopieren
d)flip

Punkt b sollte IMO mit mindestens 50% gewichtet sein, eher mehr. Durch die Wiederholung des Vorgangs fällt die Intensität der alten Frames immer weiter ab (~exponentielle Zerfallsfunktion). Und man hat quasi je nach Bedarf unendlich viele (das Mischverhältnis muss ja auch nicht fix sein ...).

edit: a und b kann man auch vertauschen. Ist wahrscheinlich sogar leichter.

aths
2003-12-18, 00:17:03
Den Framebuffer auslesen und in eine Textur hauen ist nicht, oder whuss?

Legolas
2003-12-18, 00:45:56
Original geschrieben von Xmas
KiBa,
von den Screenshots die ich bisher gesehen habe würde ich sagen, nein. Denn dafür sind zu viele Abstufungen drin.


Warum geht dann das AA aus, wenn man in den Bullet Time Modus wechselt? Hab immer gedacht, daß liegt daran, daß Motion Trail über MS realisiert ist.

zeckensack
2003-12-18, 00:48:35
Original geschrieben von aths
Den Framebuffer auslesen und in eine Textur hauen ist nicht, oder whuss? Doooch :)
einmal:

glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,width,height,0,
GL_UNSIGNED_BYTE,GL_RGB,NULL); //Textur 'reservieren'

//klampfen :freak:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
//mipmapping abknipsen
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

und dann immer und immer wieder
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,width,height);


Sehr zu empfehlen: {NV|EXT}_texture_rectangle nutzen, um die n²-Restriktion umgehen zu können. Harr (http://oss.sgi.com/projects/ogl-sample/registry/NV/texture_rectangle.txt).

Xmas
2003-12-18, 03:00:07
Original geschrieben von zeckensack
Es müsste es auch so gehen:
a)altes Zeug in den Backbuffer kopieren
b)aktuellen Frame drüberrendern
c)Backbuffer in "altes Zeug"-Textur kopieren
d)flip

Punkt b sollte IMO mit mindestens 50% gewichtet sein, eher mehr. Durch die Wiederholung des Vorgangs fällt die Intensität der alten Frames immer weiter ab (~exponentielle Zerfallsfunktion). Und man hat quasi je nach Bedarf unendlich viele (das Mischverhältnis muss ja auch nicht fix sein ...).

edit: a und b kann man auch vertauschen. Ist wahrscheinlich sogar leichter.
a) und b) muss man vertauschen, weil man ja eine Gewichtung mit Alpha-Blending rendert. Oder du müsstest sauber Front-to-Back rendern, so dass wirklich nur sichtbare Pixel mit dem Framebuffer geblendet werden.

Und wie gesagt, man muss zweimal kopieren, eben a) und c).

Generell würde ich es eher so machen:
a) Szene normal in Textur rendern
b1) Textur aus a) mit "altes Zeug" Textur kombinieren und gleich in "altes Zeug" Textur schreiben (sollte prinzipiell gehen)
oder
b2) Textur aus a) mit "altes Zeug" Textur als Render Target blenden
c) Textur aus b) in Backbuffer schreiben
d) Flip

b1) und b2) könnten auf unterschiedlicher Hardware jeweils schneller sein (Alpha Blending gegenüber 2 Texturen)

Bei c) denke ich, dass "Textur 1:1 in Backbuffer rendern" schneller sein sollte als "Backbuffer-Inhalt in eine Textur auslesen".

Xmas
2003-12-18, 03:02:42
Original geschrieben von Legolas
Warum geht dann das AA aus, wenn man in den Bullet Time Modus wechselt? Hab immer gedacht, daß liegt daran, daß Motion Trail über MS realisiert ist.
Auch bei Render-to-Texture kann es sein dass man kein AA hat. Ich bin mir da nicht ganz sicher, aber ich glaube nicht dass der Treiber AA bei R2T erzwingt. Und auch App-gesteuertes AA bei R2T scheint problematisch zu sein.