I would like to do a directional blur effect to a 2d texture using HLSL ps_1.
I did some browsing and ended up with scene nodes with blur effect using HLSL, not sure if this will help me achieve my goal (see the codes and error below).
After I run the code below I got this error:
RADEON 9250 - Secondary ati2dvag.dll 6.14.10.6606
HLSL pixel shader compilation failed:
error X4518: cannot perform texture lookup twice from a user bound or similar array access sampler in ps_1_1
Code blureffect.h:
Code: Select all
#pragma once
#include <irrlicht\irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
#define MIN_BLUR = 0.0
#define MAX_BLUR = 0.01;
class BlurEffect : public video::IShaderConstantSetCallBack
{
private:
f32 m_fAngle;
f32 m_fBlurAmount;
s32 m_Material;
public:
BlurEffect() {m_fAngle = 90.0; m_fBlurAmount = 0.01;}
bool init(ISceneManager* smgr, IVideoDriver* driver)
{
if (!smgr || ! driver)
return false;
video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices();
if (!gpu) return false;
video::E_DRIVER_TYPE edt = driver->getDriverType();
if (edt == video::EDT_OPENGL) {
m_Material = gpu->addHighLevelShaderMaterialFromFiles(
"blureffect.vp", "main", video::EVST_VS_1_1,
"blureffect.fp", "main", video::EPST_PS_1_1,
this, video::EMT_SOLID);
} else if (edt == video::EDT_DIRECT3D9) {
m_Material = gpu->addHighLevelShaderMaterialFromFiles(
"blureffect.hlsl", "vertexMain", video::EVST_VS_1_1,
"blureffect.hlsl", "pixelMain", video::EPST_PS_1_1,
this, video::EMT_SOLID);
} else {
m_Material = video::EMT_SOLID;
}
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
CMatrix4<f32> worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("mWorldViewProj", &worldViewProj[0], 16);
services->setPixelShaderConstant("Angle", &m_fAngle, 90.0f);
services->setPixelShaderConstant("BlurAmount", &m_fBlurAmount, 0.01f);
}
public:
void setAngle(float fAngle){m_fAngle = fAngle;}
void setBlurAmount(float fBlurAmount){m_fBlurAmount = fBlurAmount;}
float getAngle(){return m_fAngle;}
float getBlurAmount(){return m_fBlurAmount;}
};HLSL:
Code: Select all
uniform float4x4 mWorldViewProj;
float Angle : register(c0);
float BlurAmount : register(c1);
sampler2D Texture1Sampler : register(s0);
struct VS_OUT {
float4 Pos : POSITION;
float2 TexCoord0 : TEXCOORD0;
};
VS_OUT vertexMain(float3 Pos : POSITION, float2 Tex0 : TEXCOORD0)
{
VS_OUT o = (VS_OUT)0;
o.Pos = mul(float4(Pos,1), mWorldViewProj);
o.TexCoord0 = Tex0;
return o;
}
float4 pixelMain(VS_OUT i) : COLOR
{
float4 c = 0;
float rad = Angle * 0.0174533f;
float xOffset = cos(rad);
float yOffset = sin(rad);
for(int idx=0; idx<16; idx++)
{
i.TexCoord0.x = i.TexCoord0.x - BlurAmount * xOffset;
i.TexCoord0.y = i.TexCoord0.y - BlurAmount * yOffset;
c += tex2D(Texture1Sampler, i.TexCoord0);
}
c /= 16;
return c;
} Main Code:
Code: Select all
#include "stdafx.h"
#include <irrlicht\irrlicht.h>
#include "blureffect.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
irr::SIrrlichtCreationParameters gDeviceParam;
IrrlichtDevice* gDevice;
IVideoDriver* gVideoDriver;
scene::ISceneManager* gSmgr;
BlurEffect gBlurEffect;
int _tmain(int argc, _TCHAR* argv[])
{
gDeviceParam.WindowSize = irr::core::dimension2d<irr::s32>(1024, 768);
gDeviceParam.Bits = 32;
gDeviceParam.Fullscreen = false;
gDeviceParam.AntiAlias = 10;
gDeviceParam.DriverType = video::EDT_DIRECT3D9;
// create device
gDevice = irr::createDeviceEx(gDeviceParam);
gVideoDriver = gDevice->getVideoDriver(); // video driver
gSmgr = gDevice->getSceneManager(); // scene manager
// initialize HLSL directional blur
gBlurEffect.init(gSmgr,gVideoDriver);
while(gDevice->run())
{
gVideoDriver->beginScene(true, true);
video::ITexture* images1 = gVideoDriver->getTexture("D:/moduleTesting/images/1.png");
gVideoDriver->draw2DImage(images1, core::position2d<s32>(0,0),
core::rect<s32>(0,0,1024,768), 0,
video::SColor(255,255,255,255), true);*/
gSmgr->drawAll();
gVideoDriver->endScene();
gDevice->sleep(50);
}
return 0;
}