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
|