Code archives/3D Graphics - Effects/Circular Screen Fade

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

Download source code

Circular Screen Fade by Kryzon2013
Presented here is a screen fade effect by the way of a circle-shaped "iris".
The code builds a specific mesh and animates it to perform the effect. The mesh looks like this:



The way this mesh is positioned, the green vertices never come into view, only the red ones (and that's only when the circle is "closing"). The red vertices go toward the center of the screen, making the circular mask texture get smaller.
The shape of the iris can be customized if you want - you just need to make a square texture of it and have the shape be fully transparent.
The color of this fading mesh can also be changed, you just need to have the mesh and texture being of the same color you want.
This effect can be reproduced in any game engine that allows you to move individual vertices of meshes.

A suggested way to use this effect:
- Have a game screen being played.
- Perform the fade to "close" the view.
- While the view is "closed", change the game screen (hide some models, show others etc.).
- "Open" the view to reveal this new screen.

Original thread = http://blitzbasic.com/Community/posts.php?topic=100101
Graphics3D 800,600,0,2

camera = CreateCamera()
CameraClsColor camera,190,120,35

cube = CreateCube()
MoveEntity cube,0,0,5

light = CreateLight(1)
TurnEntity light,60,-30,0

Const SQUARE_SIZE = 256
;Calculate half the diagonal of the screen and map it to 3D units, so the circle circumscribes the screen perfectly when fully open.
Global HALF_SCREEN_DIAGONAL# = (4.0 * (Sqr(GraphicsWidth()*GraphicsWidth() + GraphicsHeight()*GraphicsHeight()) / 2.0)) / Float(GraphicsWidth()) + 0.1
fadeQuad = CreateCircleFade(camera)
fadeState = False
fadeSize# = 1.0 ;Goes from 1.0 (fully open) to 0.0 (fully closed).
fadeSpeed# = 0.015


fpsTimer = CreateTimer(60)

While Not KeyHit(1)
	WaitTimer(fpsTimer)
	
	TurnEntity cube,0.5,0.6,0.7

	If KeyHit(57) Or KeyHit(28) Then fadeState = Not fadeState
	If fadeState Then 
		fadeSize = fadeSize - fadeSpeed
		If fadeSize < 0 Then fadeSize = 0
	Else
		fadeSize = fadeSize + fadeSpeed
		If fadeSize > 1.0 Then fadeSize = 1.0
	EndIf 
	UpdateCircleFade(fadeQuad, fadeSize)
	
	RenderWorld()
	Color 255,255,255
	Text 10,10,"Press SPACE or ENTER to play the circular fade."
	
	Flip
Wend 

End 


Function CreateCircleFade(camera)
	mesh = CreateMesh(camera)
	surf = CreateSurface(mesh)
	
	xOff# = (4.0 / 2) + 1
	yOff# = (4.0 / 2) / (Float(GraphicsWidth())/GraphicsHeight()) + 1

	v0 = AddVertex(surf,-xOff,yOff,0)
	v1 = AddVertex(surf,xOff,yOff,0,0)
	v2 = AddVertex(surf,-xOff,-yOff,0)
	v3 = AddVertex(surf,xOFf,-yOff,0)
	
	diag# = HALF_SCREEN_DIAGONAL
	
	;Build the mesh.	
	v4 = AddVertex(surf,-diag,diag,0, 0,0)
	v5 = AddVertex(surf,diag,diag,0, 0,0)
	v6 = AddVertex(surf,-diag,-diag,0, 0,0)
	v7 = AddVertex(surf,diag,-diag,0, 0,0)	
		
	v8c = AddVertex(surf,-diag,diag,0, 0,0)
	v9c = AddVertex(surf,diag,diag,0, 1.0,0)
	v10c = AddVertex(surf,-diag,-diag,0, 0,1)
	v11c = AddVertex(surf,diag,-diag,0, 1,1)
	
	AddTriangle(surf,v0,v1,v4)
	AddTriangle(surf,v0,v4,v2)
	AddTriangle(surf,v1,v5,v4)
	AddTriangle(surf,v1,v3,v5)
	AddTriangle(surf,v3,v7,v5)
	AddTriangle(surf,v3,v2,v7)
	AddTriangle(surf,v2,v6,v7)
	AddTriangle(surf,v2,v4,v6)
	
	AddTriangle surf,v8c,v9c,v10c
	AddTriangle surf,v9c,v11c,v10c
	
	EntityColor mesh,0,0,0
	EntityFX mesh,1
	MoveEntity mesh,0,0,2
	
	EntityTexture mesh,CreateMaskedCircleTexture()
		
	Return mesh
End Function


;Here the texture is created procedurally, but one made in Photoshop or whatever, with alpha flag and smooth border, will
;look much better. I wanted to create everything in code so it'd be easier to run, just copy-paste.
Function CreateMaskedCircleTexture()
	Local tex = CreateTexture(SQUARE_SIZE, SQUARE_SIZE, 1+2)
	
	SetBuffer TextureBuffer(tex)
		ClsColor 0,0,0
		Cls
		Color 1,1,1
		Oval 0,0,SQUARE_SIZE,SQUARE_SIZE,True
	SetBuffer BackBuffer()
	
	LockBuffer TextureBuffer(tex)
	For x = 0 To SQUARE_SIZE-1
		For y = 0 To SQUARE_SIZE-1
			argb = ReadPixelFast(x,y,TextureBuffer(tex))			
			If (argb = $FF010101) Then WritePixelFast(x,y,$00000000,TextureBuffer(tex))
		Next
	Next
	UnlockBuffer TextureBuffer(tex)
	
	Return tex
End Function


Function UpdateCircleFade(fadeQuad, fadeSize#=1.0)
	;The "doubled" vertices are 4,5,6 and 7. Their purpose is to keep the area outside the circle black.
	;The circle`s vertices are 8,9,10 and 11, based on the order the vertices were created.
	
	Local surface = GetSurface(fadeQuad,1)
	
	;The animation consists of modulating the vertices' "open" positions by a "unit" value, such as "fadeSize" in this case. 
	;This way the vertices close the circle down.
	Local offset# = HALF_SCREEN_DIAGONAL*fadeSize
	
	VertexCoords(surface, 4,-offset,offset,0)
	VertexCoords(surface, 5,offset,offset,0)
	VertexCoords(surface, 6,-offset,-offset,0)
	VertexCoords(surface, 7,offset,-offset,0)
	
	VertexCoords(surface, 8,-offset,offset,0)
	VertexCoords(surface, 9,offset,offset,0)
	VertexCoords(surface, 10,-offset,-offset,0)
	VertexCoords(surface, 11,offset,-offset,0)

End Function

Comments

BlitzSupport2013
Nice one!


EQX2013
Nice !!


Code Archives Forum