Full Screen Motion Blur
by Viren Thambidorai · in Torque Game Engine Advanced · 09/11/2007 (11:55 pm) · 15 replies
Hi Guys,
Is there anyone who has ever worked on Full Screen Motion Blur effect?
I found few resources which deals with Full screen static blur effect..
http://www.garagegames.com/mg/forums/result.thread.php?qt=21464
but nothing really related with Motion blur, though there is a resource for Motion blur but its related to TGE
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=5686
but not for TGEA.
OK, to be precise, anything close to motion blur in San Andreas will also do :)
or smthing close to motion blur in NFS most wanted!
Does anyone has ever worked on it? any sort of help will be appriciable :)
Thanks.
Is there anyone who has ever worked on Full Screen Motion Blur effect?
I found few resources which deals with Full screen static blur effect..
http://www.garagegames.com/mg/forums/result.thread.php?qt=21464
but nothing really related with Motion blur, though there is a resource for Motion blur but its related to TGE
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=5686
but not for TGEA.
OK, to be precise, anything close to motion blur in San Andreas will also do :)
or smthing close to motion blur in NFS most wanted!
Does anyone has ever worked on it? any sort of help will be appriciable :)
Thanks.
#2
09/17/2007 (6:15 pm)
Full screen procedural that we can customize would be nice to have as a part of the official build.
#3
"...contemplate this on the tree of woe." <-- as said by James Earl Jones
Rave:
So now is it mandatory to add kuwahara, edge detection, thermal, invert, blur, radialBlur, boxBlur, horiztonalStreak, VCR, 50 million noise effects, gravity maps for fluids on the screen surface, and after image capabilities to the procedural material generator?
Point:
The nature of full screen effects keeps them from being agnostic, in that they're generally unique to a project. A method of exposure to the screen surface is a must (and that exists), but the procedural shader setup doesn't need to bogged down with dozens of things that many projects will never use.
09/17/2007 (8:35 pm)
@Vashner"...contemplate this on the tree of woe." <-- as said by James Earl Jones
Rave:
So now is it mandatory to add kuwahara, edge detection, thermal, invert, blur, radialBlur, boxBlur, horiztonalStreak, VCR, 50 million noise effects, gravity maps for fluids on the screen surface, and after image capabilities to the procedural material generator?
Point:
The nature of full screen effects keeps them from being agnostic, in that they're generally unique to a project. A method of exposure to the screen surface is a must (and that exists), but the procedural shader setup doesn't need to bogged down with dozens of things that many projects will never use.
#4
I finally got full screen radial motion blur working in TGEA!
i used this resource for TGE,
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=5686
converted code from OGL to D3D... some adjustments & it worked for me!
here am posting the code for the same...cheers! :)
------------------------------
Once u r done with these new class ... in ..\game\main.cpp
add our MotionBlur.h into headers!
then in initGame()
add
in shutdownGame() add
once this is done...move into guiTSControl.cpp
inside GuiTSCtrl::onRender() right after line
add these lines...
& u r done! :)
cheers!
10/25/2007 (10:20 pm)
HI guys!I finally got full screen radial motion blur working in TGEA!
i used this resource for TGE,
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=5686
converted code from OGL to D3D... some adjustments & it worked for me!
here am posting the code for the same...cheers! :)
#ifndef _MOTIONBLUR_H_
#define _MOTIONBLUR_H_
#ifndef LLIST_H
#include "core/llist.h"
#endif
#ifndef _MPOINT_H_
#include "math/mPoint.h"
#endif
#ifndef _MMATRIX_H_
#include "math/mMatrix.h"
#endif
#ifndef _GFXTEXTUREHANDLE_H_
#include "gfx/gfxTextureHandle.h"
#endif
#ifndef _GFX_Texture_Object_H_
#include "gfx/gfxTextureObject.h"
#endif
class MotionBlur
{
protected:
F32 mElapsedTime;
F32 mDuration;
public:
MotionBlur();
bool isExpired(){ return mElapsedTime >= mDuration; }
void setDuration( F32 duration ){ mDuration = duration; }
virtual void advanceTime(F32 dt);
virtual void preRender(GFXTextureObject* texture, const RectI &updateRect); // render b4 screen copy
virtual void render(GFXTextureObject* texture, const RectI &updateRect); // render after screen copy
};
class FXMotionBlur : public MotionBlur
{
public:
FXMotionBlur();
F32 mAlpha;
F32 mElapsedTimeToFade;
F32 mFade;
void setAlpha(F32 alpha){ mAlpha = alpha; }
void setElapsedTimeToFade(F32 timeToFade){ mElapsedTimeToFade = timeToFade; }
void setFade(F32 fade){ mFade = fade; }
virtual void advanceTime(F32 dt);
virtual void preRender(GFXTextureObject* texture, const RectI &updateRect);
};
class FXManager
{
typedef MotionBlur* MotionBlurPtr;
LList< MotionBlurPtr > mFxList;
GFXTexHandle mTexHandle;
GFXFormat mFormat;
S32 mLastWidth;
U32 mLastTimeTick;
bool mRefreshTexture;
public:
FXManager();
~FXManager();
void addFx(MotionBlur* newMotionBlur);
void clear();
GFXTexHandle getTextureHandle(){ return mTexHandle; }
void advanceTime(F32 dt);
void render(const RectI &updateRect);
};
extern FXManager* gScreenBlurMgr;
#endif------------------------------
#include "d3d9.h"
#include "d3dx9core.h"
#include "d3dx9tex.h"
#include "gfx\D3D\gfxD3DDevice.h"
#include "platform/platform.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "core/color.h"
#include "math/mRandom.h"
#include "math/mMatrix.h"
#include "game/fx/MotionBlur.h"
#include "gfx/gfxEnums.h"
#include "core/stl_fix.h"
// global Screen Motion Blur
FXManager* gScreenBlurMgr;
// Clientside function to test motion blur
ConsoleFunction(testMotionBlur, void, 3, 5, "testMotionBlur(alpha, lifetime [, timeToFade, Fade])") {
F32 alpha = dAtof(argv[1]);
S32 lifetime = dAtoi(argv[2]);
F32 timeToFade = lifetime - (lifetime/4);
F32 Fade = alpha / (lifetime - timeToFade);
if(argc > 3)
timeToFade = dAtof(argv[3]);
if(argc > 4)
Fade = dAtof(argv[4]);
FXMotionBlur *newfx = new FXMotionBlur;
newfx->setDuration(lifetime);
newfx->setAlpha(alpha);
newfx->setElapsedTimeToFade(timeToFade);
newfx->setFade(Fade);
gScreenBlurMgr->addFx(newfx);
}
MotionBlur::MotionBlur()
{
mElapsedTime = 0.0;
mDuration = 8.0;
}
void MotionBlur::advanceTime(F32 dt)
{
mElapsedTime += dt;
}
void MotionBlur::preRender(GFXTextureObject* texture, const RectI &updateRect){};
void MotionBlur::render(GFXTextureObject* texture, const RectI &updateRect){};
FXMotionBlur::FXMotionBlur()
{
mAlpha = 0.5;
mElapsedTimeToFade = mDuration;
mFade = mAlpha / (mDuration - mElapsedTimeToFade);
}
void FXMotionBlur::advanceTime(F32 dt)
{
MotionBlur::advanceTime(dt);
// Fade out alpha?
if(mElapsedTime >= mElapsedTimeToFade) {
mAlpha -= mFade * dt;
}
}
// called b4 we copy screen
void FXMotionBlur::preRender(GFXTextureObject* texture, const RectI &updateRect)
{
if(mAlpha > 0.001f)
{
GFX->setBitmapModulation(ColorF(1, 1, 1, mAlpha));
U32 newWidth = updateRect.extent.x * 0.99;
U32 newHeight = updateRect.extent.y * 0.99;
U32 deltaX = updateRect.extent.x - newWidth;
U32 deltaY = updateRect.extent.y - newHeight;
//center it and zoom
RectI srcRect(updateRect.point.x + deltaX*0.5 , updateRect.point.y + deltaY*0.5 , newWidth,newHeight );
// Draw our last frame over current frame
// NO need to flip the texture
GFX->drawBitmapStretchSR(texture, RectI(updateRect.point, updateRect.extent), RectI(updateRect.point, updateRect.extent),GFXBitmapFlip_None);
}
else
{
// No alpha left, Kill effect
mElapsedTime = mDuration;
}
}
FXManager::FXManager()
{
mTexHandle = NULL;
mLastTimeTick = 0;
mFormat = GFXFormatR8G8B8A8;
}
FXManager::~FXManager()
{
mTexHandle = NULL;
clear();
}
// add new fx to currently running list
void FXManager::addFx(MotionBlur* newMotionBlur)
{
if (mFxList.size() == 0)
{
mRefreshTexture = true;
}
mFxList.link(newMotionBlur);
}
// Clear all currently running screen effects
void FXManager::clear()
{
mFxList.free();
}
// Update screen effects
void FXManager::advanceTime(F32 dt) {
MotionBlurPtr *cur = NULL;
while((cur = mFxList.next(cur))) {
(*cur)->advanceTime(dt);
if((*cur)->isExpired()) {
MotionBlurPtr *prev = mFxList.prev(cur);
mFxList.free(cur);
cur = prev;
}
}
}
// Render effects
void FXManager::render(const RectI &updateRect)
{
LPDIRECT3DDEVICE9 D3DDevice = dynamic_cast<GFXD3DDevice *>(GFX)->getDevice();
IDirect3DSurface9* backBuffer;
IDirect3DSurface9 *surf;
if(mTexHandle)
{
// Check if we changed resolution
if(mLastWidth != updateRect.extent.x)
{
// Update next time
mTexHandle = NULL;
mLastWidth = updateRect.extent.x;
return;
}
// Set our texture active
GFXTextureObject* texture = (GFXTextureObject *) mTexHandle;
GFX->setTexture(0,texture);
if(mRefreshTexture)
{
D3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
GFXD3DTextureObject *texObj = (GFXD3DTextureObject*)texture;
texObj->get2DTex()->GetSurfaceLevel( 0, &surf );
D3DDevice->StretchRect( backBuffer, NULL, surf, NULL, D3DTEXF_NONE );
mRefreshTexture = false;
return;
}
mLastWidth = updateRect.extent.x;
// Advance effects
U32 curTime = Platform::getRealMilliseconds();
advanceTime(((F32)(curTime - mLastTimeTick)) * 0.001f);
mLastTimeTick = curTime;
if(mFxList.size() == 0)
return;
MotionBlurPtr *cur = NULL;
// preRender (before we copy screen)
while((cur = mFxList.next(cur)))
(*cur)->preRender(texture, updateRect);
D3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
GFXD3DTextureObject *texObj = (GFXD3DTextureObject*)texture;
texObj->get2DTex()->GetSurfaceLevel( 0, &surf );
D3DDevice->StretchRect( backBuffer, NULL, surf, NULL, D3DTEXF_NONE );
// render (after we copy screen)
while((cur = mFxList.next(cur)))
(*cur)->render(texture, updateRect);
}
else
{
GBitmap *bitmap = new GBitmap(updateRect.extent.x, updateRect.extent.y, false, mFormat);
if(bitmap)
{
dMemset(bitmap->pBits, 0x00, bitmap->byteSize);
mTexHandle = GFXTexHandle(bitmap, &GFXDefaultRenderTargetProfile, true);
}
}
}------------------------------Once u r done with these new class ... in ..\game\main.cpp
add our MotionBlur.h into headers!
then in initGame()
add
gScreenBlurMgr = new FXManager();
in shutdownGame() add
delete gScreenBlurMgr; gScreenBlurMgr = NULL;
once this is done...move into guiTSControl.cpp
inside GuiTSCtrl::onRender() right after line
drlSystem.sgRenderSystem();
add these lines...
if (mUpdateScreenEffects)
{
gScreenBlurMgr->render(updateRect);
}& u r done! :)
cheers!
#5
10/26/2007 (1:57 am)
Excellent work Viren and thanks for sharing! Can't wait to try this later!
#6
to see ur motion blur in action...open up console screen...type...
testMotionBlur( 0.8, 50);
where 0.8 is alpha value & 5o is duration for which effect is active in seconds :)
thanks :)
10/26/2007 (2:37 am)
Ya i almost forgot to mention one thing...to see ur motion blur in action...open up console screen...type...
testMotionBlur( 0.8, 50);
where 0.8 is alpha value & 5o is duration for which effect is active in seconds :)
thanks :)
#7
I also needed to #include "game/fx/MotionBlur.h" in guiTSControl.cpp.
Now it compiles and I am able to use use the testMotionBlur() function in the console. However, when I do use that function nothing happens!
10/26/2007 (3:27 am)
Hmm. I'm having a problem with this. At first it wouldn't even compile, but I added a few lines from the comments in the original resource:Quote:
Open gui/guiTSControl.h
find: F32 mForceFOV;
add after
bool mUpdateScreenEffects;
Save & close.
Open gui/guiTSControl.cc
find: mForceFOV = 0;
add after
mUpdateScreenEffects = false;
find: addField("forceFOV"
add after
addField("UpdateScreenEffects", TypeBool, Offset(mUpdateScreenEffects, GuiTSCtrl));
I also needed to #include "game/fx/MotionBlur.h" in guiTSControl.cpp.
Now it compiles and I am able to use use the testMotionBlur() function in the console. However, when I do use that function nothing happens!
#8
Then I realised that it's actually created a flag in the gui editor (with the addField() function above) which lets me turn it on and off.
Working now - great resource! Thanks!
10/26/2007 (6:07 am)
Duh! I set mUpdateScreenEffects = true in guiTSControl.cc which made it work.Then I realised that it's actually created a flag in the gui editor (with the addField() function above) which lets me turn it on and off.
Working now - great resource! Thanks!
#9
10/26/2007 (1:08 pm)
What files do you put this code into?
#10
Then make the smaller changes listed in Viren's post. After that I needed to make a few more chages (see my post above). I also needed to remove the #include "core/stl_fix.h" from MotionBlur.cpp as it is no longer present in TGEA 1.0.3.
After that it all compiled fine and runs a treat! Good luck!
10/28/2007 (7:27 am)
The two large entries from Viren's post are 2 new files: First, game/fx/MotionBlur.h and the second should be game/fx/MotionBlur.cpp.Then make the smaller changes listed in Viren's post. After that I needed to make a few more chages (see my post above). I also needed to remove the #include "core/stl_fix.h" from MotionBlur.cpp as it is no longer present in TGEA 1.0.3.
After that it all compiled fine and runs a treat! Good luck!
#11
...screen resolution and window resize issues
11/09/2007 (10:45 am)
- This is a good starting block for some people...it does need a few tweaks/fixes....screen resolution and window resize issues
#12
sorry guys tht i literally missed out on those changes as well to mention here :)
thx eikon!
btw, screen res isssues, i have not checked them yet...lemme me have my hand on it once again n c to it tht i can fix it or not :)
srry for miscommunication :)
11/13/2007 (10:42 pm)
Ohhh hell yeahh...sorry guys tht i literally missed out on those changes as well to mention here :)
thx eikon!
btw, screen res isssues, i have not checked them yet...lemme me have my hand on it once again n c to it tht i can fix it or not :)
srry for miscommunication :)
#13
01/18/2008 (1:55 pm)
It compiles, but when i get into my mission, i can see the skybox and thats it. My player and all objects are invisible. What is the problem? Could someone possibly send me their motionblur.cpp/h and guiTSControl.cpp/h?
#14
01/18/2008 (4:05 pm)
Ok I tryed it on a fresh build and it compiles and loads. Only problem now is that it doest work. I have used all the changes above and I am using TGEA 1.02. Any help?
#15
01/18/2008 (5:18 pm)
Sorry for the triple post but when i put in testMotionBlur( 0.8, 50); in the console, and push F10, the display goes all weird in there but when i get out of the gui editor, it will go back to normal. It seems to be working but it isnt rendered infront of everything else. Ill keep looking.
Torque Owner AcidFaucet
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=13430
in order to get the ability to more easily do full screen effects and then get on nVidia's site, and dig up post radialBlur from their shader library. Or you could just hunt down any information on radial blur and come up with your own original shader.