Volumetric clouds [CODE]

Advanced game related topics
User avatar
minimy
Enthusiast
Enthusiast
Posts: 599
Joined: Mon Jul 08, 2013 8:43 pm
Location: off world

Volumetric clouds [CODE]

Post by minimy »

Hello, after the video, the code is here. This code have a procedure to make the cloud, only one for call.
Have rain and storm effect with lights + particles.
For the clouds i use billboards.
Not tested in 6.2 but must work because is not complex code.

The winter is coming! :mrgreen: (john snow)

Code: Select all

;{ SISTEMA
UsePNGImageDecoder()

InitEngine3D(#PB_Engine3D_DebugLog):InitSprite():InitKeyboard():InitMouse()
OpenWindow(0, 0,0, 1280,720, "Clouds [Arrows= move]",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0),WindowHeight(0), 0, 0, 0)
CreateCamera(0,0,0,100,100):MoveCamera(camara,258.33,22.97,279.69,#PB_Absolute):CameraLookAt(0,0,0,0):CameraBackColor(0,$332211)
CreateLight(0,$ffffff,23,23,23)

Procedure   CameraUserControl(camera,speed.f=0.1,smooth.f=0.1,yfixed.f=1e10)
  Static.f MouseX,Mousey,depx,depz,sdepx,sdepz,     fdf.b
  
  depx=-speed*(KeyboardPushed(#PB_Key_Left)-KeyboardPushed(#PB_Key_Right))
  depz=-speed*(KeyboardPushed(#PB_Key_Down)-KeyboardPushed(#PB_Key_Up)-MouseWheel()*40)
;   depx=-speed*(KeyboardPushed(#PB_Key_A)-KeyboardPushed(#PB_Key_D))
;   depz=-speed*(KeyboardPushed(#PB_Key_S)-KeyboardPushed(#PB_Key_W)-MouseWheel()*20)
  If KeyboardReleased(#PB_Key_F12):fdf=1-fdf:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf:EndIf
  MouseX = -MouseDeltaX() *  0.05
  MouseY = -MouseDeltaY() *  0.05
  RotateCamera(camera, MouseY, MouseX, 0, #PB_Relative)
  sdepx+(depx-sdepx)*smooth
  sdepz+(depz-sdepz)*smooth
  MoveCamera  (camera, sdepX, 0, -sdepz)
  If yfixed<>1e10:MoveCamera(camera,CameraX(camera),yfixed,CameraZ(camera),#PB_Absolute):EndIf
EndProcedure
;}

;{ NUBES
Structure nube_data
  tt3D.i
  tt3Ddark.i
  mate.i
  mateDark.i
  bill.i
  Array b.i(50)
  billdark.i
  Array bd.i(50)
EndStructure
Global NewList nube.nube_data()
Procedure   nubeAdd(x,y,z, w=20,h=5, quality.a=60)
  Protected.f nx,ny,nz
  Static.f s
  Protected   q= quality*5
  Protected   i=  CreateImage(#PB_Any,q,q,32,#PB_Image_Transparent)
  Protected   ii= CreateImage(#PB_Any,q,q,32,#PB_Image_Transparent)
  AddElement(nube())
  ReDim nube()\b(quality)
  ReDim nube()\bd(quality)
  
  ;oscuro
  nube()\tt3Ddark= CreateTexture(#PB_Any,q,q)
  StartDrawing(ImageOutput(ii))
    DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Gradient)
    BackColor($eedddddd)
    GradientColor(0.7,$eedddddd)
    FrontColor($00dddddd)
    For p= 1 To 10
      nz= Random(q*0.4,q*0.2)
      nx= Random(q-(nz*2))+nz
      ny= Random(q-(nz*2))+nz
      CircularGradient(nx,ny,nz)
      Circle(nx,ny,nz)
    Next p
  StopDrawing()
  StartDrawing(TextureOutput(nube()\tt3Ddark))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0,0,q,q,$00888888)
    DrawAlphaImage(ImageID(ii),0,0)
  StopDrawing()
  
  nube()\mateDark= CreateMaterial(#PB_Any,TextureID(nube()\tt3Ddark))
  MaterialBlendingMode(nube()\mateDark,#PB_Material_AlphaBlend)
  SetMaterialAttribute(nube()\mateDark,#PB_Material_AlphaReject,1)
  SetMaterialAttribute(nube()\mateDark,#PB_Material_DepthCheck,0)
  SetMaterialAttribute(nube()\mateDark,#PB_Material_TAM,1)
  SetMaterialColor(nube()\mateDark,#PB_Material_DiffuseColor, $ffffffff)
  nube()\billdark= CreateBillboardGroup(#PB_Any,MaterialID(nube()\mateDark), 100,100, x,y,z)
  
  For p=0 To quality/2
    nx= Random(w)-(w/2)
    ny= -Random(h*0.75,h*0.25)
    nz= Random(h)-(h/2)
    nube()\bd(p)= AddBillboard(nube()\billdark, nx,ny,nz)
    If p%2=0
    s= Random(h,h*0.5) + (Random(w)*0.1)
    EndIf
    ResizeBillboard(nube()\bd(p), nube()\billdark, s,s)
  Next p
  
  ;claro
  nube()\tt3D= CreateTexture(#PB_Any,q,q)
  StartDrawing(ImageOutput(i))
    DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Gradient)
    BackColor($eeffffff)
    GradientColor(0.7,$eeffffff)
    FrontColor($00ffffff)
    For p= 1 To 10
      nz= Random(q*0.4,q*0.2)
      nx= Random(q-(nz*2))+nz
      ny= Random(q-(nz*2))+nz
      CircularGradient(nx,ny,nz)
      Circle(nx,ny,nz)
    Next p
  StopDrawing()
  StartDrawing(TextureOutput(nube()\tt3D))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0,0,q,q,$00ffffff)
    DrawAlphaImage(ImageID(i),0,0)
  StopDrawing()
;   showImage(i)
  
  nube()\mate= CreateMaterial(#PB_Any,TextureID(nube()\tt3D))
  MaterialBlendingMode(nube()\mate,#PB_Material_AlphaBlend)
  SetMaterialAttribute(nube()\mate,#PB_Material_DepthCheck,0)
  SetMaterialAttribute(nube()\mate,#PB_Material_TAM,1)
  nube()\bill= CreateBillboardGroup(#PB_Any,MaterialID(nube()\mate), 100,100, x,y,z)
  
  For p=0 To quality/2
    nx= Random(w)-(w/2)
    ny= Random(h)-(h/2)
    nz= Random(h)-(h/2)
    nube()\b(p)= AddBillboard(nube()\bill, nx,ny,nz)
    If p%2=0
    s= Random(h,h*0.5) + (Random(w)*0.1)
    EndIf
    ResizeBillboard(nube()\b(p), nube()\bill, s,s)
  Next p
  
EndProcedure

i= CreateImage(#PB_Any,32,128,32,#PB_Image_Transparent)
StartVectorDrawing(ImageVectorOutput(i))
  VectorSourceLinearGradient(0, 0, 32, 128)
  VectorSourceGradientColor($ff999999, 0.0)
  VectorSourceGradientColor($99ff9966, 0.5)
  VectorSourceGradientColor($00000000, 1.0)
  MovePathCursor(0,0):AddPathLine(32,128)
  StrokePath(2)
StopVectorDrawing()
  
tt3d= CreateTexture(#PB_Any,32,128)
StartDrawing(TextureOutput(tt3d))
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0,0,OutputWidth(),OutputHeight(),$00000000)
  DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Gradient)
  DrawAlphaImage(ImageID(i),0,0)
StopDrawing()
CreateMaterial(0, TextureID(tt3d))
DisableMaterialLighting(0, 1)
MaterialBlendingMode(0, #PB_Material_AlphaBlend)

Dim l(10)
For p= 1 To 10
  x= Random(400,300)-200
  y= Random(10)+10
  z= Random(400,300)-200
  w= Random(30,20)
  h= Random(20,10)
  nubeAdd(x,y,z,w,h,60)
  l(p)= CreateLight(#PB_Any,$ff8800,x,y,z)
  HideLight(l(p),1)
  
  part= CreateParticleEmitter(#PB_Any, w,w,h, #PB_Particle_Box, x,y-(h*0.6),z)
  ParticleMaterial(part, MaterialID(0))
  ParticleSpeedFactor(part, 6)
  ParticleVelocity(part,#PB_Particle_MinimumVelocity,10)
  ParticleVelocity(part,#PB_Particle_MaximumVelocity,20)
  ParticleEmitterDirection(part, 0.1,-1,-0.1)
  ParticleEmissionRate(part, 20)
  ParticleTimeToLive(part, 4, 6)
  ParticleSize(part, 5,20)
  ParticleColorFader(part,-0.1,-0.1,-0.1,-0.1)
Next p


;}


Repeat
  While WindowEvent():Wend
  ExamineMouse(): ExamineKeyboard()
  
  CompilerIf #PB_Compiler_Version => 620
    CameraUserControl(0,0.5)
  CompilerElse
    CameraUserControl(0,0.05)
  CompilerEndIf

  renderTime= RenderWorld()
  
  For p= 1 To 10
    HideLight(l(p),1)
  Next p
  CameraBackColor(0,$332211)
  For p= 1 To 10
    If Random(200)= p
      SetLightColor(l(p),#PB_Light_DiffuseColor,RGB(Random(55),Random(155),Random(255,155)))
      HideLight(l(p),0)
      If Random(10)=0
        CameraBackColor(0,$664422)
      EndIf
    EndIf
  Next p
  
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)
End

If translation=Error: reply="Sorry, Im Spanish": Endif
User avatar
Piero
Addict
Addict
Posts: 890
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Volumetric clouds [CODE]

Post by Piero »

Nice! :D
Works well on Mac 6.21!

PS: It's better here if I "adjust" it to part= CreateParticleEmitter(#PB_Any, w,h …
User avatar
idle
Always Here
Always Here
Posts: 5870
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Volumetric clouds [CODE]

Post by idle »

That works really well. win11 6.20, Thanks for sharing.
Post Reply