Shadows with Fastext Lib...

Blitz3D Forums/Blitz3D Programming/Shadows with Fastext Lib...

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

This is an attempt to make a ultra fast shadow system, but is not finished and only works on flat surfaces and cameras in 90° degrees.

Maybe someone can make it better. ^_^

Ok, Here is... you need FastExt Lib & PhysX Lib.

Exe + Source + Libs(Demos) = http://www.badmouse.cl/dev/ShadowTest.rar

Fastext Lib - http://www.fastlibs.com/libraries.php#fastextension
Rubux PhysX Lib - http://rubux.net/content/blogsection/1/5/

( The BlurTexture function is from the Code archive )
BlurTexture - http://www.blitzbasic.com/codearcs/codearcs.php?code=754

Include "Inc\fastext.bb"

Graphics3D 800,600,32,6
InitExt	

pxCreateWorld(1,"")
pxSetGravity(0,-58,0)


Global SunAngle# = 50 
Global ShadowRes = 512

Global SoftShadow

Global Cam = CreateCamera()
RotateEntity Cam,90,0,0
PositionEntity Cam,0,40,0
CameraClsColor Cam,255,255,255

AmbientLight 200,200,200

;Create shadow texture
Global ShadowTex = CreateTexture (ShadowRes, ShadowRes, 1+16+32+256 + FE_RENDER + FE_ZRENDER)	
TextureBlend ShadowTex, FE_PROJECT
PositionTexture ShadowTex, 0.5, 0.5									
ScaleTexture ShadowTex, 2, 2


Global plane = CreatePlane()
EntityTexture plane,ShadowTex,0,0
EntityPickMode plane,2
EntityColor plane,0,100,0

Global TestCnt=40

Global TestMesh = CreateCylinder(7,1)
ScaleEntity TestMesh,1.2,1.4,1.2
EntityColor TestMesh,100,100,100
HideEntity  TestMesh

For i=1 To TestCnt
	b=b+1:y=y+1
	If b > 5 c=c+5 :b=0:y=0
	Add_Phys(0,y*5.5,c)
Next


While Not KeyHit(1)

	If KeyDown(17) TranslateEntity Cam,0,0,.1
	If KeyDown(31) TranslateEntity Cam,0,0,-.1

	If KeyDown(32) TranslateEntity Cam,.1,0,0
	If KeyDown(30) TranslateEntity Cam,-.1,0,0

	If KeyHit(18) Add_Phys(EntityX(Cam),EntityY(Cam),EntityZ(Cam))

	If KeyDown(203) SunAngle#=SunAngle#+.1
	If KeyDown(205) SunAngle#=SunAngle#-.1
	
	If KeyHit(57) SoftShadow=1-SoftShadow

	Update_Shadows()
	Update_Phys()

	pxRenderPhysic(60,0)

	RenderWorld()

	Color 255,0,0
	Text 0,0, "Key left and right - Adjust the Sun angle " + SunAngle
	Text 0,15,"Key E - Add Cylinder" 
	Text 0,30,"Space - activate SoftShadows " + SoftShadow
	Text 0,45,"Fps: "+fps#(1000)

	Flip 0


Wend

Type Phys
	Field Mesh,Body
End Type

Function Add_Phys(x#,y#,z#)

	Asd.Phys = New Phys
	
	Asd\Mesh = CopyEntity(TestMesh)
	Asd\Body = pxBodyCreateCylinder(1.2,1.4,6,5)
	pxBodySetPosition Asd\Body, x, y, z

End Function


Function Update_Phys()

	For Asd.Phys = Each Phys
		pxBodySetEntity (Asd\Mesh, Asd\Body)
	Next

End Function


Function Update_Shadows()

	Local Px#, Pz#, Py#, NewX#
	
	Px = EntityX(Cam,1)
	Pz = EntityZ(Cam,1)
	Py = EntityY(Cam,1)
	HideEntity plane

	PositionEntity Cam,0,32,0

	RotateEntity Cam,90,0,0
	TurnEntity Cam,0,SunAngle,0
	
        NewX# = 32 / Tan( 90-SunAngle )
	PositionEntity Cam,Px+NewX,32,Pz
	CameraZoom Cam, 1 / Py
	CameraProjMode Cam,2
	ScaleEntity Cam,Cos(SunAngle),1,1

	SetBuffer TextureBuffer(ShadowTex)

	RenderWorld()

	PositionEntity Cam,Px,Py,Pz
	RotateEntity Cam,90,0,0
	ScaleEntity Cam,1,1,1
	CameraZoom Cam,1
	CameraProjMode Cam,1

	ShowEntity plane


	SetBuffer BackBuffer()


	If SoftShadow = True
		HideEntity Cam
		BlurTexture(ShadowTex,2,2)
		TextureBlend ShadowTex, FE_PROJECT
		ScaleTexture ShadowTex,2,2
		ShowEntity Cam
	EndIf


End Function




Function BlurTexture(Texture, Blur_Quality, Blur_Radius#)

	; This is used for temporary storage of the meshes used for soft shadow blurring.
	Local BlurMesh[16*4]
	Local Loop
	Local Blur_Cam

	Local BLUR_CAM_X# = 65536.0
	Local BLUR_CAM_Y# = 65536.0
	Local BLUR_CAM_Z# = 0.0

	; If blurring is enabled...
	If Blur_Quality > 0

		Blur_Cam = CreateCamera()


		; Set the camera viewport to the same size as the texture.		
		CameraViewport Blur_Cam, 0, 0, TextureWidth(Texture), TextureHeight(Texture)

		; Set the camera so it clears the color buffer before rendering the texture.
		CameraClsColor Blur_Cam, 0, 0, 0
		CameraClsMode  Blur_Cam, True, True						

		; Set the camera's range to be very small so as to reduce the possiblity of extra objects making it into the scene.
		CameraRange Blur_Cam, 0.1, 50
	
		; Set the camera to zoom in on the object to reduce perspective error from the object being too close to the camera.
		CameraZoom Blur_Cam, 16.0

		; Aim camera straight down.	
		RotateEntity Blur_Cam, 90, 0, 0, True
		
		; Position the blur camera far from other entities in the world.
		PositionEntity Blur_Cam, BLUR_CAM_X#, BLUR_CAM_Y#, BLUR_CAM_Z#
		
		; Create the sprites to use for blurring the shadow maps.
		For Loop = 0 To (Blur_Quality*4)-1
			BlurMesh[Loop] = CreateSprite()
		Next
		
		; Set the texture blend mode to multiply.
		TextureBlend Texture, 2
												
		; Scale the texture down because we scale the sprites up so they fill a larger area of the
		; screen.  (Otherwise the edges of the texture are darker than the middle because they don't
		; get covered.
		ScaleTexture    Texture, 0.5, 0.5
		PositionTexture Texture, 0.5, 0.5
						
		; Blur texture by blitting semi-transparent copies of it on top of it.
		BlurRadius# = Blur_Radius# * (1.0 / 256.0)
		BlurAngleStep# = 360.0 / Float(Blur_Quality*4)

		; Normally we would just divide 255 by the number of passes so that adding all the passes
		; together would not exceed 256.  However, if we did that, then we could not have a number of
		; passes which does not divide 256 evenly, or else the error would result in the white part of
		; the image being slightly less than white.  So we round partial values up to ensure that
		; white will always be white, even if it ends up being a little whiter than white as a result
		; when all the colors are added, since going higher than white just clamps to white.
		BlurShade = Ceil(255.0 / Float(Blur_Quality*4))
		
		; Place each of the blur objects around a circle of radius blur_radius.
		For Loop = 0 To (Blur_Quality*4)-1
		
			EntityTexture BlurMesh[Loop], Texture
			EntityFX BlurMesh[Loop], 1+8
			EntityAlpha BlurMesh[Loop], 1.0 / Float(Loop+1)
			ScaleSprite BlurMesh[Loop], 2, 2
																						
			BlurAngle# = BlurAngleStep# * Float(Loop) + 180.0*(Loop Mod 2)
							
			Xoff# = BlurRadius# * Cos(BlurAngle#)
			Yoff# = BlurRadius# * Sin(BlurAngle#)

			PositionEntity BlurMesh[Loop], BLUR_CAM_X# + Xoff#, BLUR_CAM_Y# - 16.0, BLUR_CAM_Z# + Yoff#, True
					
		Next
					
		; Render the new texture.
		RenderWorld
				
		; Copy the new texture from the screen buffer to the texture buffer.		
		CopyRect 0, 0, TextureWidth(Texture), TextureHeight(Texture), 0, 0, BackBuffer(), TextureBuffer(Texture)
					
		; Free the blur entities.
		For Loop = 0 To (Blur_Quality*4)-1
			FreeEntity BlurMesh[Loop]
		Next

		; Free the blur camera.
		FreeEntity Blur_Cam
		
	EndIf

End Function

Global fpsindex#, fpstime#, fpsfold_millisecs#, fpsfps#

Function fps#(time=1000)
	fpsindex=fpsindex+1
	fpstime=fpstime+MilliSecs()-fpsfold_millisecs
	If fpstime=>time
		fpsfps=fpsindex
		fpstime=0
		fpsindex=0
	EndIf
	fpsfold_millisecs=MilliSecs()
	Return fpsfps
End Function