UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on March 21, 2015, 11:04:36 PM

Title: Mapping Light / Shadows using Ray Intersection
Post by: kevin on March 21, 2015, 11:04:36 PM
  Mapping Light / Shadows using Ray Intersection

   This demo shows the core logic behind drawing radial lights in top down 2D game.  The light source is made up of a group triangle fragments drawn in a circular pattern.  So we just step around the edge of the circle and draw triangles from the center to the edges.   This gives us an N sided polygon that represents our light in the scene, the more sides the accurate the circle will be mapped.

  To make it act more light natural light, we need something to handle the occlusion/shadows.  In PlayBASIC we can use the ray intersection support found in the world commands.    That means we define the "hard" parts of the world and by hard I mean zones where light is not allowed to go/pas through,  by outlining them with lines.    So when we draw our light, we run ray intersections along the triangle edges against the hard / occlusion world, if there's a collision we grab the intersection point which will clip our light map triangles for us.

  This demo generates the occlusion world randomly, it's basically a cut'n'paste from the Projects/Worlds/RayIntersectWorld (http://playbasic.com/help.php?page=WORLDS.RAYINTERSECTWORLD) (PlayBASIC Help Files) demo.  

[pbcode]


   WorldWidth=GetScreenWidth()
   WorldHeight=GetScreenHeight()

; create a Camera
   CreateCamera 1

; Create world
   CreateWorld 2
   CaptureToWorld 2

; draw a series of boarder lines around this world
    line 0,0,worldwidth,0
    line worldwidth,0,worldwidth,worldheight
    line worldwidth,worldheight,0,worldheight
    line 0,worldheight,0,0

; draw a series of polygon shaped obejcts into the world
      for lp=1 to 10
         xpos#=50+rnd(worldwidth-100)
         zpos#=50+rnd(worldheight-100)
         size=rndrange(30,100)
         angle=rnd(359)
         Make_Convex(rndrange(3,20),xpos#,zpos#,Size,angle)               
      next lp

; Partition The world up into 32 by 32 cells
   PartitionWorld 2,32
   
; Tell PB to return to Immediate drawing mode
   DrawGfxImmediate

; start of DO/Loop

   Do

      ; capture to scene and grab the world info
      CaptureToScene
      ClsScene
      capturedepth 100
      CameraGrabWorld 1,2

      ; Get the mouse position
      mx#=mousex()
      my#=mousey()

      
      Draw_light(mx#,my#,100)

; draw the camera      
      DrawCamera 1

; show the fps rate and continue this loop
      text 0,0,fps()
      sync
   loop
   

; This function creates a convex polygon shape

Function Make_Convex(edges,xpos#,ypos#,Size,angle)
      sa#=360.0/edges
      c=rndrgb()
      for lp=0 to edges-1
         a#=angle+(lp*sa#)
         x1#=xpos#+cosRadius(a#,size)
         y1#=ypos#+SinRadius(a#,size)
         if lp<(edges-1)
            a#=angle+((lp+1)*sa#)
         else
            a#=angle
         endif
         x2#=xpos#+cosRadius(a#,size)
         y2#=ypos#+SinRadius(a#,size)
         line x2#,y2#,x1#,y1#
      next lp
endfunction i


Function Draw_light(Lx#,Ly#,Radius)

      rays=64

      lockbuffer
      x1#=cosnewvalue(lx#,angle#,Radius)
      y1#=sinnewvalue(ly#,angle#,Radius)
      if RayIntersectWOrld(2,lx#,ly#,x1#,y1#)=true
            x1#=getintersectx#(0)
            y1#=getintersecty#(0)
      endif


      For Ray=1 to Rays
         angle#=(360.0/Rays)*(Ray)      
         x2#=cosnewvalue(lx#,angle#,Radius)
         y2#=sinnewvalue(ly#,angle#,Radius)
         if RayIntersectWOrld(2,lx#,ly#,x2#,y2#)=true
               x2#=getintersectx#(0)
               y2#=getintersecty#(0)
         endif
         
         ; fill this area   
         Tric lx#,ly#,x1#,y1#,x2#,y2#,255

         x1#=x2#
         y1#=y2#
      next
      unlockbuffer

EndFunction

[/pbcode]




 Related Articles:
    * Spooky Shadows (https://www.underwaredesign.com/forums/index.php?topic=3125.0)






Title: Re: Mapping Light / Shadows using Ray Intersection
Post by: ATLUS on March 23, 2015, 09:41:14 AM
Nice code, thank you.