How to create a glow effect

Blitz3D Forums/Blitz3D Programming/How to create a glow effect

Could anyone tell me the teory on how to create a glow effect filter like in Prince of Persia - Sand of time

It is a 'Bloom filter' - has been done in Blitz recently. There were a couple of demos knocking about.

I don't know anything about it but Googling on 'Bloom Filter' will help.

Create a texture with texture flag 256 so it is stored in video ram. (This makes copying from video ram to it faster.)

Then each frame, render your scene in a small viewport, but do not flip, and copy the viewport to the texture you created.

Then set your viewport back to normal size, and place a quad over the viewport with the texture applied and scaled properly. Set the quad to add blend. Then render the scene and flip.

I had this in my archives:
Graphics3D 800,600,16,2
SetBuffer BackBuffer()
 
camera=CreateCamera()
MoveEntity camera,0,0,-30

planet=CreateSphere()

glow=CreateSprite()

ScaleSprite glow,2,2 ; cange the scale for more or less glow

light=CreateLight(2)
MoveEntity light,100,100,-100


tex=CreateTexture(64,64,48+2+512)
SetBuffer TextureBuffer(tex)
For i=1 To 64
	Color i*3,i*3,i*4
	Oval i/2,i/2,64-i,64-i,1
Next
EntityTexture glow,tex
EntityBlend glow,3

While Not KeyHit(1)


	PositionEntity glow,EntityX(planet),EntityY(planet),EntityZ(planet)
	PointEntity glow,camera
	MoveEntity glow,0,0,-.5

If KeyDown(200) = True Then ; UP ARROW
	y = y + 1
	MoveEntity planet,0,y,0
EndIf

If KeyDown(208) = True Then ; DOWN ARROW
	y = y - 1
	MoveEntity planet,0,y,0
EndIf
If y > 12 Then y = 12
If y < -12 Then y = -12

UpdateWorld
RenderWorld

Color 255,255,255

Text 0,0,"PLANET X: "+EntityX(planet)
Text 20,20,"PLANET Y: "+EntityY(planet)

Flip

Wend

End
Anyone know why the text refuses to print???

Yes - Because you forgot SetBuffer Backbuffer() after you used it with TextureBuffer()

And I do not know what you use as Computer - but that is so damn fast here on my old set, that after I even touch the keyboard the sphere is lightyears away ;-)

[Edited] I see what's wrong and why its so fast...
It should not be y=y+1 : better is y=1 since you use Moveentity
You programmed an enormous acceleration into it. After 1/10 second keydown it made 12 units/sec here.

D'oh!!!!
No I have the same sphere moving problem. It has to do with scale... scale everything up and the sphere moves more slowly...

Your y=1 is a great solution too... I wrote that for a missle type game... forgot to rewrite it... double d'oh!!!

RZ

Thanks guys..
sswift, you make my glow code really glow. I try and got this. I don't know how its happen but its work.
; CreateCamera Example
; --------------------

Graphics3D 640,480,16,2
SetBuffer BackBuffer()

; Create camera
Global camera=CreateCamera()
MoveEntity camera,3,3,0
RotateEntity camera,30,30,0

light=CreateLight()

Global cube=CreateCube()
PositionEntity cube,0,0,5

;glow setup
Global sizex=160
Global sizey=120
Global glowtexture=CreateTexture (384,384,256)
Global sp=CreateSprite(camera)
MoveEntity sp,-.25,-.05,1.2
EntityAlpha sp,.9
ScaleTexture glowtexture,GraphicsWidth()/sizex,GraphicsHeight()/sizey
EntityTexture sp,glowtexture

While Not KeyDown( 1 )
	CameraViewport camera,0,0,sizex,sizey
	RenderWorld
	CopyRect 0,0,sizex,sizey,0,0,BackBuffer(),TextureBuffer(glowtexture)
	CameraViewport camera,0,0,GraphicsWidth(),GraphicsHeight()
	RenderWorld
	Flip
Wend

End



..but I still don't have any idea on how to put a sprite just in front of viewport perfectlly.

looks like it is raycasting... have you tried to move the cube or increase the size of the viewport OR decrease the glow effect?

RZ

After I tweek some of the variable, I get the result that I want. I put this code in code archieve. Thanks all you guys for the help.

Graphics3D 640,480,32,2
SetBuffer BackBuffer()

; Create camera
Global camera=CreateCamera()
MoveEntity camera,3,3,0
RotateEntity camera,30,30,0

light=CreateLight()

Global cube=CreateCube()
PositionEntity cube,0,0,5
tex0=CreateTexture(300,300)
SetBuffer TextureBuffer(tex0)
ClsColor 255,255,255
Cls
SeedRnd(MilliSecs())
For k=1 To 50
	Color Rand(256),Rand(256),Rand(256)
	Rect Rand(600),Rand(600),Rand(600),Rand(600)
Next
EntityTexture cube,tex0
SetBuffer BackBuffer()

;glow setup
s=1
Global sizex=640/s
Global sizey=480/s
Global glowtexture=CreateTexture (384,384,256)
Global sp=CreateSprite(camera)
MoveEntity sp,-.25,-0.06,1.18
EntityAlpha sp,.32
ScaleTexture glowtexture,GraphicsWidth()/sizex,GraphicsHeight()/sizey
EntityTexture sp,glowtexture
TextureBlend glowtexture, 5
While Not KeyDown( 1 )
	TurnEntity cube,0.5,0.5,0.5
	CameraViewport camera,0,0,sizex,sizey
	RenderWorld
	CopyRect 0,0,sizex,sizey,0,0,BackBuffer(),TextureBuffer(glowtexture)
	CameraViewport camera,0,0,GraphicsWidth(),GraphicsHeight()
	
	RenderWorld
	Flip
Wend

End


If somebody know the best way to put a sprite in front of a screen (for this effect purpose), please help me..

Use EntityOrder for making the sprite appear in front of everything. eg. EntityOrder mysprite,-9999

A little something I used in SpaceJunk (WIP)
; ***********************************************************************************
; MOD_DreamFilter

DebugLog "MOD_Dreamfilter.bb"

;Include "LIB_Render2Tex.bb"

;InitialiseR2T()

; ***********************************************************************************

; NO GLOBALS ALLOWED!

Type DreamFilter
	Field TextureSize
	Field MotionZoom#
	Field FeedbackRed,FeedbackGreen,FeedbackBlue
	Field Strength#
	Field Position#
	Field Offset#
	Field BlurMesh
	Field BlurSurface
	Field BlurTexture
	Field Show
	;Field R2THolder
End Type

Type DreamEntity
	Field Entity
	Field Show
End Type


; *********************************************************************************

Function DreamEntity_Add(entity,show=True)    ; EXCLUDE FROM DREAM RENDER

	Local e.DreamEntity = New DreamEntity
	e\Entity = Entity
	e\Show = Show
	Return Handle(e)

End Function

; *********************************************************************************

Function DreamEntity_Remove(ent)

	Local e.DreamEntity = Object.DreamEntity(ent)
	Delete e
	
End Function

; *********************************************************************************

Function DreamEntity_State(ent,state)
	Local e.DreamEntity = Object.DreamEntity(ent)
	e\Show = State
End Function


; *********************************************************************************

Function DreamFilter_Create(cam,TexSize = 256,MotionZoom#=1.022,FeedBackRed=220,FeedBackGreen=220,FeedBackBlue=220,Strength#=100,Position#=1.1,Offset#=0.001)
	
	Local d.DreamFilter = New DreamFilter
	
	
	d\Show			= True
	d\TextureSize 	= TexSize
	d\MotionZoom# 	= MotionZoom#
	d\FeedbackRed 	= FeedbackRed
	d\FeedbackGreen = FeedbackGreen
	d\FeedbackBlue 	= FeedbackBlue
	d\Strength# 	= Strength#
	d\Position#		= Position#
	d\Offset#		= Offset#

	d\BlurMesh		= CreateMesh(cam)
	d\BlurSurface 	= CreateSurface(d\BlurMesh)
	d\BlurTexture 	= CreateTexture(d\TextureSize,d\TextureSize,256+1+16+32)
	EntityTexture 	d\blurMesh, d\BlurTexture
	
;	d\R2THolder = NewRenderTexture(TexSize,TexSize)
;	rt.RenderTexture = Object.RenderTexture(d\R2THolder)
;	MakeRenderTexture(d\BlurTexture,rt)

	AddVertex   	d\BlurSurface, -1, 1, 0, 0, 0
	AddVertex   	d\BlurSurface,  1, 1, 0, 1, 0
	AddVertex   	d\BlurSurface, -1,-1, 0, 0, 1
	AddVertex   	d\BlurSurface,  1,-1, 0, 1, 1
	AddTriangle 	d\BlurSurface, 0, 1, 2
	AddTriangle 	d\BlurSurface, 3, 2, 1

	PositionEntity 	d\BlurMesh,-d\Offset#,d\Offset#, d\Position#
	ScaleEntity   	d\BlurMesh,d\MotionZoom# * d\Position#,d\MotionZoom# * d\Position#,1.0
	EntityOrder 	d\BlurMesh,  -10000
	EntityFX 		d\BlurMesh, 1
	EntityBlend    	d\BlurMesh, 3
	
	Return Handle(d)
	
End Function

; *********************************************************************************

Function DreamFilterShow(filter,show=1)

	d.DreamFilter = Object.DreamFilter(Filter)
	d\Show = show
	If show Then
		ShowEntity d\BlurMesh
	Else
		HideEntity d\BlurMesh
	EndIf
	
End Function



; *********************************************************************************

Function DreamFilter_Destroy(filter)

	d.DreamFilter = Object.DreamFilter(Filter)
	FreeTexture d\BlurTexture
	FreeEntity  d\BlurMesh
	Delete d
 	
End Function

; *********************************************************************************

Function DreamFilter_Update(cam,filter)

	d.DreamFilter = Object.DreamFilter(Filter)

	If Not d\Show Then Return

	CameraViewport 	Cam, 0, 0, d\TextureSize, d\TextureSize
	EntityColor 	d\BlurMesh, d\FeedbackRed,d\FeedbackGreen,d\FeedbackBlue
	
	For e.DreamEntity = Each DreamEntity
		If Not e\show Then HideEntity e\Entity
	Next
;	CameraRange cam,1,10
	RenderWorld 
;	CameraRange cam,1,1000
	CopyRect  		0,0,d\TextureSize,d\TextureSize, 0, 0, BackBuffer(), TextureBuffer(d\BlurTexture)
	CameraViewport 	Cam,0,0,GraphicsWidth(),GraphicsHeight()
	EntityColor 	d\BlurMesh, d\Strength# ,d\Strength# ,d\Strength# 
	
	For e.DreamEntity = Each DreamEntity
		ShowEntity e\Entity
	Next
	
End Function

Before =

And with the filter =



Use EntityOrder for making the sprite appear in front of everything. eg. EntityOrder mysprite,-9999

Thanks, that is to force drawing layer but the sprite position is my issue.

When we move or rotate the camera, we need to also move and scale our sprite so that its perfectlly in front of our view. The distance from camera must always consistant. How do I archieve that.

Btw, really good stuff there.. I will look into the above code letter..

Then parent the sprite to the camera. It will always be where you want it:)

like in the code above

d\BlurMesh		= CreateMesh(cam)


TQ

It's a pleasure.

|
|
V

er...nm