Demo 3D - Ocean v2 (shader OpenGL)

Généralités sur la programmation 3D
Avatar de l’utilisateur
Guillot
Messages : 529
Inscription : jeu. 25/juin/2015 16:18

Demo 3D - Ocean v2 (shader OpenGL)

Message par Guillot »

Salut les gars,

je me suis fais un shader pour les vagues
vous allez voir, c'est beaucoup plus réaliste

préalablement, vous devez copier les fichiers de l'archive
http://cg.racine.free.fr/ocean.zip
dans:
...\PureBasic\Examples\3D\Data\Scripts\MaterialScriptsGeneric

et compiler en OpenGL

a cause du probleme opengl/sprite, j'ai pas pu afficher les commandes
donc:
- souris+roulette+fleches pour vous déplacer
- [F1] / [F2] : taille des 'grandes' vagues
- [F3] / [F4] : taille des 'petites' vagues
- [F5] / [F6] : houle
- [F7] / [F8] : écume

mettez votre ciré

Code : Tout sélectionner

; Océan v2 - pf Shadoko - 2020

EnableExplicit

DeclareModule ext_3D
	EnableExplicit
	Global inittime
	
	Structure f3
		x.f
		y.f
		z.f
	EndStructure
	
	Structure f2
		x.f
		y.f
	EndStructure
	
	Structure PB_MeshVertexV
		p.f3
		n.f3
		t.f3
		u.f
		v.f
		color.l
	EndStructure
	
	;________________ Lib ________________
	Declare vec3d(*v.f3,vx.f,vy.f,vz.f)
	Declare sub3D(*p.f3,*p1.f3,*p2.f3)
	Declare mul3d(*p1,v.f)
	Declare.f lng3D(*v.f3)    
	Declare norme3d(*v.f3,l.f=1)    
	Declare.f Max(v1.f,v2.f)
	Declare.f Min(v1.f,v2.f)
	Declare.f limite(V.f, i.f, s.f) 
	Declare.i Modi(v,divisor)
	Declare.f interpolarray2d(Array tt.f(2),x.f,y.f) 
	Declare ColorBlend(color1.l, color2.l, blend.f) 
	Declare GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0) 
	Declare Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
	Declare  blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
	Declare Embos2D(Array s.f(2), px.w=0, py.w=0)
	Declare grad2D(Array s.f(2),delta=1)
	Declare  outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
	Declare textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
	Declare textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
	
	;________________ océan ________________
	
	Global oc_mesh,oc_material,oc_txtnm,oc_txtdif,oc_particule,   oc_waveb.f, oc_wavel.f,oc_swell.f, oc_foam.f  
	Global oc_tilesize,oc_tilesize2,oc_prec,oc_tilenb,oc_tilenb1
	Global oc_tn,oc_tn1,oc_tn2
	Declare initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
	Declare freeocean()
	Declare renderocean()
	Declare.f oceanHeight(x.f,z.f)
	Declare oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
	
	;________________ SkyDome2 ________________
	Global skydome_m, skydome_e
	Declare SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
	Declare SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)	
EndDeclareModule 

