(c++/OpenGL) Motionblur

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Sorry but anything below a PS 2.0 will not work (They are restricted to 4 or less texture reads...). I doubt very much that this can work on a Geforce 4 unless you use some weird register combiner type thing or some fixed function effect.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Yarcanox
Posts: 33
Joined: Sat Apr 14, 2007 11:23 pm

Post by Yarcanox »

Call of Duty did such an effect somehow (on my GF4), so it is possible
Does anyone know a bloom effect which should work on a GF4? At least I think that would look even better than a motion blur...
TheGameMaker you made a bloom as I see, but I guess it won't work on my graphic card again :?
I'm not a native English speaker.
L1zb3th
Posts: 15
Joined: Thu Jul 26, 2007 1:27 am

Post by L1zb3th »

it's nice, but, very fps intensive =/
Au Revoir ^^
My Gramathicalz horrorz are precalkulated, zo Zhut Up !
_______
Bah, actually my english is poor, but...
forget it xDDDD
jonnys
Posts: 4
Joined: Sat Jan 12, 2008 3:43 pm
Contact:

Post by jonnys »

I'm trying to compile the motion blur shader code, using irrlicht 1.4, and I'm getting the following errors:

Code: Select all

----- Build started: Project: motion blur test, Configuration: Debug Win32 ------
1>Compiling...
1>Motionblurmain.cpp
1>c:\documents and settings\XX\desktop\motion blur\motion blur test\motion blur test\postprocessmotionblur.h(115) : error C2039: 'Textures' : is not a member of 'irr::video::SMaterial'

1>        c:\program files\irrlicht-1.4\include\smaterial.h(66) : see declaration of 'irr::video::SMaterial'

1>c:\documents and settings\XX\desktop\motion blur\motion blur test\motion blur test\postprocessmotionblur.h(116) : error C2039: 'Textures' : is not a member of 'irr::video::SMaterial'

1>        c:\program files\irrlicht-1.4\include\smaterial.h(66) : see declaration of 'irr::video::SMaterial'

1>c:\documents and settings\XX\desktop\motion blur\motion blur test\motion blur test\postprocessmotionblur.h(121) : error C2039: 'Textures' : is not a member of 'irr::video::SMaterial'

1>        c:\program files\irrlicht-1.4\include\smaterial.h(66) : see declaration of 'irr::video::SMaterial'

1>c:\documents and settings\XX\desktop\motion blur\motion blur test\motion blur test\motionblurmain.cpp(59) : warning C4305: 'argument' : truncation from 'double' to 'float'

1>Build log was saved at "file://c:\Documents and Settings\XX\Desktop\Motion blur\motion blur test\motion blur test\Debug\BuildLog.htm"
1>motion blur test - 3 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
What could be the problem? Is it because this source code was compiled against irrlicht 1.3 and in 1.4 'irr::video::SMaterial' had a 'Textures' declaration?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, the material stuff changed over the last versions, you have to adapt to the layout of the version you use.
jonnys
Posts: 4
Joined: Sat Jan 12, 2008 3:43 pm
Contact:

Post by jonnys »

I fixed it. Thanks. One thing I want to know though, is this the most modern way to do motion blur or is this an old method? What are the most modern methods to do it(eg. Crysis' way)?
vectorcorpse
Posts: 86
Joined: Thu Feb 14, 2008 7:30 pm
Location: Portugal

Post by vectorcorpse »

sorry for the newbie question, but how did u fixed it :P
i am having the same problem, but since i am new to irr and just restarted programing recently, i am having some trouble understanding the api reference on irr web site on the changes made to the smaterial instruction.
i can't find what do i have to use to replace the old line

Material.Textures[0]=rt0;

i know Textures[0] no longer exist but i can't find what is replacing it or how to do it :/
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Material.setTexture(0,rt0)
vectorcorpse
Posts: 86
Joined: Thu Feb 14, 2008 7:30 pm
Location: Portugal

Post by vectorcorpse »

thx :D
it working fine now
muenalan
Posts: 7
Joined: Tue Feb 26, 2008 9:11 pm

code updated

Post by muenalan »

Followed the threads and tested the code. Just to paste the working code with the latest irrlicht:


#ifndef __POST_PROCESS_EFFECT_MOTION_BLUR__
#define __POST_PROCESS_EFFECT_MOTION_BLUR__
#include "irrlicht.h"

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;



class PPE_MotionBlur_callback: public video::IShaderConstantSetCallBack
{
public:
float strength;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
int var0=0;
services->setPixelShaderConstant("texture1", (float*)(&var0), 1);
int var1=1;
services->setPixelShaderConstant("texture2", (float*)(&var1), 1);
}
};




