Code archives/3D Graphics - Effects/Simple Motion Blur
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
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
| ||
thanks! this is great |
| ||
Awsome! |
| ||
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) |
| ||
@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! :) |
| ||
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 |
| ||
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") |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
I didn't know that. So what is CameraClsMode good for at all? |
| ||
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 |
| ||
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: |
| ||
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