Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs

Blitz3D

The classic Blitz3D compiler for PC. · By Blitz Research

Vertex Lighting That exceeds the 8 light limit (up to 64 lights on MacBook Pro 2012)

A topic by Agent Williams created 14 days ago Views: 29
Viewing posts 1 to 1
(6 edits)

Hello folks my name is Ravel. 

Blitz3d was my first programming language, I started in 2004 with my journey.  I moved over to Unity back in 2012 and continued to advance exponentially, I learned C# and C++ and created a vehicle simulation system called MoDyEn.
Now I returned to Blitz3d, just because its such an awesome language and I wanted to try something new with it. So I began remastering NFSU for my own as for now. So the first problem I came about, was that, at night (that is the generic setting for this game) I soon reached the light limit of 8 lights, which seems to be the limit in Unity as well actually. So I began thinking, how other games surpass this limitation and create beautiful night scenery, with dozens of real-time lights. Soon I understood, that most of the games actually don't use real lights at all, but simply switch on and of from lights near by and bake a light-map to present a lit scenery. 

Now I was still curious that how I could achieve my goal, to have many real-time lights, as it seemed simple as painting a render texture, because all I do is change 3 colors and a range value, meaning I only need 4 dimensions per unit. So its a nice unified number and today's CPU's  should be enable to do a-lot with  dividable numbers. So I quickly found this function "LightMesh" and the combination of "TFormed" posted by puki, back in 2004'ish, that quickly became very interesting to me. Since there are no shader program's available and I did not want to go in depth with triangles and vertices, as things can get really slow, really quickly with these functions (massive loops that are not unified at all!) So I wrote a piece of code from scratch and when I ran it, to my surprise the FPS was sustainable and the scenery looked well lit! There can be still many provements to be made, but as a RAW piece of code, it works surprisingly well!  So here take a look at it, and if you care enough, maybe post updates to it aswell. 

Cheers and have a nice day!
Ravel

;Include "../AShadowBBinclude/fps.bb"

Type TLight
Field source%
Field r#
Field g#
Field b#
Field range#
End Type

Type TLightReceiver
Field entity%
End Type

Global TLightCount% = 0

Function CreateTLight.TLight(lType%=1, parent%=0)
Local l.TLight = New TLight
If parent <> 0
l\source = CreatePivot(parent)
Else
l\source = CreatePivot()
EndIf
l\r=255
l\g=255
l\b=255
l\range=20
TLightCount = TLightCount + 1
Return l
End Function

Function TLightColor( light.TLight, red#, green#, blue# )
light\r = red
light\g = green
light\b = blue
End Function

Function TLightRange( light.TLight, range# )
light\range = range
End Function

Function TLightSetReceiver( entity% )
receiver.TLightReceiver = New TLightReceiver
If (entity=0) Then RuntimeError "Sorry captain, I don't have a clue what to do with 'nothing'... this means there is no receiver defined, Sir!"
EntityFX entity,2; enable vertex colors (!), make sure that the previous FX come along with the entity... otherwise we are going to have a bad time.
receiver\entity = entity
End Function

Function UpdateTLights()
For r.TLightReceiver=Each TLightReceiver
;reset all vertex colors before continuing
LightMesh r\entity,-(255),-(255),-(255)
For l.Tlight=Each TLight
TFormPoint 0,0,0,l\source,r\entity
; Some clever Pythagoras stuff, for further modifications!
ex# = EntityX(r\entity,1)
ey# = EntityY(r\entity,1)
ez# = EntityZ(r\entity,1)
lx# = EntityX(l\source,1)
ly# = EntityY(l\source,1)
lz# = EntityZ(l\source,1)
;emag# = Sqr(ex*ex+ey*ey+ez*ez)
;lmag# = Sqr(lx*lx+ly*ly+lz*lz)
dx# = ex - lx
dy# = ey - ly
dz# = ez - lz
dist# = Sqr(dx*dx+dy*dy+dz*dz)
; I know we should attach the distance to the receiver and compare the distances, but I got confused... 
;If(dist<(l\range*2))
LightMesh r\entity,l\r,l\g,l\b,l\range*l\range,TFormedX(),TFormedY(),TFormedZ()
;EndIf
Next
Next
End Function

AppTitle "Vertex Lighting with unlimited lights"
Graphics3D 1280,720,32,2

; Create some lights
For x=0 To 8
For y=0 To 8

sph = CreateSphere()
ScaleEntity sph,.1,.1,.1
PositionEntity sph,(x-4)*15,(y-4)*15,-4
light.TLight = CreateTLight(1,sph)
TLightColor(light,Rand(10,255),Rand(10,255),Rand(10,255))
TLightRange(light,1)

Next
Next

;Create the camera
camera=CreateCamera()
MoveEntity camera,0,0,-10
 
; Create the player
ent=CreateSphere(32)
TLightSetReceiver(ent);  Make the object receive light (NB!)
ent2=CreateSphere(16,ent)
ScaleMesh ent2,50,50,0.2
PositionEntity ent2,0,0,2
TLightSetReceiver(ent2);  Make the object receive light (NB!)

PointEntity camera,ent
While Not KeyDown(1)


; move the player
mov#=1
If KeyDown(203) MoveEntity ent,-mov,0,0
If KeyDown(205) MoveEntity ent,mov,0,0
If KeyDown(200) MoveEntity ent,0,mov,0
If KeyDown(208) MoveEntity ent,0,-mov,0
PositionEntity camera,EntityX(ent,1),EntityY(ent,1),EntityZ(ent,1)-30

;update the new lights and receiverss
UpdateTLights()

UpdateWorld()
RenderWorld
Text 20,20,"A Test of 8x8 Vertex Light Matrix (64 light sources acting on the receiver!)"
;Text 20,40,"FPS: "+Fps(50)
Flip 0
Wend
End