class IPostProcessMotionBlur : public scene::ISceneNode
{

public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;//the material used with shader
video::SMaterial Accum;//a simple diffuse material..
video::ITexture* next; //the rendertarget
video::ITexture* prev; //the rendertarget
video::ITexture* accum; //the rendertarget
int mat;
PPE_MotionBlur_callback* callback;

IPostProcessMotionBlur(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}


void initiate(unsigned int sizeW,unsigned int sizeH,float strength,scene::ISceneManager* smgr)
{
static stringc vertShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";

static stringc fragShader =
"uniform sampler2D texture1;"
"uniform sampler2D texture2;"
"varying vec2 vTexCoord;"
"uniform float strength;"
"void main()"
"{"
" gl_FragColor = mix( texture2D( texture1, vTexCoord ), texture2D( texture2, vTexCoord ), vec4( strength,strength,strength,strength) );"
"}";


static stringc fragShader2 =
"uniform sampler2D texture1;"
"varying vec2 vTexCoord;"
"void main()"
"{"
" gl_FragColor =texture2D( texture1, vTexCoord );"
"}";


video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();

callback= new PPE_MotionBlur_callback();
callback->strength=strength;

Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
Accum.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader2.c_str(), "main", video::EPST_PS_1_1,
NULL, (video::EMT_SOLID)
);
next = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));
prev = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));
accum = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW,sizeH));

Material.Wireframe = false;
Material.Lighting = false;

Material.setTexture(0,next);
Material.setTexture(1,prev);


Accum.Wireframe = false;
Accum.Lighting = false;

Accum.setTexture(0,accum);

}




virtual void OnPreRender(){}

virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver(); //Fills Next
driver->setRenderTarget(next, true, true, video::SColor(0,0,0,0));
SceneManager->drawAll();

driver->setRenderTarget(accum, true, true, video::SColor(0,0,0,0)); //Combine Next&prev in accum
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);

driver->setRenderTarget(prev, true, true, video::SColor(0,0,0,0)); //Write back accum into prev
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}

virtual void renderFinal()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
u16 indices[] = {0,1,2,3,4,5};
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}


virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};

#endif
6opoDuJIo
Posts: 7
Joined: Fri Aug 21, 2009 5:20 pm

Post by 6opoDuJIo »

it's great man :!:
BIG THX to you :D
that's wonderfull:mrgreen:
stefbuet
Competition winner
Posts: 495
Joined: Sun Dec 09, 2007 4:13 pm
Location: france

Post by stefbuet »

Thanks for sharing the code ;)
I got a problem.
The effect is working fine, however, I can see old rendered frames over my skybox like this :

Image

When I move the camera, they're staying, but if I rotate the camera then they disapear progressively (alpha -> 0)
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Post by devsh »

dude check out how they do it in garry's mod, you dont need shaders and its pretty convincing

YOU ONLY NEED 1 or 2 RTT

render scene
set render target to "copiedLastFrame"
draw "lastScene" with a wuad onto the screen using some alpha value like 0.1
set render target to "lastScene" and copy "copiedLastFrame" into it

now the last scene amasses the frames before it...
Jallen
Posts: 46
Joined: Tue Jun 19, 2007 5:28 pm
Location: Hampshire, England

Post by Jallen »

I edited it a bit, the following works with irrlicht 1.6.
However I'm also getting that wierd ghosting effect.

Would really appreciate it if a more pro kind of guy came around and helped us out with the ghosting issue. I really like the idea of being able to use motion blur with ease in my irrlicht apps but with the ghosting it's just not going to happen right now...
Hybrid or someone? Help?

Code: Select all

#ifndef __POST_PROCESS_EFFECT_MOTION_BLUR__
#define __POST_PROCESS_EFFECT_MOTION_BLUR__
#include "irrlicht.h"

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;



class PPE_MotionBlur_callback: public video::IShaderConstantSetCallBack
{
public:
	float strength;
	virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
	{
		video::IVideoDriver* driver = services->getVideoDriver();
		services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
		int var0=0;
		services->setPixelShaderConstant("texture1", (float*)(&var0), 1);
		int var1=1;
		services->setPixelShaderConstant("texture2", (float*)(&var1), 1);
	}
};




class IPostProcessMotionBlur : public scene::ISceneNode
{

public:
	core::aabbox3d<f32> Box;
	video::S3DVertex Vertices[6];//the vertices for the onscreenquad
	video::SMaterial Material;//the material used with shader
	video::SMaterial Accum;//a simple diffuse material..
	video::ITexture* next; //the rendertarget
	video::ITexture* prev; //the rendertarget
	video::ITexture* accum; //the rendertarget
	int mat;
	PPE_MotionBlur_callback* callback;

	IPostProcessMotionBlur(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
	{
		Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
		Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
		Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
		Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
		Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
		Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
	}


	void initiate(unsigned int sizeW,unsigned int sizeH,float strength,scene::ISceneManager* smgr)
	{
		static stringc vertShader =
			"varying vec2 vTexCoord;"
			"void main(void)"
			"{"
			" vec2 Position;"
			" Position.xy = sign(gl_Vertex.xy);"
			" gl_Position = vec4(Position.xy, 0.0, 1.0);"
			"vTexCoord =Position.xy *.5 + .5;"
			"}";

		static stringc fragShader =
			"uniform sampler2D texture1;"
			"uniform sampler2D texture2;"
			"varying vec2 vTexCoord;"
			"uniform float strength;"
			"void main()"
			"{"
			" gl_FragColor = mix( texture2D( texture1, vTexCoord ), texture2D( texture2, vTexCoord ), vec4( strength,strength,strength,strength) );"
			"}";


		static stringc fragShader2 =
			"uniform sampler2D texture1;"
			"varying vec2 vTexCoord;"
			"void main()"
			"{"
			" gl_FragColor =texture2D( texture1, vTexCoord );"
			"}";


		video::IVideoDriver* driver = smgr->getVideoDriver();
		video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();

		callback= new PPE_MotionBlur_callback();
		callback->strength=strength;

		Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
			(
			vertShader.c_str(), "main", video::EVST_VS_1_1,
			fragShader.c_str(), "main", video::EPST_PS_1_1,
			callback, (video::EMT_SOLID)
			);
		Accum.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
			(
			vertShader.c_str(), "main", video::EVST_VS_1_1,
			fragShader2.c_str(), "main", video::EPST_PS_1_1,
			NULL, (video::EMT_SOLID)
			);

		next = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
		prev = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
		accum = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));

		Material.Wireframe = false;
		Material.Lighting = false;

		Material.setTexture(0,next);
		Material.setTexture(1,prev);


		Accum.Wireframe = false;
		Accum.Lighting = false;

		Accum.setTexture(0,accum);

	}




	virtual void OnPreRender(){}

	virtual void render()
	{
		u16 indices[] = {0,1,2,3,4,5};
		video::IVideoDriver* driver = SceneManager->getVideoDriver(); //Fills Next
		driver->setRenderTarget(next, true, true, video::SColor(0,0,0,0));
		SceneManager->drawAll();

		driver->setRenderTarget(accum, true, true, video::SColor(0,0,0,0)); //Combine Next&prev in accum
		driver->setMaterial(Material);
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);

		driver->setRenderTarget(prev, true, true, video::SColor(0,0,0,0)); //Write back accum into prev
		driver->setMaterial(Accum);
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
	}

	virtual void renderFinal()
	{
		video::IVideoDriver* driver = SceneManager->getVideoDriver();
		u16 indices[] = {0,1,2,3,4,5};
		driver->setMaterial(Accum);
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
	}


	virtual u32 getMaterialCount(){return 1;}
	virtual video::SMaterial& getMaterial(s32 i){return (Material);}
	virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};

#endif
rainfall20000
Posts: 1
Joined: Wed Dec 08, 2010 9:54 am

Post by rainfall20000 »

How can it words on version 1.7.2?
Post Reply