News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Mapping Light / Shadows using Ray Intersection

Started by kevin, March 21, 2015, 11:04:36 PM

Previous topic - Next topic

kevin

  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 (PlayBASIC Help Files) demo.  

PlayBASIC Code: [Select]
   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







 Related Articles:
    * Spooky Shadows







ATLUS