[bb] Snowflakes accumulation on the ground with some texels of a texture colored in white by RemiD [ 1+ years ago ]

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

Previous topic - Next topic

BlitzBot

Title : Snowflakes accumulation on the ground with some texels of a texture colored in white
Author : RemiD
Posted : 1+ years ago

Description : This version uses a mesh sphere for each snowflake

Code :
Code (blitzbasic) Select
Graphics3D(800,600,32,2)

SeedRnd(MilliSecs())

Camera = CreateCamera()
CameraRange(Camera,0.1,1000)

GreySkyMesh = CreateCube()
FlipMesh(GreySkyMesh)
ScaleMesh(GreySkyMesh,256,256,256)
PositionEntity(GreySkyMesh,16,0,16)
EntityColor(GreySkyMesh,100,100,100)
EntityFX(GreySkyMesh,1)

TerrainB3D = CreateTerrain(32)
ScaleEntity(TerrainB3D,1,25.5,1)
TerrainDetail(TerrainB3D,2048,True)
TerrainShading(TerrainB3D,True)
PositionEntity(TerrainB3D,0,0,0)

For VX% = 0 To 31
 For VZ% = 0 To 31
  HeightRGB% = Rand(030,035)
  Height# = 1.0/255*HeightRGB
  ModifyTerrain(TerrainB3D,VX,VZ,Height,False)
 Next
Next

TerrainTexColors = CreateTexture(256,256)
SetBuffer(TextureBuffer(TerrainTexColors))
 ClsColor(000,100,000)
 Cls()
 For PX% = 0 To 255
  For PY% = 0 To 255
   R% = 000
   G% = Rand(090,110)
   B% = 000
   Color(R,G,B)
   Plot(PX,PY)
  Next
 Next
SetBuffer(BackBuffer())
ScaleTexture(TerrainTexColors,32,32)
EntityTexture(TerrainB3D,TerrainTexColors,0,0)

SnowFlakeXMesh = CreateSphere(2)
ScaleMesh(SnowFlakeXMesh,0.0625/2,0.0625/2,0.0625/2)
EntityFX(SnowFlakeXMesh,1)
HideEntity(SnowFlakeXMesh)

Const CIsStatic% = 1
Const CIsMoving% = 2

Global SnowFlakesCount% = 0
Type SnowFlake
 Field Mesh
 Field State%
 Field TY#
End Type

SLight = CreateLight(1)
LightColor(SLight,225,225,225)
PositionEntity(SLight,-1000,1000,-1000)
RotateEntity(SLight,45,-45,0)
AmbientLight(100,100,100)

PositionEntity(Camera,16,3.0+1.6,0)

Global SC#

Repeat

 MainLoopStart% = MilliSecs()

 If(KeyDown(17)=1)
  MoveEntity(Camera,0,0,0.1*SC)
 ElseIf(KeyDown(31)=1)
  MoveEntity(Camera,0,0,-0.1*SC)
 EndIf
 If(KeyDown(30)=1)
  TurnEntity(Camera,0,1*SC,0)
 ElseIf(KeyDown(32)=1)
  TurnEntity(Camera,0,-1*SC,0)
 EndIf

 If(SnowFlakesCount < 10000)
  For i% = 1 To 10*SC
   SnowFlakesCount = SnowFlakesCount + 1
   s.SnowFlake = New SnowFlake
   sMesh = CopyEntity(SnowFlakeXMesh)
   PositionEntity(sMesh,16+Rnd(-16.0,16.0),1.6+15,Rnd(0,32.0))
   sTY# = TerrainY(TerrainB3D,EntityX(sMesh,True),0,EntityZ(sMesh,True))
   sState = CIsMoving
  Next
 EndIf

 For s.SnowFlake = Each SnowFlake
  If(sState = CIsMoving)
   If(EntityY(sMesh,True) > sTY+0.025)
    TranslateEntity(sMesh,0,-0.1*SC,0)
   ElseIf(EntityY(sMesh,True) <= sTY+0.025)
    PositionEntity(sMesh,EntityX(sMesh,True),sTY+0.025,EntityZ(sMesh,True))
    sState = CIsStatic
    PX% = Floor(EntityX(sMesh,True)*8)
    PY% = 256-1-Floor(EntityZ(sMesh,True)*8)
    SetBuffer(TextureBuffer(TerrainTexColors))
     Color(255,255,255)
     Plot(PX,PY)
    SetBuffer(BackBuffer())
    FreeEntity(sMesh)
    sMesh = 0
    Delete(s)
    SnowFlakesCount = SnowFlakesCount - 1
   EndIf
  EndIf
 Next

 If(KeyDown(2)=1)
  WireFrame(True)
 Else
  WireFrame(False)
 EndIf
 
 SetBuffer(BackBuffer())
 RenderWorld()

 Color(255,255,255)
 Text(0,0,"Triangles = "+TrisRendered())
 Text(0,20,"FPS = "+Str(FPS))
 Text(0,40,"SnowFlakesCount = "+Str(SnowFlakesCount))

 Flip(1)

 MainLoopTime% = MilliSecs() - MainLoopStart
 If(MainLoopTime = 0)
  MainLoopTime = 1
 EndIf

 FPS% = 1000/MainLoopTime
 SC# = Float(30) / 1000 * MainLoopTime

Until(KeyDown(1)=1)

End()


Comments :


RemiD(Posted 1+ years ago)

 This demo does not use a single surface system for particles so it may be slow on some machines...


Guy Fawkes(Posted 1+ years ago)

 Hi, Remi. First off, I would like to say, AWESOME! :D I've  been looking for something like this for YEARS! Second, I would like to ask if it's possible for you to tweak it so that it has a controllable variable that uses a timer to know when to turn on and off the snow, and make the "accumlation" stack up on the terrain, so that way it's just like real life.Thank You!


RemiD(Posted 1+ years ago)

 Another version with a mesh quad + a texture for each snowflake :
Graphics3D(800,600,32,2)

SeedRnd(MilliSecs())

Camera = CreateCamera()
CameraRange(Camera,0.1,1000)

GreySkyMesh = CreateCube()
FlipMesh(GreySkyMesh)
ScaleMesh(GreySkyMesh,256,256,256)
PositionEntity(GreySkyMesh,16,0,16)
EntityColor(GreySkyMesh,100,100,100)
EntityFX(GreySkyMesh,1)

TerrainB3D = CreateTerrain(32)
ScaleEntity(TerrainB3D,1,25.5,1)
TerrainDetail(TerrainB3D,2048,True)
TerrainShading(TerrainB3D,True)
PositionEntity(TerrainB3D,0,0,0)

For VX% = 0 To 31
 For VZ% = 0 To 31
  HeightRGB% = Rand(030,035)
  Height# = 1.0/255*HeightRGB
  ModifyTerrain(TerrainB3D,VX,VZ,Height,False)
 Next
Next

TerrainTexColors = CreateTexture(256,256)
SetBuffer(TextureBuffer(TerrainTexColors))
 ClsColor(000,100,000)
 Cls()
 For PX% = 0 To 255
  For PY% = 0 To 255
   R% = 000
   G% = Rand(090,110)
   B% = 000
   Color(R,G,B)
   Plot(PX,PY)
  Next
 Next
SetBuffer(BackBuffer())
ScaleTexture(TerrainTexColors,32,32)
EntityTexture(TerrainB3D,TerrainTexColors,0,0)

SnowFlakeXMesh = CreateQuad()
ScaleMesh(SnowFlakeXMesh,0.0625/2,0.0625/2,0.0625/2)
EntityFX(SnowFlakeXMesh,1)
HideEntity(SnowFlakeXMesh)

SnowFlakeImage = CreateImage(16,16)
SetBuffer(ImageBuffer(SnowFlakeImage))
 ClsColor(000,000,000)
 Cls()
 Color(255,255,255)
 Oval(0,0,16,16)
SetBuffer(BackBuffer())
SaveImage(SnowFlakeImage,"SnowFlakeTexDiffuse.bmp")
FreeImage(SnowFlakeImage)
SnowFlakeTexDiffuse = LoadTexture("SnowFlakeTexDiffuse.bmp",4)
EntityTexture(SnowFlakeXMesh,SnowFlakeTexDiffuse,0,0)

Const CIsStatic% = 1
Const CIsMoving% = 2

Global SnowFlakesCount% = 0
Type SnowFlake
 Field Mesh
 Field State%
 Field TY#
End Type

SLight = CreateLight(1)
LightColor(SLight,225,225,225)
PositionEntity(SLight,-1000,1000,-1000)
RotateEntity(SLight,45,-45,0)
AmbientLight(100,100,100)

PositionEntity(Camera,16,3.0+1.6,0)

Global SC#

Repeat

 MainLoopStart% = MilliSecs()

 If(KeyDown(17)=1)
  MoveEntity(Camera,0,0,0.1*SC)
 ElseIf(KeyDown(31)=1)
  MoveEntity(Camera,0,0,-0.1*SC)
 EndIf
 If(KeyDown(30)=1)
  TurnEntity(Camera,0,1*SC,0)
 ElseIf(KeyDown(32)=1)
  TurnEntity(Camera,0,-1*SC,0)
 EndIf

 If(SnowFlakesCount < 10000)
  For i% = 1 To 10*SC
   SnowFlakesCount = SnowFlakesCount + 1
   s.SnowFlake = New SnowFlake
   sMesh = CopyEntity(SnowFlakeXMesh)
   PositionEntity(sMesh,16+Rnd(-16.0,16.0),1.6+15,Rnd(0,32.0))
   RotateEntity(sMesh,0,180,0)
   sTY# = TerrainY(TerrainB3D,EntityX(sMesh,True),0,EntityZ(sMesh,True))
   sState = CIsMoving
  Next
 EndIf

 For s.SnowFlake = Each SnowFlake
  If(sState = CIsMoving)
   If(EntityY(sMesh,True) > sTY+0.025)
    TranslateEntity(sMesh,0,-0.1*SC,0)
    PointEntity(SMesh,Camera)
   ElseIf(EntityY(sMesh,True) <= sTY+0.025)
    PositionEntity(sMesh,EntityX(sMesh,True),sTY+0.025,EntityZ(sMesh,True))
    sState = CIsStatic
    PX% = Floor(EntityX(sMesh,True)*8)
    PY% = 256-1-Floor(EntityZ(sMesh,True)*8)
    SetBuffer(TextureBuffer(TerrainTexColors))
     Color(255,255,255)
     Plot(PX,PY)
    SetBuffer(BackBuffer())
    FreeEntity(sMesh)
    sMesh = 0
    Delete(s)
    SnowFlakesCount = SnowFlakesCount - 1
   EndIf
  EndIf
 Next

 If(KeyDown(2)=1)
  WireFrame(True)
 Else
  WireFrame(False)
 EndIf
 
 SetBuffer(BackBuffer())
 RenderWorld()

 Color(255,255,255)
 Text(0,0,"Triangles = "+TrisRendered())
 Text(0,20,"FPS = "+Str(FPS))
 Text(0,40,"SnowFlakesCount = "+Str(SnowFlakesCount))

 Flip(1)

 MainLoopTime% = MilliSecs() - MainLoopStart
 If(MainLoopTime = 0)
  MainLoopTime = 1
 EndIf

 FPS% = 1000/MainLoopTime
 SC# = Float(30) / 1000 * MainLoopTime

Until(KeyDown(1)=1)

End()

Function CreateQuad()
 TMesh = CreateMesh()
 TSurface = CreateSurface(TMesh)
 AddVertex(TSurface, 1.0, 1.0, 0.0, 0.000, 0.000)
 AddVertex(TSurface, -1.0, 1.0, 0.0, 1.000, 0.000)
 AddVertex(TSurface, 1.0, -1.0, 0.0, 0.000, 1.000)
 AddVertex(TSurface, -1.0, -1.0, 0.0, 1.000, 1.000)
 AddTriangle(TSurface,0,1,2)
 AddTriangle(TSurface,2,1,3)
 UpdateNormals(TMesh)
 Return TMesh
End Function



Krischan(Posted 1+ years ago)

 Nice. I've tried something similar years ago but 3D is too slow and the snow "pixels" on the texture were too big so I coded the <a href="../Community/post4162.html?topic=101692&post=1209015" target="_blank">Snowflakes in 2D</a> using a matte and some tweaking to achieve a fake 3D effect. [/i]