Aktuelle Zeit: 12.12.2018 18:15

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 31 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4  Nächste
Autor Nachricht
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 10.04.2012 22:17 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hi,

nachdem wir im letzten Tutorial gelernt haben Mesh zu bewegen zeig ich Euch heute ein praktische Umsetzung um eine Fahne wehen zu lassen. Die hier verwendete Formel ist trickreich und leicht erklärt.

Als erstes benötigen wir einen float angle Wert der über den time Faktor erzeugt wird
Code:
float angle= time *4;

Der Wert 4 bestimmt quasi die Geschwindigkeit mit der die Fahne schwingt

Die Bewegung der Fahne wird erst einmal sinusförmig über
Code:
v.z = sin( v.x+angle)


bestimmt indem der laufende x Positionswert + time *4 mal dem Sinuswert gerechnet wird, also eine Sinuswelle über die Länge des Mesh
danach wird die halbe Sinuswelle über die Höhe berechnet, da die Fahne sich nie gleichförmig bewegt
Code:
v.z += sin( v.y /2+angle);

"Var1+=" heist "Var1 = Var1 +"

Mit dem nächsten Trick wird die Fahne am Anfang gar nicht bewegt, aber je weiter weg desto oller äh doller.
Zitat:
v.z *= (v.x+halvewidh ) * 0.09f;

das Mesh beginnt bei x position -10 und endet bei x position + 10. demnach ist halvewidh bei diesem Mesh 10. Mit diesem Trick wird links am Mesh keien Bewegung ausgeführt, da ja bekanntlich v.z = v.z * (-10+10)* 0.09 = 0 ist (rechnet es ruhig nach) bei v.x = 10 kommt was anderes raus

Der Shader braucht jetzt nur noch

http://www.flasharts.de/mpz/flagge.x
http://www.flasharts.de/mpz/Flagge.JPG

im Shadereditor wird das Mesh Flagge.x geladen und als texture0 die flagge.jpg

Vom Shadereditor übergeben Variablen:
worldViewProj -> Weltposition vom Editor übergeben
texture0 -> geladene Textur, z.B. "flagge.jpg"
time -> die laufende Zeit in ms

Code:
//-----------------------------------------------------------------------------
//           Name: MoveFlagge.fx
//         Author: Michael Paulwitz
//  Last Modified: 10.04.12
//    Description: move Flag
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4 worldViewProj : WorldViewProjection; // This matrix will be loaded by the application
texture texture0;
float time;
float halvewidh = 10;

sampler Sampler1 = sampler_state
{
texture   = <texture0>;
};

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position   : POSITION;
    float2 texture0     : TEXCOORD0;
};

// Once the vertex shader is finished, it will
// pass the vertices on to the pixel shader like this...

struct VS_OUTPUT
{
    float4 hposition : POSITION;
    float2 texture0  : TEXCOORD0;
};


//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN )
{
    VS_OUTPUT OUT;

        float4 v = float4( IN.position.x, IN.position.y, IN.position.z, 1.0f );
        float angle= time*4;
        v.z += sin( v.x+angle) ;
        v.z += sin( v.y /2+angle);
        v.z *= (v.x+halvewidh ) * 0.09f;

        OUT.hposition = mul( v, worldViewProj   );
        OUT.texture0 = IN.texture0;
        return OUT;
}

//-----------------------------------------------------------------------------
// Simple Effect (1 technique with 1 pass)
//-----------------------------------------------------------------------------

technique flag
{
    pass Pass0
    {
      Sampler[0] = (Sampler1); // Needed by pixel shader
      VertexShader = compile vs_2_0 myvs();
    }
}



Sollte die Fahne nicht nur links, sondern auch oben ruhig sein kann man das leicht mit dem Zuatz
Code:
v.z *= (v.y-6 ) * 0.09f;

erreichen.

Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 11.04.2012 21:48 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hi,

so die Fahne weht im Wind, aber... Noch bewegt sie sich unrealistisch weil die Lichtschatten bzw die Ambientlight Berechnung fehlt. Zur Berechnung benötigen wie die Normals, welche sich aber dummerweise bei einem bewegten Mesh auch ändert. Die Normals sind quasi Vectoren die im 90 Grad Winkel von der Fläche wegzeigen. Steckt in einer Styroporkugel Nadeln, dann sind die Nadeln die "Normals".
Schnell gegoogelt um die Berechnung zu finden und...nix da. Also gehen wir jetzt an die Grundlagen der Normals Berechnung. Meshs bestehen aus Dreiecksflächen die aus drei Vertex Punkten bestehen (V0,V1,V2). Um Ein Normal des VertexPunktes Vo zu berechnen Wird das CrossProdukt aus (V0 - V1) und (V0 - V2) berechnet

