Procedural dynamic textures

Blitz3D Forums/Blitz3D Programming/Procedural dynamic textures

caff_(Posted 2007) [#1]
Any ideas how to make a procedural texture, e.g. one to simulate clouds forming / dispersing?


IPete2(Posted 2007) [#2]
Caffy

Procedural textures? Not sure how having a procedural texture would help you develop a layer of clouds...(at best that would be quite slow) however, you may be better thinking about developing some kind of large particle engine, there is one for fog in the code archives which works quite well.


IPete2.


LAB[au](Posted 2007) [#3]
Well that could be preprocessed (3D? in fact a stack of 2D textures) textures (still procedural tho') in this case the function you need to search for (and implement) is called Perlin Noise.


caff_(Posted 2007) [#4]
Thanks

I found a code archive entry for perlin noise - however I think the technique will be far too slow for real time... particularly as I want them to be quite hi-res clouds, which would take up a fair chunk of vid memory.

I think I'll stick with layering 3 or 4 different cloud textures with alpha to create the effect of clouds forming and dispersing.


MixailV(Posted 2007) [#5]
My simple "perlin-noise" generator


;2-уровневый генератор шума Перлина (почти)
;для упрощения и ускорения используется рендер видюхи
;созданная текстура может генериться "бесшовной" по горизонтали и вертикали


Global GW=1280
Global GH=1024

Graphics3D GW,GH,0,1
Global cam=CreateCamera()
SetFont LoadFont ("",15)
Dim s(100)
Dim t(100)
Dim sp(100)


tx=CreateTexture(GH,GH,1)
i=0
sp(i)=CreateQuad()
EntityFX sp(i),1+8+16
EntityOrder sp(i),-i
PositionEntity sp(i),0,0,Float(GW)/Float(GH)
EntityTexture sp(i),tx

.loop
	r0=Rand(9,10)
	r1=Rand(0,5)
	Generate r0,r1,tx,1,1
	AutoContrast 1,tx		;фильтр автоконтрастности с управляемым порогом "черного"
	RenderWorld
	Text 10,10,"Base Freq: "+Str(r0)
	Text 10,25,"Modulate Freq: "+Str(r1)
	Text 10,40,"G - new generate"
	Flip 0
	k=WaitKey()
	If k=103 Then Goto loop
End




;iq - частота генерации основного аддитивного шума (все частотные составляющие СКЛАДЫВАЮТСЯ)
;iq = 2 ... 10 (1024 pix)

;iq0 - частота генерации модуляционного шума (шум iq УМНОЖАЕТСЯ на шум iq0)
;если iq0<1 то негенериться
;мной использован для генерации низкочастотных модуляций основного шума - "облаков"

;tt - текстурный буффер, куда будет помещена сгенеренный шум

;lpX и lpY - флаги "бесшовности" по осях X и Y

;размер текстуры генерящейся текстуры = 2^iq (2^iq0), также зависит от видеоразрешения
;и вообще возможностей видеокарты

Function Generate(iq,iq0,tt,lpX=0,lpY=0)
	RotateEntity cam,0,180,0
	CameraClsColor cam,0,0,0

	SeedRnd MilliSecs ()

	For i=2 To iq
		s(i)=CreateQuad()
		EntityFX s(i),1+8+16
		EntityOrder s(i),-i
		PositionEntity s(i),0,0,-Float(GW)/Float(GH)
		EntityAlpha s(i),1.0/Float(iq)
		EntityBlend s(i),3
		
		d=2^i
		t(i)=CreateTexture (d,d,1)
		b=TextureBuffer( t(i) )
		SetBuffer b
		LockBuffer b
		For x=0 To d-1
			For y=0 To d-1
				c=Rand(0,255)
				WritePixelFast x,y,(c Shl 16)+(c Shl 8)+c
			Next
		Next
		
		If lpX>0 Then
		For y=0 To d-1				;бесшовность по горизонтали
			c=ReadPixelFast (0,y)
			WritePixelFast d-1,y,c
		Next
		EndIf
		If lpY>0 Then
		For x=0 To d-1				;бесшовность по вертикали
			c=ReadPixelFast (x,0)
			WritePixelFast x,d-1,c
		Next
		EndIf
		
		UnlockBuffer b

		kk#=Float(d)/Float(d-1)
		ScaleEntity s(i),kk,1.0,1.0
		EntityTexture s(i),t(i)
	Next

	SeedRnd MilliSecs ()
	
	If iq0>0 Then
	For i=1 To iq0
		i0=iq+i
		
		s(i0)=CreateQuad()
		EntityFX s(i0),1+8+16
		EntityOrder s(i0),-i0
		PositionEntity s(i0),0,0,-Float(GW)/Float(GH)
		EntityBlend s(i0),2
		
		d=2^i
		t(i0)=CreateTexture (d,d,1)
		b=TextureBuffer( t(i0) )
		SetBuffer b
		LockBuffer b
		For x=0 To d-1
			For y=0 To d-1
				c=Rand(128,255)
				WritePixelFast x,y,(c Shl 16)+(c Shl 8)+c
			Next
		Next
		
		If lpX>0 Then
		For y=0 To d-1				;бесшовность по горизонтали
			c=ReadPixelFast (0,y)
			WritePixelFast d-1,y,c
		Next
		EndIf
		If lpY>0 Then
		For x=0 To d-1				;бесшовность по вертикали
			c=ReadPixelFast (x,0)
			WritePixelFast x,d-1,c
		Next
		EndIf
		UnlockBuffer b
		
		kk#=Float(d)/Float(d-1)
		ScaleEntity s(i0),kk,1.0,1.0
		EntityTexture s(i0),t(i0)
	Next
	EndIf


	SetBuffer BackBuffer()
	RenderWorld


	d=GH
	dx=(GW-GH)/2
	CopyRect dx,0,d,d,0,0,BackBuffer(),TextureBuffer(tt)


	For i=2 To (iq+iq0)
		FreeEntity s(i)
		FreeTexture t(i)
	Next
	RotateEntity cam,0,0,0

End Function

Function AutoContrast(lev,tx)
	min=255
	max=0
	b=TextureBuffer (tx)
	SetBuffer b
	LockBuffer b
	
	For x=0 To GH-1
		For y=0 To GH-1
			c=ReadPixelFast (x,y) And 255
			If c>max Then max=c
			If c<min Then min=c
		Next
	Next

	min=min+lev
	max=max-lev
	k#=255.0/Float(max-min)
	
	For x=0 To GH-1
		For y=0 To GH-1
			c=ReadPixelFast (x,y) And 255
			
			cm=c-min
			If cm<0 Then cm=0
			
			c0=(Float(cm)*k)
			If c0>255 Then c0=255
			
			WritePixelFast x,y,(c0 Shl 16)+(c0 Shl 8)+c0
		Next
	Next

	UnlockBuffer b
	SetBuffer BackBuffer()
End Function

Function CreateQuad()
	m=CreateMesh()
	sf=CreateSurface(m)

	v0=AddVertex(sf, -1.0,1.0,0.0, 0.0,0.0)
	v1=AddVertex(sf, 1.0,1.0,0.0, 1.0,0.0)
	v2=AddVertex(sf, 1.0,-1.0,0.0, 1.0,1.0)
	v3=AddVertex(sf, -1.0,-1.0,0.0, 0.0,1.0)

	AddTriangle sf,v0,v1,v2
	AddTriangle sf,v0,v2,v3
	
	Return m
End Function



caff_(Posted 2007) [#6]
That's quite neat :)

Too slow for real time though - but thanks for the example


b32(Posted 2007) [#7]
Yes, the 2d commands are too slow for realtime rendering.
However, maybe you could use this: (2d)
http://www.blitzbasic.com/Community/posts.php?topic=34301
or this: (3d)
http://www.blitzbasic.com/Community/posts.php?topic=49271


.Squid(Posted 2007) [#8]
Hey, MixailV! Russian comments rulezzz))))