and here is the multi pass for shadowing the terrain in realtime
=> TerrainRealtimeShadowMap(Terrain%,LMap%,Scx#,scy#,Sun%=0)
Specify the LightMap Texture applyied to the terrain
So, you 'll have 2 choices :
choise 1 : -> Make a first complete rendering using "ExtractLightMap" function
For convinience, I had an extra "LightmapExtracted" global, if the Lightmap has not yet been extracted, then the lightmap will be automatically generated...
choise 2 : -> Make a cleared texture, apply it to the terrain, and specify the texture to LMap parameter for TerrainRealtimeShadowMap(Terrain%,LMap%,Scx#,scy#,Sun%=0)
the function TerrainRealtimeShadowMap() is made to be used inside the main loop
it performs line after line shadow render
the larger the terrain, most time it needs.
It ran it at 500 FPS on a 1024*1024 TerrainSize (Config in Sig)
Dim Terr_Shd#(0,0) Global LightmapExtracted%=False Function ExtractLightMap%(Terrain%,Scx#,Scy#,Sun%=0,FreeLightmap%=True) Local Sz# = TerrainSize(Terrain) Dim Terr_Shd(Sz,Sz) Local LMap = CreateTexture(Sz,Sz,1+16+32):ScaleTexture(LMap,Sz,Sz):EntityTexture(Terrain,LMap,0,2) Local CBuff%= GraphicsBuffer(),TBuff%=TextureBuffer(LMap) If Sun<>0 :TFormNormal(0,0,1,Sun,0) :Else :TFormNormal(-1,-.5,-.8,0,0) :EndIf Local SunVx#=TFormedX(),SunVy#=TFormedY(),SunVz#=TFormedZ() scy#=Scy/Scx For i = 0 To Sz-1:For j = 0 To Sz-1 :dx#=0.0:dy#=0.0:dz#=0.0:dh#=TerrainHeight(Terrain,i,j)*scy :Repeat dx=dx+SunVx*.95:dy=dy+SunVy*.95:dz=dz+SunVz*.95 If i+dx>=0 And i+dx<Sz And j+dz>=0 And j+dz<Sz TrY#=TerrainHeight(Terrain,i+dx,j+dz)*scy:If TrY>dh+dy:Exit:EndIf:Terr_Shd(i+dx,j+dz)=.9-.4*(dh-Try)/Scy Else :Exit :EndIf Forever :Next:Next SetBuffer(TBuff):LockBuffer(TBuff) For i= 0 To Sz-1:For j= 0 To Sz-1 If terr_Shd(i,j)<>0 :rgb=255*terr_Shd(i,j) :Else :rgb=255 :EndIf WritePixelFast i,Sz-j-1,RGB Shl(16) + RGB Shl(8) + RGB + 255 Shl(24) Next:Next UnlockBuffer(TBuff):SetBuffer CBuff:TextureBlend(LMap,5) If FreeLightmap :FreeTexture(LMap):Dim Terr_Shd(0,0):LightmapExtracted=False Else :LightmapExtracted=True:Return LMap EndIf End Function Global CurseurI%,CurseurJ% Global CurseurFromI%,CurseurToI Global CurseurFromJ%,CurseurToJ Function TerrainRealtimeShadowMap(Terrain%,LMap%,Scx#,scy#,Sun%=0) Local Sz# = TerrainSize(Terrain) If LightmapExtracted=False LMap=ExtractLightMap(Terrain,Scx,Scy,Sun,False) :CurseurToI=Sz-1 :CurseurToJ=Sz-1 :CurseurFromI=0: CurseurFromJ=0 Local CBuff%= GraphicsBuffer(),TBuff%=TextureBuffer(LMap) If Sun<>0 :TFormNormal(0,0,1,Sun,0) :Else :TFormNormal(-1,-.5,-.8,0,0) :EndIf Local SunVx#=TFormedX(),SunVy#=TFormedY(),SunVz#=TFormedZ():scy#=Scy/Scx CurseurFromI=0 :CurseurToI=Sz-1 If CurseurFromJ=Sz-1 :CurseurFromJ=0 :Else :CurseurFromJ=CurseurFromJ+1 :EndIf If CurseurFromJ>Sz-1 CurseurFromJ=Sz-1 CurseurToJ=CurseurFromJ Local dx#,dy#,dz#,dh# For i = CurseurFromI To CurseurToI :For j = CurseurFromJ To CurseurToJ:dx=0:dy=0:dz=0:dh=TerrainHeight(Terrain,i,j)*scy :Repeat dx=dx+SunVx*.95:dy=dy+SunVy*.95:dz=dz+SunVz*.95 If i+dx>=0 And i+dx<Sz And j+dz>=0 And j+dz<Sz TrY#=TerrainHeight(Terrain,i+dx,j+dz)*scy :If TrY>dh+dy:Exit:EndIf:Terr_Shd(i+dx,j+dz)=.9-.4*(dh-Try)/Scy Else :Exit :EndIf Forever:Next:Next SetBuffer(TBuff):LockBuffer(TBuff) For i = CurseurFromI To CurseurToI:For j = CurseurFromJ To CurseurToJ If terr_Shd(i,j)<>0 :rgb=255*terr_Shd(i,j) :Else :rgb=255 :EndIf WritePixelFast i,Sz-j-1,RGB Shl(16) + RGB Shl(8) + RGB; + 255 Shl(24) Next:Next UnlockBuffer(TBuff):SetBuffer CBuff:Return LMap End Function
=> TerrainRealtimeShadowMap(Terrain%,LMap%,Scx#,scy#,Sun%=0)
Specify the LightMap Texture applyied to the terrain
So, you 'll have 2 choices :
choise 1 : -> Make a first complete rendering using "ExtractLightMap" function
For convinience, I had an extra "LightmapExtracted" global, if the Lightmap has not yet been extracted, then the lightmap will be automatically generated...
choise 2 : -> Make a cleared texture, apply it to the terrain, and specify the texture to LMap parameter for TerrainRealtimeShadowMap(Terrain%,LMap%,Scx#,scy#,Sun%=0)
the function TerrainRealtimeShadowMap() is made to be used inside the main loop
it performs line after line shadow render
the larger the terrain, most time it needs.
It ran it at 500 FPS on a 1024*1024 TerrainSize (Config in Sig)