Module ext_3D
	
	;{ ============================= biblio
	
	Procedure vec3d(*v.f3,vx.f,vy.f,vz.f)
		*v\x=vx
		*v\y=vy
		*v\z=vz
	EndProcedure
	
	Procedure sub3D(*p.f3,*p1.f3,*p2.f3)
		*p\x=*p1\x-*p2\x
		*p\y=*p1\y-*p2\y
		*p\z=*p1\z-*p2\z
	EndProcedure
	
	Procedure add3d(*p.f3,*p1.f3,*p2.f3)
		*p\x=*p1\x+*p2\x
		*p\y=*p1\y+*p2\y
		*p\z=*p1\z+*p2\z
	EndProcedure
	
	Procedure mul3d(*p1.f3,v.f)
		*p1\x*v
		*p1\y*v
		*p1\z*v
	EndProcedure
	
	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 / lng3d(*v)
		*V\x * lm
		*V\y * lm
		*V\z * lm  
	EndProcedure
	
	Procedure.f Max(v1.f,v2.f)
		If v1>v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
	EndProcedure
	
	Procedure.f Min(v1.f,v2.f)
		If v1<v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
	EndProcedure
	
	Procedure.f limite(V.f, i.f, s.f)
		If V < i :v=i:EndIf
		If V > s :v=s:EndIf
		ProcedureReturn V
	EndProcedure
	
	Procedure.i Modi(v,divisor) 
		ProcedureReturn (V+$10000*divisor) % divisor
	EndProcedure
	
	Procedure.f POM(v.f)
		ProcedureReturn (Random(v*1000)-v*500)/500
	EndProcedure
	
	;##############################################################################################
	
	Procedure CoRBinv(c.l)
		ProcedureReturn  RGBA(Blue(c),Green(c),Red(c),Alpha(c))
	EndProcedure
	
	Procedure ColorBlend(color1.l, color2.l, blend.f)
		Protected r.w,g.w,b.w,a.w
		r=  Red(color1) + (Red(color2)     - Red(color1)) * blend
		g=Green(color1) + (Green(color2) - Green(color1)) * blend
		b= Blue(color1) + (Blue(color2) -   Blue(color1)) * blend
		a=Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
		ProcedureReturn  RGBA(r,g,b,a)
	EndProcedure
	
	Procedure GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0)
		Protected i,j, apos,pos, acol.l,col.l,p,lt.s
		n-1
		Dim pal(n)
		
		Repeat
			apos=pos
			acol=col
			i+1
			lt=StringField(gradient,i,"/"):If lt="":Break:EndIf
			pos=ValF(lt)*n
			p=FindString(lt,",")
			If p
				col=Val(Mid(lt,p+1))
				If inv  :col=CoRBinv(col):EndIf
				If alpha:col | $ff000000:EndIf
			Else
				col=acol
			EndIf
			For j=apos To pos:pal(j)=ColorBlend(acol,col,(j-apos)/(pos-apos)):Next
		ForEver
	EndProcedure
	
	Procedure Array2Dlimit(Array t.f(2),*min.float,*max.float)
		Protected i,j,dx1,dy1
		Protected.f v,smin,smax
		
		dy1 = ArraySize(t(), 1)
		dx1 = ArraySize(t(), 2)
		smax = -1e10
		smin =  1e10
		For j=0 To dy1
			For i=0 To dx1
				v=t(j,i)
				If v<smin : smin=v: EndIf
				If v>smax : smax=v: EndIf
			Next
		Next
		*min\f=smin
		*max\f=smax
	EndProcedure
	
	Procedure Array2Dclamp(Array t.f(2),min.f,max.f)
		Protected i,j,dx1,dy1
		
		dy1 = ArraySize(t(), 1)
		dx1 = ArraySize(t(), 2)
		For j=0 To dy1
			For i=0 To dx1
				t(j,i)=limite(t(j,i),min,max)
			Next
		Next
	EndProcedure
	
	Procedure blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
		If di=0 And dj=0:ProcedureReturn:EndIf
		Protected i,j,k,d,dii,djj,dx,dy,dij,tx.f
		
		dx = ArraySize(s(), 2):di=min(di,dx)
		dy = ArraySize(s(), 1):dj=min(dj,dy)
		Dim d.f(dy,dx)
		dii=di+1
		djj=dj+1
		dij = dii * djj
		
		If loop
			d=dx-dii/2:Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = (i+d) % (dx+1): Next
			d=dx-dii/2:Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = (i+d) % (dy+1): Next    
		Else
			Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = limite(i-1-dii/2, 0, dx): Next
			Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = limite(i-1-djj/2, 0, dy): Next
		EndIf  
		For k=1 To pass
			Dim ty.f(dx)
			For j = 0 To djj - 1: For i = 0 To dx: ty(i) + s(ly(j),i): Next: Next    
			For j = 0 To dy
				For i = 0 To dx: ty(i) + s(ly(djj+j),i) - s(ly(j),i): Next
				tx=0:For i = 0 To dii-1: tx+ty(lx(i)): Next
				For i = 0 To dx: tx + ty(lx(dii+i)) - ty(lx(i) ): d(j,i) = tx / dij: Next
			Next
			CopyArray(d(),s())
		Next
	EndProcedure
	
	Procedure Embos2D(Array s.f(2), px.w=0, py.w=0)
		Protected i,j,dx,dy
		px=1<<Int(Abs(px))*Sign(px)
		py=1<<Int(Abs(py))*Sign(py)
		
		Macro gra(j0,i0,j1,i1)
			t(j0,i0)=Abs(s(j0,i0)-s(j0,i1)+px)+Abs(s(j0,i0)-s(j1,i0)+py)
		EndMacro
		dy = ArraySize(s(), 1)
		dx = ArraySize(s(), 2)
		Dim T.f(dy,dx)
		For j=0 To dy-1
			For i=0 To dx-1
				gra(j,i,j+1,i+1)
			Next
			gra(j,dx,j+1,0)
		Next
		For i = 0 To dx-1
			gra(dy,i,0,i+1)
		Next
		gra(dy,dx,0,0)
		CopyArray(t(),s())
	EndProcedure
	
	Procedure grad2D(Array s.f(2),delta=1)
		Protected i,j,dx,dy
		
		dy = ArraySize(s(), 1)
		dx = ArraySize(s(), 2)
		Dim d.f(dy,dx)
		For j=0 To dy
			For i=0 To dx
				d(j,i)= 4*s(j,i)   -s(j,(i-delta) & dx)-s(j,(i+delta) & dx)-s((j-delta) & dy,i)-s((j+delta) & dy,i)
			Next
		Next
		CopyArray(d(),s())
	EndProcedure
	
	Procedure superpose(Array s.f(2),n.w=1)
		Protected i,j,k,dx,dy,x,y,ii,jj
		
		dy = ArraySize(s(), 1)
		dx = ArraySize(s(), 2)
		Dim T.f(dy,dx)
		For k=1 To n
			x=Random(dx)
			y=Random(dy)
			For j=0 To dy
				For i=0 To dx
					t(i,j)+s((i+x) & dx,(j+y) & dy)
				Next
			Next
		Next
		CopyArray(t(),s())
	EndProcedure
	
	Procedure Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
		Protected i,j,n,d,dd,d3,dx1=dx-1,dy1=dy-1,coef.f=9,den.f=1/(2*coef-2),amp.f=1/$1000
		Dim t(dy1, dx1)
		
		RandomSeed(rnd)
		n = 1<<oinit
		dd=min(dx,dy) / n: If dd<1:dd=1:EndIf
		j=0:While j<dy1:i=0:While i<dx1: t(j,i) = (Random($2000) - $1000)*amp:i+dd:Wend:j+dd:Wend
		While dd > 1
			If onb=0:amp=0:EndIf
			d = dd / 2:d3=d*3:amp/2
			j=d:While j<dy
				i=0:While i<dx
					t(j,i) = (-t((j - d3) & dy1,i) - t((j +d3) & dy1,i) + coef*(t((j - d) & dy1,i) + t((j + d) & dy1,i))) *den + (Random($2000) - $1000)*amp
				i+dd:Wend
			j+dd:Wend
			j=0:While j<dy
				i=d:While i<dx
					t(j,i) = (-t(j,(i - d3) & dx1) - t(j,(i +d3) & dx1) + coef*(t(j,(i - d) & dx1) + t(j,(i + d) & dx1))) *den + (Random($2000) - $1000)*amp
				i+dd:Wend
			j+d:Wend
			dd/2:onb-1
		Wend     
	EndProcedure
	
	Procedure Finterpol(Array F.f(1),profil.s,dmin.f=1,dmax.f=0)
		Protected.l i,j,n,c,ac,rx,   t.s
		Protected.f y,dx,dy,p
		
		rx=ArraySize(f())
		n=CountString(profil,"/")
		Dim s.f2(n)
		For i=0 To n
			t=StringField(profil,i+1,"/")
			s(i)\x=ValF(t)*rx
			s(i)\y=ValF(StringField(t,2,","))*(dmax-dmin)+dmin
		Next  
		
		For j=0 To n-1
			y=s(j)\y
			dx=s(j+1)\x-s(j)\x
			dy=s(j+1)\y-s(j)\y
			p=dy/dx
			ac=c
			While c<=s(j+1)\x
				f(c)=y+p*(c-ac):c+1
			Wend
		Next
	EndProcedure
	
	Procedure outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
		Protected dx1,dy1,i,ii,j,k,xi
		Protected.f smin,smax,sr,tt,x,y0,y1,x0,dminl,dmaxl
		
		dy1 = ArraySize(t(), 1)
		dx1 = ArraySize(t(), 2)
		Array2Dlimit(t(),@smin,@smax)
		sr=smax-smin
		
		Dim conv.f(256)
		Finterpol(conv(),outline,dmin,dmax)
		If smaxl-sminl<>0
			ii=(sminl-smin)/sr*255:For i=0 To ii:conv(i)=conv(ii):Next
			ii=(smaxl-smin)/sr*255:For i=ii To 255:conv(i)=conv(ii):Next
		EndIf
		
		For j=0 To dy1
			For i=0 To dx1
				x=(t(j,i)-smin)/sr*255
				xi=Int(x):x0=x-xi
				y0=conv(xi)
				y1=conv(xi+1)
				t(j,i)=y1*x0+y0*(1-x0)
			Next
		Next
	EndProcedure
	
	Procedure textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
		Protected i,j,n,dx,dy
		Protected.f min,max,r
		
		dx=ArraySize(t(),2)+1
		dy=ArraySize(t(),1)+1
		Dim bmp.l(dy-1,dx-1)
		
		Protected Dim grad.l(0):gradienttoarray(grad(),1024,grad,1)
		Array2Dlimit(t(),@min,@max):r=1023/(max-min)
		For j=0 To dy-1:For i=0 To dx-1:n=(t(j,i)-min)*r:bmp(j,i)=grad(n):Next:Next
		
		n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
		StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
		ProcedureReturn tex
	EndProcedure
	
	Procedure textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
		Protected i,j,n,dx,dy
		Protected.f h00,h10,h01,x,y,z,l, max=1/amplitude,max2=max*max
		Protected.f3 p
		
		Dim a.f(0,0) :CopyArray(t(),a())
		Select alphavalue
			Case 0:outline2d(a(),0,255)
			Case 1:grad2d(a(),4):Array2Dclamp(a(),-0.4,0):outline2d(a(),0,255,"0,0/1,1")
		EndSelect
		
		dx=ArraySize(t(),2)+1
		dy=ArraySize(t(),1)+1
		Dim bmp.l(dy-1,dx-1)
		For j=0 To dy-1
			For i=0 To dx-1
				h00=t(j,i)
				h10=t(j,(i+1) % dx)
				h01=t((j+1) % dy,i)
				p\x=h00-h10
				p\y=h00-h01
				l=min(p\x*p\x+p\y*p\y,max2)
				p\z=Sqr(max2-l)
				Norme3D(p,127)
				bmp(j,i)=RGBA(p\z+128,p\y+128,p\x+128,a(j,i))
			Next
		Next  
		n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
		StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
		ProcedureReturn tex
	EndProcedure
	
	Procedure.f interpolarray2d(Array tt.f(2),x.f,y.f)
		Protected.l i0, j0,i1,j1,dx1,dy1
		Protected.f dx, dy
		dx1=ArraySize(tt(),1)
		dy1=ArraySize(tt(),2)
		i0 = Int(X) & dx1:i1=(i0+1) & dx1: dx = X - Int(x)
		j0 = Int(Y) & dy1:j1=(j0+1) & dy1: dy = Y - Int(y)
		ProcedureReturn (((1 - dx) * tt(j0,i0) + dx * tt(j0,i1)) * (1 - dy) + ((1 - dx) * tt(j1,i0) + dx * tt(j1,i1)) * dy)
	EndProcedure
	
	;}===================================================================================================================================================
	
	;{ Océan
	
	Procedure initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
		; tilesize: must be a power of 2 
		; precision : 1-> 1 meters,  2->2 meters, 3->4 meters, 4-> 8 meters...
		; range : distance to the camera where the oocean should be rendered
		; wavebig,wavelittle,swell,foam : value: 0.0 -> 1.0
		; particule : for sea spray
		; heightmap : texture containing the depth. only the red component is used : red=depth*16+128, and clamped between 0 and 255 
		
		Protected i,j,k,r,n,a.f
		oc_tilesize=tilesize:oc_tilesize2=oc_tilesize/2
		oc_prec=1<<(prec-1)
		oc_tilenb=range/tilesize*2:oc_tilenb1=oc_tilenb-1 
		oc_tn=oc_tilesize/oc_prec:oc_tn1=oc_tn-1:oc_tn2=oc_tn/2
		oc_particule=particule
		
		Global Dim oc_h.f(oc_tn1,oc_tn1)
		Global Dim oc_entity(oc_tilenb1,oc_tilenb1)
		
		Dim t.f(0,0)
		;Waves (noramlmap)
		Noise2d(oc_h(),512,512,0,4)
		outline2d(oc_h(),0,1,"0,0/0.5,1/1,0")
		blur2D(oc_h(),1,1,1)    
		oc_txtnm=textureArraytoNM(-1,oc_h(),16) 
		;foam (diffusemap)
		Noise2d(t(),512,512,0,7)
		outline2d(t(),0,1,"0,0/0.2,0.2/0.5,1/0.7,0.2/1,0") 
		oc_txtdif=textureArrayToColor(-1,t()) 
		
		oc_material=GetScriptMaterial(-1,"ocean"):MaterialTextureAliases(oc_material,TextureID(oc_txtnm),TextureID(oc_txtdif),TextureID(heightmap),0)
		MaterialFilteringMode(oc_material,#PB_Material_Anisotropic,4)
		MaterialShininess(oc_material,64)
		SetMaterialAttribute(oc_material,#PB_Material_TAM,#PB_Material_ClampTAM,2)
		oceanset(wavebig,wavelittle,swell,foam,watercolor,skycolor)
		
		For k=0 To 4:r=1<<k
			Dim mv.PB_MeshVertexv(oc_tn/r,oc_tn/r)
			For j=0 To oc_tn/r
				For i=0 To oc_tn/r
					With mv(j,i) 
						vec3d(\p,(i*r-oc_tn2)*oc_prec,pom(16),-(j*r-oc_tn2)*oc_prec)          
						\u=i*r/oc_tn
						\v=j*r/oc_tn
					EndWith
				Next
			Next
			If k=0
				oc_mesh=CreateDataMesh(-1,mv())
			Else
				n=CreateDataMesh(-1,mv())
				AddMeshManualLOD(oc_mesh,n,128 *r)
				SetMeshMaterial(n,MaterialID(oc_material))
			EndIf
		Next
		
		For j=0 To oc_tilenb1
			For i=0 To oc_tilenb1
				oc_entity(j,i)=CreateEntity(-1,MeshID(oc_mesh),MaterialID(oc_material))
			Next
		Next
	EndProcedure
	
	Procedure freeocean()
		Protected i,j
		For j=0 To ArraySize(oc_entity(),1)
			For i=0 To ArraySize(oc_entity(),2)
				FreeEntity(oc_entity(j,i))
			Next
		Next
		FreeMesh(oc_mesh)
		FreeArray(oc_entity())
		FreeMaterial(oc_material)
		FreeTexture(oc_txtnm)
		FreeTexture(oc_txtdif)
	EndProcedure
	
	Procedure.f oceanHeight(x.f,z.f)
		Protected time.f=(ElapsedMilliseconds()-inittime)/1000*0.01, dx.f=time*512
		x*2-0.5
		z*2-0.5
		ProcedureReturn (interpolarray2d(oc_h(),x+dx,z)+interpolarray2d(oc_h(),x+256-dx,z+256)-1)*oc_waveb*4+Sin(z/512*20-time*100)*oc_swell*4
	EndProcedure
	
	Procedure oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
		oc_waveb=wavebig
		oc_wavel=wavelittle
		oc_swell=swell
		oc_foam =foam	
		SetMaterialColor(oc_material,#PB_Material_AmbientColor,RGBA(wavebig*255,wavelittle*255,swell*255,foam*255))
		If watercolor:SetMaterialColor(oc_material,#PB_Material_DiffuseColor,watercolor):EndIf
		If skycolor:SetMaterialColor(oc_material,#PB_Material_SpecularColor,skycolor):EndIf
	EndProcedure
	
	Procedure renderocean()
		Protected i,j,  pos.f3
		
		If oc_particule>=0
			pos\x=CameraX(0)+pom(100)+CameraDirectionX(0)*100
			pos\z=CameraZ(0)+pom(100)+CameraDirectionZ(0)*100
			pos\y=oceanHeight(pos\x,pos\z)+1
			If pos\y>0:MoveParticleEmitter(oc_particule,pos\x,pos\y,pos\z,#PB_Absolute):EndIf
		EndIf
		;------------------- tuiles
		Protected da=oc_tilenb*oc_tilesize
		Static api=0,pi=1000,  apj=0,pj=1000,  i0,i1,  j0,j1,  e
		api=pi:pi=(CameraX(0)-da/2)/oc_tilesize:If pi<api:i0=pi:i1=api-1:Else:i0=api+1+oc_tilenb1:i1=pi+oc_tilenb1:EndIf
		apj=pj:pj=(CameraZ(0)-da/2)/oc_tilesize:If pj<apj:j0=pj:j1=apj-1:Else:j0=apj+1+oc_tilenb1:j1=pj+oc_tilenb1:EndIf
		For j=pj To pj+oc_tilenb1
			For i=pi To pi+oc_tilenb1
				If (i>=i0 And i<=i1) Or (j>=j0 And j<=j1)
					MoveEntity(oc_entity(Modi(j,oc_tilenb),Modi(i,oc_tilenb)), i*oc_tilesize+oc_tilesize2,0,j*oc_tilesize+oc_tilesize2,#PB_Absolute)
				EndIf
			Next
		Next 
		
		;------------------- sous / sur l'eau
		If CameraY(0)<oceanHeight(CameraX(0),CameraZ(0))
			Fog($332200,100,0,30)
			MaterialCullingMode(oc_material,#PB_Material_AntiClockWiseCull)
		Else
			Fog($ffaa88,100,0,da/2)
			MaterialCullingMode(oc_material,#PB_Material_ClockWiseCull)
		EndIf       
	EndProcedure
	;}
	
	;{ SkyDome2
	Procedure SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
		If skydome_m:FreeMesh(skydome_m):EndIf
		If skydome_e:FreeEntity(skydome_e):EndIf
		Protected i,j,d=16,icol   ,d1=d-1,d2=d/2,mesh
		Protected.f x,y,z,  xo,yo,  u,v,   ai,aj,  lat,lng, mx  
		Dim t.PB_MeshVertexv(d,d)
		Dim col.l(0)
		
		DisableDebugger:CreateMaterial(0,0):EnableDebugger
		GradientToArray(col(),256,degrade)
		For j=0 To d
			For i=0 To d
				With t(i,j)
					xo=1-i/d2
					yo=1-j/d2
					lng=ATan2(xo,yo)
					mx=max(Abs(xo),Abs(yo))
					\u=(Cos(lng)* mx+1)/2
					\v=(Sin(lng)* mx+1)/2
					lat=mx* #PI/2
					x=Cos(lng)* Sin(lat)*rayon
					z=Sin(lng)* Sin(lat)*rayon
					y=Cos(lat)*hauteur
					vec3d(\p,-x,y,z)
					icol=255*(x+rayon)/(2*rayon)
					\color=$ff000000+col(icol)
				EndWith
			Next
		Next  
		skydome_m=CreateDataMesh(-1,t())
		skydome_e=CreateEntity(-1,MeshID(skydome_m),MaterialID(material))
		DisableMaterialLighting(material,1)
	EndProcedure
	
	Procedure SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)
		Protected layer
		AddMaterialLayer(0,TextureID(txt),#PB_Material_AlphaBlend) 
		layer=CountMaterialLayers(0)-1
		ScaleMaterial(0,scale,scale,layer)
		RotateMaterial(0,angle,#PB_Material_Fixed,layer)
		ScrollMaterial(0,0,scroll,#PB_Material_Animated,layer)
	EndProcedure
	;}
EndModule
;#####################################################################################################################################################

UseModule ext_3d

Procedure texturecolor(tex,dx,dy,rnd=0,f=0,lissage=0,grad.s="0,$000000/1,$ffffffff",outline.s="0,0/1,1")
	Protected Dim t.f(0,0)
	
	Noise2d(t(),dx,dy,rnd,f)
	blur2D(t(),lissage,lissage,2)    
	outline2d(t(),0,1,outline)
	ProcedureReturn textureArrayToColor(tex,t(),grad) 
EndProcedure

Procedure texturenormal(tex,dx,dy,rnd=0,f=0,lissage=0,relief.f=1,outline.s="0,0/1,1",alphavalue=0)
	Protected Dim t.f(0,0)
	
	Noise2d(t(),dx,dy,rnd,f)
	outline2d(t(),0,1,outline)
	blur2D(t(),lissage,lissage,3)    
	ProcedureReturn textureArraytoNM(tex,t(),relief,alphavalue) 
EndProcedure

Procedure menu(waveb.f,wavel.f,swell.f,foam.f)
	ProcedureReturn
	Protected p=8
	Macro DT(t1,t2="")
		DrawText(8,p,t1)
		DrawText(120,p,t2)
		p+20
	EndMacro
	CreateSprite(0,240,200,#PB_Sprite_AlphaBlending)
	StartDrawing(SpriteOutput(0))
	DrawingMode(#PB_2DDrawing_AllChannels)
	DrawingFont(FontID(0))
	Box(0,0,240,200,$44000000)
	DrawingMode(#PB_2DDrawing_AllChannels|#PB_2DDrawing_Outlined)
	Box(0,0,240,200,$ffffffff)
	BackColor($44000000)
	FrontColor($ffffffff)
	dt("Moving:")
	dt("Mouse + wheel+ arrow keys")    
	dt("")
	dt("Commandes:")
	dt("[F1] / [F2]","Wave big: "+Str(waveb*100)+"%")
	dt("[F3] / [F4]","Wave little: ")
	dt("[F5] / [F6]","Swell height: ")
	dt("[F7] / [F8]","foam: ")
	dt("[F12]","Wireframe")
	dt("[Esc]","Quit")
	StopDrawing()
EndProcedure

Procedure main()
	Protected sky,heightmap,seaspray	
	Protected ex,ey,c,v, i,j, fly=1,fdf
	Protected.f MouseX,Mousey,keyx,keyy,keyz,dist,aval, och, waveb,wavel,swell,foam
	
	InitEngine3D():InitSprite():InitKeyboard():InitMouse()
	
	ExamineDesktops()
	ex=DesktopWidth(0)
	ey=DesktopHeight(0)
	;OpenWindow(0,0,0,ex,ey,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered):OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0),WindowHeight(0))
	OpenScreen(ex,ey,32,"")
	LoadFont(0,"arial",12*100/DesktopScaledX(100))
	
	Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Scripts\MaterialScriptsGeneric", #PB_3DArchive_FileSystem )
	Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
	Parse3DScripts()
	
	;------------------- scene
	
	CreateCamera(0, 0, 0, 100, 100):CameraBackColor(0,$332200)
	MoveCamera(0,0,10,0)
	CameraLookAt(0, 0,10,-10)
	CreateLight(0,$ffffff, 10000, 10000,0)
	AmbientColor($444444)
	
	;---- ilot / island
	Protected di=256,dj=256,di1=di-1,dj1=dj-1,ii,jj,h.f,g.f,   x.f,y.f
	Dim h.f(0,0)
	Dim g.f(0,0)
	Dim t.PB_MeshVertexv(di,dj)
	
	Noise2d(h(),di,dj,0,3):outline2d(h(),0,15,"0,0/0.4,0.2/0.5,0.4/0.7,0.9/1,1")
	For j=0 To dj1:For i=0 To di1:x=i/di*#PI:y=j/dj*#PI:h(i,j)*Sin(x)*Sin(y)*#PI-8:Next:Next
	CopyArray(h(),g()):Embos2D(g(),0,0):outline2d(g(),0,255)
	
	For j=0 To dj:  jj=j & dj1
		For i=0 To di:ii=i & di1
			h=h(ii,jj)
			g=g(ii,jj)        
			With t(i,j)
				vec3d(\p,i,h,j)
				vec3d(\n,h((i-1) & di1,jj)-h((i+1) & di1,jj),2,h(ii,(j-1) & dj1)-h(ii,(j+1) & dj1)):norme3d(\n)
				\u=i*0.1
				\v=j*0.1
				Select g
					Case 0 To 80:\color=$22556677
					Case 80 To 120:\color=$225599aa
					Default:\color=$4488aadd
				EndSelect
				If h<7:\color | $CC000000 :EndIf
			EndWith
		Next
	Next    
	CreateDataMesh(10,t())
	BuildMeshTangents(10)
	texturecolor (10,512,512,1,5,0,"0,$ff888888/1,$ffffffff")
	texturenormal(11,512,512,0,2,0,22,"0,1/0.3,0.4/0.5,0/0.7,0.4/1,1")
	GetScriptMaterial(10,"bump"):MaterialTextureAliases(10,TextureID(10),TextureID(11),0,0)
	MaterialFilteringMode(10,#PB_Material_Anisotropic,4)
	MaterialShininess(10,64):SetMaterialColor(10,#PB_Material_SpecularColor,$ffffff)
	CreateEntity(10,MeshID(10),MaterialID(10))
	;heightmap
	heightmap=CreateTexture(-1,256,256)
	StartDrawing(TextureOutput(heightmap))
	For j=0 To dj1:For i=0 To di1:Plot(i,j,limite(h(i,j)*16+128,0,255)):Next:Next
	StopDrawing()
	
	
	;---- sky / ciel
	sky=texturecolor(-1,512,512,0,3,0,"0,$00ffffff/0.4/0.7,$ffffffff/1,$ff888888")
	SkyDome2(1024,200,0,"0,$ff4400/1,$ff4400")
	SkyDome2AddLayer(sky,0.1,0.04,0)      
	SkyDome2AddLayer(sky,0.2,0.04,90)      
	SkyDome2AddLayer(sky,0.4,0.04,180)      
	
	; Sea spray / embruns
	LoadTexture(4, "water.png")
	CreateMaterial(4, TextureID(4))
	DisableMaterialLighting(4, 1)
	MaterialBlendingMode   (4, #PB_Material_AlphaBlend)
	SetMaterialAttribute(4,#PB_Material_TAM,#PB_Material_ClampTAM)
	
	seaspray=CreateParticleEmitter(-1,8, 2, 8, #PB_Particle_Box)
	ParticleMaterial    (Seaspray, MaterialID(4))
	ParticleSize        (Seaspray, 0.25,0.25):ParticleScaleRate(Seaspray,4)
	ParticleColorFader(Seaspray, 0, 0, 0, -1)
	ParticleEmitterDirection(Seaspray, 0, 0.2, 1)
	ParticleTimeToLive  (Seaspray, 1,1)
	ParticleVelocity(Seaspray, 2,20)
	ParticleAcceleration(Seaspray, 0, -0.1, 0)
	ParticleAngle(Seaspray,-180,180)
	ParticleEmissionRate(Seaspray, 500)
	
	waveb=1
	wavel=0.4
	swell=0.4
	foam=0.6
	
	initocean(128,1,1024,waveb,wavel,swell,foam, $ff332200, $ff886644,Seaspray,heightmap)
	
	inittime=ElapsedMilliseconds()
	Repeat
		;WindowEvent() 
		ExamineMouse()
		ExamineKeyboard()
		MouseX = -MouseDeltaX() *  0.05
		MouseY = -MouseDeltaY() *  0.05
		Macro param(val,key1,key2)
			aval=val :val +(-KeyboardReleased(key1)+KeyboardReleased(key2))*0.1:val =limite(val ,0.1,1)
			If val <>aval:menu(waveb,wavel,swell,foam):oceanset(waveb,wavel,swell,foam):EndIf
		EndMacro
		param(waveb,#PB_Key_F1,#PB_Key_F2)
		param(wavel,#PB_Key_F3,#PB_Key_F4)
		param(swell,#PB_Key_F5,#PB_Key_F6)
		param(foam ,#PB_Key_F7,#PB_Key_F8)
		If KeyboardReleased(#PB_Key_F11):fly=1-fly:EndIf
		If KeyboardReleased(#PB_Key_F12):fdf=1-fdf:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf:EndIf
		
		keyx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*0.5
		keyz=(-Bool(KeyboardPushed(#PB_Key_Up  ))+Bool(KeyboardPushed(#PB_Key_Down )))*0.5-MouseWheel()*10;-fly*0.2
		RotateCamera(0, MouseY, MouseX, 0, #PB_Relative):dist+(keyz-dist)*0.05:MoveCamera  (0, KeyX, 0, dist)
		If fly=0:och+(oceanHeight(CameraX(0),CameraZ(0))+1-och)*0.2:MoveCamera(0,CameraX(0),och,CameraZ(0),#PB_Absolute):EndIf
		
		renderocean()
		RenderWorld()
		MoveEntity(skydome_e,CameraX(0),  -8,CameraZ(0),#PB_Absolute)
		;DisplayTransparentSprite(0,8,8)
		FlipBuffers()
	Until KeyboardPushed(#PB_Key_Escape) Or MouseButton(3)
EndProcedure

main()
Avatar de l’utilisateur
Mindphazer
Messages : 639
Inscription : mer. 24/août/2005 10:42

Re: Demo 3D - Ocean v2 (shader OpenGL)

Message par Mindphazer »

Waow
C'est... hallucinant !!!
Bureau : Win10 64bits
Maison : Macbook Pro M1 14" SSD 512 Go / Ram 16 Go - iPad Pro 32 Go (pour madame) - iPhone 15 Pro Max 256 Go
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Demo 3D - Ocean v2 (shader OpenGL)

Message par Kwai chang caine »

En ce qui concerne l'eau, comme si il existait des mots 8O :oops:
La mer est tellement parfaite, que peut être l'eau sur les rochers parait un petit peu moins réaliste :wink:
En tout cas , milles mercis pour cet édifiant partage 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Demo 3D - Ocean v2 (shader OpenGL)

Message par Micoute »

Merci professeur pour le partage, c'est grandiose.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Répondre