für meine 3D Engine auf Basis von DX9 unter Windows habe ich gerade mathematische Texturen näher beleuchtet und umgesetzt. Ich würde mich freuen wenn Ihr auch noch ein paar einfache Algorithmen beisteuern könntet. Das Programm stellt Rauschen, Unruhemuster (Perlin Noise), Sinus Rohre, Ringe und Karomuster dar. Die Parameter habe ich etwas erklärt, hier gilt einfach ausprobieren. Es gibt sicherlich einige Sin/cos/tan Funktionen die zu erstaunlichen Ergebnissen führen können. Warum ich GenerateNoise, smoothNoise und turbulence mit 2d benannt habe ist leicht erklärt, es gibt auch 3d wobei hierbei eine zeitliche Veränderung (wolken, Rost, Bewegung o.ä.) stattfindet. Der einfachthalber habe ich es hier aber bei 2d gelassen. 3d gibt es dann in der 3D Engine..
Vermutlich lassen sich die Funktionen GenerateNoise, smoothNoise und turbulence auch mit Assembler beschleunigen. Hoffentlich hat jemand Lust das zu realisieren…
Edit: Weiteres Muster und Bewegung integriert
Gruß Michael
Code: Alles auswählen
;////////////////////////////////////////////////////////////////
;//
;// Project Title: Mathematische Texturen für meine 3D Engine
;// File Title: Math_Textur.pb
;// Erstellt am: 3.9.2008
;// Update am:
;// Author: Michael Paulwitz
;//
;// 2d Texturen freigegeben zu erweiterung...
;//
;//
;////////////////////////////////////////////////////////////////
;Wahl = 1 ; Rauschmuster erstellen
;Wahl = 2 ; Rauschmuster um Faktor 8 vergrössert
;Wahl = 3 ; Rauschmuster um Faktor 8 vergrössern und weichzeichnen
;Wahl = 4 ; Rauschmuster mehrfach vergrössern und aufeinander addieren = Unruhenmuster = Perlin Noise
;Wahl = 5 ; Rauschmuster mehrfach vergrössern und aufeinander addieren und Blau einfärben für Himmel
;Wahl = 6 ; Sinusmuster erzeugen
;Wahl = 7 ; Aus Sinusmuster wird ein Marmormuster
;Wahl = 8 ; Marmormuster 2 mit weniger Unruhe
;Wahl = 9 ; Marmormuster 3 mit mehr Unruhe
;Wahl = 10 ; Marmormuster 4 mit nur einer Linie und mehr Unruhe
;Wahl = 11 ; Marmormuster 5 mit nur einer Linie und noch mehr Unruhe und Farbe;
;Wahl = 12 ; Ringmuster mit erzeugen
;Wahl = 13 ; Ringmuster mit Holzfarbe mit wenig Rauschen erzeugen
;Wahl = 14 ; Ringmuster mit Holzfarbe mit mehr Ringen und Rauschen erzeugen
;Wahl = 15 ; Karomuster
;Wahl = 16 ; Karomuster mit kleiner veränderung
;Wahl = 17 ; Karomuster mit gossen Veränderungen
Wahl = 18 ; Ungleichmässiges Muster mitVeränderungen
Moveing = 1 ; Bewegt das Rauschen
#noiseWidth = 256
#noiseHeight = 256
Global Dim noise2d.d (#noiseWidth,#noiseHeight); //Rauschfeld
Procedure Uint8(x.l)
If x > 256
x = 256
ElseIf x < 0
x = 0
EndIf
ProcedureReturn x
EndProcedure
Procedure generateNoise2d()
For x = 0 To #noiseWidth
For y = 0 To #noiseHeight
noise2d(x,y) = Random(32768) / 32768;
Next
Next
EndProcedure
Procedure.d smoothNoise2d(x.d, y.d)
; Bruchwert
fractX.d = x - Int(x);
fractY.d = y - Int(y);
; Nachtbarwerte
x1.l = (Int(x) + #noiseWidth) % #noiseWidth;
y1.l = (Int(y) + #noiseHeight) % #noiseHeight;
; Nachtbarwerte
x2.l = (x1 + #noiseWidth - 1) % #noiseWidth;
y2.l = (y1 + #noiseHeight - 1) % #noiseHeight;
; Rauschen wird geglättet
value.d = 0.0;
value = value + (fractX * fractY * noise2d(x1,y1))
value = value + (fractX * (1 - fractY) * noise2d(x1,y2))
value = value + ((1 - fractX) * fractY * noise2d(x2,y1))
value = value + ((1 - fractX) * (1 - fractY) * noise2d(x2,y2))
ProcedureReturn value;
EndProcedure
Procedure.d turbulence2d(x.d, y.d, size.d)
initialSize = size;
While (size >= 1)
value.d = value + (smoothNoise2d(x / size, y / size) * size);
size = size / 2.0;
Wend
ProcedureReturn (128.0 * value / initialSize);
EndProcedure
Procedure ChangeNoise(Value.l) ; Veränderung in %
Value = 327.68 * Value
Random = Value / 2
For x = 0 To #noiseWidth
For y = 0 To #noiseHeight
noise2d(x,y) = noise2d(x,y) + (Random(Value)-Random) / 32768;
If noise2d(x,y) > 1
noise2d(x,y) = 1
ElseIf noise2d(x,y) < 0
noise2d(x,y) = 0
EndIf
Next
Next
EndProcedure
;- main
OpenWindow(0, 100, 200, #noiseWidth, #noiseHeight, "Random Noise", #PB_Window_SystemMenu )
generateNoise2d();
StartDrawing(WindowOutput(0))
Repeat
For x = 0 To #noiseWidth
For y = 0 To #noiseHeight
Select Wahl
Case 1 ; Rauschmuster
color = Uint8(256 * noise2d(x,y))
Plot(x, y , RGB(color,color,color))
Case 2 ; Rauschmuster vergrössert
color = Uint8(256 * noise2d(x/8,y/8))
Plot(x, y , RGB(color,color,color))
Case 3 ; Rauschmuster vergrössert und weichgezeichnet
color = Uint8(256 * smoothNoise2d(x/8,y/8))
Plot(x, y , RGB(color,color,color))
Case 4 ; Unruhenmuster
color = Uint8(turbulence2d(x, y, 64))
Plot(x, y , RGB(color,color,color))
Case 5 ; Wolkenmuster
color = Uint8(turbulence2d(x, y, 64));
Plot(x,y,RGB(color, 55 + (color * 0.78), 255))
Case 6 ; Sinusmuster
Abstand.f = 0.15
color = Uint8(255 * Sin(x * Abstand + y * Abstand))
Plot(x,y,RGB(color, color, color))
Case 7 ; Marmormuster 1
;//xPeriod und yPeriod definieren zusammen den Winkel der Linien
;//xPeriod und yPeriod beide 0 ==> ergibt normale Wolken oder ein Unruhenmuster
xPeriod.d = 6; //Definiert die Wiederholungen der Marmorlinien in x Richtung
yPeriod.d = 10; //Definiert die Wiederholungen der Marmorlinien in y Richtung
;//turbPower = 0 ==> Ergibt normales Sinusmuster
turbPower.d = 5; //Veränderungstärke
turbSize.d = 32; // Stärke der Unruhe
xyValue.d = x * xPeriod / #noiseHeight + y * yPeriod / #noiseWidth + turbPower * turbulence2d(x, y, turbSize) / 256
color = Uint8(255 * Abs(Sin(xyValue * 3.14159)));
Plot(x,y,RGB(color, color, color))
Case 8 ; Marmormuster 2
xPeriod.d = 5 : yPeriod.d = 10 : turbPower.d = 1 : turbSize.d = 32
xyValue.d = x * xPeriod / #noiseHeight + y * yPeriod / #noiseWidth + turbPower * turbulence2d(x, y, turbSize) / 256
color = Uint8(255 * Abs(Sin(xyValue * 3.14159)));
Plot(x,y,RGB(color, color, color))
Case 9 ; Marmormuster 3
xPeriod.d = 5 : yPeriod.d = 10 : turbPower.d = 5 : turbSize.d = 16
xyValue.d = x * xPeriod / #noiseHeight + y * yPeriod / #noiseWidth + turbPower * turbulence2d(x, y, turbSize) / 256
color = Uint8(255 * Abs(Sin(xyValue * 3.14159)));
Plot(x,y,RGB(color, color, color))
Case 10 ; Marmormuster 4
xPeriod.d = 0 : yPeriod.d = 1 : turbPower.d = 1 : turbSize.d = 32
xyValue.d = x * xPeriod / #noiseHeight + y * yPeriod / #noiseWidth + turbPower * turbulence2d(x, y, turbSize) / 256
color = Uint8(255 * Abs(Sin(xyValue * 3.14159)));
Plot(x,y,RGB(color, color, color))
Case 11 ; Marmormuster 5
xPeriod.d = 0 : yPeriod.d = 1 : turbPower.d = 5 : turbSize.d = 32
xyValue.d = x * xPeriod / #noiseHeight + y * yPeriod / #noiseWidth + turbPower * turbulence2d(x, y, turbSize) / 256
color = Uint8(255 * Abs(Sin(xyValue * 3.14159))) * 0.88;
Plot(x,y,RGB(color+30,color+10,color))
Case 12 ; Ringmuster
xyPeriod.d = 12; //Anzahl der Ringe
xValue.d = (x - #noiseHeight / 2) / #noiseHeight;
yValue.d = (y - #noiseWidth / 2) / #noiseWidth;
color = Uint8(255 * Sin(2 * xyPeriod * 3.14159 * Sqr(xValue*xValue + yValue*yValue)))
Plot(x,y,RGB(color, color, color))
Case 13 ; Ringmuster 2 mit Holzton
xyPeriod.d = 12; //Anzahl der Ringe
turbPower.d = 0.1; //Veränderungstärke
turbSize.d = 32; //Stärke der Unruhe
xValue.d = (x - #noiseHeight / 2) / #noiseHeight;
yValue.d = (y - #noiseWidth / 2) / #noiseWidth;
distValue.d = Sqr(xValue * xValue + yValue * yValue) + turbPower * turbulence2d(x, y, turbSize) / 256;
color = 128.0 * Abs(Sin(2 * xyPeriod * distValue * 3.14159));
Plot(x,y,RGB(80+color, 20+color, 30))
Case 14 ; Ringmuster 3 mit Holzton
xyPeriod.d = 18; //Anzahl der Ringe
turbPower.d = 0.2;//Veränderungstärke
turbSize.d = 32;//Stärke der Unruhe
xValue.d = (x - #noiseHeight / 2) / #noiseHeight;
yValue.d = (y - #noiseWidth / 2) / #noiseWidth;
distValue.d = Sqr(xValue * xValue + yValue * yValue) + turbPower * turbulence2d(x, y, turbSize) / 256;
color = 128.0 * Abs(Sin(2 * xyPeriod * distValue * 3.14159));
Plot(x,y,RGB(80+color, 20+color, 30))
Case 15 ; Karomuster
xyPeriod.d = 8; //Anzahl der Muster
xValue.d = (x - #noiseHeight / 2) / #noiseHeight
yValue.d = (y - #noiseWidth / 2) / #noiseWidth
color = uint8(127 * Abs(Sin(xyPeriod * xValue * 3.1415) + Sin(xyPeriod * yValue * 3.1415)));
Plot(x,y,RGB(color, color, color))
Case 16 ; Karomuster mit kleiner Veränderung
xyPeriod.d = 8; //Anzahl der Muster
turbPower.d = 0.2;//Veränderungstärke
turbSize.d = 32;//Stärke der Unruhe
xValue.d = (x - #noiseHeight / 2) / #noiseHeight + turbPower * turbulence2d(x, y, turbSize) / 256;
yValue.d = (y - #noiseWidth / 2) / #noiseWidth + turbPower * turbulence2d(#noiseHeight - y, #noiseWidth - x, turbSize) / 256.0;
color = uint8(127 * Abs(Sin(xyPeriod * xValue * 3.1415) + Sin(xyPeriod * yValue * 3.1415)));
Plot(x, y, RGB(color,color,color));
Case 17 ; Karomuster mit grossen Veränderung
xyPeriod.d = 8; //Anzahl der Muster
turbPower.d = 2;//Veränderungstärke
turbSize.d = 128;//Stärke der Unruhe
xValue.d = (x - #noiseHeight / 2) / #noiseHeight + turbPower * turbulence2d(x, y, turbSize) / 256;
yValue.d = (y - #noiseWidth / 2) / #noiseWidth + turbPower * turbulence2d(#noiseHeight - y, #noiseWidth - x, turbSize) / 256.0;
color = uint8(127 * Abs(Sin(xyPeriod * xValue * 3.1415) + Sin(xyPeriod * yValue * 3.1415)));
Plot(x, y, RGB(color,color,color));
Case 18 ; Ungleichmässiges Muster
turbPower.d = 1;//Veränderungstärke
turbSize.d = 32;//Stärke der Unruhe
color = Uint8((ATan(x/y/3)*122) + turbPower * (turbulence2d(x, y, turbSize) - 132))
Plot(x,y,RGB(color, color, color))
;Debug turbulence2d(x, y, turbSize)
EndSelect
Next
Next
ChangeNoise(12)
Until Moveing = 0 Or WindowEvent() = #PB_Event_CloseWindow
StopDrawing()
Repeat
Delay(1)
Until WindowEvent() = #PB_Event_CloseWindow