Game Development Community

Added motion blur....sort of

by Adam Beer · in Torque Game Engine Advanced · 09/22/2007 (4:05 pm) · 28 replies

I have got a simple static 'motion blur' shader working. I tested it with the full screen shaders resource and it worked nicely. Basically I have 2 parameters, MotionBlurStart and MotionBlurLength. The lower the value on MotionBlurLength the less of a blur there is. At 0.1 the blur is minor and at 0.3 the blur is pretty blurry. Any idea on how I could get the game to get the camera's speed and apply the appropriate value for MotionBlurLength based on the speed.

Here is the hosted files in cause anyone wants to have a shot at this.

www.heartofthebattle.com/motionblur.zip
Page «Previous 1 2
#1
10/03/2007 (12:58 pm)
Nice shader Adam and thanks for sharing it!

You should be able to get the camera velocity like this:

GameConnection* conn = GameConnection::getConnectionToServer();
if (!conn)
   return;

ShapeBase* camObj = conn->getCameraObject();
if (!camObj)
   return;

VectorF camVel  = camObj->getVelocity();
F32 vel = camVel.len();

Would be nice if you keep us updated :)
#2
10/03/2007 (1:29 pm)
Thanks, now I need to figure out how I can change the shader value based on the velocity of the camera.
#3
10/03/2007 (1:30 pm)
Oops, forgot to post that link:

www.garagegames.com/mg/forums/result.thread.php?qt=31404

Hope it helps.
#4
10/03/2007 (2:30 pm)
Thanks again. I am not a c++ programmer so this is not an easy task for me to do. That post that you sent me doesnt really make sense to me. I have this 1 parameters that will change called MotionBlurLength. The post talks about using something other than parameters like this. The one thing about the code that I dont get is how to make the value of the shader increase based on how high the cameras velocity is. Sorry if this is really simple but I really dont know alot about c++.
#5
10/04/2007 (9:16 am)
Sorry Adam but I'm afraid I can't help you more at this point. Maybe somebody else can give an advice on how to pass that dynamic data to your shader.
#6
10/15/2007 (6:42 pm)
This resource is great and lets you set up new parameters very easily for shaders. All you'd really need to do is have a function that gets the camera's velocity and viola, you have your parameter. Then create a function to update the fx constant every 150ms(So the change in velocity is taken into account).

function doFxBlur()
{
	canvas.setCanvasFxVars($spotFxVars[0] SPC $spotFxVars[1] SPC $spotFxVars[2] SPC $spotFxVars[3]);
	canvas.setCanvasFx(RadialBlur);
	canvas.startCanvasFx();
}

function TickFX(%val)
{
$spotFxVars[0] = GetCameraVelocity(); //Set the parameter as whatever the velocity is.
doFxBlur(); //Update the result. This could probably be replaced with canvasFxUpdateVars()
$FixVis = schedule(500, 0, "TickFX");  //Call this function every so often. (500 ms in this case)
}
#7
10/15/2007 (7:12 pm)
Thanks Matt.

So basicaly I would set the first line to this:

canvas.setCanvasFxVars($MotionBlurLength[0]);

MotionBlurLength is the only thing that would be changed as it is the variable that increases/decreases the blur amount. Also how would I make it increase the amount this variable is?
#8
10/15/2007 (7:18 pm)
It's just a float. You can increase it in any way you want. Look at how the fx spot shader is set up and see how it translates into the script.
#9
10/16/2007 (1:06 am)
Oooo.... I would love to add a this to my game, when you get it working.
#10
10/16/2007 (7:27 am)
Ok I looked at the shader and I'm still not getting how it would know that MotionBlurLength would be the parameter to change.

Would this be correct?:

function doFxBlur()
{	
canvas.setCanvasFxVars($spotFxVars[0] SPC $spotFxVars[1]);
	canvas.setCanvasFx(RadialBlur);
	canvas.startCanvasFx();
                canvas.setCanvasFxGen(0,1.3,500);
}

function TickFX(%val)
{
$FxBlurVars[0] = GetCameraVelocity(); //Set the parameter as whatever the velocity is.
$FXBlurVars[1] = MotionBlurLength;
doFxBlur(); //Update the result. This could probably be replaced with canvasFxUpdateVars()
$FixVis = schedule(500, 0, "TickFX");  //Call this function every so often. (500 ms in this case)
}
#11
10/16/2007 (8:09 am)
Just guessing here, but you wouldn't need $FXBlurVars[1] = MotionBlurLength;
fxBlurVars[0] should be the MotionBlurLentgh.
#12
10/16/2007 (4:01 pm)
Not being able to download your shader, I can't add this in for you. Basically $spotFxVars[0] is just a number. In this case you'd want it to be whatever the camera's velocity would be. Hence why $spotFxVars[0] = GetCameraVelocity(); Or whatever you named your function.

