[bb] Simple shadows by nawi [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:39

Previous topic - Next topic

BlitzBot

Title : Simple shadows
Author : nawi
Posted : 1+ years ago

Description : This is a simple shadow system I made for fun. It's not that fast, and alpha shadows don't work properly.. but you might learn something from this.

Pic:
[img]img146.imageshack.us/img146/8527/shadow2ti1.html">


Code :
Code (blitzbasic) Select
Graphics3D 800,600,0,2
SetBuffer BackBuffer()


Global Cam = CreateCamera()
MoveEntity Cam,0,5,-2



NewObject = GetObject()



;Position our entity
MoveEntity NewObject,0,2.5,0

;White plane
Plane = CreatePlane()
EntityColor Plane,255,255,255
MoveEntity Plane,0,-0.01,0

;Create light
Light = CreateSphere(5)
Spot = CreateLight(2,Light)
ScaleEntity Light,0.1,0.1,0.1
EntityColor Light,255,255,0



Repeat
;Camera movement
If KeyDown(200) Then MoveEntity Cam,0,0,1
If KeyDown(208) Then MoveEntity Cam,0,0,-1
If KeyDown(203) Then MoveEntity Cam,-1,0,0
If KeyDown(205) Then MoveEntity Cam,1,0,0


;Shadow object must be created and destroyed every frame
Shadow = CreateMesh()

EntityAlpha Shadow,1
;There is sadly a bug with alpha shadows.. Didn't figure out a proper solution to this one
;You could use a camera, but would be a major slowdown

; EntityColor Shadow,0,0,0


;Light movement
GY# = 7+Sin(MilliSecs()/10)*0.5
GX# = Cos(MilliSecs()/10)*3

;Draw shadow
DrawShadow(NewObject,GX#,GY#,GZ#,Shadow)
PositionEntity Light,GX#,GY#,GZ#


;FPS
FPSC=FPSC+1
If MilliSecs()>FPSTimer+999 Then
FPSTimer = MilliSecs()
FPS=FPSC
FPSC=0
EndIf




RenderWorld

Text 0,0,"FPS: " + FPS
;Text 0,20,"Trisrendered: " + TrisRendered()
Flip 0

;Destroy shadow
FreeEntity Shadow

Until KeyHit(1)

Function DrawShadow(Entity,SX#,SY#,SZ#,Shadow)
;This works by looping through all triangles, then calculating a line for each vertex to ground (y=0)

EX#=EntityX#(Entity,1)
EY#=EntityY#(Entity,1)
EZ#=EntityZ#(Entity,1)
ShadowSurface = CreateSurface(Shadow)
Surfaces=CountSurfaces(Entity)
For s=1 To Surfaces
Surface = GetSurface(Entity,s)


Triangles=CountTriangles(Surface)-1
For t=0 To Triangles
v1 = TriangleVertex(Surface,t,0)
v2 = TriangleVertex(Surface,t,1)
v3 = TriangleVertex(Surface,t,2)

v1X# = VertexX#(Surface,v1)+EX#
v1Y# = VertexY#(Surface,v1)+EY#
v1Z# = VertexZ#(Surface,v1)+EZ#
K#=-SY#/(SY#-v1Y#)
v1XR# = SX# + (SX#-v1X#)*K#
v1ZR# = SZ# + (SZ#-v1Z#)*K#

v2X# = VertexX#(Surface,v2)+EX#
v2Y# = VertexY#(Surface,v2)+EY#
v2Z# = VertexZ#(Surface,v2)+EZ#
K#=-SY#/(SY#-v2Y#)
v2XR# = SX# + (SX#-v2X#)*K#
v2ZR# = SZ# + (SZ#-v2Z#)*K#

v3X# = VertexX#(Surface,v3)+EX#
v3Y# = VertexY#(Surface,v3)+EY#
v3Z# = VertexZ#(Surface,v3)+EZ#
K#=-SY#/(SY#-v3Y#)
v3XR# = SX# + (SX#-v3X#)*K#
v3ZR# = SZ# + (SZ#-v3Z#)*K#

;Backface culling works by calculating a camera vector and a surface normal
;If the dot product is > 0 then draw

;Camera vector
CX#=SX#-(v1X#+v2X#+v3X#)*0.33333
CY#=SY#-(v1Y#+v2Y#+v3Y#)*0.33333
CZ#=SZ#-(v1Z#+v2Z#+v3Z#)*0.33333

;Surface normal, create 2 vectors and then create vector W from their cross product
UX# = V2X#-V1X#
UY# = V2Y#-V1Y#
UZ# = V2Z#-V1Z#
VX# = V3X#-V1X#
VY# = V3Y#-V1Y#
VZ# = V3Z#-V1Z#
WX# = UY#*VZ#-UZ#*VY#
WY# = -(UX#*VZ#-UZ#*VX#)
WZ# = UX#*VY#-UY#*VX#

;Add triangle
If (SY#>v1Y#) And (SY#>v2Y#) And (SY#>v3Y#) And (CX#*WX#+CY#*WY#+CZ#*WZ#)>0.0 Then
AddTriangle(ShadowSurface,AddVertex(ShadowSurface,v1XR#,0,v1ZR#),AddVertex(ShadowSurface,v2XR#,0,v2ZR#),AddVertex(ShadowSurface,v3XR#,0,v3ZR#))
EndIf

Next
Next
End Function

;Create a test object
Function GetObject()
NewObject = CreateMesh()
Cube = CreateCube()
ScaleMesh Cube,0.6,2.5,0.6

PositionMesh Cube,-3,0,3
AddMesh Cube,NewObject

PositionMesh Cube,6,0,0
AddMesh Cube,NewObject

PositionMesh Cube,-6,0,-6
AddMesh Cube,NewObject

PositionMesh Cube,6,0,0
AddMesh Cube,NewObject

Sphere = CreateSphere(16)


PositionMesh Sphere,-3,2.5,3
AddMesh Sphere,NewObject

PositionMesh Sphere,6,0,0
AddMesh Sphere,NewObject

PositionMesh Sphere,-6,0,-6
AddMesh Sphere,NewObject

PositionMesh Sphere,6,0,0
AddMesh Sphere,NewObject

FreeEntity Cube
FreeEntity Sphere

EntityColor NewObject,0,200,0
Return NewObject
End Function


Comments :


Kryzon(Posted 1+ years ago)

 Neat! Did you test it with animated meshes?


Dabhand(Posted 1+ years ago)

 Thats pretty good nawi! :)


Nate the Great(Posted 1+ years ago)

 I doesn't work when I use rotateentity() but it works when I use turnmesh().Why could that be?


Stevie G(Posted 1+ years ago)

 Replace this ..
v1X# = VertexX#(Surface,v1)+EX#
v1Y# = VertexY#(Surface,v1)+EY#
v1Z# = VertexZ#(Surface,v1)+EZ#
K#=-SY#/(SY#-v1Y#)
v1XR# = SX# + (SX#-v1X#)*K#
v1ZR# = SZ# + (SZ#-v1Z#)*K#

v2X# = VertexX#(Surface,v2)+EX#
v2Y# = VertexY#(Surface,v2)+EY#
v2Z# = VertexZ#(Surface,v2)+EZ#
K#=-SY#/(SY#-v2Y#)
v2XR# = SX# + (SX#-v2X#)*K#
v2ZR# = SZ# + (SZ#-v2Z#)*K#

v3X# = VertexX#(Surface,v3)+EX#
v3Y# = VertexY#(Surface,v3)+EY#
v3Z# = VertexZ#(Surface,v3)+EZ#
K#=-SY#/(SY#-v3Y#)
v3XR# = SX# + (SX#-v3X#)*K#
v3ZR# = SZ# + (SZ#-v3Z#)*K#
With this ...TFormPoint VertexX( Surface, v1 ), VertexY( Surface, v1 ) , VertexZ( Surface, v1 ) , Entity, 0
v1X# = TFormedX()
v1Y# = TFormedY()
v1Z# = TFormedZ()
K#=-SY#/(SY#-v1Y#)
v1XR# = SX# + (SX#-v1X#)*K#
v1ZR# = SZ# + (SZ#-v1Z#)*K#

TFormPoint VertexX( Surface, v2 ), VertexY( Surface, v2 ) , VertexZ( Surface, v2 ) , Entity, 0
v2X# = TFormedX()
v2Y# = TFormedY()
v2Z# = TFormedZ()
K#=-SY#/(SY#-v2Y#)
v2XR# = SX# + (SX#-v2X#)*K#
v2ZR# = SZ# + (SZ#-v2Z#)*K#

TFormPoint VertexX( Surface, v3 ), VertexY( Surface, v3 ) , VertexZ( Surface, v3 ) , Entity, 0
v3X# = TFormedX()
v3Y# = TFormedY()
v3Z# = TFormedZ()
K#=-SY#/(SY#-v3Y#)
v3XR# = SX# + (SX#-v3X#)*K#
v3ZR# = SZ# + (SZ#-v3Z#)*K#
Will ensure it works when using rotateentity.Stevie


Ben(t)(Posted 1+ years ago)

 edit: nevermind


Ryudin(Posted 1+ years ago)

 Very nice! [/i]