ProfilProfil
 Registrieren
 Login
Bild der WocheBild der Woche

(von Backslider)
Kommentare (0)
****

Weitere
User onlineBenutzer online
Gäste online: 5
Mitglieder online: Keine
Registrierte Mitglieder: 2116
Neustes Mitglied: onkel_keks

Texture Blending

Autor: Astror Enales

Inhaltsverzeichnis

  1. Einleitung
  2. Informationen
  3. Der Shader
  4. Ende

^ Einleitung


Inspiriert von den CryEngine3 Entwickler-Videos musste ich einen ziemlich schicken Effekt der Engine nachbauen und möchte diesen nun hier für Alle bereit stellen.
Es handelt sich dabei um einen Effekt mit dem man zwei Texturen (z.b. Wand rot und Wand weiß) über eine Noise Maske übereinander blenden kann.
Wie dies aussieht habe ich einmal in einem kleinen Video zusammengefasst:
http://vimeo.com/11309657

Interesse geweckt? Dann nichts wie los.

^ Informationen


Die Maske folgt in meinem Beispiel einer gewissen Richtlinie. Und zwar benutze ich den Alpha-Bereich von 0-255 um die Texturen zu "blenden". Wir geben unserem Shader einen Strength Wert, den wir beliebig verändern können, je nachdem wie stark die Texturen geblendet werden sollen. Der Alpha-Wert gibt dabei an wie "früh" die Texturen geblendet werden.
Im Download am Ende der Artikels findet ihr Beispiel-Texturen die eine gute Impression geben wie man die Textur machen kann. (Die Wand-Textur ist von http://www.cgtextures.com/)

^ Der Shader


Fangen wir also mit der Deklaration unserer Variablen und Textur-Samplern an:
float4x4 World;
float4x4 View;
float4x4 Projection;

float Strength;

texture Texture0;
sampler2D sampler0 = sampler_state
{
   Texture = (Texture0);
   MIPFILTER = LINEAR;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
};

texture Texture1;
sampler2D sampler1 = sampler_state
{
   Texture = (Texture1);
   MIPFILTER = LINEAR;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
};

texture TextureMask;
sampler2D samplerMask = sampler_state
{
   Texture = (TextureMask);
   MIPFILTER = LINEAR;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
};

Neben den obligatorischen Variablen für Welt-, Kamera- und Projektionsmatrix, kommt eine float-Variable welche die Stärke des Effektes repräsentiert. Es folgen die drei Texturen, die wir in unserem Fall benötigen: Textur 1 und 2 sowie die Maske.
Nun kommen wir zum Vertex-Shader:
struct VertexShaderInput
{
    float4 Position : POSITION0;
    float2 TexCoords : TEXCOORD0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TexCoords : TEXCOORD0;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    output.Position = mul(input.Position, mul(mul(World, View), Projection));
    output.TexCoords = input.TexCoords;

    return output;
}

Kommen wir nun zum interessanten Teil, dem Pixel-Shader.
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
   float4 color0 = tex2D(sampler0, input.TexCoords);
   float4 color1 = tex2D(sampler1, input.TexCoords);
   float4 mask = tex2D(samplerMask, input.TexCoords);
   if(Strength >= mask.a)
      return color1;
   else
      return color0;
}

technique TextureBlend
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

Dieser Teil ist allerdings auch leicht erklärt.
Zuerst holen wir uns die Farbinformationen des Texels aus den Texturen 1, 2 sowie der Maske. Nun vergleichen wir ob die Stärke, welche wir dem Shader angegeben haben, größer ist als der Alpha-Wert der Maske. Wenn dies der Fall ist, geben wir Textur 2 zurück, sonst Textur 1.
Und das ist schon Alles. Gar nicht so schwer oder? Wink

^ Ende


Über Lob und Kritik freue ich mich natürlich immer gern Smile

Downloaden könnt ihr ein Beispielprojekt mit Content unter folgender Url:
TextureBlend_Tutorial.zip

Infos

Name: Texture Blending
Autor: Astror Enales
Kommentare: Thread