http://www.gamedev.net/page/resources/_ ... tors-r1089

Jetzt haben wir nur das Problem das bei einem Vertex Shader jeder VertexPunkt nacheinander durchgegangen wird, wir aber keinen Zugriff auf "alte" Vertex Punkte haben. Also definieren wir einfach temporäre Punkte um die Normals zu berechnen. In dem Fall der Flage durch die 2d Fläche einfach anzunehmen.

Code:
V0 ist der gerade berechnete v.xyz VertexPunkt
V1 ist der V.xyz Vertex Punkt + 0.5 auf X Achse und v.z für diese neue Koordinate berechnet
V2 ist der V.xyz Vertex Punkt + 0.5 auf y Achse und v.z gleich wie bei V

Die zweite Variante bei der auch bei V2 der v.z Wert neu berechnet wird zeige ich Euch auch noch, aber die erste variante gefällt mir selber schon gut genug.

Der Shader braucht jetzt nur noch

http://www.flasharts.de/mpz/flagge.x
http://www.flasharts.de/mpz/Flagge.JPG

im Shadereditor wird das Mesh Flagge.x geladen und als texture0 die flagge.jpg

Vom Shadereditor übergeben Variablen:

worldViewProj -> Weltposition vom Editor
matWorld -> Meshposition vom Editor
texture0 -> geladene Textur, z.B. "flagge.jpg"
time -> die laufende Zeit in ms
halvewidh = 10 -> Hälte der Meshlänge
lightDir -> Lichtrichtung vom Editor


Code:
//-----------------------------------------------------------------------------
//           Name: MoveFlaggeNormals.fx
//         Author: Michael Paulwitz
//  Last Modified: 28.10.09
//    Description: move Flag
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4 worldViewProj : WorldViewProjection; // This matrix will be loaded by the application
float4x4   matWorld      ; // For calculating normals

texture texture0;
float time;
float halvewidh = 10;
float3          lightDir            ; // Our lights direction

sampler Sampler1 = sampler_state
{
texture   = <texture0>;
};

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position   : POSITION;
    float2 texture0     : TEXCOORD0;
    float4 normal   : NORMAL0 ;
};


// Once the vertex shader is finished, it will
// pass the vertices on to the pixel shader like this...

struct VS_OUTPUT
{
    float4 hposition : POSITION;
    float2 texture0  : TEXCOORD0;
    float4 lightnormal : COLOR0;
};


//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN )
{
    VS_OUTPUT OUT;

        float4 v = float4( IN.position.x, IN.position.y, IN.position.z, 1.0f );
        float angle= time *4;

        v.z = sin( v.x+angle) ;
        v.z += sin( v.y /2+angle);
        v.z *= (v.x+halvewidh ) * 0.09f;
        //v.z *= (v.y-6 ) * 0.09f;

        float v2 = sin( v.x+angle-0.5) ;
        v2 += sin( v.y /2+angle);
        v2 *= (v.x-0.5+halvewidh ) * 0.09f;
        //v2 *= (v.y-6 ) * 0.09f;

         float3 poss[3];
               
         poss[0] = v.xyz;
         poss[1] = float3(v.x-0.5,v.y,v2);
         poss[2] = float3(v.x,v.y-0.5,v.z);

         float3 side1 = poss[0] - poss[2];
         float3 side2 = poss[0] - poss[1];
         IN.normal.xyz = cross(side1,side2);

        OUT.hposition = mul( v, worldViewProj   );
       
        float3 L = normalize(-lightDir);
        // transform our normal with matInverseWorld, and normalize it
        float3 N = normalize(mul(IN.normal.xyz,matWorld ));

        OUT.lightnormal =  saturate(dot(L, N));

       OUT.texture0 = IN.texture0;
        return OUT;
}

float4 myps(VS_OUTPUT IN) : COLOR
{
    return tex2D(Sampler1, IN.texture0)*(IN.lightnormal*0.8+0.2);
}

//-----------------------------------------------------------------------------
// Simple Effect (1 technique with 1 pass)
//-----------------------------------------------------------------------------

technique flag
{
    pass Pass0
    {
      PixelShader = compile ps_2_0 myps();
      VertexShader = compile vs_2_0 myvs();
    }
}



Man kann die Ambientlight Berechnung als Variante 2 auch so durchführen:

