Try my new website:
www.urcho.com
- the new SIMPLE social network
Sign up
|
357
members |
125
snippets
Search for:
ALL
POPULAR
File Controls
Multiplayer Code
2D Effects
3D Effects
Oldskool demos
Basic Functions
Maths/Physics
Sound
Tutorials
Misc
Username:
Password:
Sign up
Realtime Shadows by fredborg
[
back
]
Author:
Archive
| Viewed:
593
times | Language:
BlitzBasic 3D
| Category:
3D Effects
; ; Realtime Shadow thingy ; ; Created by Mikkel Fredborg ; Use as you please! ; Type dl_receiver Field mesh Field surf Field orig End Type Type dl_light Field entity,camera Field width,height Field backcull Field lastx#,lasty#,lastz# Field lastpitch#,lastyaw#,lastroll# End Type Global dl_brush Global dl_tex Function DL_Init() ClearTextureFilters dl_tex = CreateTexture(512,512,1+16+32+256) TextureBlend dl_tex,5 dl_brush = CreateBrush() BrushBlend dl_brush,2 BrushFX dl_brush,1 BrushTexture dl_brush,dl_tex End Function Function DL_Free() For dlr.dl_receiver = Each dl_receiver FreeEntity dlr\mesh Delete dlr Next For dll.dl_light = Each dl_light Delete dll Next If dl_tex Then FreeTexture dl_tex If dl_brush Then FreeBrush dl_brush dl_tex = 0 dl_brush = 0 End Function Function DL_SetReceiver(mesh) dlr.dl_receiver = New dl_receiver dlr\mesh = CreateMesh(mesh) dlr\surf = CreateSurface(dlr\mesh) PaintSurface dlr\surf,dl_brush dlr\orig = mesh End Function Function DL_SetLight(entity,width=256,height=256,backcull=False) dll.dl_light = First dl_light If dll = Null dll.dl_light = New dl_light End If dll\camera = CreateCamera(entity) CameraProjMode dll\camera,0 CameraRange dll\camera,1.0,1000.0 CameraClsColor dll\camera,255,255,255 CameraViewport dll\camera,0,0,width,height CameraZoom dll\camera,0.002 ;<--- This may need changing depending on the scene and light position dll\entity = entity dll\width = width dll\height = height dll\backcull = backcull End Function Function DL_Update() dll.dl_light = First dl_light If dll = Null Then Return ; Hide shadow meshes For dlr.dl_receiver = Each dl_receiver HideEntity dlr\mesh Next ; Render shadow CameraProjMode dll\camera,2 ;<---- Works with perspective as well, but you need to change the zoom RenderWorld CopyRect 0,0,dll\width,dll\height,0,0,BackBuffer(),TextureBuffer(dl_tex) ; Show shadow meshes For dlr.dl_receiver = Each dl_receiver ShowEntity dlr\mesh Next x# = EntityX(dll\entity,True) y# = EntityY(dll\entity,True) z# = EntityZ(dll\entity,True) pitch# = EntityPitch(dll\entity,True) yaw# = EntityYaw(dll\entity,True) roll# = EntityRoll(dll\entity,True) For dlr.dl_receiver = Each dl_receiver If dll\backcull ; ; Remove backfacing triangles If x<>dll\lastx Or y<>dll\lasty Or z<>dll\lastz Or pitch<>dll\lastpitch Or yaw<>dll\lastyaw Or roll<>dll\lastroll ClearSurface dlr\surf n_surfs = CountSurfaces(dlr\orig) For s = 1 To n_surfs surf = GetSurface(dlr\orig,s) n_tris = CountTriangles(surf)-1 For t = 0 To n_tris v0 = TriangleVertex(surf,t,0) v1 = TriangleVertex(surf,t,1) v2 = TriangleVertex(surf,t,2) ex0# = VertexX(surf,v1) - VertexX(surf,v0) ey0# = VertexY(surf,v1) - VertexY(surf,v0) ez0# = VertexZ(surf,v1) - VertexZ(surf,v0) ex1# = VertexX(surf,v2) - VertexX(surf,v0) ey1# = VertexY(surf,v2) - VertexY(surf,v0) ez1# = VertexZ(surf,v2) - VertexZ(surf,v0) ; Triangle normal nx# = ey0 * ez1 - ez0 * ey1 ny# = ez0 * ex1 - ex0 * ez1 nz# = ex0 * ey1 - ey0 * ex1 ; Transform it compared to light TFormNormal nx,ny,nz,dlr\orig,dll\entity If TFormedZ()<0.0 nv0 = AddVertex(dlr\surf,VertexX(surf,v0),VertexY(surf,v0),VertexZ(surf,v0)) nv1 = AddVertex(dlr\surf,VertexX(surf,v1),VertexY(surf,v1),VertexZ(surf,v1)) nv2 = AddVertex(dlr\surf,VertexX(surf,v2),VertexY(surf,v2),VertexZ(surf,v2)) AddTriangle dlr\surf,nv0,nv1,nv2 End If Next Next End If ElseIf CountVertices(dlr\surf) = 0 ; ; No backface culling ClearSurface dlr\surf n_surfs = CountSurfaces(dlr\orig) For s = 1 To n_surfs surf = GetSurface(dlr\orig,s) n_tris = CountTriangles(surf)-1 For t = 0 To n_tris v0 = TriangleVertex(surf,t,0) v1 = TriangleVertex(surf,t,1) v2 = TriangleVertex(surf,t,2) nv0 = AddVertex(dlr\surf,VertexX(surf,v0),VertexY(surf,v0),VertexZ(surf,v0)) nv1 = AddVertex(dlr\surf,VertexX(surf,v1),VertexY(surf,v1),VertexZ(surf,v1)) nv2 = AddVertex(dlr\surf,VertexX(surf,v2),VertexY(surf,v2),VertexZ(surf,v2)) AddTriangle dlr\surf,nv0,nv1,nv2 Next Next End If ; ; Calculate uv's n_verts = CountVertices(dlr\surf)-1 For v = 0 To n_verts TFormPoint VertexX(dlr\surf,v),VertexY(dlr\surf,v),VertexZ(dlr\surf,v),dlr\mesh,0 CameraProject dll\camera,TFormedX(),TFormedY(),TFormedZ() tu# = ProjectedX()/Float(dll\width) tv# = ProjectedY()/Float(dll\height) VertexTexCoords dlr\surf,v,tu,tv Next Next ; Update positions dll\lastx = x dll\lasty = y dll\lastz = z dll\lastpitch = pitch dll\lastyaw = yaw dll\lastroll = roll ; disable shadow camera CameraProjMode dll\camera,0 End Function ; ; Example ; Graphics3D 800,600,0,2 SetBuffer BackBuffer() HidePointer AmbientLight 32,32,32 SeedRnd MilliSecs() camera = CreateCamera() bob = CreateCube() ScaleMesh bob,15,5,5 EntityColor bob,255,255,255 For i = 0 To 20 cube = CreateCube() ScaleMesh cube,Rnd(1,10),Rnd(1,10),Rnd(1,10) RotateMesh cube,Rnd(-90,90),Rnd(-180,180),Rnd(-180,180) PositionMesh cube,Rnd(-100,100),Rnd(-100,100),Rnd(-100,100) AddMesh cube,bob FreeEntity cube Next For i = 0 To 20 sphere = CreateSphere() s# = Rnd(4,20) ScaleMesh sphere,s,s,s PositionMesh sphere,Rnd(-100,100),Rnd(-100,100),Rnd(-100,100) AddMesh sphere,bob FreeEntity sphere Next scene = CreateSphere(32) ScaleEntity scene,100,100,100 FlipMesh scene light = CreateLight() RotateEntity light,70,40,0 PositionEntity light,0,1000,0 PointEntity light,scene DL_Init() DL_SetReceiver(scene) DL_SetLight(light,512,512) spd# = 2.0 zoom# = 1.0 a# = 0.0 b# = 0.0 Repeat MoveEntity camera,(KeyDown(205)-KeyDown(203))*spd,0,(KeyDown(200)-KeyDown(208))*spd TurnEntity camera,-MouseYSpeed()*0.25,-MouseXSpeed()*0.25,0 RotateEntity camera,EntityPitch(camera,True),EntityYaw(camera,True),0 If KeyDown(2) Or KeyDown(3) zoom# = zoom + (KeyDown(2)-KeyDown(3))*0.01 CameraZoom camera,zoom End If MoveMouse 320,240 b = b + 1 RotateEntity light,90+(Sin(b)*20),20+(Cos(b)*20),0 a# = a+1 PositionEntity bob,Sin(a)*50,(Sin(a)*50)+100,Cos(a)*50 TurnEntity bob,1,1,1 HideEntity scene CameraProjMode camera,0 EntityColor bob,0,0,0 DL_Update() EntityColor bob,255,255,255 ShowEntity scene CameraProjMode camera,1 RenderWorld Text 0,0,zoom Flip Until KeyHit(1) DL_Free() End
Author Comments:
Look at the code, and figure it out! :) Only works for a single (directional or spot) light!
Login or
create an account
to comment on this snippet