I made a v2
with a shader to animate the fishes, it looks pretty good, for not much money.
+ a few other improvements
[ F1 ] to put the camera on a big fish (or free it)
hi coders,
the 3D version of my model of a shoal of fish
not bad!
remove lee debugger
if that's not enough, compile with the C backend with optimization
if that's still not enough, reduce the number of fish (line 5)
Code: Select all
; ---------------------------------------------------------------------------------------------------------
; demo 3D : Banc de poisson V2 - Pf Shadoko - 2023
; -----------------------------------------------------------------------------------------------------------
EnableExplicit
Macro f3:vector3:EndMacro
Macro def3d(v,vx,vy,vz)
v\x=vx
v\y=vy
v\z=vz
EndMacro
Macro sub3D(p,p1,p2)
p\x=p1\x-p2\x
p\y=p1\y-p2\y
p\z=p1\z-p2\z
EndMacro
Macro add3d(p,p1,p2)
p\x=p1\x+p2\x
p\y=p1\y+p2\y
p\z=p1\z+p2\z
EndMacro
Procedure.f lng3D(*v.f3)
ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
EndProcedure
Procedure Norme3D(*V.f3,l.f=1)
Protected.f lm
lm = l / Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
*V\x * lm
*V\y * lm
*V\z * lm
EndProcedure
Procedure.f POM(v.f)
ProcedureReturn (Random(v*1000)-v*500)/500
EndProcedure
; ----------------------------------------------------------------------------------------------------------
Structure sespece
num.b
cible.f3
v.f ;vitesse
prox.f
prox2.f
EndStructure
Structure spoisson
p.f3 ;position centre
pt.f3 ;position tete
v.f3 ;vitesse
entity.i
*e.sespece
EndStructure
Global nbe=-1,nbf=-1
Global Dim espece.sespece(20)
Global Dim p.spoisson(0)
Procedure poisson(ccoprs1,ccoprs2,ctete,cnageoire,robe, Lo.f,ha.f,la.f,queue.f, vit.f, nage.f, nb)
Protected.f a,ai,jj,j1,rx,ry,rz,r
Protected i,j,c,anbf,mat
nbe+1
; ---------------------- texture + material
CreateTexture(nbe,512,256)
StartDrawing(TextureOutput(nbe))
DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Gradient)
GradientColor(0.0,$ff000000)
GradientColor(0.5,ccoprs1)
GradientColor(1.0,$ffffffff)
LinearGradient(0,-100,0,300)
Box(0,0,512,256,ccoprs1)
ResetGradientColors()
GradientColor(0,ctete)
GradientColor(0.9,ctete)
GradientColor(0.91,$22000000)
GradientColor(1,ccoprs1)
ClipOutput(0,70,512,200)
CircularGradient(511,100,150)
Circle(511,100, 150)
UnclipOutput()
DrawingMode(#PB_2DDrawing_AllChannels)
Select robe
Case 0:For i=30 To 400:Box(i,0,1,(Sin(i/7.5)+1.8)*40,ccoprs2):Next
Case 1:For i=64 To 160 Step 24:Ellipse(200,i,150,4,ccoprs2):Next
Case 2:For i=0 To 3:Circle(100+i*70,100,10,$ffffffff):Circle(100+i*70,100,8,ccoprs2):Next
EndSelect
Circle(420,85,16,$ff00ffff)
Circle(420,85,8,0)
Ellipse(512,128,60,10,$666666)
If cnageoire
Box(0,0,30,256,cnageoire)
Ellipse(322,188,37,30,cnageoire)
Ellipse(174,190,40,16,cnageoire)
Ellipse(110,255,30,10,cnageoire)
Box(130,0,92,28,cnageoire)
EndIf
StopDrawing()
For i=0 To 7:mat=nbe*8+i
CreateShaderMaterial(mat,0)
MaterialShaderTexture(mat,TextureID(nbe),0,0,0)
MaterialShaderParameter(mat,0,"phase",1,i/8,0,0,0)
MaterialShininess(mat,64,$ffffff)
MaterialFilteringMode(mat,#PB_Material_Anisotropic)
SetMaterialAttribute(mat,#PB_Material_TAM,#PB_Material_ClampTAM)
Next
; ---------------------- mesh
Dim v.MeshVertex(16,16)
For j=0 To 16
jj=(j-8)/8:j1=j/16
For i=0 To 16
r=(1-jj*jj)
ry=r*ha
rx=r*la
rz=j1
a=i/16*2*#PI
With v(j,i)
If i>4 And i<12:ry*1.5:EndIf
If j=10 And (i=2 Or i=14):rx*3:ry*1.5:rz-0.15:EndIf
If j=0 :ry=ha:rz=-(1-Abs(Sin(a))*queue)*0.2:EndIf
If i=8 And (j=5 Or j=6):ry*1.4:rz-0.15:EndIf
\x=Sin(a)*rx
\y=-Cos(a)*ry
\z=(rz-0.5)*2*lo
\Color=RGB(2*nage*vit/lo*255,(rz+0.2)/2*255,(1/nage+Pow(1-(rz+0.2)/1.2,nage))*lo)
\u=j/16
\v=Abs(8-i)/8
EndWith
Next
Next
CreateDataMesh(nbe,v(),1+8)
; ---------------------- info espece
With espece(nbe)
\num=nbe
\v=vit
\prox=lo*2
\prox2=\prox*\prox
def3D(\cible,pom(1000),pom(200)-300,pom(1000))
EndWith
; ---------------------- creation poissons
anbf=nbf
nbf+nb
ReDim p(nbf)
For i=anbf+1 To nbf
With p(i)
def3D(\p,pom(1000),pom(200)-300,pom(1000))
\pt=\p
\e=espece(nbe)
\entity=CreateEntity(-1,MeshID(\e\num),MaterialID(nbe*8+i&7))
EntityFixedYawAxis(\entity,1)
EndWith
Next
EndProcedure
InitEngine3D():InitSprite():InitKeyboard():InitMouse()
ExamineDesktops()
OpenWindow(0, 0,0, DesktopWidth(0)*1,DesktopHeight(0)*1, "poisson",#PB_Window_ScreenCentered|#PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)
CreateCamera(0, 0, 0, 100, 100):MoveCamera(0,0,-400,-1000):CameraLookAt(0,0,-300,0)
CreateLight(0,$111111*8, -10000, 10000, -10000)
AmbientColor($111111*6)
Fog($886600,1,0,3000):CameraBackColor(0,$886600)
Define.s vert_pg,frag_pg
vert_pg="%#version 130%%uniform mat4 P24;//+24%uniform mat4 P0;//+0%uniform vec4 P77;//+77%uniform vec4 P76;//+76%uniform vec4 P44;//+44 0%uniform vec4 P31;//+31%uniform float P86;//+86 4%uniform float phase;//1%%varying vec3 oviewdir;%varying vec3 olightdir;%varying vec3 onormal;%varying vec2 ouv;%varying float ofogf;%varying float olum;%%void main()%{%vec4 v=gl_Vertex;%v.x+=sin((gl_Color.r*P86+gl_Color.g+phase)*6)*gl_Color.b*80;%oviewdir=normalize(P77.xyz-v.xyz);%olightdir=normalize(P44.xyz-v.xyz);%gl_Position=P24*v;%onormal=gl_Normal;%ouv=(gl_TextureMatrix[0]*gl_MultiTexCoord0).xy;%ofogf=P31.z>0?min(abs(gl_Position.z)*P31.w,1):0;%vec3 posv=(P0*v).xyz;%float d=min(abs(gl_Position.z),P31.z);%vec3 posl=P76.xyz+normalize(posv.xyz-P76.xyz)*d;%olum=1-clamp(-posl.y/3000,0,1);%}"
frag_pg="%#version 130%%uniform vec4 P69;//+69 0%uniform vec4 P70;//+70 0%uniform vec4 P67;//+67 0%uniform float P36;//+36%uniform vec4 P30;//+30%%uniform sampler2D diffuseMap;//0%%varying vec3 oviewdir;%varying vec3 olightdir;%varying vec3 onormal;%varying vec2 ouv;%varying float ofogf;%varying float olum;%%void main()%{%vec3 normal=normalize(onormal);%vec3 viewdir=normalize(oviewdir);%vec3 lightdir=normalize(olightdir);%%vec4 tcolor=vec4(texture(diffuseMap,ouv));%%float dif=max(dot(lightdir,normal),0);%float spe=pow(max(dot(normalize(lightdir+viewdir),normal),0),P36);%vec4 color=vec4(tcolor.rgb,1)*(P67+P69*dif)+P70*tcolor.a*spe;%gl_FragColor=mix(color,P30,ofogf)*olum;%}"
CreateShader(0,vert_pg,frag_pg)
CreateShaderMaterial(100,0)
MaterialCullingMode(100,#PB_Material_NoCulling)
MaterialShininess(100,64,$ffffff)
CreateSphere(100,30000,64,64)
CreateEntity(0,MeshID(100),MaterialID(100))
poisson($ff8888ff,$88444488,$ffaaaaaa,$000000,0, 130,40,35,0.6,7,4,1)
poisson($ff888888,$88884444,$ffaaaaaa,$000000,0, 70,20,15,0.6,4,3,10)
poisson($ffaaaaaa,$88666666,$ffaaaaaa,$44aaff,0, 40,8,6,0.5,3,2,100)
poisson($ffaaaaaa,$ff444444,$ffccccdd,$66cccc,1, 30,12,7,0.5,2.5,2,150)
poisson($880088ff,$88000000,$8800aaff,$4488cc,2, 30,12,7,0.5,2.5,2,150)
poisson($8877bbdd,$880000ff,$8888bbcc,$7799ff,2, 20,12,5,0.2,2,2,200)
poisson($880000ff,$ff0088ff,$880066cc,$0099ff,1, 20,7,4,0.2,1.5,3,200)
Define.f f, al,lg,lg2, align.f=0.2
Define ff.f3,f0.f3,cc.f3,d.f3,pt.f3, *p.spoisson,*pi.spoisson, t0,i,j,np,tok,Iespece,camp
Define.f MouseX,Mousey,depx,depz,dist
Repeat
While WindowEvent():Wend
ExamineKeyboard():ExamineMouse()
depx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*10
depz=(-Bool(KeyboardPushed(#PB_Key_Down))+Bool(KeyboardPushed(#PB_Key_Up )))*10+MouseWheel()*100
MouseX = -MouseDeltaX() * 0.05
MouseY = -MouseDeltaY() * 0.05
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
dist+(depz-dist)*0.05:MoveCamera (0, depX, 0, -dist)
If KeyboardReleased(#PB_Key_F1):camp=1-camp:If camp:AttachEntityObject(p(1)\entity,"",CameraID(0)):RotateCamera(0,0,180,0):MoveCamera (0, 0, 40, -170, 0):Else:DetachEntityObject(p(1)\entity,CameraID(0)):EndIf:EndIf
If ElapsedMilliseconds()-t0>10000/(nbe+1):t0=ElapsedMilliseconds():Iespece=(Iespece+1)% (nbe+1):def3D(espece(Iespece)\cible,pom(1000),pom(200)-300,pom(1000)):EndIf
For j=0 To nbf
*p=p(j):np=0:ff=f0
For i=0 To nbf:If i=j:Continue:EndIf
*pi=p(i):With *pi
sub3d(d,\pt,*p\pt)
lg2=d\x*d\x+d\y*d\y+d\z*d\z:If lg2>\e\prox2:Continue:EndIf:lg=Sqr(lg2)
tok=Bool(*p\e\num=\e\num)
f=(tok - \e\prox/lg)*0.1:If IsNAN(f):Continue:EndIf
al=align*tok
ff\x+d\x*f+\v\x*al
ff\y+d\y*f+\v\y*al
ff\z+d\z*f+\v\z*al
np+1
EndWith
Next
sub3d(cc,*p\p,*p\e\cible):norme3d(cc,-0.1):add3d(*p\v,*p\v,cc)
If np:norme3d(ff,0.2):add3d(*p\v,*p\v,ff):EndIf
norme3d(*p\v,*p\e\v):*p\v\y*0.95
pt=*p\v:norme3d(pt,*p\e\prox):add3d(*p\pt,*p\p,pt)
Next
For i=0 To nbf
With p(i)
add3d(\p,\p,\v)
MoveEntity(\entity,\p\x,\p\y,\p\z,0)
EntityDirection(\entity,\v\x,\v\y,\v\z,#PB_World,#PB_Vector_Z)
EndWith
Next
RenderWorld()
FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape) Or MouseButton(3)