Code:
        v.z = sin( v.x+angle) ;
        v.z += sin( v.y /2+angle);
        v.z *= (v.x+halvewidh ) * 0.09f;
       // v.z *= (v.y-6 ) * 0.09f;

        float v2 = sin( v.x+0.5+angle) ;
        v2 += sin( v.y /2+angle);
        v2 *= (v.x+0.5+halvewidh ) * 0.09f;
       // v2 *= (v.y-6 ) * 0.09f;

        float v3 = sin( v.x+angle) ;
        v3 += sin( (v.y+0.5) /2+angle);
        v3 *= (v.x+0.5+halvewidh ) * 0.09f;
       // v3 *= (v.y-6+0.5 ) * 0.09f;

         float3 poss[3];
               
         poss[0] = v.xyz;
         poss[1] = float3(v.x+0.5,v.y,v2);
         poss[2] = float3(v.x,v.y+0.5,v3);

         float3 side1 = poss[0] - poss[2];
         float3 side2 = poss[0] - poss[1];
         IN.normal.xyz = cross(side1,side2);



Aber manchmal ist weniger mehr

Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 20.04.2012 14:48 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hi,

es gibt einen neuen Shadereditor Version 0.5 (download über den ersten Beitrag). Mit einigen neuen Funktionen:

* Anzeige der Zeile und Position
* Bei einem ShaderFehler sprung auf die Position des ersten erkannten Fehler
* diverse editor Funktionen (suchen ersetzen etc)
* FPS Anzeige
* Vsync on/off
* Tiefe des Meshs über Mauswheel steuerbar
* Mesh kann nur noch bewegt werden wenn das Editorfeld nicht aktiv ist (1 mal ESC drücken)

Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 20.04.2012 19:27 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hallo,

heute werden wir ein 3D Mesh über eine eigene Procedure verdrehen. Dazu benötigen wir
ein Mesh (in diesem Fall eine Turm), die Länge des Meshs und den Drehwinkel.
Die Längeneinheit des Mesh beträgt 300 und der Drehwinkel soll 360 Grad betragen

Code:
float height = float(300);
float angle_deg_max = float(360);


Über die folgende Formel kann ich dann den Winkel errechnen

Code:
float angle_deg = angle_deg_max*sin(time);// Änderung des Winkels über die Zeit
float angle_rad = angle_deg * 3.14159 / 180.0; // Umrechnung in Rad


die Veränderung der Drehrichtung erfolgt über die IN.position.y - Achse

Code:
 
float ang = (height*0.5 + IN.position.y)/height * angle_rad;


In einem Shader kann man vergleichbar mit PB auch Proceduren verwirklichen,
die machen in diesem Fall die Berechnung einfacher.

Die Vertexe.xyz werden damit über "Winkel t" gedreht

Code:
 
float3 DoTwist( float3 pos, float t )
{
   float st = sin(t);
   float ct = cos(t);
   float3 new_pos;
   
   new_pos.x = pos.x*ct - pos.z*st;
   new_pos.z = pos.x*st + pos.z*ct;
   new_pos.y = pos.y;

   return( new_pos );
}


Der Shader braucht jetzt nur noch das Mesh
http://www.flasharts.de/mpz/Tower.x
und eine geladene Textur texture0

Vom Shadereditor übergeben Variablen:

worldViewProj -> Weltposition vom Editor
texture0 -> geladene Textur, z.B. "Demo_Texture_1.bmp"
height -> länge 300 des Mesh
angle_deg_max - Drehrichtung 360 Grad
time -> die laufende Zeit in ms

Code:
//-----------------------------------------------------------------------------
//     Name: Mesh_Twister_Shader.fx
//     Author: Michael Paulwitz
//    Last Modified:
//    Description: Mesh Twister Shader with texture
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4 worldViewProj : WorldViewProjection; // This matrix will be loaded by the application

float time;
float height = float(300);
float angle_deg_max = float(360);
texture texture0;

sampler Sampler1 = sampler_state
{
texture   = <texture0>;
};


float3 DoTwist( float3 pos, float t )
{
   float st = sin(t);
   float ct = cos(t);
   float3 new_pos;
   
   new_pos.x = pos.x*ct - pos.z*st;
   new_pos.z = pos.x*st + pos.z*ct;
   new_pos.y = pos.y;

   return( new_pos );
}

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position   : POSITION;
    float2 tex0       : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 hposition : POSITION;
    float2 tex0        : TEXCOORD0;
};

//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN )
{
    VS_OUTPUT OUT;
    float angle_deg = angle_deg_max*sin(time);
    float angle_rad = angle_deg * 3.14159 / 180.0;
    float ang = (height*0.5 + IN.position.y)/height * angle_rad;
   
    IN.position = DoTwist(IN.position, ang);

    OUT.hposition = mul( float4(IN.position.x ,IN.position.y ,IN.position.z, 1), worldViewProj); //
    OUT.tex0 = IN.tex0 ;

    return OUT;
}

float4 myps(float2 Tex : TEXCOORD0) : COLOR
{
    return tex2D(Sampler1, Tex);
}

