lightmesh lighting shading on walls and shapes (more than 8 lights)

Started by RemiD, March 17, 2021, 17:12:59

Previous topic - Next topic

RemiD

an example on how to use lightmesh() to light a scene with more than 8 lights.

this is slow and too bright imo (whatever the range set), but a good start if you want to learn custom vertices lighting shading.

;lighting shading with lightmesh on walls and shapes
;by RemiD 2021/03/16

Graphics3D(800,600,32,2)
HidePointer()


SeedRnd(MilliSecs())

;Origine
Global Origine = CreateCube()
ScaleMesh(Origine,0.01,0.01,0.01)
EntityColor(Origine,255,000,255)
EntityFX(Origine,1)

;Camera
Global Camera = CreateCamera()
CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())
CameraRange(Camera,0.15,150)
CameraClsColor(Camera,000,000,000)

Global Pivot = CreatePivot()

;Input
Global MX%
Global MY%
Global MXDiff%
Global MYDiff%

;Ghost
Global GhostRoot
Global GhostRootYaw#
Global GhostEyes
Global GhostEyesPitch#
AddGhost()

;create some walls (pipe)
;texture the walls
;set fx to fullbright, allow vertices colors (Fx 1+2)
PipeSeg = CreatePipeSeg(32,5.0,1.0)
HideEntity(PipeSeg)
;Global Pipe_Mesh = CreateCylinder(32) : ScaleMesh(Pipe_Mesh,5,50.0/2,5) : PositionMesh(Pipe_Mesh,0,50.0/2,0) : RotateMesh(Pipe_Mesh,90,0,0) : FlipMesh(Pipe_Mesh)
Global Pipe_Mesh = CreateMesh()
For S% = 1 To 50 Step 1
Part = CopyMesh(PipeSeg)
PositionMesh(Part,0,0,S-1)
AddMesh(Part,Pipe_Mesh) : FreeEntity(Part)
Next
ColorTex = CreateTexture(8,8)
SetBuffer(TextureBuffer(ColorTex))
Color(240,240,240) : Rect(0,0,8,8,True)
EntityTexture(Pipe_Mesh,ColorTex)
EntityFX(Pipe_Mesh,1+2)
FreeEntity(PipeSeg)

;create some shapes (cubes)
;texture the shapes
;set fx to fullbright, allow vertices colors (Fx 1+2)
Global ShapesCount%
Dim Shape_Mesh(30)

For n% = 1 To 30 Step 1
ShapesCount = ShapesCount + 1 : I% = ShapesCount
Shape_Mesh(I) = CreateCube()
ScaleMesh(Shape_Mesh(I),1.0/2,1.0/2,1.0/2)
ColorTex = CreateTexture(8,8)
SetBuffer(TextureBuffer(ColorTex))
  Color(Rand(180,240),Rand(180,240),Rand(180,240)) : Rect(0,0,8,8,True)
EntityTexture(Shape_Mesh(I),ColorTex)
EntityFX(Shape_Mesh(I),1+2)
PositionEntity(Shape_Mesh(I),0,0,Rnd(0+1,50-1),True)
RotateEntity(Shape_Mesh(I),90,0,0,True)
TurnEntity(Shape_Mesh(I),0,Rand(-180,180),0) : MoveEntity(Shape_Mesh(I),Rand(2,4),0,0)
Next

;create some lights (only the properties)
Global LightsCount%
Dim Light_I#(16) ;intensity
Dim Light_R%(16)
Dim Light_G%(16)
Dim Light_B%(16)
Dim Light_Source(16)

For n% = 1 To 16
LightsCount = LightsCount + 1 : I% = LightsCount
Light_I(I) = 0.75
Light_R(I) = Rand(024,240) : Light_G(I) = Rand(024,240) : Light_B(I) = Rand(024,240)
Light_Source(I) = CreateSphere(2) : ScaleMesh(Light_Source(I),0.05/2,0.05/2,0.05/2) : EntityColor(Light_Source(I),Light_R(I),Light_G(I),Light_B(I)) : EntityFX(Light_Source(I),1)
Z# = Rnd(0+3,50-3)
PositionEntity(Pivot,0,0,Z,True) : RotateEntity(Pivot,0,0,Rand(-180,+180),True)
TFormPoint(0,+5-Rnd(1.5,2.5),0,Pivot,0)
PositionEntity(Light_Source(I),TFormedX(),TFormedY(),TFormedZ(),True)
Next

;define the ambient light
AmbientR% = 030
AmbientG% = 030
AmbientB% = 030

;light the scene using lightmesh()
;light the walls of pipe
LightMesh(Pipe_Mesh,-255,-255,-255) ;reset vertices color
LightMesh(Pipe_Mesh,AmbientR,AmbientG,AmbientB) ;color with ambientlight
For LI% = 1 To LightsCount
TFormPoint(0,0,0,Light_Source(LI),Pipe_Mesh)
LightMesh(Pipe_Mesh,Light_R(LI),Light_G(LI),Light_B(LI),Light_I(LI),TFormedX(),TFormedY(),TFormedZ()) ;light color
Next
;light the shapes
For I% = 1 To ShapesCount
LightMesh(Shape_Mesh(I),-255,-255,-255) ;reset vertices color
LightMesh(Shape_Mesh(I),AmbientR,AmbientG,AmbientB) ;color with ambientlight
For LI% = 1 To LightsCount
  TFormPoint(0,0,0,Light_Source(LI),Shape_Mesh(I))
  LightMesh(Shape_Mesh(I),Light_R(LI),Light_G(LI),Light_B(LI),Light_I(LI),TFormedX(),TFormedY(),TFormedZ()) ;light color
Next
Next

PositionEntity(GhostRoot,0,1.0,-5)

Repeat

MX = MouseX() : MY = MouseY()

MXDiff = MouseXSpeed() : MYDiff = MouseYSpeed()

UpdateGhost()     

PositionEntity(Camera,EntityX(GhostEyes,True),EntityY(GhostEyes,True),EntityZ(GhostEyes,True),True)
RotateEntity(Camera,EntityPitch(GhostEyes,True),EntityYaw(GhostEyes,True),EntityRoll(GhostEyes,True),True)

WireFrame(False)
If( KeyDown(2)=1 )
  WireFrame(True)
EndIf

SetBuffer(BackBuffer())
RenderWorld()

Color(250,250,250) : Text(0,0,MilliTime)

Flip(1)

Until( KeyDown(1)=1 )

End

Function AddGhost()

GhostRoot = CreatePivot()

GhostEyes = CreatePivot()
EntityParent(GhostEyes,GhostRoot,True)

End Function

Function UpdateGhost()

MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
GhostEyesPitch = GhostEyesPitch + Float(MYDiff)/10
If( GhostEyesPitch < -89 )
  GhostEyesPitch = -89
Else If( GhostEyesPitch > 89 )
  GhostEyesPitch = 89
EndIf
RotateEntity(GhostEyes,GhostEyesPitch,0,0,False)
GhostRootYaw = GhostRootYaw - Float(MXDiff)/10
RotateEntity(GhostRoot,0,GhostRootYaw,0,False)

If( KeyDown(42) = 0 And KeyDown(29) = 0 )
  Speed# = 0.1
Else If( KeyDown(42) = 1 And KeyDown(29) = 0 )
  Speed# = 1
Else If( KeyDown(42) = 0 And KeyDown(29) = 1 )
  Speed# = 0.01
EndIf

If( KeyDown(17)=1 )
  MoveEntity(GhostRoot,0,0,Speed)
Else If( KeyDown(31)=1 )
  MoveEntity(GhostRoot,0,0,-Speed)
EndIf
If( KeyDown(30)=1 )
  MoveEntity(GhostRoot,-Speed,0,0)
Else If( KeyDown(32)=1 )
  MoveEntity(GhostRoot,Speed,0,0)
EndIf
If( KeyDown(16)=1 )
  MoveEntity(GhostRoot,0,-Speed,0)
Else If( KeyDown(18)=1 )
  MoveEntity(GhostRoot,0,Speed,0)
EndIf

End Function

Function CreatePipeSeg(Sides%=32,Radius#=5.0,Length#=1.0)

Rotor = CreatePivot()

Mesh = CreateMesh()

;surface
Surface = CreateSurface(Mesh)

;vertices
S% = 0 
SRoll# = 360.0/Sides
PositionEntity(Rotor,0,0,0,True) : RotateEntity(Rotor,0,0,0,True)
For Z# = 0 To Length Step 1
  S% = 0
  Repeat
   S = S + 1
   TFormPoint(0,+Radius,Z,Rotor,0)
   ;Marker = CreateCube() : ScaleMesh(Marker,0.03/2+Float(S)/1000,0.03/2+Float(S)/1000,0.03/2+Float(S)/1000)
   ;PositionEntity(Marker,TFormedX(),TFormedY(),TFormedZ())
   AddVertex(Surface,TFormedX(),TFormedY(),TFormedZ())
   TurnEntity(Rotor,0,0,SRoll)
  Until( S = Sides )
Next

;triangles
For S% = 1 To Sides Step 1
  V0I% = S  : If( S = Sides ) : V0I% = 0 : EndIf
  V1I% = S-1
  V2I% = Sides+S : If( S = Sides ) : V2I% = Sides+0 : EndIf
  V3I% = Sides+S-1
  AddTriangle(Surface,V0I,V1I,V2I)
  AddTriangle(Surface,V2I,V1I,V3I)
Next

FreeEntity(Rotor)

UpdateNormals(Mesh)

;DebugLog(CountVertices(Surface))
;DebugLog(CountTriangles(Surface))

Return Mesh

End Function