Hi all, I was visiting the TAFE today, so I decided to grab a shadow tutorial off my computer to post on the site... but once I got here, I noticed a major differance in the appearance of the effect once I ran it on the TAFE computers... On mine, it runs fine and creates a shadow... on this computer I'm currently on it blurs with the past shadow creating a very odd motion blur with the shadow texture. I'm pretty sure I know what's causing it.. but I want to know if it's a common accurance.
here is the code:
Sorry it's written oddly, I was writting it as a tutorial.
(not really finished... I should shorten it)
I think the conundrum lies in the fact I was lazey here and tried to hide everything that wasn't the caster, with fog... my card seems to block everything in the haze... (so that's what I had in mind while writting it), but this card lets objects remain visable through the fog...
Is this common?
Oh well, while I'm talking about the tutorial, I want to point out the focus of the long winded tutorial I wrote was actually just these lines:
It casts the texture directionly across the mesh.
This can be used in other ways aswell, such as flashlights.
I hope this helps, plese check it out, best of luck.
the controls are:
"left arrow" - lowers the Xscale# variable.
"right arrow" - highers the Xscale# variable.
"esc" - quit.
(this will make the shadow clearer... when you first start it up, you'll have to lower the Xscale# variable by tapping the left arrow about 6 times before you'll see a nice-ish kinda shadow.)
here is the code:
;Here is file I put together to show the average joe programmer ;how to cast a shadow from an object onto a surface. ;Please note the shadow created is only a directional shadow. ;I hope someone finds this helpful. ;I found the basis of this in the blitz forums years ago... ;But I didn't save the page so I don't know the original coder. ;If you know who it is, please get in contact with me and ;Tell me, he deserves alot of credit. ;I've re-written and tweaked it as I needed, ;but the concept ramains the same. ;It is the basis of my shadow systeml; shaKAL. Graphics3D 800,600 SetBuffer BackBuffer() AmbientLight 0,0,0 ;Ssize: ;the size of the shadows texture. ;(remember To use base 2... eg: 2 4 8 16 32 64 128 256 512) ;make sure it's smaller than the games resolution... ;eg: you can't render a 512x512 map on a 320x240 screen... Global ssize=64 Global shadow_tex=CreateTexture(ssize,ssize,16+32) ;create the shadow texture ;Xscale: ;lets say the default zoom the shadow camera is 1.(it's actually .06, but 1 sounds easyier :P ) ;so if Xscale = 1, the zoom = 1/Xscale# = 1 ;but if Xscale is smaller than 1 it will make the camera zoom in more. ;It's hard for me to explain... play with it, you'll get it in time. Global Xscale#=1 ;creating and setting up the shadow rendering camera. shadowcam=CreateCamera() CameraViewport shadowcam,0,0,ssize,ssize ;the viewport the shadows will be rendered through. CameraClsColor shadowcam,255,255,255 ;Yup, white background for shadow textures. CameraProjMode shadowcam,2 ;Orthographic view, sorry, I've only figured out very simple directional shadows. CameraZoom shadowcam,.06/xscale# ;though the function "shadow_test" does this every time it's used, here it is for you to see anyway. It's not needed here. CameraFogMode shadowcam,1 ;The fog is put on so it seems like everythings white... to make a caster visable to the camera, disable fogging to that object. CameraFogRange shadowcam,1,1 CameraFogColor shadowcam,255,255,255 HideEntity shadowcam ;we don't want it onscreen now. ;just setting up the scene======== camera=CreateCamera() ;<-the game camera PositionEntity camera,0,10,-20 scene=CreateCube() ;<-later used as the receiver. ScaleEntity scene,20,1,20 caster=CreateCube() EntityColor caster,200,0,0 RotateMesh caster,0,0,180 PositionEntity caster, 0,2,0 light=CreateLight(2) ;<-the light source vis_light = CreateSphere(12,light) ;<-sphere used to make the light source visable. EntityColor vis_light,0,200,0 EntityFX vis_light,1 PositionEntity light,-20,8,-1 ;================================= ;placing the shadow texture onto the receiver... ;but If you make a shadow lib For a game, ;You'll probably want this in the actual function... not here. EntityTexture scene,shadow_tex ;Main loop============================================ While quit=0 Cls MoveEntity light,0,0,1:TurnEntity light,0,-5,0 ;A rotating light source. Much more intresting. TurnEntity caster,0,.1,0 RenderWorld UpdateWorld If KeyHit(1) Then quit=1 shadow_test(shadowcam,camera,light,caster,scene) ;<- our function. Text 500,10,"Xscale#: "+ Xscale# Text 500,20,"zoom: "+ .06/Xscale# Text 300,30,"hit ''<-'' & ''->'' to change the Xscale#." Flip If KeyHit(203) Then xscale#=Xscale#*.8 If KeyHit(205) Then xscale#=Xscale#*1.2 Wend End ;===================================================== ;shadow_test function: ;I made this to help explain the how the real magic is done. ;used like so: ;shadow_test(s_camera,g_camera,s_light,s_caster,s_receiver) ; ;>s_camera ; The shadow camera used to render the shadows. ; ;>g_camera ; The in game camera used to render the game. ; ;>s_light ; The light source. ; ;>s_caster ; The object that shadows are casted from. ; ;>s_receiver ; Where the shadows land onto. Function shadow_test(s_camera,g_camera,s_light,s_caster,s_receiver) CameraZoom s_camera,.06/xscale# ;<-setting up the zoom for the shadow rendering camera. HideEntity g_camera ;The in game camera must be hidden, ShowEntity s_camera ;and the shadow camera must become visable. EntityFX s_caster,1+8 ;<- setting up the caster: EntityColor s_caster,0,0,0 ;It needs to be black and unnefexted by fog and lights. ;The shadow rendering camera must be placed at ;the light source Then pointed at the caster. PositionEntity s_camera,EntityX(s_light,1),EntityY(s_light,1),EntityZ(s_light,1) PointEntity s_camera,s_caster ;Here we render the camera and convert it to a texture. RenderWorld() Color 255,255,255: Rect 0,0,ssize,ssize,0 ;<-this rectangle is used to cull anything that tries to poke outside of the textures boundry box. CopyRect 0,0,ssize,ssize,0,0,BackBuffer(),TextureBuffer(shadow_tex) ;The surface and verticy loop. ;This loops through every surface of the receiver mesh, ;Then every surfaces vertecies. ;Our main focus should be the ;"Tformpoint" And "vertextexcoords" commands. ;These commands actually paint the texture onto the ;receiver correctly. For s=1 To CountSurfaces(s_receiver) surf=GetSurface(s_receiver,s) For v=0 To CountVertices(surf)-1 TFormPoint VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v),s_receiver,s_camera VertexTexCoords surf,v,(TFormedX()/Xscale#)/32+0.5,1-((TFormedY()/Xscale#)/32+.5) Next Next ;Here we just switch the attributes of the caster back to normal. ;In an actual game engine you might have to make this more complex. ;I suggest keeping the old attributes in tempory memory then ;calling them back at about this point. EntityFX s_caster,0 EntityColor s_caster,200,0,0 ;here we hide the shadow camera and bring back the game camera, ;ready to go back to the main game loop like nothing ever happend. ShowEntity g_camera HideEntity s_camera End Function
Sorry it's written oddly, I was writting it as a tutorial.
(not really finished... I should shorten it)
I think the conundrum lies in the fact I was lazey here and tried to hide everything that wasn't the caster, with fog... my card seems to block everything in the haze... (so that's what I had in mind while writting it), but this card lets objects remain visable through the fog...
Is this common?
Oh well, while I'm talking about the tutorial, I want to point out the focus of the long winded tutorial I wrote was actually just these lines:
For s=1 To CountSurfaces(s_receiver) surf=GetSurface(s_receiver,s) For v=0 To CountVertices(surf)-1 TFormPoint VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v),s_receiver,s_camera VertexTexCoords surf,v,(TFormedX()/Xscale#)/32+0.5,1-((TFormedY()/Xscale#)/32+.5) Next Next
It casts the texture directionly across the mesh.
This can be used in other ways aswell, such as flashlights.
I hope this helps, plese check it out, best of luck.
the controls are:
"left arrow" - lowers the Xscale# variable.
"right arrow" - highers the Xscale# variable.
"esc" - quit.
(this will make the shadow clearer... when you first start it up, you'll have to lower the Xscale# variable by tapping the left arrow about 6 times before you'll see a nice-ish kinda shadow.)