C#/XNA Texture Rendering Fehler

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    C#/XNA Texture Rendering Fehler

    Hey Leute,
    Ich habe derzeit ein Problem und frage mich ob ihr es wisst wie ich es beheben kann...

    Ich füge zu meinem Terrain eine Texture hinzu:

    C#-Quellcode

    1. effekt.View = camera.view;
    2. effekt.Projection = camera.projection;
    3. effekt.EnableDefaultLighting();
    4. effekt.CurrentTechnique.Passes[0].Apply();
    5. effekt.TextureEnabled = true;
    6. effekt.Texture = tex;
    7. device.SamplerStates[0] = SamplerState.LinearClamp;
    8. device.DrawUserIndexedPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3);

    Jetzt meine Frage...warum brauch ich das device.SamplerStates[0] = SamplerState.LinearClamp;

    Ohne dem Funktioniert es nicht...

    Und warum sieht es im Anhang so aus, wenn die Texture eingentlich so aussieht...

    Aya und nur für die Leute die die Texture verwenden wollen, man braucht für diese eine License ich darf sie hochladen da ich eine Erlaubnis dafür habe, jedoch darf man sie nicht weiterverwenden ohne diese zu besitzen(kleine Anmerkung)

    Bitte um Hilfe wäre echt nett!!!
    Bilder
    • _3d_game 2016-09-01 16-08-10-10.png

      130,97 kB, 800×480, 169 mal angesehen
    • Unbenannt.png

      5,37 MB, 2.048×1.152, 189 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „flo2000ace“ ()

    Hi
    Sampler States sind dafür zuständig, z.B. eine Abbildung der UV-Koordinaten auf die Textur durchzuführen.
    Ich bin in XNA nicht bewandert, aber
    - wie generierst du die Vertices bzw. wie sind die UV-Koordinaten beschaffen? Also Wertebereich, usw.
    - welcher SamplerState ist vorher in device.SamplerStates[0] gesetzt?

    Im Allgemeinen gilt, dass jedes Vertex eine Texturkoordinate aufweist, die zwischen 0 und 1 einzuordnen ist. U und V können aber beliebige Werte sein. Der Sampler State dürfte dafür sorgen, dass die UV-Werte korrekt abgebildet wirden. Bei LinearClamp würde ich vermuten, dass es Us und Vs auf das Intervall [0, 1] beschränkt und lineare Interpolation durchführt. Was da interpoliert wird, kann ich aber nicht sicher sagen, vmtl. die Textur an der entsprechenden Koordinate.
    Wenn's dich genauer interessiert, ich würde vermuten, dass LinearClamp so aussieht:
    - Werte für U, V kleiner 0 werden zu 0, Werte größer 1 zu 1
    - die neuen U, V werden auf die Textur abgebildet (absolute Texturkoordinaten ergeben sich zu (U * Texturbreite, V * Texturhöhe))
    - Interpoliere zwischen den Nachbarn (int)(U * Texturbreite) und (int)(U * Texturbreite) + 1 und V analog
    --> Lineare Interpolation dürfte sein, dass mit p = U * Texturbreite % 1, q = V * Texturhöhe % 1 folgendes berechnet wird, wobei Tex(x, y) den Farbwert der Textur angibt:
    (1 - p) * (1 - q) * Tex(x, y) + p * (1 - q) * Tex(x + 1, y) + (1 - p) * q * Tex(x, y + 1) + p * q * Tex(x + 1, y + 1)
    p und q geben in % an, wie weit sich der der Pixel in Richtung (x + 1, y + 1) befindet. Der Farbeinfluss wird dann in Abhängigkeit dieser Prozentzahl ermittelt.

    Aber keine Garantie auf Richtigkeit. Ich hoffe, es ist kein völliger Blödsinn, was ich hier verzapf'. ;)

    Beantworte am Besten einfach die Fragen, sofern das Problem weiterbesteht.

    Viele Grüße
    ~blaze~
    Das ganze basiert auf einer Vermutung: Die U-V-Koordinaten sind nicht richtig, bzw. nicht so gesetzt, wie sie gehören.
    Es kommt drauf an, wie "richtig" aussieht. Wenn die Textur sich wiederholen soll, müssen die U-V-Koordinaten entsprechend gesetzt werden.
    Z.B. wenn jedes Vertex-Rechteck (a, b, c, d) die Textur haben soll, müssen die U-V-Koordinaten für a, b, c, d entsprechend (0, 0), (1, 0), (0, 1), (1, 1) sein.
    Wenn das nicht der Fall ist, gilt halt, dass du jedem Vertex (x, y, z) (ich nehme frech an, dass die Vertices ein Rechteck bilden, das in der x-z-Ebene aufgespannt ist und dabei um y senkrecht zu dieser Ebene verschoben werden) die U-V-Koordinate
    (x / width, z / height)
    zuordnen musst.

    Viele Grüße
    ~blaze~

    C#-Quellcode

    1. private void setUpVertex()
    2. {
    3. vertices = new VertexPositionNormalTexture[WIDTH * HEIGHT];
    4. for(int x=0; x<WIDTH; x++)
    5. {
    6. for(int z=0;z<HEIGHT;z++)
    7. {
    8. vertices[x + z * WIDTH].Position = new Vector3(x, height[x,z], -z);
    9. }
    10. }
    11. }

    Meinst du das ich mach die vertexe so

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „flo2000ace“ ()

    Bitte füge in die beiden Codes noch einen [cs][/cs]-Tag ein. ;)

    Ja genau, an dieser Stelle musst du die U-V-Koordinaten setzen. Ich fürchte nur, dass das wegen dem Indexpuffer entweder nicht mit dem LinearClamp (liefe auf Tiling hinaus) hinhaut oder auf Spiegelung.

    Während der Indexpuffer die Redundanz der Vertices verhindert, ist sie in deinem Fall fast nötig. Zumindest wäre mir ohne Shader keine Lösung bekannt, die das elegant löst.

    Viele Grüße
    ~blaze~
    vertices[x + z * WIDTH].

    Innerhalb der Shleife einfach mal das hier eintippen, dann siehst du hinter dem . nicht nur Position verwenden kannst, sondern eben auch Normal/TextureCoordinate, welche du beide nicht setzt

    Normal ist die Normale auf den Vertex, welche später für Licht und Schatten relevanz hat.

    Die textureCoordinate zeigt quasi an, welcher Pixel der Textur auf genau diesem Vertex angezeigt werden soll. Die Texturkoordinaten sind zwischen 1 und 0. mit (0,0) als der linken oberen Ecke deiner Textur und (1,1) deiner rechten unteren Ecke. Wenn du also die Texturkoordinaten von 4 Vertices(Quad) so setzt, dass die 4 Ecken der Textur auf die 4 Vertices gemappt sind, dann wird deine Textur eben genauso kopiert, dass die Textur über diese 4 Vertices aufgespannt wird.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Erstmal danke jedoch wie gesagt kann ich dort nicht auf die Texturen zugreifen ich werde es mal versuchen trotzdem danke!!

    Edit:

    C#-Quellcode

    1. vertices[x + z * WIDTH].Position = new Vector3(x, height[x,z], -z);
    2. vertices[x + z * WIDTH].TextureCoordinate.X = 1;
    3. vertices[x + z * WIDTH].TextureCoordinate.Y = 0;


    Aha da geht doch was wie soll ich das jetzt machen die Cordinaten sind da aber ich sehe das es nur dunkler/heller wird...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „flo2000ace“ ()

    C#-Quellcode

    1. vertices[x + z * WIDTH].TextureCoordinate = new Vector2((float)x / WIDTH,(float)y / HEIGHT);

    Es ist noch dasselbe Problem, also gibt ein neuer Thread keinen Sinn. Wenn du jeden Punkt in deiner Welt die selbe Texturkoordinate gibtst, dann wird natürlich auch jeder Punkt diese Farbe haben. Du solltest dich vielleicht erstmal mit den Grundlagen von 3D Rendering bekannt machen und verstehen, was der Code überhaupt macht. Du wirst in 3D nicht weit mit Copy&Pasta kommen
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---