Seite 1 von 1

Mathematische Texturen erstellen

Verfasst: 05.09.2008 01:28
von mpz
Hallo Leute,

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 
quote durch code ersetzt - Kaeru fecit

Verfasst: 05.09.2008 08:56
von dige
Stark!! :allright:

Verfasst: 05.09.2008 20:36
von Little John
Sehr schön, danke!

Gruß, Little John

Verfasst: 05.09.2008 20:45
von RSBasic
Schick Bild