Code archives/3D Graphics - Effects/Simple Motion Blur

This code has been declared by its author to be Public Domain code.

Download source code

Simple Motion Blur by GIB3D2009
It uses an overlay+texture to create motion blur. It grabs what you see on screen and puts it on the texture. The down side is that the screen or cameraviewport must be to the power of 2 (meaning it must be 2x2,4x4,512x512,1024x1024).

Change the overlay position/alpha/other changeable stuff to make oher interesting effects. You can also add on more overlays and move then around too.
InitGraphics(1024,1024)

Global Light = CreateLight()
	
Global Camera = CreateCamera()
	PositionEntity Camera,0,1,-5
	CameraRange Camera,.001,100
	

CreatePlane()

Local Cube = CreateCube()
PositionEntity Cube,0,1,0
RotateEntity Cube,30,40,0

Local Overlay = CreateQuad(1,1,-1,Camera)
PositionEntity Overlay,0,0,.5
EntityAlpha Overlay,.8

Local Texture = CreateTexture(1024,1024,1+16+32)
EntityTexture Overlay,Texture

LockBuffer TextureBuffer(Texture)
	For y = 0 To TextureHeight(Texture)-1
		For x = 0 To TextureWidth(Texture)-1
			WritePixelFast x,y,0,TextureBuffer(Texture)
		Next
	Next
UnlockBuffer TextureBuffer(Texture)
	
RenderTexture(Texture)

While Not KeyDown(1)
	
	TurnEntity Cube,.5,1,.5
	
	If KeyDown(200) TranslateEntity Camera,0,0,.1
	If KeyDown(208) TranslateEntity Camera,0,0,-.1
	If KeyDown(203) TranslateEntity Camera,-.1,0,0
	If KeyDown(205) TranslateEntity Camera,.1,0,0
	
	UpdateWorld
	
	RenderTexture(Texture)
	
	Flip
Wend
End

Function RenderTexture(texture)
	RenderWorld
	CopyRect 0,0,1024,1024,0,0,FrontBuffer(),TextureBuffer(texture)
End Function

Function InitGraphics(w = 1024, h = 768,title$="Blitz3D Program",exit_message$="")
	Graphics3D w, h, 32, 2
	SetBuffer BackBuffer()
	SeedRnd MilliSecs()
	
	If exit_message <> ""
		AppTitle title,exit_message
			Else
				AppTitle title
	EndIf
End Function

Function CreateQuad(width#,height#,order%=-1,parent%=False)
	Local v0,v1,v2,v3
	Local Point,Surface
	
	If Not parent = False
		Point = CreateMesh(parent)
			Else
				Point = CreateMesh()
	EndIf
	
	If order <> 0
		EntityOrder Point,order
	EndIf
	
	EntityFX Point,1
			
	Surface = CreateSurface(Point)
	
	v0=AddVertex(Surface,-(width*.5),(height*.5),0 ,0,0)
	v1=AddVertex(Surface,(width*.5),(height*.5),0 ,1,0)
	v2=AddVertex(Surface,-(width*.5),-(height*.5),0 ,0,1)
	v3=AddVertex(Surface,(width*.5),-(height*.5),0 ,1,1)
	
	AddTriangle(Surface,v0,v1,v2)
	AddTriangle(Surface,v1,v3,v2)
	
	Return Point
End Function

Comments

Nate the Great2009
thanks! this is great


Knight #512009
Awsome!


laytonkinyon2016
Is there a way to get around the power of two problem? I'd really like to play with accumulation blur for a horror game I'm making (not really too inspired by the SCP games btw)


RustyKristi2016
@laytonkinyon

Use OpenB3D and Blitzmax instead so you can actually do some shader stuff. Check out the examples here:
https://github.com/markcwm/openb3d.mod/search?utf8=%E2%9C%93&q=blur

There's already a DOF shader where you can get started.

Don't do any workaround post effects with Blitz3D, it will just cripple the fps of your game. I know this because I tried some of it not on a demo but on a demo I'm trying to make.

for a horror game I'm making (not really too inspired by the SCP games btw)

lol no one asked you about that SCP thing, but hey good luck and welcome! :)


Kryzon2016
That texture will always have a power of two size, but the camera viewport doesn't have to be the same.
You can change the UV coordinates of the quad being created in that "CreateQuad" function so the UV coordinates only capture the section of that power-of-two texture that has the non-power-of-two viewport content.

This is done in this example:
http://www.blitzbasic.com/Community/posts.php?topic=95702#1104688


Bobysait2016
There is an error in the code (not dramatic as the texture size is square, but could lead to a MAV if you modify the texture size)
For y = 0 To TextureWidth-1
For x = 0 To TextureHeight-1
it must be swapped ! x -> texturewidth, y -> textureheight.


Then, here is a "non power of 2" viewport (the texture will always be power of 2 ... but it's not a big deal)

For the example I used 600*400 arbitrarily, to let you know the texture will be 1024*512
but actually, there is no other restriction than the video memory of the graphics card (ex: a 1920*1080 will create a 2048*2048 texture which use a lot of memory and is slower to "copyrect")




BlitzSupport2016
Well spotted! I don't normally do it, but I've edited GIB3D's code to fix this, as it would be really hard to notice.


jfk EO-111102016
When I recently run some code that didn't do a boundary check and wrotepixelfast to some way offscreen coords, it drew me pixels right onto the Desktops tray bar. So, be careful.

Anyhow, speaking of delay and motion-blur: one real cheap method is to disable the cameras cls and instead render a black plane with like 80% opacy ontop of the last scene render, so there will be a very fast, easily adjustable trail of fading past frames.


xlsior2016
Anyhow, speaking of delay and motion-blur: one real cheap method is to disable the cameras cls and instead render a black plane with like 80% opacy ontop of the last scene render, so there will be a very fast, easily adjustable trail of fading past frames.


It's also very unreliable, since the state of the backbuffer is undetermined after a flip. Depending on the videocard and the drivers, you COULD see the previous frame, or random memory noise, OR some cards use 2,3,4 or 5 backbuffers, meaning that your background could go back in time 2,3, or 4 frames which can lead to really annoying flickering.

So... while it may work perfectly fine when you test it on your own PC, it WILL give odd results on a lot of computers in the wild, and isn't recommended.

(My previous videocard cycled through 3 backbuffers, and it lead to really annoying visuals when you assumed the frame was left in place unaltered.)

Only way to ensure that you see what you expect is to do a screengrab and redraw it first.


jfk EO-111102016
I didn't know that. So what is CameraClsMode good for at all?


xlsior2016
If you explicitly redraw the entire screen yourself there is no need to clear it out first,so I suppose you can forego that.

Apparently the multiple backbuffers things is called a 'swap chain', and is there to help prevent tearing and such: https://msdn.microsoft.com/en-us/library/windows/desktop/bb206356(v=vs.85).aspx


Kryzon2016
CameraClsMode is useful if you want to layer different render passes (i.e call RenderWorld more than once in the same frame).

You can use it to combine different camera positions in the same shot, like the game below (Radiata Stories) does it by showing a scene in the background and the character speaking on the foreground, they are two different passes:




jfk EO-111102016
Ok I see. But you still could use copyrect from backbuffer to frontbuffer, instead of a flip, which is what windows does anyway in windowed mode, afaik.

So theoreticly the speed loss wouldn't be so bad.


Code Archives Forum