technique inverse
{
    pass p1 
    {
        VertexShader = compile vs_2_0 myvs();
        PixelShader = compile ps_2_0 myps();
    }
}



Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 23.04.2012 23:11 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hallo,

nachdem wir wirklich schön ein Rechteck verdreht haben, fehlt nur noch die
Spielerei mit den Variablen und der Schatten der das Objekt realistisch werden läßt.

z.B. Wird das Objekt mit den Werten

Code:
float height = float(1);
float angle_deg_max = float(1);


mittig verdreht. Die Frage ist warum und hier die Fleißaufgabe an Euch, fällt Euch dazu was ein? :) :) :)

Jetzt wieder zu der Schattenbildung. Die Procedure DoTwist verdreht die Vertex Punkte.
Der Trick hier ist es einfach die Normals Vectoren auch damit verdrehen zu lassen.
Wir setzen dazu wieder unseren Standard Textur Normals Shader ein und benutzen auch
für die Normals die Procedure

Code:
    IN.position = DoTwist(IN.position, ang);
    IN.normal.xyz= DoTwist(IN.normal.xyz, ang);


Wie man sieht recht einfach gehalten, aber effektiv

Der Shader braucht jetzt nur noch das Mesh
http://www.flasharts.de/mpz/Tower.x
und eine geladene Textur texture0

Vom Shadereditor übergeben Variablen:

worldViewProj -> Weltposition vom Editor
matWorld -> Meshposition vom Editor
lightDir -> Lichtrichtung vom Editor
texture0 -> geladene Textur, z.B. "Demo_Texture_1.bmp"
height -> länge 300 des Mesh
angle_deg_max - Drehrichtung 360 Grad
time -> die laufende Zeit in ms

Code:
//-----------------------------------------------------------------------------
//     Name: Mesh_Twister_Shader_with_light.fx
//     Author: Michael Paulwitz
//    Last Modified:
//    Description: Mesh Twister Shader with texture
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4 worldViewProj : WorldViewProjection; // This matrix will be loaded by the application
float4x4   matWorld      ; // For calculating normals
float3          lightDir            ; // Our lights direction
uniform float time;

uniform float height = float(1);
uniform float angle_deg_max = float(1);
texture texture0;

sampler Sampler1 = sampler_state
{
texture   = <texture0>;
};

float3 DoTwist( float3 pos, float t )
{
             float st = sin(t);
   float ct = cos(t);
   float3 new_pos;
   
   new_pos.x = pos.x*ct - pos.z*st;
   new_pos.z = pos.x*st + pos.z*ct;
   new_pos.y = pos.y;

   return( new_pos );
}

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position   : POSITION;
    float4 normal   : NORMAL0 ;
    float2 tex0       : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 hposition : POSITION;
    float2 tex0        : TEXCOORD0;
    float4 lightnormal : COLOR0;
};

//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN )
{
    VS_OUTPUT OUT;
    float angle_deg = angle_deg_max*sin(time);
    float angle_rad = angle_deg * 3.14159 / 180.0;
    float ang = (height*0.5 + IN.position.y)/height * angle_rad;
   
    IN.position = DoTwist(IN.position, ang);

    OUT.hposition = mul( float4(IN.position.x ,IN.position.y ,IN.position.z, 1), worldViewProj); //
    OUT.tex0 = IN.tex0 ;
     // normalize(a) returns a normalized version of a.
     // in this case, a = vLightDirection
     float3 L = normalize(-lightDir);
     // transform our normal with matInverseWorld, and normalize it

     IN.normal.xyz= DoTwist(IN.normal.xyz, ang);

     float3 N = normalize(mul(IN.normal.xyz,matWorld      ));
     OUT.lightnormal =  saturate(dot(L, N));
     OUT.tex0 = IN.tex0;
    return OUT;
}

float4 myps(VS_OUTPUT IN) : COLOR
{
    return tex2D(Sampler1, IN.tex0 )*(IN.lightnormal*0.9+0.1) ;
}

technique inverse
{
    pass p1 
    {
        VertexShader = compile vs_2_0 myvs();
        PixelShader = compile ps_2_0 myps();
    }
}



Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 29.04.2012 21:50 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hallo,

bei meinem heutigen Shader hat mir Stargate geholfen. viewtopic.php?f=4&t=25462
Wie wollen heute ein Mesh verformen. Wer kennt Ihn nicht den Frosch den man aufbläst zur Kugel. Dazu gehen wir wie folgt vor.
Als erstes benötigen wir eine Variable die den Wert 0-1 über eine Zeit variierend annimmt. Da wir wissen der sin(time) wert ist ein wert zwischen -1 und +1
können wir die folgende Formel nutzen:

Code:
float var = (1+ sin (time))/2; // Wert von 0-1


