Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started by: Shockwave on June 26, 2011
-
This is just a little test while I was making up my mind what render effect to use for the Image Processing challenge, I've since decided to do something else instead of motion blur so this is posted just so it doesn't end up gathering dust on my HD.
A lot of motion blur is faked and simply works by keeping the last few frames and drawing them with increasing opacity. It's a cheap way of doing the effect and looks kind of shitty.
Motion blur happens when a fast moving image is over exposed to film, photography where you see the trailing headlights of cars at night time is a good example of this, so to simulate the effect I've rendered a cheap and shitty 3D starfield 4 times each vbl, after the rendering, the four frame buffers are combined into one to give a more true representation of motion blur.
Hope it helps someone.
'
' MOTION BLUR
' ===========
'
' By Shockwave / Codigos 2011
'
' WWW.DBFINTERACTIVE.COM
' Coded in a hurry - could be made 500% faster ;-)
' This just explains the technique.
'-------------------------------------------------------------------------------
RANDOMIZE TIMER
'-------------------------------------------------------------------------------
#INCLUDE "TINYPTC_EXT.BI"
#INCLUDE "WINDOWS.BI"
OPTION STATIC
OPTION EXPLICIT
'-------------------------------------------------------------------------------
CONST XRES = 640
CONST YRES = 480
CONST HALFX = 320
CONST HALFY = 240
DIM SHARED AS DOUBLE RAD2DEG
RAD2DEG = (4 * ATN ( 1 )) / 180
DIM SHARED AS UINTEGER SCREEN_BUFFER ( XRES * YRES )
DIM SHARED AS UINTEGER M_BUFFER_1 ( XRES * YRES )
DIM SHARED AS UINTEGER M_BUFFER_2 ( XRES * YRES )
DIM SHARED AS UINTEGER M_BUFFER_3 ( XRES * YRES )
DIM SHARED AS UINTEGER M_BUFFER_4 ( XRES * YRES )
CONST STARNUM = 4000
DIM SHARED STARX (STARNUM) AS DOUBLE
DIM SHARED STARY (STARNUM) AS DOUBLE
DIM SHARED STARZ (STARNUM) AS DOUBLE
DIM SHARED PALETTE_(10000)
DECLARE SUB SETSTARS()
DECLARE SUB DRAWSTARS(BYVAL BUFFER AS INTEGER)
DECLARE SUB RENDER()
SETSTARS()
'-------------------------------------------------------------------------------
PTC_ALLOWCLOSE(0)
PTC_SETDIALOG(1,"Test"+CHR$(13)+"Full Screen?",0,1)
IF (PTC_OPEN("Shockwave 2011",XRES,YRES)=0) THEN
END-1
END IF
SLEEP 5
DIM SHARED AS DOUBLE DV,OLD,GADD,RR ,SAD
'-------------------------------------------------------------------------------
WHILE(GETASYNCKEYSTATE(VK_ESCAPE)<> -32767 and PTC_GETLEFTBUTTON=FALSE)
OLD=TIMER
DRAWSTARS(1)
DRAWSTARS(2)
DRAWSTARS(3)
DRAWSTARS(4)
RENDER()
PTC_UPDATE@SCREEN_BUFFER(0)
SLEEP 1
DV=(TIMER-OLD)*4
GADD=GADD+DV
WEND
EXITPROCESS(0)
'-------------------------------------------------------------------------------
END
SUB RENDER()
DIM AS UINTEGER PTR PP1
DIM AS UINTEGER PTR PP2
DIM AS UINTEGER PTR PP3
DIM AS UINTEGER PTR PP4
DIM AS UINTEGER PTR PP5
PP1=@M_BUFFER_1(0)
PP2=@M_BUFFER_2(0)
PP3=@M_BUFFER_3(0)
PP4=@M_BUFFER_4(0)
PP5=@SCREEN_BUFFER(0)
DIM LP AS INTEGER
FOR LP=1 TO XRES*YRES
*PP5 = PALETTE_(((*PP1+*PP2+*PP3+*PP4) shr 1))
PP1+=1
PP2+=1
PP3+=1
PP4+=1
PP5+=1
NEXT LP
ERASE M_BUFFER_1
ERASE M_BUFFER_2
ERASE M_BUFFER_3
ERASE M_BUFFER_4
END SUB
SUB DRAWSTARS(BYVAL BUFFER AS INTEGER)
DIM AS INTEGER LP,TX,TY
SAD = SAD+(DV*.015)
DIM AS INTEGER L
'-------------------------------------------------------------------------------
' WE WILL ROTATE ONE AXIS OF IT BEFORE WE DO ANYTHING ELSE;
'-------------------------------------------------------------------------------
DIM AS DOUBLE RGADD :' STORES THETA (ROTATION ANGLE)
DIM AS DOUBLE MO1,MO2:' STORES MATRIX CONSTANTS FOR SPEED.
DIM AS DOUBLE MMM,NNN:' STORES X+Y FOR ROTATION
RGADD=.025*SIN(SAD):' CALCULATE THETA
MO1= COS(RGADD):' GENERATE MATRIX CONSTANT 1
MO2= SIN(RGADD):' GENERATE MATRIX CONSTANT 2
FOR L=1 TO STARNUM
'-----------------------------------------------------------------------
' ROTATE THE GRID
'-----------------------------------------------------------------------
NNN=STARX(L)
MMM=STARY(L)
STARX(L) = MO1 * NNN - MO2 * MMM:' ONE AXIS OF ROTATION
STARY(L) = MO1 * MMM + MO2 * NNN:
NEXT
SELECT CASE BUFFER
CASE 1
FOR LP=1 TO STARNUM
TX=(STARX(LP)/STARZ(LP))+HALFX
TY=(STARY(LP)/STARZ(LP))+HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
M_BUFFER_1(TX+(TY*XRES))=(32-STARZ(LP))*8
END IF
STARZ(LP)=STARZ(LP)-DV
IF STARZ(LP)<=0 THEN STARZ(LP)=STARZ(LP)+32
NEXT
CASE 2
FOR LP=1 TO STARNUM
TX=(STARX(LP)/STARZ(LP))+HALFX
TY=(STARY(LP)/STARZ(LP))+HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
M_BUFFER_2(TX+(TY*XRES))=(32-STARZ(LP))*8
END IF
STARZ(LP)=STARZ(LP)-DV
IF STARZ(LP)<=0 THEN STARZ(LP)=STARZ(LP)+32
NEXT
CASE 3
FOR LP=1 TO STARNUM
TX=(STARX(LP)/STARZ(LP))+HALFX
TY=(STARY(LP)/STARZ(LP))+HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
M_BUFFER_3(TX+(TY*XRES))=(32-STARZ(LP))*8
END IF
STARZ(LP)=STARZ(LP)-DV
IF STARZ(LP)<=0 THEN STARZ(LP)=STARZ(LP)+32
NEXT
CASE 4
FOR LP=1 TO STARNUM
TX=(STARX(LP)/STARZ(LP))+HALFX
TY=(STARY(LP)/STARZ(LP))+HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
M_BUFFER_4(TX+(TY*XRES))=(32-STARZ(LP))*8
END IF
STARZ(LP)=STARZ(LP)-DV
IF STARZ(LP)<=0 THEN STARZ(LP)=STARZ(LP)+32
NEXT
END SELECT
END SUB
SUB SETSTARS()
DIM LP AS INTEGER
FOR LP=1 TO STARNUM
STARX(LP) = ((RND(1)*5000))-2500
STARY(LP) = ((RND(1)*5000))-2500
STARZ(LP) = (RND(1)*32)
NEXT
DIM AS DOUBLE RR,GG,BB
RR=0
GG=0
BB=0
FOR LP=1 TO 5000
RR+=1
GG+=.75
BB+=.5
IF RR>255 THEN RR=255
IF GG>255 THEN GG=255
IF BB>255 THEN BB=255
PALETTE_(LP)=RGB(RR,GG,BB)
NEXT
END SUB
-
Cool one :) Used the same technique in Magnus (but with 3 frames). My only issue is that this actually runs a bit too fast; some of the outer stars look a bit like trails. I think slower spinning should do the trick :) .
-
If you imagine what's happening in the camera when motion blur occurs, you can try to work out why computer images need to be 'enhanced' to see it.
To take a photo or a movie frame, the shutter on the camera opens, some light gets in and exposes the film, and then the shutter closes. If something moves while the shutter is open that object will be blurry.
Computer generated images are generated instantaneously, with an infinitely small exposure time. This means nothing can move at all while the shutter is open.
One way to fix this is to render multiple frames to simulate the shutter being open, and then average them to get the final output. That's why the 'cheat' of blending in previous rendered frames works so well (though you should really render lots more frames at a higher rate and only display the blended ones, and avoiding feedback from previous blur which has already been added to old frames).
Another way is actually to render the 'defect' directly, which I believe is what Shockwave is doing (got an exe mate? (edit - ta!)).
There's another time-based effect you can see with older video (not film) cameras. It's especially obvious with 1970s TV shows like Doctor Who. The CCD which records the image is exposed just like film - the shutter opens, the CCD is charged up, and the shutter closes. This image is then processed to video tape. The CCD needs to discharge to zero between every frame. Sometimes this does not happen, meaning some of the last image's details are superimposed on the next frame, and leads to the smeary trails that bright objects leave on dark backgrounds on old telly. Modern CCDs hardly have this problem at all.
It's odd though, because motion blur, like lens flare, is an optical fault introduced by using lenses and electronics. Quite why a computer image would be enhanced by adding the defects back in is perverse ;)
Jim
-
Cool one :) Used the same technique in Magnus (but with 3 frames). My only issue is that this actually runs a bit too fast; some of the outer stars look a bit like trails. I think slower spinning should do the trick :) .
I'm really amazed that you only used 3 frames in Magnus! That's as smooth as silk, I thought there was at least 4 frames per pass! The classic sphere bouncing on a plane really does lend it's self well to this technique though.
It's odd though, because motion blur, like lens flare, is an optical fault introduced by using lenses and electronics. Quite why a computer image would be enhanced by adding the defects back in is perverse ;)
It is really - but there's no doubt in my mind that it's worth doing in situations where you can afford it. You only have to look at a static image that has been enhanced with motion blur and you can see which way it was moving.
-
A lot of motion blur is faked and simply works by keeping the last few frames and drawing them with increasing opacity. It's a cheap way of doing the effect and looks kind of shitty.
Hmm, I guess I'll drop my idea then. I don't wanna end up last place again. :P
Anyway, nice example. Thanks for sharing!
-
For a single image, yeah, I reckon that motion blur can help give the impression of movement. Thinking again about real life though, I don't see motion blur on trains or cars going by. :) The question is, what is it that for us determines movement in real life that we feel is lacking in the computer image?
There's no question that it's an important technique in animated movies, and should be part of any demo coder's arsenal of fx :)
Jim
-
Thinking again about real life though, I don't see motion blur on trains or cars going by. :)
That's because your eyes automatically follow the object so it remains sharp - which is fundamental as there's some sort of edge detection going on in the brain.
-
Run so smooth on full screen and Window
very good :)
-
Looking good Shockwave!
Thinking again about real life though, I don't see motion blur on trains or cars going by. :) The question is, what is it that for us determines movement in real life that we feel is lacking in the computer image?
Context I think. If you follow the train, the background is blurry and vice versa. Also because all movies we see are made with cameras with similar defects we've become accustomed to them, so it makes something artificial seem more natural.
This image (http://kirl.nl/picview_cjack.html) for example would just have a few weird floating glowy spheres without the blur. The blur makes seem like a familiar effect. Also when you photograph frothy water with very high shutter speeds, it looks really weird and alien, because it's just never observed like that.
-
......
It's odd though, because motion blur, like lens flare, is an optical fault introduced by using lenses and electronics. Quite why a computer image would be enhanced by adding the defects back in is perverse ;)
Jim
I'm sure I've seen it on a train, looking at ground, foliage or walls passing close by but not allowing your eyes to follow the movement you can see the streaking.
On a slightly different note, the other week I was seeing aliasing and moire patterns, it turned out to be the visuals just before a migraine which I've never suffered from before.
Fryer