Edit: I assumed that motion blur length would be derived from the camera velocity.
#13
10/17/2007 (7:13 am)
Ill upload my shader somewhere else when I get home. Would adding motion blur like this require source changes not inclusing the ones for the resource?
#14
10/17/2007 (2:35 pm)
Here you go Matt:

hotb.100webspace.net/motionblur.zip

Thanks alot for helping me out on this everyone. I cant wait to see this when it works.
#15
10/17/2007 (4:07 pm)
Ah, I've seen this shader before. This is the Nvidia radial blur shader. (Actually, I ported this over for Illumina) Yours differs a bit, but here's the one I created for Illumina along with the code I use to affect the player's vision.

rBlurP.hlsl
//Copyright 2007 Matt Vitelli
#define IN_HLSL
#include "shdrConsts.h"

//-----------------------------------------------------------------------------
// Data
//-----------------------------------------------------------------------------
struct v2f
{
   float4 HPOS             : POSITION;
   float2 TEX0             : TEXCOORD0;
   float2 texCoord		   : TEXCOORD1;
};
float val : register(PC_CANVAS_P1);
//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
float4 main(v2f IN,
				uniform sampler2D    diffMap  : register(S0)
) : COLOR
{
	
   half4 c = 0;
   float4 tex = tex2D(diffMap, IN.texCoord);
   float2 Center = {0.5,0.5};
   float BlurStart = 1.0f;
   float BlurWidth = -0.2f;
   float nsamples = 16;
    // this loop will be unrolled by compiler and the constants precalculated:
    for(int i=0; i<nsamples; i++) {
    	float scale = BlurStart + BlurWidth*(i/(float) (nsamples-1));
    	c += tex2D(diffMap, IN.TEX0.xy*scale + Center );
   	}
   	c /= nsamples;
    return lerp(tex,c,val);
}

rBlurV.hlsl
//Copyright 2007 Matt Vitelli
#define IN_HLSL
#include "shdrConsts.h"

//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
struct Appdata
{
	float4 position   : POSITION;
	float4 baseTex    : TEXCOORD0;
};


struct Conn
{
   float4 HPOS             : POSITION;
   float2 TEX0             : TEXCOORD0;
   float2 texCoord		   : TEXCOORD1;
   
};



//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
Conn main( Appdata In, 
           uniform float4x4 modelview : register(VC_WORLD_PROJ)
)
{
   Conn Out;
   float2 Center = {0.5,0.5};
   Out.HPOS = mul(modelview, In.position);
   Out.TEX0 = In.baseTex - Center;
   Out.texCoord = In.baseTex;
   
   return Out;
}

Shaders.cs
new ShaderData( RadialBlur )
{
	DXVertexShaderFile	= "shaders/rblurV.hlsl";
	DXPixelShaderFile	= "shaders/rblurP.hlsl";
	pixVersion 			= 2.0;
};

function doFxRBlur()
{
	canvas.setCanvasFx(RadialBlur);
	canvas.startCanvasFx();
}

$spotFxVars[0] = 0;
$spotFxVars[1] = "0 0 0 0";
$spotFxVars[2] = "0 0 0 0";
$spotFxVars[3] = "0 0 0 0";

function doFxColorFade()
{
	canvas.setCanvasFxVars($spotFxVars[0] SPC $spotFxVars[1] SPC $spotFxVars[2] SPC $spotFxVars[3]);
	canvas.setCanvasFx(RadialBlur);
	canvas.startCanvasFx();
}

function doColorFade(%val)
{
$spotFxVars[0] = $spotFxVars[0] + %val;
doFxColorFade();
$FixVis = schedule(3000, 0, "FixVision", %val);
}

function FixVision(%val)
{
		if($spotFxVars[0] > 0)
		{
		$spotFxVars[0] = $spotFxVars[0] - (%val/5);
		doFxColorFade();
		$FixVis = schedule(1300, 0, "FixVision",%val);
		}
		else
		{
		echo("Are we getting called?");
		cancel($FixVis);
		}
}
#16
10/17/2007 (4:09 pm)
Now all that is needed is some sort of console command to get the camera's velocity and send it to the client. Then through a linear interpolation, we can blend the two terms full blur and no blur accordingly.
#17
10/17/2007 (4:53 pm)
Thanks alot Matt. In one of the above posts Stefan suggested this code for getting the cameras velocity:

GameConnection* conn = GameConnection::getConnectionToServer();
if (!conn)
   return;

ShapeBase* camObj = conn->getCameraObject();
if (!camObj)
   return;

VectorF camVel  = camObj->getVelocity();
F32 vel = camVel.len();

Would this work?
#18
10/23/2007 (7:57 pm)
I've been toying around with this a bit. Now, at the moment this is not working, but all the math for calculating the velocity is correct.

This is a server-side function.
//Copyright 2007 Matt Vitelli
function GetVelocityChanges(%obj)
{

%obj.oldPosX = %obj.currPosX;
%obj.oldPosY = %obj.currPosY;
%obj.oldPosZ = %obj.currPosZ;

%obj.currPosX = getWord(%obj.getPosition(),0);
%obj.currPosY = getWord(%obj.getPosition(),1);
%obj.currPosZ = getWord(%obj.getPosition(),2);

%VelocityX = mabs((%obj.currPosX - %obj.oldPosX)) / 2;
%VelocityY = mabs((%obj.currPosY - %obj.oldPosY)) / 2;
%VelocityZ = mabs((%obj.currPosZ - %obj.oldPosZ)) / 2;

%Velocity = "\"" @ %VelocityX @ " " @ %VelocityY @ " " @ %VelocityZ @ " 0" @ "\"";

if(isObject(%obj.client))
commandToClient(%obj.client,'GetVelocity',%Velocity);

if(isObject(%obj))
%obj.VelSched = schedule(2000,0,"GetVelocityChanges",%obj);

}
//Copyright 2007 Matt Vitelli

Client-side commands:
//Copyright 2007 Matt Vitelli
new ShaderData( VelBlur )
{
	DXVertexShaderFile	= "shaders/vblurV.hlsl";
	DXPixelShaderFile	= "shaders/vblurP.hlsl";
	pixVersion 			= 2.0;
};

$Vel[0] = "0 0 0 0";

function doFxVelBlur()
{
    canvas.setCanvasFxVars($Vel[0] SPC $Vel[0] SPC $Vel[0] SPC $Vel[0]);
	canvas.setCanvasFx(VelBlur);
	canvas.startCanvasFx();
}

function clientCmdGetVelocity(%Velocity)
{
echo("Velocity = " @ %Velocity);
$Vel[0] = %Velocity;
doFxVelBlur();
}
//Copyright 2007 Matt Vitelli

vBlurP.hlsl
//Copyright 2007 Matt Vitelli
#define IN_HLSL
#include "shdrConsts.h"

struct ConnData
{

float2 TexCoord : TEXCOORD0;

};

float3 Velocity : register(PC_CANVAS_P1);
//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
float4 main(ConnData IN,
	    uniform sampler2D diffMap : register(S0)
) : COLOR
{

float4 tex = tex2D(diffMap, IN.TexCoord);

const float2 Scale[8] = {
   -Velocity.x, -Velocity.y
   -Velocity.x, -Velocity.z,
   -Velocity.x,  Velocity.y,
   -Velocity.x,  Velocity.z,
    Velocity.x, -Velocity.y,
    Velocity.x, -Velocity.z,
    Velocity.x,  Velocity.y,
    Velocity.x, -Velocity.z
};

for (int i = 0; i < 8; i++)
{
	tex += tex2D(diffMap, IN.TexCoord + 0.2 * Scale[i]);
}

return tex / 9;

}
//Copyright 2007 Matt Vitelli


vBlurV.hlsl
#define IN_HLSL
#include "shdrConsts.h"

//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
struct Appdata
{
	float4 position   : POSITION;
	float4 baseTex    : TEXCOORD0;
};

struct Conn
{
   float4 HPOS             : POSITION;
   float2 TEX0             : TEXCOORD0;
   
};

//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
Conn main( Appdata In, 
           uniform float4x4 modelview : register(VC_WORLD_PROJ)
)
{
   Conn Out;
   Out.HPOS = mul(modelview, In.position);
   Out.TEX0 = In.baseTex;
   
   return Out;
}
#19
10/24/2007 (2:52 pm)
Thanks Matt. Nice work so far. I wish I were better at scripting so I could help you out on this.
#20
11/01/2007 (5:24 am)
Er.. can u share the resource again!!
Page «Previous 1 2