der Rest ist einfach. Die Vertex Kordinaten V1.xyz bwegen sich zwischen den Ausgangkoordinaten und den
normalisierten "Kugelkoordinaten"

Code:
normalize(IN.position.xyz)*high ); // high = Grösse der Kugel


Der Shader braucht jetzt nur noch das Mesh
http://www.flasharts.de/mpz/Tower.x
und eine geladene Textur texture0

Vom Shadereditor übergeben Variablen:

worldViewProj -> Weltposition vom Editor
texture0 -> geladene Textur, z.B. "Demo_Texture_1.bmp"
float high = 200; // high = Grösse der Kugel
time -> die laufende Zeit in ms


Code:
//-----------------------------------------------------------------------------
//     Name: Simple_DeformToBall_Shader.fx
//     Author: Michael Paulwitz
//    Last Modified:
//    Description: Easy Vertex Shader, to defom mesh to ball
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4 worldViewProjI : WorldViewProjection; // This matrix will be loaded by the application
texture texture0;
float time;
float high = 200; // high = Grösse der Kugel

sampler Sampler1 = sampler_state
{
texture   = <texture0>;
};

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position   : POSITION;
    float2 tex0       : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 hposition : POSITION;
    float2 tex0        : TEXCOORD0;
};

//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN )
{
    VS_OUTPUT OUT;
   
    float var = (1+ sin (time))/2; // Wert von 0-1
    float3 pos = ((var* IN.position)+((1-var)*normalize(IN.position)*high ) ); // mix zwischen Ausgangskoodinaten und Ballkoordinaten

    OUT.hposition = mul( worldViewProjI, float4(pos, 1) ); //
    OUT.tex0 = IN.tex0 ;
    return OUT;
}

float4 myps(float2 Tex : TEXCOORD0) : COLOR
{
    return tex2D(Sampler1, Tex);
}

technique Ball
{
    pass p1 
    {
        VertexShader = compile vs_2_0 myvs();
        PixelShader = compile ps_2_0 myps();
    }
}


Und auch hier kann man über die IN.position.y ein Bewegungskomponente hinzufügen...

Code:
float var = (1+ sin (time+ (IN.position.y/100)))/2; // Wert von 0-1


Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 02.05.2012 12:14 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hi,

wie man abeer sieht fehlt wieder die "realistische" Beleuchtung. Also müssen wir wieder an die Normals ran. Bei einer Kugel mit einem Mittelpunkt xyz = 0,0,0 ist das aber einfach. Hier nehmen wir einfach
Code:
float3 nor =  normalize(IN.position);
um die Normals der Kugel zu errechnen. Jetzt benutzen wir
die gleiche Formel die wir zur Verschiebung der Vertex Koodinaten benutzen um zwischen den Rechteck Normals und den Kugelnormals zu verschieben.

Veränderung der Normals
Code:
float3 nor =  normalize(IN.position); // new normalize position  of ball
nor = (var*IN.normal.xyz) + ((1-var)*nor);


Der Shader braucht jetzt nur noch das Mesh
http://www.flasharts.de/mpz/Tower.x
und eine geladene Textur texture0

Vom Shadereditor übergeben Variablen:

worldViewProj -> Weltposition vom Editor
matWorld -> Meshposition vom Editor
lightDir -> Lichtrichtung vom Editor
texture0 -> geladene Textur, z.B. "Demo_Texture_1.bmp"
float high = 200; // high = Grösse der Kugel
time -> die laufende Zeit in ms

Code:
//-----------------------------------------------------------------------------
//     Name: Simple_DeformToBall_Shader_light.fx
//     Author: Michael Paulwitz
//    Last Modified:
//    Description: Easy Vertex Shader, to defom mesh to ball with light
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4  worldViewProj : WorldViewProjection; // This matrix will be loaded by the application
float4x4  matWorld      ; // For calculating normals
float3      lightDir            ; // Our lights direction
float time;
float high = 200; // high = Grösse der Kugel
texture texture0;

sampler Sampler1 = sampler_state
{
texture   = <texture0>;
};

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position   : POSITION;
    float4 normal   : NORMAL0 ;
    float2 tex0            : TEXCOORD0;
};

// Once the vertex shader is finished, it will
// pass the vertices on to the pixel shader like this...

struct VS_OUTPUT
{
    float4 hposition    : POSITION;
    float2 tex0           : TEXCOORD0;
    float4 lightnormal : COLOR0;
};

