Moires-Muster trotz Verwendung von Mipmaps

7

Ich arbeite an der Silverlight App. Ich versuche, den Boden mit Fliesen zu bedecken. Obwohl ich Mip-Maps verwende, bekomme ich immer noch schreckliche Moire-Muster, wenn ich versuche, große Flächen zu rendern.

Ich erstelle einen Quader und bedecke ihn dann mit einer einzelnen Kachel:

Geben Sie hier die Bildbeschreibung ein

In meinem Pixel-Shader multipliziere ich Texturkoordinaten, um einen Fliesenboden zu erstellen (andernfalls würde ich eine Fliese über meinen Quader spannen). Pixel-Shader-Code:

float Width                 : register(c3);                  //Width of cuboid
float Height                : register(c4);                  //Height of cuboid

texture texTexture;
sampler textureSampler  : register(s0) = sampler_state {
    Texture = (texTexture);
};

struct VsOutput
{
    float4 position : POSITION;
    float3 dirLightPosition : COLOR;
    float2 texCoord : TEXCOORD0;
    float3 normal   : TEXCOORD1;
    float3 view : TEXCOORD2;
};

float4 main(VsOutput IN) : COLOR
{
    float2 texCoord = float2(IN.texCoord.x * Width / 4.0f, 
                             IN.texCoord.y * Height / 4.0f); //multiplying texture coordinates


    float4 texColor = tex2D(textureSampler, texCoord);

    return float4(color.r, color.g, color.b, 1.0f);
}

Meine Ausgabe ist:

Geben Sie hier die Bildbeschreibung ein

Was kann ich noch tun, um zu verhindern, dass Moires-Muster auf Texturen erstellt werden?

bartosz.baczek
quelle
Haben Sie überprüft, ob Mipmaps tatsächlich verwendet werden? Der Screenshot sieht aus wie bilineare Filterung statt trilinear,
Julien Guertault
@ JulienGuertault Es mag nur mein schlechtes Sehvermögen sein, aber ich kann keine deutlichen Diskontinuitäten erkennen, die nur auf eine bilineare + nächste MIP-Karte hinweisen würden.
Simon F
Eigentlich ist mein Sampler-Status auf AnisotropicWrap eingestellt, was meiner Meinung nach der beste ist. Außerdem bin ich mir zu 100% sicher, dass ich Mipmaps verwende.
Bartosz.baczek
@ SimonF: Entschuldigung für die Verwirrung, ich meinte linear. Aber anscheinend wäre das Problem woanders.
Julien Guertault
1
@Nero Ich habe es getan :)
bartosz.baczek

Antworten:

5

Zwei Dinge fallen mir ein:

  1. Wenn Ihre kleine mip Kartenebenen zu erzeugen versuchen , einen einfachen 2x2 Box - Filter zu vermeiden , mit , weil sie zwar billig und fröhlich, sie haben einen wirklich schlechten Job zu entfernen Hochfrequenzinformationen als auch (bei der die Nyquist - Grenze übersteigt) über Filterung einige der unteren Frequenzinformationen, die Sie aufbewahren müssen. (Nebenbei müssen Sie die MIP-Kartengenerierung im linearen Raum durchführen. Wenn Ihre Quelldaten sRGB sind, müssen Sie daher linear zu und von linear zuordnen.) FWIW, In Williams 'Originalarbeit über MIP-Mapping sagte er, er habe ein "Box (Fourier) -Fenster" verwendet, um die vorgefilterten Ebenen zu erzeugen, was eine wichtige Funktion im Bildraum wäre.

  2. Durch die standardmäßige trilineare Filterung werden auch Teile der Textur über- und unterfiltert. Wenn Ihnen das Aliasing nicht gefällt, müssen Sie möglicherweise a) die Vorspannung anpassen, um die Filterung zu erhöhen (was die Unschärfe erhöht), und / oder b) versuchen, eine anisotrope Filterung zu verwenden.

Simon F.
quelle
Entschuldigung für die vielleicht dumme Frage, aber was ist '2x2 Box Filter'? Hat es einen anderen Namen?
Bartosz.baczek
Ich meinte nur die naive Methode, die nächst niedrigere X * Y MIP-Kartenebene aus der darüber liegenden 2X * 2Y-Ebene zu generieren. Das heißt, dass 2x2 Texel in der oberen Ebene gemittelt werden, um das entsprechende Texel in der unteren Ebene zu erzeugen. Es ist billig, aber nicht großartig. Selbst ein einfacher 4x4-Zeltfilter sollte ein weitaus besseres Ergebnis erzielen.
Simon F
Nur um sicherzugehen, dass ich Sie vollständig verstehe - jetzt erstelle ich meine Mip-Maps wie folgt : pastebin.com/nX1MVvEp . Stattdessen sollte ich aus meiner ursprünglichen Textur Mipmaps mit Originalgröße generieren, ja?
Bartosz.baczek
Nun, ich weiß nicht, was sich in der Funktion "Größe ändern" befindet, daher ist es etwas schwierig zu beantworten. Die Verkettung, dh. 1024 generiert 512, 512 generiert 256 usw. wird kein großes Problem sein, solange das, was in "resize" vor sich geht, in Ordnung ist. Könnten Sie als Experiment eine 1024 ^ 2-Textur erstellen, die alle 0xFFFFFF enthält, mit Ausnahme des oberen linken Pixels, das Sie auf reines Rot (0x0000FF) eingestellt haben. Was bekommen Sie im 512 ^ 2 Ergebnis?
Simon F
Mein Ergebnis: postimg.org/image/atd8nc4j3/3636ad65
bartosz.baczek
2

LÖSUNG

Ich habe es geschafft, mein Problem zu lösen, indem ich die Größe der Textur 2048x2048px vergrößert habe, damit mehr Mipmaps generiert werden. Außerdem scheint es mir geholfen zu haben, meine SamplerState-Form anisotrop zu ändern.

SamplerState MirrorTexCoord = new SamplerState()
        {
            AddressU = TextureAddressMode.Mirror,
            AddressV = TextureAddressMode.Mirror,
            .
            .
            .
        };

Eigentlich weiß ich nicht, was TextureAdressMode.Mirror ist, aber es hat sehr geholfen, jetzt sieht es so aus:

Geben Sie hier die Bildbeschreibung ein

bartosz.baczek
quelle
1
Der Spiegel definiert wahrscheinlich, was passiert, wenn sich Ihre Textur wiederholt. Im normalen Modus (nur unter Berücksichtigung der Horizontalen) würden Sie "<<<<<" erhalten, wenn Sie eine Textur hätten, die wie "<" aussieht. Beim Spiegeln erhalten Sie "<> <> <> <> <". Kann natürlich auch in vertikaler Richtung gelten.
Simon F
Es sieht so aus, als ob die Erhöhung der Auflösung der Haupthelfer ist. In der hinteren Ecke des Rechtecks ​​bilden sich gerade erst Moiré-Muster.
RichieSams
Eigentlich nein, das Spiegeln macht den größten Teil der Arbeit :) Ich habe es nur mit Spiegeln und nur mit größerer Textur getestet und festgestellt, dass der Spiegel einen großartigen Effekt bietet. Glücklicherweise ist die Fliesentextur simetrisch, es ist also keine große Sache.
Bartosz.baczek
Es ist schwer zu beurteilen, wie stark sich dies verbessert hat, da sich das Flugzeug nicht so weit in die Ferne erstreckt wie im Beispiel in der Frage.
Trichoplax