March 02, 2021, 02:29:58 PM

Author Topic: [bb] Unique Hardware-Processed Lighting Environments per entity by Drey [ 1+ years ago ]  (Read 659 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Unique Hardware-Processed Lighting Environments per entity
Author : Drey
Posted : 1+ years ago

Description : Controls:
Right Mouse(with movement) makes the cam rotate around the entity

Middle Mouse Resets the camera so it's behide the mesh.

Normal Mouse Rotation steers the mesh around the environment

Mouse Wheel moves the camera away or towards the entity.

M shows light markers

N shows Active Lights

Standard WASD movement

Num 4 and 6 rotates lights
Num 5 stops them and turns on static mode.

Update: Now demoing a better lighting options.  This should be saficient for getting how you'll make a lighting engine.
This is still testing code and i'll make a much cleaner system in the future.  Still to add is fade in, fade out, light types.  

I get about 141fps on my machine.

Update: To better demo the technique, i modded the code a bit to show how it works with many objects on the screen and to better prove how the lighting will work.  Now with
100 objects all gettin their unqiue hardware processed lighting.

Basicly, in this demo, 42 "lights" are created.  I create a speical types called Objects and MavLights( maverick 2.0 is the name of my engine).

Objects have a max value of 8 lights to work on it at once.  MaxLights is a variable tho and can be set from 0 to 8.

Then with that, the nearest number of lights will be turned on and then the object is to be rendered.  

It's important to note a few things:

Though the light markers in the demo aren't, everything else has a default of hidden.  

The first renderworld doesn't show anything at all, instead, places everything into the Z buffer for later rendering.  It's IMPORTANT to change the camera's clsmode to 0,0 after the first renderworld.  

The light searching system works pretty well, but i want to make some bigger improvements on it.  In fact, this section of code probably won't be used in the engine at all.  Because i'm gion to have something called LightPackages.  That really help countdown pointless checks and controls a few other properties.

If u plan to make a game using this technique.  It's important to consider that if u want directional light and such like that.  U'll have to make sure to create those properties in your lighting system.

Also consider what lights u always want to be on.  Directional light should probably always be one of your active lights.

I just threw this together.  In a few months, u should see more from my engine.  For now, i think this techinque is important enough to share.

Any comments are welcome.  
To see the true speed of the system, make sure no markers are on.


Code :
Code: BlitzBasic
  1. Graphics3D 800, 600,32, 2
  2. SetBuffer BackBuffer()
  3. HidePointer
  4.  
  5. Global Cam = CreateCamera()
  6. Global ShowActiveLights
  7.  
  8. SeedRnd MilliSecs()
  9.  
  10. MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
  11. FlushMouse()
  12.  
  13.  
  14. Type MavObject
  15.  
  16.         Field Pivot
  17.         Field Mesh ; What's important to hidden
  18.         Field X#
  19.         Field Y#
  20.         Field Z#
  21.  
  22.         Field  ObjectType
  23.        
  24.        
  25.         Field MaxLights;  How many lights can act on it
  26.  
  27.         Field AmbR; What just a quick option for custom ambient light
  28.         Field AmbG
  29.         Field AmbB
  30.  
  31.        
  32.        
  33.  
  34. End Type
  35.  
  36. Type MavLight
  37.  
  38.         Field Pivot ; Something i might end up using later
  39.         Field Mesh ; Something I might end up using later
  40.         Field X#,Y#,Z#; Placement
  41.        
  42.  
  43.         Field R, G, B ;  Color Values
  44.         Field LightRange# ;  Sets the Range for the light
  45.         Field TriggerRange# ; Sets the Trigger Range, Used to see if it's even worth goin through the check. this is to help take up some processes
  46.  
  47.         Field LightType;  for later use, used for what type of light it is.
  48.         Field AngleIn# ; Used for SpotLights, later use
  49.         Field AngleOut#; Used for SpotLights, later use
  50.  
  51.         Field Static;
  52.         Field Testing
  53.  
  54. End Type
  55.  
  56.  
  57. Dim LC(8) ; Light Checkers( MavLight Handles) .  basicly, the lights that will end up being used for the lighting system
  58. Dim Dis#(8) ; Parallel with LC, it saves the distance of the light
  59.  
  60. Dim DyLC(8)
  61. Dim DyDis#(8)
  62.  
  63. Dim TempCube(8);  if light markers are on
  64.  
  65.  
  66.  
  67.  
  68. Repeat
  69.  
  70.         Locate 0,0
  71.         Cls
  72.         Flip 0
  73.         NumOfLights = Input("NumberOfLights(0 to 8) activiated: " )
  74.        
  75. Until NumOfLights > -1 And NumOfLights < 9
  76.  
  77.  
  78. ST = CreateTexture(16,16,  4)
  79. SetBuffer TextureBuffer(ST)
  80.         Color 0,0,0
  81.         Rect 0,0,16,16
  82.         Color 255,255,255
  83.  
  84.         Oval 0, 0,16,16
  85. SetBuffer BackBuffer()
  86.  
  87.  
  88. Gray = 32
  89.  
  90.  
  91.  
  92. Mesh = CreateSphere(8)
  93. ScaleEntity Mesh, 2.5, 2.5, 2.5
  94.  
  95.  
  96.  
  97.  
  98. HideEntity Mesh
  99.  
  100. Ship.MavObject = New MavObject
  101.  
  102. ShipPivot = CreatePivot()
  103. ShipMesh = Mesh
  104.  
  105. SHipObjectType = 1
  106.         shipMaxLights = NumOfLights
  107.  
  108.  
  109. ShipAmbR = Gray
  110. shipAmbG = Gray
  111. ShipAmbB = Gray
  112.  
  113. ;Not important for the techinque
  114. ;{
  115. CamPointPivot = CreatePivot()
  116.  
  117.  
  118. EntityParent ShipMesh, ShipPivot
  119.  
  120. EntityParent CamPointPivot, ShipPivot
  121.  
  122. EntityParent Cam, CamPOintPivot
  123.  
  124.  
  125.  
  126. MoveEntity Cam, 0, 0, -50
  127.  
  128.  
  129. PositionEntity ShipPivot, 0,0, 0
  130.  
  131. CameraRange Cam, 0.01, 5000
  132. ;}
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. ; This creates the lights, then hiddens them.  I figure it'll be alil after than creating and destroying lights all the time.
  140. Dim Light(8)
  141.  
  142. For I = 0 To 8
  143.  
  144.         Light(I) = CreateLight(2)
  145.  
  146.         HideEntity Light(I)
  147.  
  148. Next
  149.  
  150. ShowActiveLights = 1
  151.  
  152. Sign = 1
  153.  
  154. For X = -5 To 4
  155.         For Z = 0 To 9
  156.        
  157.                 ObjectCount = ObjectCount + 1
  158.                 NO.MavObject = New mavobject ; New Object
  159.  
  160.                 NOPivot = CreatePivot()
  161.                 NOMesh = CopyEntity(Mesh)
  162.                 HideEntity NoMesh
  163.                 NOMaxLights = NumOfLights
  164.  
  165.                
  166.  
  167.                 NOAmbR = Gray
  168.                 NOAmbG =Gray
  169.                 NOAmbB = Gray
  170.  
  171.                 PositionEntity NOMesh, X * 45, 0, Z * 45
  172.                
  173.  
  174.                 NoX = EntityX(NoMesh)
  175.                 NoY = EntityY(nomesh)
  176.                 No = EntityZ(nomesh)
  177.  
  178.         Next
  179. Next
  180.  
  181. ; Light Creation and Placement
  182.  
  183. RotationPivot = CreatePivot()
  184. PositionEntity RotationPivot, 0, 0, 3 * 75
  185.  
  186. LightMesh = CreateSprite()
  187. HideEntity LightMesh
  188. EntityTexture LightMesh, ST
  189.  
  190.  
  191.  
  192.         GLightRange = 45
  193.  
  194.  
  195.  
  196.         GTriggerRange = 150
  197.  
  198.  
  199. For X = -3 To 3 Step 1
  200.         For  Z =0 To 5
  201.         count = count + 1
  202.  
  203.        
  204.        
  205.         L.MavLight = New MavLight
  206.  
  207.        
  208.  
  209.  
  210.        
  211.  
  212.        
  213.                 LR = Rand(255 * Sign)
  214.                 LB = Rand(255 * Sign)
  215.                 LG = Rand(255 * Sign)
  216.  
  217.                 LLightRange = GLightRange
  218.  
  219.                 LTriggerRange = GTriggerRange
  220.        
  221.                
  222.                
  223.                 LX = X * (75)
  224.                 LY =  7 ;Rand(5, 10)
  225.                 L = Z * (75)
  226.  
  227.                 markCube = CopyEntity(LightMesh)
  228.                 HideEntity MarkCube
  229.                 PositionEntity MarkCube, LX, LY, L
  230.                 ScaleEntity MarkCube, .5, .5, .5
  231.                
  232.                         EntityColor MarkCube, Abs(LR), Abs(LG),Abs( LB)
  233.  
  234.                 EntityFX MarkCube, 1
  235.                 HideEntity markcube
  236.                 LMesh = MarkCube
  237.        
  238.                 LPivot = LMesh
  239.                 ;PositionEntity LPivot, LX, LY, L
  240.                 EntityParent LPivot, RotationPivot
  241.                
  242.  
  243.                
  244.  
  245.  
  246.         Next
  247. Next
  248.  
  249.  
  250. LightStatic = 1
  251.  
  252. MoSpd# = 1.5
  253. MeshSpd# = 1
  254. Show_FPS_Counter=1
  255. While KeyHit(1) < 1
  256.  
  257.                
  258.        
  259.         ;MUST OCCUR
  260.         ;Camera Refreshes it's Z buffer( color buffer is optional )
  261.         CameraClsMode Cam, 1,1
  262.         RenderWorld(); This renders NOTHING, but puts things in the Z buffer, important for when u render More than one Object.
  263.        
  264.         ;Must Occur, make sure that the color and z buffer doesn't refresh one bit
  265.         CameraClsMode Cam, 0, 0
  266.         If CreateMarkers
  267.                 RenderLightPlaceHolders()
  268.         EndIf
  269.         LightObjects(); The lighting rountie
  270.        
  271.         ;Mouse wheel allows for a up close look at the action
  272.         MouseZSpeed = MouseZSpeed()
  273.         MoveEntity Cam, 0, 0, MouseZSpeed * 5
  274.  
  275.         MoveEntity ShipPivot, (KeyDown(32) - KeyDown(30))*MeshSpd, (KeyDown(57) - KeyDown(29)) * MeshSpd, (KeyDown(17) - KeyDown(31)) * MeshSpd
  276.  
  277.         If MouseDown(2) ;Mouse Button 2 allows for All angle camera movement
  278.                
  279.                 TurnEntity CamPointPivot, -MouseYSpeed() * MoSpd,  -MouseXSpeed() * MoSpd, 0
  280.                 RotateEntity CamPointPivot, EntityPitch(CamPointPivot), EntityYaw(CamPointPivot), 0
  281.  
  282.         Else
  283.  
  284.                 TurnEntity ShipPivot,0, -MouseXSpeed() * MoSpd, 0
  285. EndIf
  286.  
  287.         If MouseDown(3) ; Somewhat recenters the camera
  288.  
  289.                 RotateEntity CamPointPivot, 25, 0,0
  290.                
  291.         EndIf
  292.  
  293.         TurnEntity RotationPivot, 0, rotationspeed/100.0, 0
  294.  
  295.         If KeyDown(76)
  296.  
  297.                 RotationSpeed = 0
  298.                 LightStatic = 1
  299.                 static(LightStatic)
  300.  
  301.         EndIf
  302.  
  303.         RotationTest = (KeyDown(75) - KeyDown(77))
  304.  
  305.         If RotationTest <> 0
  306.        
  307.                 Rotationspeed = rotationspeed + RotationTest
  308.                
  309.                 If LightStatic = 1 Then
  310.                         LightStatic = 0
  311.                         Static(0)
  312.                 EndIf
  313.         EndIf
  314.        
  315.         ;recenters mouse
  316.         MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
  317.  
  318.  
  319.  
  320.  
  321.         NewLightRange# = (KeyDown(205) - KeyDown(203))
  322.  
  323.         If newLightRange <> 0 Then
  324.        
  325.                 GLightRange  = GLightRange + NewLightRange
  326.                 AddLightRangeAll(NewLightRange)
  327.  
  328.         EndIf
  329.        
  330.         NewTriggerRange# =  (KeyDown(200) - KeyDown(208))
  331.  
  332.  
  333.         If NewTriggerRange <> 0 Then
  334.  
  335.                 GTriggerRange = GTriggerRange + NewTriggerRange
  336.                 AddTriggerRangeAll(NewTriggerRange)
  337.  
  338.         EndIf
  339.  
  340.  
  341.         If KeyHit(50) Then
  342.                 CreateMarkers = Not createMarkers
  343.         EndIf
  344.  
  345.         If KeyHit(49) Then
  346.                 ShowActiveLights = Not ShowActiveLights
  347.         EndIf
  348.  
  349.         ;Cheap instaneous FPS rate
  350.     If Show_FPS_Counter = True Then
  351.        
  352.         EndingFPS = MilliSecs()
  353.         MilliDif% = EndingFPS - StartingFPS
  354.        
  355.         If MilliDif < 1 Then
  356.             MilliDif = 1
  357.        EndIf
  358.  
  359.        FPS_Count = 1000/MilliDif
  360.        
  361.        Text 0,0, "FPS: " + FPS_Count
  362.      
  363.     EndIf
  364.  
  365. StartingFPS = MilliSecs()
  366. If (MilliSecs() - MilliLast) > 1000
  367.         AverFPS = FPSCount
  368.         MilliLast = MilliSecs()
  369.         FPSCount = 0
  370. Else
  371.         FPSCount = FPSCount + 1
  372. EndIf
  373.  
  374.         Text 0, 20, "Object Count: " + ObjectCount
  375.         Text 0, 10, "Lights: " +  count
  376.        
  377.         Text 0, 40, "General Light Range: " +  GLightRange
  378.         Text 0, 50, "General Trigger Range: " + GTriggerRange
  379.         Text 0, 60, "Rotation Speed: " + RotationSpeed
  380.         Text 0, 70, "Aver FPS: " + AverFPS
  381.  
  382.         For I = 0 To ( NumOfLights -1  )
  383.  
  384.                 Text 0, I * 10 + 80, "Light " + DyLC(I)  + " Dis: " + DyDis(I)
  385.  
  386.         Next
  387.        
  388.        
  389.  
  390. Flip False
  391.  
  392.  
  393.  
  394.  
  395.  
  396. Wend
  397. ShowPointer
  398.  
  399. End
  400.  
  401.  
  402.  
  403.  
  404.  
  405. Function LightObjects()
  406.  
  407.  
  408.  
  409.         ;For every mesh u put in MavObjects
  410.         For Obj.MavObject = Each MavObject
  411.  
  412.                 ;Of course, this is important
  413.                 ShowEntity ObjMesh
  414.  
  415.                 ;for now, i just slapped this on the mesh
  416.                 AmbientLight ObjAmbR, objAmbG , objAmbB
  417.                
  418.                 ;Dims all
  419.                 Dim LC(objmaxlights)
  420.                 ;A cheap lil way to make sure it grabs some near by lights.  
  421.                                
  422.                 For L.MavLight = Each MavLight
  423.  
  424.  
  425.                 ActiveShown = 0
  426.                                
  427.                         NewDis = EntityDistance(ObjMesh, LPivot)
  428.                                
  429.                                
  430.                                
  431.                                
  432.                         If NewDis < (LTriggerRange)
  433.  
  434.                                 If Not LStatic
  435.                                         TFormPoint 0,0,0, LPivot, 0
  436.                                        
  437.                                         LX = TFormedX()
  438.                                         LY = TFormedY()
  439.                                         L = TFormedZ()
  440.                                 EndIf
  441.                                
  442.                                         ;This system here see how the NewDistance Compares with the current once.
  443.                                         ;The system is built on a stack idea.
  444.                                         ;Example:
  445.                                         ;ArrayNumber - Handle - Distance
  446.                                         ;   0-1-30
  447.                                         ;   1-2-40
  448.                                         ;   2-26-50
  449.                                         ;If NewDis = 35 and MavLight Handle is 5, this basicly happens
  450.                                         ; 0-1-30
  451.                                         ; 1-5-35
  452.                                         ; 2-2-40
  453.                                         ;The 26-50 gets pushed upward.  The idea is the closest light is 0 and the farthest is ObjMaxLights-1
  454.                                
  455.  
  456.                                        
  457.                                        
  458.                                         For X = 0 To ObjMaxLights - 1
  459.                                
  460.                                                
  461.  
  462.                                                         If LC(X) = 0 Then
  463.  
  464.                                                                 DIS(X) = NewDis
  465.                                                                 LC(X) = Handle(L)
  466.  
  467.         Exit
  468.  
  469.                                                         Else
  470.  
  471.                                                                 If Dis(X) >= NewDis And LC(X) <> Handle(L)
  472.                                                                
  473.                                                                        
  474.                                                                         ;The stack push system
  475.                                                                        
  476.                                                                         For II = ObjmaxLights - 2 To X Step -1
  477.  
  478.                                                                                 LC(II + 1 ) = LC(II )
  479.                                                                                 Dis(II + 1) = Dis(II)
  480.                                                                         Next
  481.                                                                         Dis(X) = NewDis
  482.                                                                         LC(X) = Handle(L)
  483.                                                                        
  484.                                                                        
  485.                                                                         Exit
  486.  
  487.                                                                 EndIf
  488.                                                                
  489.                                                         EndIf
  490.                                                        
  491.                                                 Next
  492.                                                
  493.                                 EndIf
  494.                                
  495.                 Next
  496.                
  497.                 For I = 0 To ObjMaxLights -1
  498.                
  499.                         CurMavLight.MavLight = Object.MavLight( LC( I ) )
  500.                        
  501.                         If CurMavLight <> Null
  502.                                 ; If U want the current lights to have temp makers
  503.  
  504.                                 LightCounter = LightCounter + 1
  505.                                 If ShowActiveLights
  506.  
  507.                                         If ObjObjectType Then
  508.  
  509.                                                
  510.  
  511.                                                 ActiveShown = 1
  512.                                                 TempCube(i) = CreateCube()
  513.                                                 EntityColor TempCube(i), CurMavLightR, CurMavLightG, CurMavLightB
  514.                                                 PositionEntity TempCube(i), CurMavLightX, CurMavLightY, CurMavLight
  515.                                
  516.                                                 EntityFX TempCube(i), 1
  517.                                                 ;ScaleEntity TempCube(i), 1.5, 1.5, 1.5
  518.                                         EndIf
  519.                                 EndIf
  520.  
  521.                                 ;Where all the light placement happens
  522.                                 PositionEntity Light(I), CurMavLightX, CurMavLightY, CurMavLight
  523.                                 LightColor Light(I), CurMavLightR, CurMavLightG, CurMavLightB
  524.                                 LightRange Light(I), CurMavLightLightRange
  525.                                 ShowEntity Light(I)
  526.                                
  527.                         EndIf
  528.                        
  529.                 Next
  530.                
  531.                
  532.                 RenderWorld()
  533.  
  534.  
  535.                 ;resets everything
  536.                 If ActiveShown
  537.                
  538.                         For I = 0 To LightCounter -1
  539.                                 FreeEntity TempCube(i)
  540.                         Next
  541.  
  542.                 EndIf
  543.  
  544.  
  545.                 If  ObjObjectType = 1
  546.  
  547.                         For I = 0 To ObjMaxLights - 1
  548.  
  549.                                 DyLC(I) = LC(I)
  550.                                 DyDis(I) = Dis(I)
  551.  
  552.                         Next
  553.  
  554.                 EndIf
  555.                
  556.                 For i = 0 To ObjMaxLights
  557.  
  558.                                 HideEntity Light(I)
  559.                        
  560.                 Next
  561.  
  562.  
  563.                 ;Hides the Entity
  564.                 HideEntity ObjMesh
  565.  
  566.                
  567.                
  568.         Next
  569.        
  570.  
  571. End Function
  572.  
  573. Function RenderLightPlaceHolders()
  574.  
  575.         For CurLight.MavLight = Each MavLight
  576.  
  577.                 ShowEntity CurLightMesh
  578.  
  579.                 RenderWorld()
  580.  
  581.                 HideEntity CurLightMesh
  582.  
  583.         Next
  584.        
  585. End Function
  586.  
  587. Function AddLightRangeALL(AddThis#)
  588.  
  589.         For L.MavLight = Each MavLight
  590.  
  591.                 LLightRange = LLightRange + AddThis
  592.  
  593.         Next
  594.  
  595. End Function
  596.  
  597. Function AddTriggerRangeALL(AddThis#)
  598.  
  599.         For L.MavLight = Each MavLight
  600.  
  601.                 LTriggerRange = LTriggerRange + AddThis
  602.  
  603.         Next
  604.  
  605. End Function
  606.  
  607. Function Static(value)
  608.  
  609.        
  610.         For L.MavLight = Each MavLight
  611.  
  612.                 LStatic = value
  613.  
  614.                 If  Value = 0
  615.                
  616.                         LX = EntityX(LPivot)
  617.                         LY = EntityY(LPivot)
  618.                         L = EntityZ(LPivot)
  619.                        
  620.                 EndIf
  621.  
  622.         Next
  623.  
  624.  
  625. End Function


Comments :


JoshK(Posted 1+ years ago)

 This is the correct way to do lighting for moving characters, vehicles, etc.


Drey(Posted 1+ years ago)

 Thanks.  After looking at games like Half Life 2 and unreal.  I figured they must be using a system similar to this.Also, thanks for your help with the Z buffer Halo.


puki(Posted 1+ years ago)

 Mmm.I thought this was a bit naff at first - then, instead of 8 active lights, I just used 1 and now I see the effect.  Best to start with 1 and increase the number to see the effect.I like this - in fact, excellent stuff.


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal