Code archives/3D Graphics - Effects/Depth of Field

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

Download source code

Depth of Field by fredborg2004
A simple depth of field effect.

Depth of field, you ask? It is a simulation of the loss of focus a camera (or your eyes) has at a range beyond its focal point.

Should be more or less plug-and-pray!

Have fun!
;
; Depth of field
;
; Created by Mikkel Fredborg
; Use as you please!
;
Graphics3D 800,600,0,2
SetBuffer BackBuffer()

HidePointer

;
; Create a camera...
camera = CreateCamera()
CameraRange camera,0.1,1000.0
CameraFogMode camera,True
CameraFogRange camera,100,1000

;
; create some cubes
For i = 0 To 100
	cube = CreateCube()
	PositionEntity cube,Rnd(-100,100),Rnd(-100,20),Rnd(-100,100)
	RotateEntity cube,Rnd(-180,180),Rnd(-180,180),Rnd(-180,180)
	ScaleEntity cube,Rnd(1,10),Rnd(1,10),Rnd(1,10)
Next
			
;
; Light
light = CreateLight()
RotateEntity light,90,0,0

; Depth of Field setup
Type DepthOfField
	Field layers
	Field layer[99]
	Field texture
	Field tsize
	Field tbuffer
	Field near#,far#
	Field camera
End Type

dof.DepthOfField = DOF_Create(camera,3,2.0)

Repeat
	RotateEntity camera,MouseY(),-MouseX(),0
	MoveEntity camera,KeyDown(205)-KeyDown(203),0,KeyDown(200)-KeyDown(208)

	DOF_Update(dof)
	
	RenderWorld
	
	Flip False

Until KeyHit(1)

End

Function DOF_Update(dof.depthoffield)

	HideEntity dof\layer[0]

	CameraRange dof\camera,dof\near*0.95,1000
	CameraViewport dof\camera,0,0,dof\tsize,dof\tsize
	RenderWorld
	CopyRect 0,0,dof\tsize,dof\tsize,0,0,BackBuffer(),dof\tbuffer
	
	ShowEntity dof\layer[0]

	CameraRange dof\camera,0.1,1000	
	CameraViewport dof\camera,0,0,GraphicsWidth(),GraphicsHeight()
	
End Function

Function DOF_Create.DepthOfField(camera,layers,spread#=0.0)

	dof.depthoffield = New depthoffield

	dof\camera = camera

	dof\layers = layers

	dof\tsize	 = 512
	dof\near	 = 100.0
	dof\far		 = 300.0
	
	ClearTextureFilters
	dof\texture = CreateTexture(dof\tsize,dof\tsize,1+256+16+32)
	dof\tbuffer = TextureBuffer(dof\texture)
	
	ang# = 360.0/Float(dof\layers)
	For i = 0 To dof\layers-1
		dof\layer[i] = CreateFace(1)
			
		EntityAlpha dof\layer[i],1.0/Float(dof\layers)
		EntityFX	dof\layer[i],1+8
	
		ps# = dof\near+(i*((dof\far-dof\near)/Float(dof\layers)))

		px# = Sin(i*ang)*(i/Float(dof\layers))*spread
		py# = Cos(i*ang)*(i/Float(dof\layers))*spread
		
		PositionEntity dof\layer[i],px,py,ps
		ScaleEntity dof\layer[i],ps,ps,1.0		
	
		EntityTexture dof\layer[i],dof\texture
		
		If i = 0
			EntityParent dof\layer[i],dof\camera,True
		Else
			EntityParent dof\layer[i],dof\layer[i-1],True
		End If
	Next

	Return dof

End Function

Function CreateFace(segs=1,parent=0)

	mesh=CreateMesh( parent )
	surf=CreateSurface( mesh )
	stx#=-1.0
	sty#=stx
	stp#=Float(2)/Float(segs)
	y#=sty
	For a=0 To segs
		x#=stx
		v#=a/Float(segs)
		For b=0 To segs
			u#=b/Float(segs)
			AddVertex(surf,x,-y,0,u,v) ; swap these for a different start orientation
			x=x+stp
		Next
		y=y+stp
	Next
	For a=0 To segs-1
		For b=0 To segs-1
			v0=a*(segs+1)+b:v1=v0+1
			v2=(a+1)*(segs+1)+b+1:v3=v2-1
			AddTriangle( surf,v0,v2,v1 )
			AddTriangle( surf,v0,v3,v2 )
		Next
	Next
	
	FlipMesh mesh
	UpdateNormals mesh

	Return mesh
	
End Function

Comments

Floyd2004
This is extremely slow for me.

After any input, such a moving the mouse, it takes about one second before I see any movement on screen.

But it all works beautifully if I switch from windowed graphics to full screen.
i.e. use mode 1 in Graphics3D, and change nothing else.


fredborg2004
Switching from 'Flip False' to 'Flip True' may fix it?


CyBeRGoth2004
Brilliant!

The effect is just as good as the one in Zelda the wind waker on the GC :)

Edit

Floyd try putting the line

EnableDirectInput 1 this seems to help a lot, I had a similar problem.


Stevie G2004
Just curious John - what does that do? My help files are not up to date.

Cheers
Stevie


CyBeRGoth2004
A while ago some people were having problems with direct input, it would work ok on their PC but on other peoples the mouse, keyboard, joysyick etc would not work correctly.

That command reverts the way blitz handles input to how it was before it was changed.

seems to fix a lot of problems like this tho, another way is to use windowed mode but that is not ideal for games


jfk EO-111102006
this version is trying to allow camerazooms other than 1.0:




Robert Cummings2006
The problems people are experiencing are typical of "mouse lag" and can be fixed by locking and unlocking the backbuffer. What happens is the card buffers ahead in situations with high fill rate and potentially high framerate.


Ben(t)2007
sorry if I sound stupid but what is it supposed to do?


Mustang2007

what is it supposed to do?



Live and learn, there are no stupid questions... and wikipedia or google is your best friend (if these forums fail which is rare):

http://en.wikipedia.org/wiki/Depth_of_field


virtualjesus2012
This not working for 640x480
Please help me!!!


Code Archives Forum