//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN)
{
    VS_OUTPUT OUT;
               
                float var = (1+ sin (time))/2;

                float3 nor =  normalize(IN.position); // new normalize position  of ball

                float3 pos = ((var* IN.position)+((1-var)*nor*high ) ); // move position
                nor = (var*IN.normal.xyz) + ((1-var)*nor);

   OUT.hposition = mul( float4(pos,1) ,worldViewProj); //

   // normalize(a) returns a normalized version of a.
   // in this case, a = vLightDirection
   float3 L = normalize(-lightDir);
   // transform our normal with matInverseWorld, and normalize it
   float3 N = normalize(mul(nor,matWorld ));
                OUT.lightnormal =  saturate(dot(L, N));
                OUT.tex0 = IN.tex0;
   return OUT;
}

float4 myps(VS_OUTPUT IN) : COLOR
{
    return tex2D(Sampler1, IN.tex0 )*IN.lightnormal ;
}

//-----------------------------------------------------------------------------
// Simple Effect (1 technique with 1 pass)
//-----------------------------------------------------------------------------

technique Technique0
{
    pass Pass0
    {

                VertexShader = compile vs_2_0 myvs();
   PixelShader = compile ps_2_0 myps();
    }
}


_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 26.05.2012 22:00 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hi,

es gibt einen neuen Shadereditor Version 0.6 (download über den ersten Beitrag). Mit einigen neuen Funktionen:

* Änderung der Hintergrundfarbe
* Setze Farbe von Vertex eines Meshs
* Lösche Farbe von Vertex eines Meshs


Das heutige Thema lautet Darstellung von Texturen. Dazu laden wir den "Simple_VertexTexture_Shader.fx"
und modifizieren hier die Textur UV Werte indem wir diese verdreifachen. Dadurch werden die Veränderungen besser sichtbar

VS_OUTPUT myvs( VS_INPUT IN )
...
OUT.tex0 = IN.tex0 *3 ; // * 3 ist hier die verdreifachung



Vom Shadereditor übergeben Variablen:

worldViewProj -> Weltposition vom Editor
texture0 -> geladene Textur, z.B. "Demo_Texture_1.bmp"

Code:
//-----------------------------------------------------------------------------
//     Name: Simple_VertexTexture_Shader.fx
//     Author: Michael Paulwitz
//    Last Modified:
//    Description: Easy Vertex Shader, Show only the texture of the mesh
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4 worldViewProj : WorldViewProjection; // This matrix will be loaded by the application

texture texture0;

sampler Sampler1 = sampler_state
{
texture   = <texture0>;

};

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position   : POSITION;
    float2 tex0       : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 hposition : POSITION;
    float2 tex0        : TEXCOORD0;
};

//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN )
{
    VS_OUTPUT OUT;
    OUT.hposition = mul( float4(IN.position.x ,IN.position.y ,IN.position.z, 1),worldViewProj ); //

    OUT.tex0 = IN.tex0 *3 ;  // * 3 ist hier die verdreifachung

    return OUT;
}

float4 myps(float2 Tex : TEXCOORD0) : COLOR
{
    return tex2D(Sampler1, Tex);
}

technique inverse
{
    pass p1 
    {
        VertexShader = compile vs_2_0 myvs();
        PixelShader = compile ps_2_0 myps();
    }
}




wie wir sehen wird die Textur auf dem Würfel verdoppelt.

Jetzt modifizieren wir aber einfach die Funktion der Texuren

Normale verdreifachung der Textur
Code:
sampler Sampler1 = sampler_state
{
    texture   = <texture0>;
    AddressU = Wrap;
    AddressV = Wrap;
};


Textur wird einmal dargestellt aber letzte Farbreihe weitergeführt
Code:
sampler Sampler1 = sampler_state
{
    texture   = <texture0>;
    AddressU = Clamp;
    AddressV = Clamp;
};


Textur wird einmal dargestellt und die zweite Textur gespiegelt
Code:
sampler Sampler1 = sampler_state
{
    texture   = <texture0>;
    AddressU = MIRROR;
    AddressV = MIRROR;

};


Textur wird einmal dargestellt und der Rest schwarz
Code:
sampler Sampler1 = sampler_state
{
    texture   = <texture0>;
    AddressU = BORDER;
    AddressV = BORDER;

};


Das nächste Thema ist schon fertig und kommt bald, das animieren von Grass.

Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 27.05.2012 23:08 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hallo,

da wir das letzte mal mit Texturen beschäftigt waren denke ich das es am sinnvollsten ist
hier noch ein paar Möglichkeiten zu erleutern. Zudem werde ich beginnen ein paar Proceduren
zu erstellen die im Shaderbereich einfacher zu benutzen sind. Eine Erweiterung mit einer
kleinen Datenbank um die Proceduren zu verwalten wird es zukünftig im Shadereditor geben.

