Ooops
January 15, 2021, 06:11:54 PM

Author Topic: [bb] Realtime Shadows by fredborg [ 1+ years ago ]  (Read 584 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Realtime Shadows by fredborg [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : Realtime Shadows
Author : fredborg
Posted : 1+ years ago

Description : Look at the code, and figure it out! :)

Only works for a single (directional or spot) light!


Code :
Code: BlitzBasic
  1. ;
  2. ; Realtime Shadow thingy
  3. ;
  4. ; Created by Mikkel Fredborg
  5. ; Use as you please!
  6. ;
  7.  
  8. Type dl_receiver
  9.         Field mesh
  10.         Field surf
  11.         Field orig
  12. End Type
  13.  
  14. Type dl_light
  15.         Field entity,camera
  16.         Field width,height
  17.         Field backcull
  18.         Field lastx#,lasty#,lastz#
  19.         Field lastpitch#,lastyaw#,lastroll#
  20. End Type
  21.  
  22. Global dl_brush
  23. Global dl_tex
  24.  
  25. Function DL_Init()
  26.  
  27.         ClearTextureFilters
  28.         dl_tex = CreateTexture(512,512,1+16+32+256)
  29.         TextureBlend dl_tex,5
  30.  
  31.         dl_brush = CreateBrush()
  32.         BrushBlend dl_brush,2
  33.         BrushFX dl_brush,1
  34.         BrushTexture dl_brush,dl_tex   
  35.  
  36. End Function
  37.  
  38. Function DL_Free()
  39.  
  40.         For dlr.dl_receiver = Each dl_receiver
  41.                 FreeEntity dlrmesh
  42.                 Delete dlr
  43.         Next
  44.  
  45.         For dll.dl_light = Each dl_light
  46.                 Delete dll
  47.         Next
  48.  
  49.         If dl_tex       Then FreeTexture dl_tex
  50.         If dl_brush     Then FreeBrush dl_brush
  51.  
  52.         dl_tex          = 0
  53.         dl_brush        = 0
  54.  
  55. End Function
  56.  
  57. Function DL_SetReceiver(mesh)
  58.  
  59.         dlr.dl_receiver = New dl_receiver
  60.         dlrmesh = CreateMesh(mesh)
  61.         dlrsurf = CreateSurface(dlrmesh)
  62.         PaintSurface dlrsurf,dl_brush
  63.         dlrorig = mesh
  64.        
  65. End Function
  66.  
  67. Function DL_SetLight(entity,width=256,height=256,backcull=False)
  68.  
  69.         dll.dl_light = First dl_light
  70.  
  71.         If dll = Null
  72.                 dll.dl_light = New dl_light
  73.         End If
  74.        
  75.         dllcamera        = CreateCamera(entity)
  76.         CameraProjMode dllcamera,0
  77.         CameraRange dllcamera,1.0,1000.0
  78.         CameraClsColor dllcamera,255,255,255
  79.         CameraViewport dllcamera,0,0,width,height
  80.         CameraZoom dllcamera,0.002 ;<--- This may need changing depending on the scene and light position
  81.        
  82.         dllentity        = entity
  83.         dllwidth         = width
  84.         dllheight        = height
  85.  
  86.         dllackcull = backcull
  87.                
  88. End Function
  89.  
  90. Function DL_Update()
  91.  
  92.         dll.dl_light = First dl_light
  93.         If dll = Null Then Return
  94.  
  95.         ; Hide shadow meshes
  96.         For dlr.dl_receiver = Each dl_receiver
  97.                 HideEntity dlrmesh
  98.         Next
  99.        
  100.         ; Render shadow
  101.         CameraProjMode dllcamera,2 ;<---- Works with perspective as well, but you need to change the zoom
  102.         RenderWorld
  103.         CopyRect 0,0,dllwidth,dllheight,0,0,BackBuffer(),TextureBuffer(dl_tex)
  104.  
  105.         ; Show shadow meshes
  106.         For dlr.dl_receiver = Each dl_receiver
  107.                 ShowEntity dlrmesh
  108.         Next
  109.        
  110.         x# = EntityX(dllentity,True)
  111.         y# = EntityY(dllentity,True)
  112.         z# = EntityZ(dllentity,True)
  113.  
  114.         pitch#  = EntityPitch(dllentity,True)
  115.         yaw#    = EntityYaw(dllentity,True)
  116.         roll#   = EntityRoll(dllentity,True)
  117.                
  118.         For dlr.dl_receiver = Each dl_receiver
  119.  
  120.                 If dllackcull
  121.                        
  122.                         ;
  123.                         ; Remove backfacing triangles
  124.                         If x<>dlllastx Or y<>dlllasty Or z<>dlllastz Or pitch<>dlllastpitch Or yaw<>dlllastyaw Or roll<>dlllastroll
  125.                                 ClearSurface dlrsurf
  126.                                 n_surfs = CountSurfaces(dlrorig)
  127.                                 For s = 1 To n_surfs
  128.                                         surf = GetSurface(dlrorig,s)
  129.                                         n_tris = CountTriangles(surf)-1
  130.                                         For t = 0 To n_tris
  131.                                                 v0 = TriangleVertex(surf,t,0)
  132.                                                 v1 = TriangleVertex(surf,t,1)
  133.                                                 v2 = TriangleVertex(surf,t,2)
  134.                                                
  135.                                                 ex0# = VertexX(surf,v1) - VertexX(surf,v0)                             
  136.                                                 ey0# = VertexY(surf,v1) - VertexY(surf,v0)
  137.                                                 ez0# = VertexZ(surf,v1) - VertexZ(surf,v0)
  138.                
  139.                                                 ex1# = VertexX(surf,v2) - VertexX(surf,v0)                             
  140.                                                 ey1# = VertexY(surf,v2) - VertexY(surf,v0)
  141.                                                 ez1# = VertexZ(surf,v2) - VertexZ(surf,v0)
  142.                
  143.                                                 ; Triangle normal
  144.                                                 nx# = ey0 * ez1 - ez0 * ey1
  145.                                                 ny# = ez0 * ex1 - ex0 * ez1
  146.                                                 nz# = ex0 * ey1 - ey0 * ex1
  147.                                                
  148.                                                 ; Transform it compared to light
  149.                                                 TFormNormal nx,ny,nz,dlrorig,dllentity
  150.                                                 If TFormedZ()<0.0
  151.                                                         nv0 = AddVertex(dlrsurf,VertexX(surf,v0),VertexY(surf,v0),VertexZ(surf,v0))
  152.                                                         nv1 = AddVertex(dlrsurf,VertexX(surf,v1),VertexY(surf,v1),VertexZ(surf,v1))
  153.                                                         nv2 = AddVertex(dlrsurf,VertexX(surf,v2),VertexY(surf,v2),VertexZ(surf,v2))
  154.                                                         AddTriangle dlrsurf,nv0,nv1,nv2
  155.                                                 End If
  156.                                         Next
  157.                                 Next
  158.                         End If
  159.                        
  160.                 ElseIf CountVertices(dlrsurf) = 0
  161.                
  162.                         ;
  163.                         ; No backface culling
  164.                         ClearSurface dlrsurf
  165.                         n_surfs = CountSurfaces(dlrorig)
  166.                         For s = 1 To n_surfs
  167.                                 surf = GetSurface(dlrorig,s)
  168.                                 n_tris = CountTriangles(surf)-1
  169.                                 For t = 0 To n_tris
  170.                                         v0 = TriangleVertex(surf,t,0)
  171.                                         v1 = TriangleVertex(surf,t,1)
  172.                                         v2 = TriangleVertex(surf,t,2)
  173.  
  174.                                         nv0 = AddVertex(dlrsurf,VertexX(surf,v0),VertexY(surf,v0),VertexZ(surf,v0))
  175.                                         nv1 = AddVertex(dlrsurf,VertexX(surf,v1),VertexY(surf,v1),VertexZ(surf,v1))
  176.                                         nv2 = AddVertex(dlrsurf,VertexX(surf,v2),VertexY(surf,v2),VertexZ(surf,v2))
  177.                                         AddTriangle dlrsurf,nv0,nv1,nv2
  178.                                 Next
  179.                         Next                   
  180.                        
  181.                 End If
  182.                
  183.                 ;
  184.                 ; Calculate uv's
  185.                 n_verts = CountVertices(dlrsurf)-1
  186.                 For v = 0 To n_verts
  187.                         TFormPoint VertexX(dlrsurf,v),VertexY(dlrsurf,v),VertexZ(dlrsurf,v),dlrmesh,0
  188.                         CameraProject dllcamera,TFormedX(),TFormedY(),TFormedZ()
  189.                         tu# = ProjectedX()/Float(dllwidth)
  190.                         tv# = ProjectedY()/Float(dllheight)
  191.                         VertexTexCoords dlrsurf,v,tu,tv
  192.                 Next
  193.         Next
  194.  
  195.         ; Update positions
  196.         dlllastx = x
  197.         dlllasty = y
  198.         dlllastz = z
  199.         dlllastpitch    = pitch
  200.         dlllastyaw              = yaw
  201.         dlllastroll     = roll
  202.  
  203.         ; disable shadow camera
  204.         CameraProjMode dllcamera,0
  205.        
  206. End Function
  207.  
  208.  
  209.  
  210. ;
  211. ; Example
  212. ;
  213. Graphics3D 800,600,0,2
  214. SetBuffer BackBuffer()
  215.  
  216. HidePointer
  217. AmbientLight 32,32,32
  218. SeedRnd MilliSecs()
  219.  
  220. camera = CreateCamera()
  221.  
  222. bob = CreateCube()
  223. ScaleMesh bob,15,5,5
  224. EntityColor bob,255,255,255
  225.  
  226. For i = 0 To 20
  227.         cube = CreateCube()
  228.         ScaleMesh cube,Rnd(1,10),Rnd(1,10),Rnd(1,10)
  229.         RotateMesh cube,Rnd(-90,90),Rnd(-180,180),Rnd(-180,180)
  230.         PositionMesh cube,Rnd(-100,100),Rnd(-100,100),Rnd(-100,100)
  231.         AddMesh cube,bob
  232.         FreeEntity cube
  233. Next
  234.  
  235. For i = 0 To 20
  236.         sphere = CreateSphere()
  237.         s# = Rnd(4,20)
  238.         ScaleMesh sphere,s,s,s
  239.         PositionMesh sphere,Rnd(-100,100),Rnd(-100,100),Rnd(-100,100)
  240.         AddMesh sphere,bob
  241.         FreeEntity sphere      
  242. Next
  243.  
  244. scene = CreateSphere(32)
  245. ScaleEntity scene,100,100,100
  246. FlipMesh scene
  247.  
  248. light = CreateLight()
  249. RotateEntity light,70,40,0
  250. PositionEntity light,0,1000,0
  251. PointEntity light,scene
  252.  
  253. DL_Init()
  254. DL_SetReceiver(scene)
  255. DL_SetLight(light,512,512)
  256.  
  257. spd# = 2.0
  258.  
  259. zoom# = 1.0
  260.  
  261. a# = 0.0
  262. b# = 0.0
  263.  
  264. Repeat
  265.  
  266.         MoveEntity camera,(KeyDown(205)-KeyDown(203))*spd,0,(KeyDown(200)-KeyDown(208))*spd
  267.         TurnEntity camera,-MouseYSpeed()*0.25,-MouseXSpeed()*0.25,0
  268.         RotateEntity camera,EntityPitch(camera,True),EntityYaw(camera,True),0
  269.  
  270.         If KeyDown(2) Or KeyDown(3)
  271.                 zoom# = zoom + (KeyDown(2)-KeyDown(3))*0.01
  272.                 CameraZoom camera,zoom
  273.         End If
  274.  
  275.         MoveMouse 320,240
  276.  
  277.         b = b + 1
  278.  
  279.         RotateEntity light,90+(Sin(b)*20),20+(Cos(b)*20),0
  280.  
  281.         a# = a+1
  282.         PositionEntity bob,Sin(a)*50,(Sin(a)*50)+100,Cos(a)*50
  283.         TurnEntity bob,1,1,1
  284.  
  285.         HideEntity scene
  286.         CameraProjMode camera,0
  287.         EntityColor bob,0,0,0
  288.  
  289.         DL_Update()
  290.  
  291.         EntityColor bob,255,255,255    
  292.         ShowEntity scene
  293.         CameraProjMode camera,1
  294.  
  295.         RenderWorld
  296.        
  297.         Text 0,0,zoom
  298.         Flip
  299.  
  300. Until KeyHit(1)
  301.  
  302. DL_Free()
  303.  
  304. End


Comments :


Filax(Posted 1+ years ago)

 Thanks ! An idea for colouring shadow ?


fredborg(Posted 1+ years ago)

 Try changing:
Code: [Select]
EntityColor bob,0,0,0

DL_Update()

EntityColor bob,255,255,255
To:
Code: [Select]
EntityColor bob,28,50,100
EntityFX bob,1

DL_Update()

EntityColor bob,255,255,255
EntityFX bob,0



Filax(Posted 1+ years ago)

 Thanks fredborg !


Filax(Posted 1+ years ago)

 Do you think it is possible to do the same with multi light ?


fredborg(Posted 1+ years ago)

 Sure, but it will get pretty slow if you use it on a complex scene, as each light would make a clone of your level.


Olive(Posted 1+ years ago)

 Cool effect thx Fredborg.even if you are a borg...i won't be assimilated.


erbbysam(Posted 1+ years ago)

 I tried to use this but it does cause some pretty massive slow downs in any complex scenes, because, as fredborg said it would.


D4NM4N(Posted 1+ years ago)

 is there a way of applying alpha to shadows ie. not black [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal