I got it to work(TGM Motion Blur), i just start rewriting code a bit and
it apeirs to work althought i cant see much of a difference.here is a working code:
PostProcessMotionBlur.h
Code: Select all
#ifndef __POST_PROCESS_EFFECT_MOTION_BLUR__
#define __POST_PROCESS_EFFECT_MOTION_BLUR__
#include <irrlicht.h>
using namespace irr;
class CMotionBlurCallback : public video::IShaderConstantSetCallBack
{
private:
float m_ScreenWidth, m_ScreenHeight, m_Strength;
public:
CMotionBlurCallback(float screenWidth, float screenHeight, float strength)
{
m_ScreenWidth = screenWidth;
m_ScreenHeight = screenHeight;
m_Strength = strength;
}
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
services->setVertexShaderConstant("screenWidth", &m_ScreenWidth, 1);
services->setVertexShaderConstant("screenHeight", &m_ScreenHeight, 1);
services->setPixelShaderConstant("strength", &m_Strength, 1);
}
};
class IPostProcessMotionBlur : scene::ISceneNode
{
private:
core::aabbox3d<f32> m_BBox;
video::S3DVertex m_Vertices[6];
video::SMaterial m_Material1;
video::SMaterial m_Material2;
video::ITexture* m_rtNext;
video::ITexture* m_rtPrev;
video::ITexture* m_rtAccum;
public:
IPostProcessMotionBlur(scene::ISceneNode* parent, scene::ISceneManager* smgr, s32 id)
: scene::ISceneNode(parent, smgr, id)
{
m_Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f, 0, 0, 0, video::SColor(0), 0.0f, 1.0f);
m_Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f, 0, 0, 0, video::SColor(0), 0.0f, 0.0f);
m_Vertices[2] = video::S3DVertex(1.0f, 1.0f, 0.0f, 0, 0, 0, video::SColor(0), 1.0f, 0.0f);
m_Vertices[3] = video::S3DVertex(1.0f, -1.0f, 0.0f, 0, 0, 0, video::SColor(0), 1.0f, 1.0f);
m_Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f, 0, 0, 0, video::SColor(0), 0.0f, 1.0f);
m_Vertices[5] = video::S3DVertex(1.0f, 1.0f, 0.0f, 0, 0, 0, video::SColor(0), 1.0f, 0.0f);
}
~IPostProcessMotionBlur()
{
m_rtPrev->drop();
m_rtNext->drop();
m_rtAccum->drop();
}
void initiate(u32 sizeW, u32 sizeH, float strength)
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
const c8* pixelSha1 = "pixelSha1.hlsl";
const c8* pixelSha2 = "pixelSha2.hlsl";
const c8* vertSha = "vertSha.hlsl";
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
CMotionBlurCallback* callback = new CMotionBlurCallback((float)sizeW, (float)sizeH, strength);
m_Material1.MaterialType = (video::E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterialFromFiles(
vertSha, "vertexMain", video::EVST_VS_1_1,
pixelSha1, "pixelMain", video::EPST_PS_1_4,
callback, video::EMT_SOLID);
m_Material2.MaterialType = (video::E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterialFromFiles(
vertSha, "vertexMain", video::EVST_VS_1_1,
pixelSha2, "pixelMain", video::EPST_PS_1_1,
0, video::EMT_SOLID);
m_rtNext = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW, sizeH));
m_rtPrev = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW, sizeH));
m_rtAccum = driver->createRenderTargetTexture(core::dimension2d<s32>(sizeW, sizeH));
m_Material1.Textures[0] = m_rtNext;
m_Material1.Textures[1] = m_rtPrev;
m_Material2.Textures[0] = m_rtAccum;
callback->drop();
}
virtual void render()
{
u16 indices[] = {0, 1, 2, 3, 4, 5};
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setRenderTarget(m_rtNext, true, true, 0);
SceneManager->drawAll();
driver->setRenderTarget(m_rtAccum, true, true, 0);
driver->setMaterial(m_Material1);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&m_Vertices[0], 6, &indices[0], 2);
driver->setRenderTarget(m_rtPrev, true, true, 0);
driver->setMaterial(m_Material2);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&m_Vertices[0], 6, &indices[0], 2);
}
virtual void renderFinal()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
u16 indices[] = {0, 1, 2, 3, 4, 5};
driver->setMaterial(m_Material2);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&m_Vertices[0], 6, &indices[0], 2);
}
virtual video::SMaterial& getMaterial(s32 i)
{
return m_Material1;
}
virtual const core::aabbox3d<f32>& getBoundingBox() const
{
return m_BBox;
}
};
#endif
main.cpp
Code: Select all
#include "irrlicht.h"
#pragma comment(lib, "Irrlicht.lib")
using namespace irr;
#include "PostProcessMotionBlur.h"
IrrlichtDevice* device = 0;
const s32 winWidth = 800, winHeight = 600;
class MER : public IEventReceiver
{
bool OnEvent(SEvent event)
{
if(event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.Key == KEY_ESCAPE &&
!event.KeyInput.PressedDown)
{
device->closeDevice();
return true;
}
return false;
}
};
int main()
{
MER receiver;
SIrrlichtCreationParameters param;
param.AntiAlias = false;
param.Bits = 32;
param.DriverType = video::EDT_DIRECT3D9;
param.EventReceiver = &receiver;
param.Fullscreen = false;
param.HighPrecisionFPU = true;
param.Stencilbuffer = true;
param.Vsync = false;
param.WindowSize.Width = winWidth;
param.WindowSize.Height = winHeight;
device = createDeviceEx(param);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();
cam->setPosition(core::vector3df(0.0f, 150.0f, 0.0f));
scene::IAnimatedMesh* room = smgr->getMesh("room.3ds");
smgr->getMeshManipulator()->makePlanarTextureMapping(room->getMesh(0), 0.002f);
scene::IAnimatedMeshSceneNode* aroom = smgr->addAnimatedMeshSceneNode(room);
aroom->getMaterial(0).Lighting = false;
aroom->getMaterial(0).Textures[0] = driver->getTexture("rockwall.bmp");
IPostProcessMotionBlur* blur = new IPostProcessMotionBlur(cam, smgr, -2);
blur->initiate(winWidth, winHeight, 0.758462f);
while(device->run())
{
driver->beginScene(true, true, 0);
blur->render();
driver->setRenderTarget(0);
blur->renderFinal();
driver->endScene();
}
return 0;
}
vertex shader
Code: Select all
float screenWidth;
float screenHeight;
struct VS_OUTPUT
{
float4 position : POSITION;
float2 texCoord : TEXCOORD0;
};
VS_OUTPUT vertexMain(in float4 position : POSITION,
in float2 texCoord : TEXCOORD0)
{
VS_OUTPUT Out;
position.xy = sign(position.xy);
Out.position = float4(position.xy, 0.0f, 1.0);
Out.texCoord.x = 0.5 * (1.0 + position.x + (1.0 / screenWidth));
Out.texCoord.y = 0.5 * (1.0 - position.y + (1.0 / screenHeight));
return Out;
}
pixel shader 1
Code: Select all
sampler texture1 : register(s0);
sampler texture2 : register(s1);
float strength;
float4 pixelMain(float2 texCoord : TEXCOORD0) : COLOR
{
float4 tex1 = tex2D(texture1, texCoord);
float4 tex2 = tex2D(texture2, texCoord);
return lerp(tex1, tex2, strength);
}
pixel shader 2
Code: Select all
sampler texture1 : register(s0);
float4 pixelMain(float2 texCoord : TEXCOORD0) : COLOR
{
return tex2D(texture1, texCoord);
}
luben wrote:If i'm not wrong, sio2 did his shader like this
He keeps the old transformation matrix of each object, and passes it to the vertex shader along with the current matrix.
In the vertex shader, he calculates the vertex positions and output them(Normal). But he also stores the position as a texture coord, so that the position will be interpolated and somewhat correct for each pixel. He does this with bot the new and the old matrices, so that for each vertex the texcoord represents the new and old position.
In the pixel shader, this is interpolated, and he can use the first and second texture coord difference to calculate how far that pixel 'traveled' since the last frame.
Then he uses this value and does something else, like per pixel blurring based on the pixel-speed.
At least i think it is like this
thanks luben, i will try to represent your idea in code.
maybie i could find some sample code as reference.