Also gibt es heute die Procedure um eine Texture zu drehen. Dazu folgende Vorüberlegungen:
Die UV Texturkoordinaten kann man als 2D Vectoren ansehen mit den Vetorenpaaren:
UV1 = (0,0) , UV2 = (1,0), UV3 = (0,1), UV4 = (1,1)
UM eine Textur zu drehen mus man quasi die UV(1-4) drehen.

Dazu gibt es den
x1=sin(Arctan2 (x,y)+rad)
y1=cos(Arctan2 (x,y)+rad)

gilt aber nur für den Radius mit den Einheitsvector "1" um das auf die Koordinaten zu
projezieren benutzen wir den alten Phytagoras x1* sqr(1*1+1*1)/2

x1=sin(Arctan2 (x,y)+rad)*0.71
y1=cos(Arctan2 (x,y)+rad)*0.71

Dazu müssen wir noch den Mittelpunkt bestimmen den wir als middle = 0.5 bezeichnen

Das Ergebniss ist folgende Funktion:
Code:
float2 DoTurnTex( float2 postex, float t ) // t = Rad oder t * 0.017453 = Grad
{
  float2 new_postex;
  float middle = float (0.5);
  postex -= 0.5 ;
  // t*= 0.017453; // makes from radiant to grad
  new_postex.x = sin(atan2(postex.x,postex.y)+t)*0.71+ middle;
  new_postex.y = cos(atan2(postex.x,postex.y)+t)*0.71+ middle;
  return( new_postex );
}


Das testen wir mit einem Standardshader

Vom Shadereditor übergeben Variablen:

worldViewProj -> Weltposition vom Editor
texture0 -> geladene Textur, z.B. "Demo_Texture_1.bmp"

Code:
//-----------------------------------------------------------------------------
//     Name: Simple_Texture_Shader.fx

//     Author: Michael Paulwitz
//    Last Modified:
//    Description: Easy Vertex Shader, Show only the texture of the mesh
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Effect File Variables
//-----------------------------------------------------------------------------

float4x4 worldViewProjI : WorldViewProjection; // This matrix will be loaded by the application

texture texture0;
float time;
sampler Sampler1 = sampler_state
{
texture   = <texture0>;
};

//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------

// Our sample application will send vertices
// down the pipeline laid-out like this...

struct VS_INPUT
{
    float3 position   : POSITION;
    float2 tex0       : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4 hposition : POSITION;
    float2 tex0        : TEXCOORD0;
};


float2 DoTurnTex( float2 postex, float t ) // t = Rad oder t * 0.017453 = Grad
{
  float2 new_postex;
  float middle = float (0.5);
  postex -= 0.5 ;
  // t*= 0.017453; // makes from radiant a grad function
  new_postex.x = sin(atan2(postex.x,postex.y)+t)*0.71+ middle;
  new_postex.y = cos(atan2(postex.x,postex.y)+t)*0.71+ middle;
  return( new_postex );
}




//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------

VS_OUTPUT myvs( VS_INPUT IN )
{
    VS_OUTPUT OUT;
    OUT.hposition = mul( worldViewProjI, float4(IN.position.x ,IN.position.y ,IN.position.z, 1) ); //
   
    OUT.tex0 = DoTurnTex( IN.tex0,time); // Hier dreht die Texture
   
    return OUT;
}

float4 myps(float2 Tex : TEXCOORD0) : COLOR
{
    return tex2D(Sampler1, Tex);
}

technique inverse
{
    pass p1 
    {
        VertexShader = compile vs_2_0 myvs();
        PixelShader = compile ps_2_0 myps();
    }
}



Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Tutorial: Vertex Shader & Pixel Shader Unterstützung in
BeitragVerfasst: 25.07.2012 12:18 
Offline
Benutzeravatar

Registriert: 14.06.2005 15:53
Wohnort: Berlin, Kreuzberg
Hallo,

da mein dieswöchiger Urlaub aufgrund eines Motorschadens nicht stattfand habe ich mal
wieder Zeit ein Tutorial vorzubereiten.

Hier geht es jetzt um Grassanimation und die "mehr Pass" Funktion.

Was wir daher als erstes benötigen ist eine Mesh der im Prinzip aus 3 flachen Rechtecken
besteht der in der Mitte um 120 Grad verschoben ist und ein Grass Bild mit Alphakanal damit
das Bild an der richtigen Stelle durchscheint. Wer es mag kann auch verschiedene Meshes
benutzen und mehr oder weniger Rechtecke ungleichmäßig zusammenstellen.

Bild

Wie man den letzten Tutorial entnehmen konnte ist es am einfachste ein Mesh in der x und z Achse
über den y Positionswert zu animieren. D.h. das der höchste y Positionswert sich auch am meisten
bewegt. Hier wird zudem die z Achse doppelt so schnell über die Zeit bewegt wie der Pos.x Wert

