Code archives/3D Graphics - Effects/Motion Blur
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| (Updated Version July 2007: This didn0t seem to work on some machines, and it was also TOO subtile. Now both is hopefully fixed - try it, it's a nice effect now) Like the other Motion Blur solutions around here, this one isn't real Motion Blur since it's using pixel sustain, aka Delay. what is special about this variant is: the "Blurquad" that is positioned in front of the camera isn't a simple 2-Tris Quad or sprite, but a 4 Tris Quad with a central vertex using vertexalpha zero. So in this effect things get more blured the closer they are to the screen edges. It gives a litte turbo effect when used with car or airplane racing sims. Right now it's only working in 1024*768 Pixels. | |||||
Graphics3D 1024,768,32,1
SetBuffer BackBuffer()
light=CreateLight()
RotateEntity light,45,45,0
cube=CreateCube()
TranslateEntity cube,0,0,3.0
ScaleEntity cube,.1,2,.1
camera=CreateCamera()
CameraRange camera,0.01,100
CameraClsColor camera,255,0,0
; init motionblur
motion_blur_on=1
motion_blur_quad=create_blurquad(camera) ; create a special 4-tris quad with a zero Alpha center vertex.
EntityFX motion_blur_quad,2 Or 1 Or 16
motion_blur_tex=CreateTexture(1024,1024,256)
EntityAlpha motion_blur_quad,0.333
; use the following remarked lines if you need to visually control texture alignement (skip copyrect render to tex!)
;SetBuffer TextureBuffer(motion_blur_tex)
;Color 0,255,0
;Rect 0,128,1024,768,0
;SetBuffer BackBuffer()
EntityTexture motion_blur_quad,motion_blur_tex
TranslateEntity motion_blur_quad,-(1.0/2048.0),0-(1.0/2048.0), 0.995 ;1.0 would be exact screen matching (pixelperfect)
EntityOrder motion_blur_quad,-1
; eo init motion blur
While KeyDown(1)=0
; call motion blur in mainloop--------
If KeyHit(57) ; space= toggle motion blur
motion_blur_on=motion_blur_on Xor 1
If motion_blur_on=0 Then
HideEntity motion_blur_quad
Else
ShowEntity motion_blur_quad
EndIf
EndIf
; update motion blur texture
If motion_blur_on<>0
CopyRect 0,0,1024,768,0,128,BackBuffer(),TextureBuffer(motion_blur_tex)
EndIf
;-----
TurnEntity cube,.2,.4,.6
UpdateWorld()
RenderWorld()
VWait:Flip 0
Wend
Function create_blurquad(par=0)
Local al1#,al2#,m,s,v0,v1,v2,tr
al1#=1.0
al2#=0.2
m=CreateMesh()
s=CreateSurface(m)
v0=AddVertex(s,-1,-1,0, 0,1)
v1=AddVertex(s,+1,-1,0, 1,1)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,+1,-1,0, 1,1)
v1=AddVertex(s,+1,+1,0, 1,0)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,+1,+1,0, 1,0)
v1=AddVertex(s,-1,+1,0, 0,0)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,-1,+1,0, 0,0)
v1=AddVertex(s,-1,-1,0, 0,1)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
FlipMesh m
UpdateNormals m
If par <>0 Then EntityParent m,par
Return m
End Function |
Comments
| ||
Here's a further example, using the driver demo from the Blitz installation samples (seek driver.bb for the media files):
Global info1$="Driver"
;Include "../start.bb"
Graphics3D 1024,768,32,1
SetBuffer BackBuffer()
Const GRAVITY#=-.01
Const BODY=1,WHEEL=2,SCENE=3
Collisions BODY,SCENE,2,3
Collisions WHEEL,SCENE,2,3
terr=LoadTerrain( "heightmap_256.bmp" )
ScaleEntity terr,1000/TerrainSize(terr),70,1000/TerrainSize(terr)
TerrainDetail terr,1000,True
TerrainShading terr,True
PositionEntity terr,-500,0,-500
tex=LoadTexture( "terrain-1.jpg" )
ScaleTexture tex,15,15 ;50;50
EntityTexture terr,tex
EntityType terr,SCENE
car=LoadMesh( "car.x" )
ScaleMesh car,1,1,-1
FlipMesh car
FitMesh car,-1.5,-1,-3,3,2,6
PositionEntity car,0,70,0
EntityShininess car,1
EntityType car,BODY
Global wheels[4]
cnt=1
For z#=1.5 To -1.5 Step -3
For x#=-1 To 1 Step 2
wheels[cnt]=CreateSphere( 8,car )
EntityAlpha wheels[cnt],.5
ScaleEntity wheels[cnt],.5,.5,.5
EntityRadius wheels[cnt],.5
PositionEntity wheels[cnt],x,0,z
EntityType wheels[cnt],WHEEL
cnt=cnt+1
Next
Next
light=CreateLight()
TurnEntity light,45,45,0
target=CreatePivot( car )
PositionEntity target,0,5,-12
camera=CreateCamera()
CameraClsColor camera,0,128,255
CameraRange camera,0.1,1000
speed#=0
x_vel#=0:prev_x#=EntityX( car )
y_vel#=0:prev_y#=EntityY( car )
z_vel#=0:prev_z#=EntityZ( car )
; init motionblur
motion_blur_on=1
motion_blur_quad=create_blurquad(camera) ; create a special 4-tris quad with a zero Alpha center vertex.
EntityFX motion_blur_quad,2 Or 1
motion_blur_tex=CreateTexture(1024,1024,256 Or 2)
; use the following remarked lines if you need to visually control texture alignement (skip copyrect render to tex!)
;SetBuffer TextureBuffer(motion_blur_tex)
;Color 0,255,0
;Rect 0,128,1024,768,0
;SetBuffer BackBuffer()
EntityTexture motion_blur_quad,motion_blur_tex
TranslateEntity motion_blur_quad,-(1.0/2048.0),0-(1.0/2048.0), 0.995 ;1.0 would be exact screen matching (pixelperfect)
EntityOrder motion_blur_quad,-1000
;this 2nd "quad" will amplify the effect (tho slower, so maybe remove it):
motion_blur_quad2=CopyEntity(motion_blur_quad)
TranslateEntity motion_blur_quad2,0,0,-.0025
EntityParent motion_blur_quad2,motion_blur_quad
EntityOrder motion_blur_quad2,-2000
; eo init motion blur
While Not KeyHit(1)
; motion blur
If KeyHit(57) ; space= toggle motion blur
motion_blur_on=motion_blur_on Xor 1
If motion_blur_on=0 Then
HideEntity motion_blur_quad
Else
ShowEntity motion_blur_quad
EndIf
EndIf
; update motion blur texture
If motion_blur_on<>0
CopyRect 0,0,1024,1024,0,128,BackBuffer(),TextureBuffer(motion_blur_tex)
EndIf
;
;align car to wheels
zx#=(EntityX( wheels[2],True )+EntityX( wheels[4],True ))/2
zx=zx-(EntityX( wheels[1],True )+EntityX( wheels[3],True ))/2
zy#=(EntityY( wheels[2],True )+EntityY( wheels[4],True ))/2
zy=zy-(EntityY( wheels[1],True )+EntityY( wheels[3],True ))/2
zz#=(EntityZ( wheels[2],True )+EntityZ( wheels[4],True ))/2
zz=zz-(EntityZ( wheels[1],True )+EntityZ( wheels[3],True ))/2
AlignToVector car,zx,zy,zz,1
zx#=(EntityX( wheels[1],True )+EntityX( wheels[2],True ))/2
zx=zx-(EntityX( wheels[3],True )+EntityX( wheels[4],True ))/2
zy#=(EntityY( wheels[1],True )+EntityY( wheels[2],True ))/2
zy=zy-(EntityY( wheels[3],True )+EntityY( wheels[4],True ))/2
zz#=(EntityZ( wheels[1],True )+EntityZ( wheels[2],True ))/2
zz=zz-(EntityZ( wheels[3],True )+EntityZ( wheels[4],True ))/2
AlignToVector car,zx,zy,zz,3
;calculate car velocities
cx#=EntityX( car ):x_vel=cx-prev_x:prev_x=cx
cy#=EntityY( car ):y_vel=cy-prev_y:prev_y=cy
cz#=EntityZ( car ):z_vel=cz-prev_z:prev_z=cz
;resposition wheels
cnt=1
For z=1.5 To -1.5 Step -3
For x=-1 To 1 Step 2
; PositionEntity wheels[cnt],0,0,0
; ResetEntity wheels[cnt]
PositionEntity wheels[cnt],x,-1,z
cnt=cnt+1
Next
Next
;move car
If KeyDown(203) TurnEntity car,0,3,0
If KeyDown(205) TurnEntity car,0,-3,0
If EntityCollided( car,SCENE )
If KeyDown(200)
speed=speed+.02
If speed>.7 speed=.7
Else If KeyDown(208)
speed=speed-.02
If speed<-.5 speed=-.5
Else
speed=speed*.9
EndIf
MoveEntity car,0,0,speed
TranslateEntity car,0,GRAVITY,0
Else
TranslateEntity car,x_vel,y_vel+GRAVITY,z_vel
EndIf
;update camera
If speed>=0
dx#=EntityX( target,True )-EntityX( camera )
dy#=EntityY( target,True )-EntityY( camera )
dz#=EntityZ( target,True )-EntityZ( camera )
TranslateEntity camera,dx*.1,dy*.1,dz*.1
EndIf
PointEntity camera,car
UpdateWorld
RenderWorld
Text 0,0,"space= toggle motion blur"
VWait:Flip 0
Wend
End
Function create_blurquad(par=0)
Local al1#,al2#,m,s,v0,v1,v2,tr
al1#=1.0
al2#=0.2
m=CreateMesh()
s=CreateSurface(m)
v0=AddVertex(s,-1,-1,0, 0,1)
v1=AddVertex(s,+1,-1,0, 1,1)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,+1,-1,0, 1,1)
v1=AddVertex(s,+1,+1,0, 1,0)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,+1,+1,0, 1,0)
v1=AddVertex(s,-1,+1,0, 0,0)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,-1,+1,0, 0,0)
v1=AddVertex(s,-1,-1,0, 0,1)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
FlipMesh m
UpdateNormals m
If par <>0 Then EntityParent m,par
Return m
End Function
|
| ||
| Something's not right here. I don't see any blur effect at all. |
| ||
| hit space to toggle |
| ||
| I knew to press space, but neither demo produces any blur at all for me. |
| ||
| Nice effect!! Thanks! |
| ||
| FreetimeCoder: thank you! Barliesque - this is strange. Try to add this somewhere: entitycolor motion_blur_quad,255,0,255 Now you should at least see the quad, that is fully transparent in the center and fades to half opaque on the edges. If you can't see it, then maybe it's out of the camera range for some reason. I have no idea why this should happen. Anyway, try to lower the min range of the camerarange. Also make sure it's running with eg. 60 FPS or 30 FPS. Disabling the vsync of your graphicscard will probably make the effect insignificant. |
| ||
| Same as Barliesque. I tried putting "entitycolor motion_blur_quad,255,0,255" right above the "While Not KeyHit(1)"... still dont see anyhting. I made the Z value 10 to try to see something... anything.... TranslateEntity motion_blur_quad,0-(1.0/2048.0),0-(1.0/2048.0), 10 ;1.0 would be exact screen matching (pixelperfect) I saw two short black horizontal bars over the car. :\ |
| ||
| Same here. I don't see anything. |
| ||
| Same as Gabe.. |
| ||
This code is working.
Global info1$="Driver"
;Include "../start.bb"
Graphics3D 1024,768,32,1
SetBuffer BackBuffer()
Const GRAVITY#=-.01
Const BODY=1,WHEEL=2,SCENE=3
Collisions BODY,SCENE,2,3
Collisions WHEEL,SCENE,2,3
terr=LoadTerrain( "heightmap_256.bmp" )
ScaleEntity terr,1000/TerrainSize(terr),70,1000/TerrainSize(terr)
TerrainDetail terr,1000,True
TerrainShading terr,True
PositionEntity terr,-500,0,-500
tex=LoadTexture( "terrain-1.jpg" )
ScaleTexture tex,15,15 ;50;50
EntityTexture terr,tex
EntityType terr,SCENE
car=LoadMesh( "car.x" )
ScaleMesh car,1,1,-1
FlipMesh car
FitMesh car,-1.5,-1,-3,3,2,6
PositionEntity car,0,70,0
EntityShininess car,1
EntityType car,BODY
Global wheels[4]
cnt=1
For z#=1.5 To -1.5 Step -3
For x#=-1 To 1 Step 2
wheels[cnt]=CreateSphere( 8,car )
EntityAlpha wheels[cnt],.5
ScaleEntity wheels[cnt],.5,.5,.5
EntityRadius wheels[cnt],.5
PositionEntity wheels[cnt],x,0,z
EntityType wheels[cnt],WHEEL
cnt=cnt+1
Next
Next
light=CreateLight()
TurnEntity light,45,45,0
target=CreatePivot( car )
PositionEntity target,0,5,-12
camera=CreateCamera()
CameraClsColor camera,0,128,255
CameraRange camera,0.1,1000
speed#=0
x_vel#=0:prev_x#=EntityX( car )
y_vel#=0:prev_y#=EntityY( car )
z_vel#=0:prev_z#=EntityZ( car )
Global m
; init motionblur
motion_blur_on=1
motion_blur_quad=create_blurquad(camera) ; create a special 4-tris quad with a zero Alpha center vertex.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; change
EntityFX motion_blur_quad,3;2 Or 1
motion_blur_tex=CreateTexture(1024,1024,256); Or 2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; use the following remarked lines if you need to visually control texture alignement (skip copyrect render to tex!)
;SetBuffer TextureBuffer(motion_blur_tex)
;Color 0,255,0
;Rect 0,128,1024,768,0
;SetBuffer BackBuffer()
EntityTexture motion_blur_quad,motion_blur_tex
TranslateEntity motion_blur_quad,-(1.0/2048.0),0-(1.0/2048.0), 0.995; 1.0 would be exact screen matching (pixelperfect)
EntityOrder motion_blur_quad,-1000
;this 2nd "quad" will amplify the effect (tho slower, so maybe remove it):
motion_blur_quad2=CopyEntity(motion_blur_quad)
TranslateEntity motion_blur_quad2,0,0,-.0025
EntityParent motion_blur_quad2,motion_blur_quad
EntityOrder motion_blur_quad2,-2000
; eo init motion blur
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; add
TextureBlend motion_blur_tex,2
EntityAlpha motion_blur_quad,.25
EntityAlpha motion_blur_quad2,.25
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
While Not KeyHit(1)
; motion blur
If KeyHit(57) ; space= toggle motion blur
motion_blur_on=motion_blur_on Xor 1
If motion_blur_on=0 Then
HideEntity motion_blur_quad
Else
ShowEntity motion_blur_quad
EndIf
EndIf
; update motion blur texture
If motion_blur_on=True
CopyRect 0,0,1024,1024,0,128,BackBuffer(),TextureBuffer(motion_blur_tex)
EndIf
;
;align car to wheels
zx#=(EntityX( wheels[2],True )+EntityX( wheels[4],True ))/2
zx=zx-(EntityX( wheels[1],True )+EntityX( wheels[3],True ))/2
zy#=(EntityY( wheels[2],True )+EntityY( wheels[4],True ))/2
zy=zy-(EntityY( wheels[1],True )+EntityY( wheels[3],True ))/2
zz#=(EntityZ( wheels[2],True )+EntityZ( wheels[4],True ))/2
zz=zz-(EntityZ( wheels[1],True )+EntityZ( wheels[3],True ))/2
AlignToVector car,zx,zy,zz,1
zx#=(EntityX( wheels[1],True )+EntityX( wheels[2],True ))/2
zx=zx-(EntityX( wheels[3],True )+EntityX( wheels[4],True ))/2
zy#=(EntityY( wheels[1],True )+EntityY( wheels[2],True ))/2
zy=zy-(EntityY( wheels[3],True )+EntityY( wheels[4],True ))/2
zz#=(EntityZ( wheels[1],True )+EntityZ( wheels[2],True ))/2
zz=zz-(EntityZ( wheels[3],True )+EntityZ( wheels[4],True ))/2
AlignToVector car,zx,zy,zz,3
;calculate car velocities
cx#=EntityX( car ):x_vel=cx-prev_x:prev_x=cx
cy#=EntityY( car ):y_vel=cy-prev_y:prev_y=cy
cz#=EntityZ( car ):z_vel=cz-prev_z:prev_z=cz
;resposition wheels
cnt=1
For z=1.5 To -1.5 Step -3
For x=-1 To 1 Step 2
; PositionEntity wheels[cnt],0,0,0
; ResetEntity wheels[cnt]
PositionEntity wheels[cnt],x,-1,z
cnt=cnt+1
Next
Next
;move car
If KeyDown(203) TurnEntity car,0,3,0
If KeyDown(205) TurnEntity car,0,-3,0
If EntityCollided( car,SCENE )
If KeyDown(200)
speed=speed+.02
If speed>.7 speed=.7
Else If KeyDown(208)
speed=speed-.02
If speed<-.5 speed=-.5
Else
speed=speed*.9
EndIf
MoveEntity car,0,0,speed
TranslateEntity car,0,GRAVITY,0
Else
TranslateEntity car,x_vel,y_vel+GRAVITY,z_vel
EndIf
;update camera
If speed>=0
dx#=EntityX( target,True )-EntityX( camera )
dy#=EntityY( target,True )-EntityY( camera )
dz#=EntityZ( target,True )-EntityZ( camera )
TranslateEntity camera,dx*.1,dy*.1,dz*.1
EndIf
PointEntity camera,car
UpdateWorld
RenderWorld
Text 0,0,"space= toggle motion blur"
VWait:Flip 0
Wend
End
Function create_blurquad(par=0)
Local al1#,al2#,s,v0,v1,v2,tr;,m
al1#=1.0
al2#=0.2
m=CreateMesh()
s=CreateSurface(m)
v0=AddVertex(s,-1,-1,0, 0,1)
v1=AddVertex(s,+1,-1,0, 1,1)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,+1,-1,0, 1,1)
v1=AddVertex(s,+1,+1,0, 1,0)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,+1,+1,0, 1,0)
v1=AddVertex(s,-1,+1,0, 0,0)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
v0=AddVertex(s,-1,+1,0, 0,0)
v1=AddVertex(s,-1,-1,0, 0,1)
v2=AddVertex(s, 0,0 ,0, .5,.5)
VertexColor s,v0,255,255,255,al1#
VertexColor s,v1,255,255,255,al1#
VertexColor s,v2,255,255,255,al2#
tr=AddTriangle(s,v0,v1,v2)
FlipMesh m
UpdateNormals m
If par <>0 Then EntityParent m,par
Return m
End Function
|
| ||
| Thank you. I really don't know why it doesn't work on some machines. Tho, this line: CopyRect 0,0,1024,1024,0,128,BackBuffer(),TextureBuffer(motion_blur_tex) Seems very strange to me right now. probably this should rather be something like: CopyRect 0,0,1024,768,0,128,BackBuffer(),TextureBuffer(motion_blur_tex) since the backbuffer simply isn't 1024*1024. Maybe that was causing strange behaviour? However, the effect isn't that spectacular anyway. But the special quad with transparent center may be useful for many other things too. |
| ||
| In fact many spectacular effects can be made with the method that you did not find spectacular. when you make CopyRect 1024*1024 the monitor exceeds from top an bootom so ram can be a problem in some monitor cards. I tried with 1024*768 and it also gave the same result. besides if you examine the code you will see that in the parts that I have changed, especially when you use "OR" in the parameters of entityFX and createTexture command there can be a problem. Also it does not work when the entityalpha command is not used. As far as I guess, I am not sure but the information used in VRAM can be arranged differently in each monitor card. or it can be a bug. the only thing I am curious is whether the view in the machines that the original code works and the output of the last arranged code are the same? |
| ||
| maybe it's due to the depth of the screen. => Set the graphics3D to 1024,768,0,2 If the desktop isn't 32 bit, sometimes problems occures. other possibility, your graphics card does not support texture greater than 512 but it would be really strange. anyway, copyrecting screen does not always walk in fullscreen you can modify the copyrect size by 512*512 to be sure it copyrect a part of the screen. |
| ||
| That's why it's a lot easier to develop for consoles. (Tho, something like Blitz3D is much more friendly than "hacking based on the hardwares white papers"). I think most cards support 1024 textures these days. From Geforce 2 on, I guess. EntityFX seems to be ok: 1(fullbright) and 2(use vertexcolor, including alpha). But the texture flags may be wrong: motion_blur_tex=CreateTexture(1024,1024,256 Or 2) should be motion_blur_tex=CreateTexture(1024,1024,256) I think there's no need for the alpha flag, because we'll use entityalpha and vertex alpha, not texel alpha. This quad may however be used for some weird fx, imagine one camera renders to the quad and an other camera renders to the background. Or something. |
| ||
| BTW I have updated the first, original sourcecode, it may now work on all machines. Try it again. |
| ||
| ty ty i always wondered if blitz could do this. is it supposed to get blurry-er near the edges of the screen , or is it how the object is positioned? |
| ||
| yes, blurier near the edges (if in motion). think racing game. |
Code Archives Forum