Code:
    Pos.x   += cos(time) * Pos.y * 0.02;
    Pos.z   += cos(time*2) * Pos.y * 0.02;


Jetzt kommen wir zur der "mehr Pass" Funktion. D.h wir sagen dem Shader führe erst die Funktion 1,
dann die Funktion 2 und dan die Funktion 3 aus

Code:
pass p0
   {
                   Funktion 1 ausführen
   }
pass p1
   {
                   danach Funktion 2 ausführen
   }
pass p2
   {
                   als letztes die Funktion 3 ausführen
   }


in meinem Beispiel verdreifachen wir einfach das Mesh und
stellen es unterschiedlich mit unterschiedlichen Bewegungen dar.

Code:
"Hauptmesh"
    Pos.x   += cos(time) * Pos.y * 0.02;
    Pos.z   += cos(time*2) * Pos.y * 0.02;

"Rechtsmesh"
    Pos.x   += cos(time*2) * Pos.y * 0.02 + 4;
    Pos.z   += cos(time) * Pos.y * 0.02;

die +4 bestimmt die rechte Position 

"Linksmesh"
    Pos.x   += cos(time*2) * Pos.y * 0.02 - 4;
    Pos.z   += cos(time*2) * Pos.y * 0.02;

die -4 bestimmt die linke Position 


Hier jetzt das Beispiel:
Vom Shadereditor übergeben Variablen:

worldViewProj -> Weltposition vom Editor
texture0 -> geladene Textur, z.B. "grass1.tga"
time -> die laufende Zeit in ms

Der Shader braucht jetzt nur noch das Mesh
http://www.flasharts.de/mpz/Grass_Variante_1.x

und eine geladene Textur texture
http://www.flasharts.de/mpz/grass1.tga

Code:
// Modified Version of the Grass Demo From ATI
// grass.fx
// Modifyt for MP3D by Michael
 
texture   texture0;
float4x4  worldViewProj;
float time;

// Faktoren (Tweakables)
float   g_fAlpha          = 10;

// float4    windDirection;

sampler GrassSampler= sampler_state
{
   Texture = <texture0>;
   
   MinFilter = LINEAR;
   MagFilter = LINEAR;
   MipFilter = LINEAR;
                AddressU = Clamp;
                AddressV = Clamp;
};

struct VS_OUTPUT
{
    float4 Pos   : POSITION;
    float2 Tex   : TEXCOORD0;
};

//
// V E R T E X - S H A D E R
//

VS_OUTPUT VSGrass(float4 Pos : POSITION,
                  float2 Tex : TEXCOORD0)
{
    VS_OUTPUT Out;

    Pos.x   += cos(time) * Pos.y * 0.02;
    Pos.z   += cos(time*2) * Pos.y * 0.02;

    Out.Pos   = mul(Pos, worldViewProj);
    Out.Tex   = Tex;

    return Out;
}

VS_OUTPUT VSGrass2(float4 Pos : POSITION,
                  float2 Tex : TEXCOORD0)
{
    VS_OUTPUT Out;

    Pos.x   += cos(time*2) * Pos.y * 0.02 + 4;
    Pos.z   += cos(time) * Pos.y * 0.02;

    Out.Pos   = mul(Pos, worldViewProj);
    Out.Tex   = Tex;

    return Out;
}

VS_OUTPUT VSGrass3(float4 Pos : POSITION,
                  float2 Tex : TEXCOORD0)
{
    VS_OUTPUT Out;

    Pos.x   += cos(time*2) * Pos.y * 0.02 - 4;
    Pos.z   += cos(time*2) * Pos.y * 0.02;

    Out.Pos   = mul(Pos, worldViewProj);
    Out.Tex   = Tex;

    return Out;
}

//
// P I X E L - S H A D E R
//

float4 PSGrass(VS_OUTPUT In) : COLOR0
{
    float4 TexColor = tex2D(GrassSampler, In.Tex);
    return float4(TexColor.rgb, g_fAlpha * TexColor.a);
}

// Techniques
technique grass
{
   pass p0
   {
                                Lighting         = FALSE;
                                AlphaTestEnable  = TRUE;
                                AlphaFunc        = Greater;

      VertexShader = compile vs_2_0 VSGrass();
      PixelShader = compile ps_2_0 PSGrass ();
   }
   pass p1
   {
             VertexShader = compile vs_2_0 VSGrass2();
      PixelShader = compile ps_2_0 PSGrass ();
   }
   pass p2
   {
             VertexShader = compile vs_2_0 VSGrass3();
      PixelShader = compile ps_2_0 PSGrass ();
   }
}



Gruß Michael

_________________
Working on - MP3D Engine -


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 31 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3, 4  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye