Variablen in HLSL



  • @Dot

    Was die Sortierung anbelangt, nimm doch einfach den Abstand zur Kamera?

    Ja weisst du die Koordinaten der Pflanzen sind eben nirgends gespeichert, die werden in jedem Frame (abhängig von der aktiven Kameraposition) berechnet (in einem 96x96 Quadrad mit der Kameraposition als Zentrum). Eigentlich bewegen sich die Pflanzen mit der Kamera mit (aber weil diese in einem fixen Raster angeordnet sind, bemerkt man es nicht).

    Irgendwie kann ich mir grad nicht vorstellen, wie man das sortieren kann, aber vermutlich sehe ich einfach den Wald vor lauter Bäume nicht 🙂



  • Ishildur schrieb:

    Funktioniert das Nvidia Teil auch (zuverlässig) mit ATI Karten? Habe eben ein ATI Teil drinnen...

    Deswegen hab ich ja das ATI Ding gepostet 😉
    Probieren kannst dus aber ja aber mal: http://developer.nvidia.com/object/nvperfhud_home.html



  • Hat leider nix funktioniert... 😞



  • Ishildur schrieb:

    @TGGC
    Ich hatte vor einigen Posts auf freundliche Weise versucht, dir mitzuteilen, dass ich wenig übrig habe für deine selbstinszenierenden Posts die an Überheblichkeit wohl kaum mehr zu überbieten sind, daher sage ich es nun etwas deutlicher: Du hörst dich für mich an wie ein unangenehmes Rauschen in meiner Kommunikationsleitung mit Dot...

    Jo, bloed wenn man auf eine Wahrheit hingewisen wird, die einem nicht gefaellt. Dann noch viel Spass beim flags setzen. f'`8k

    Gruß, TGGC (der kostenlose DMC Download)



  • schon wieder dieses Rauschen in der Leitung...



  • @Dot
    Vielleicht lässt sich dies ausbauen:

    Ich habe diesen Code:

    pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,12,0,6);
    

    Zu diesem erweitert

    // render into the zbuffer
     pDev->SetRenderState(D3DRS_ZFUNC,D3DCMP_LESS);
     pDev->SetRenderState(D3DRS_COLORWRITEENABLE,0x00);
     pDev->SetPixelShader(this->psDsc->GetShader());
     pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,12,0,6);
    
     // render into the color buffer
     pDev->SetRenderState(D3DRS_COLORWRITEENABLE,0x0f);
     pDev->SetRenderState(D3DRS_ZWRITEENABLE,false);
     pDev->SetPixelShader(this->psFlo->GetShader());
     pDev->SetRenderState(D3DRS_ZFUNC,D3DCMP_LESSEQUAL);
     pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,12,0,6);
    

    Resultat, die Framerate hat sich verdoppelt. Allerdings scheint das Z-Buffering zu ungenau zu sein, er zeichnet die Planzen nicht mehr korrekt (es hat Artefakte, die vermutlich durch ein Z-Fighting des zweiten Renderpasses mit dem ersten entsteht).

    Was ich bräuchte wär eine Toleranz Zone, also nicht einfach D3DCMP_LESSEQUAL, sondern so ala: "Wenn der aktuelle Z-Wert kleiner als ist als der existierende + 2.0f, dann gilt der Test als bestanden".

    Ich habe leider kein entsprechendes RenderState in Direct3D gefunden, gibt es vielleicht eine Möglichkeit, dies zu umgehen? Habe mir auch überlegt, nach dem ersten Renderpass sämtliche Werte im ZBufer manuell mit 2.0f zu subtrahieren, aber das wäre dann vermutlich wieder zu langsam....


  • Mod

    Ishildur schrieb:

    @rapso
    Naja, Tage sitze ich noch nicht drann, es handelt sich eher um Stunden, aber dein Vorschlag hört sich absolut vernünftig an. Kannst du mir einen GPU Profiler nennen, mit dem du gute Erfahrungen gemacht hast? Dann mache ich mich gleich an die Arbeit! 🙂

    nimm was du hast
    http://blogs.msdn.com/b/manders/archive/2006/12/15/a-painless-introduction-to-pix-for-windows.aspx

    btw. wir haben hier eine grossartige editierfunktion, man muss nicht zwingend mehrmals posten 😉

    :schland:

    (edit: tolleranz zone heisst Bias bei d3d)



  • @rapso u. Dot

    Mit DepthBiasing funktioniert es nun, allerdings ist die Framerate wieder dort wo sie vor dieser Modifikation war. Ich hab hier mal das Ganze Zeugs:

    // disable mipmap filtering and backface culling
      pDev->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_NONE);
      pDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
    
      // enable alpha testing
      pDev->SetRenderState(D3DRS_ALPHATESTENABLE,true);
      pDev->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATER);
      pDev->SetRenderState(D3DRS_ALPHAREF,0xf0);
    
      // render into the zbuffer
      pDev->SetRenderState(D3DRS_COLORWRITEENABLE,0x00);
      pDev->SetPixelShader(this->psDsc->GetShader());
      pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,12,0,6);
    
      // render into the color buffer
      pDev->SetRenderState(D3DRS_COLORWRITEENABLE,0x0f);
      pDev->SetRenderState(D3DRS_DEPTHBIAS,1);
      pDev->SetRenderState(D3DRS_ZWRITEENABLE,false);
      pDev->SetPixelShader(this->psFlo->GetShader());
      pDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,12,0,6);
    
      // finally restore all render states  
      pDev->SetRenderState(D3DRS_ALPHAREF,0x00);
      pDev->SetRenderState(D3DRS_ALPHATESTENABLE,false);
      pDev->SetRenderState(D3DRS_ZWRITEENABLE,true);
      pDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
      pDev->SetRenderState(D3DRS_DEPTHBIAS,0);
    
      // restore the previous stream frequency settings
      pDev->SetStreamSource(1,0x00,0,0);
      pDev->SetStreamSourceFreq(0,1);
      pDev->SetStreamSourceFreq(1,1);
    

    psDsc (Pixelshader Discard) ist folgendermassen definiert:

    sampler2D FloraSampler: register(s0); // the flora sampler
    
    float4 main(float2 Tex:TEXCOORD0):COLOR0{
     return tex2D(FloraSampler,Tex);
    }
    

    Könnte man da noch was vereinfachen oder ist dies so OK? Mir fällt auf, dass wenn ich AlphaTesting generell abschalte, läuft es mit 3 facher Geschwindigkeit, was mich nun ein wenig irritiert, weil mit dieser Technik sollten die Anzahl der Write Operations in den Framebuffer ja mit sowie ohne Alphatesting identisch sein?



  • Ishildur schrieb:

    Ja weisst du die Koordinaten der Pflanzen sind eben nirgends gespeichert, die werden in jedem Frame (abhängig von der aktiven Kameraposition) berechnet (in einem 96x96 Quadrad mit der Kameraposition als Zentrum). Eigentlich bewegen sich die Pflanzen mit der Kamera mit (aber weil diese in einem fixen Raster angeordnet sind, bemerkt man es nicht).

    Ok, dann brauchst du im Idealfall ja gar nichts cullen und sortieren sondern kannst direkt die Positionen von vorne nach hinten (oder umgekehrt) generieren. Wie genau muss man sich überlegen. Mein erster Gedanke wäre jetzt einfach wie du es scheinbar schon versucht hast auf den Kamerabasisvektoren die Pflanzen generieren und das ganze auf dein Worldspaceraster runden. Wenn es da zu Aliasingeffekten kommt muss man sich was andres einfallen lassen. Man könnte auch versuchen die Pflanzen im Worldspace zu positionieren und z.b. entlang der Dimension in der die z-Achse der Kamera (View Vektor) die betragsmäßig kleinste Komponente hat zuerst laufen (das ist natürlich nicht ganz korrekt aber vielleicht schauts gut genug aus). Ansonsten halt die Positionen einfach mit einem normalen Sortierverfahren anhand ihres Abstands zur Kamera sortieren...

    Ishildur schrieb:

    Könnte man da noch was vereinfachen oder ist dies so OK? Mir fällt auf, dass wenn ich AlphaTesting generell abschalte, läuft es mit 3 facher Geschwindigkeit, was mich nun ein wenig irritiert, weil mit dieser Technik sollten die Anzahl der Write Operations in den Framebuffer ja mit sowie ohne Alphatesting identisch sein?

    Naja, wie schon gesagt drückt Alphatesting ziemlich auf die Fillrate (zusätzlicher Test für jedes Fragment). Würdest du Front to Back rendern könntest du evtl. noch ein bisschen was sparen aber generell ist Alphatesting halt leider nicht ganz gratis. Ich würde jetzt zwei Dinge versuchen: 1) Front to Back mit einem Z-Only Pass mit Alphatesting und drauf dann ein normaler Pass mit Alphablending und 2) Back to Front mit nur einem Pass und ohne Alphatesting. Wär mal interessant was da schneller läuft.



  • @dot

    wie du es scheinbar schon versucht hast auf den Kamerabasisvektoren die Pflanzen generieren und das ganze auf dein Worldspaceraster runden.

    Man kann sich das mit dem Aliasing vermutlich nur schwer vorstellen. Es wirkte sich folgendermasse aus: Solange man die Kamera still hatte bemerkte man nichts ungewöhnliches, doch sobal man die Kamera drehte, fing alles extrem an zu flackern, weil er ständig Planzen an einem Ort zeichnete, dann im nächsten Frame nicht mehr im übernächsten Frame wieder usw. Mann kann sich das so vorstellen:
    Man hat einen sehr niedrig aufgelösten Bildschirm und nun zeichnet man eine rotierende Linie (eben ohne Antialiasing), dann wird praktisch in jedem Frame ein anderer Pixel als Teil der Linie angenommen und völlig äquivalent ist es dann eben mit den Pflanzen passiert (Planze = gefüllter Pixel, World Space Raster = Bildschirm Raster Punkt).

    Ich kriege langsam den Eindruck das Alphatesting langsamer als Alphablending ist? Also ich erinnere mich noch Aussagen, wo empfohlen wurde Alphatesting IMMER zu aktivieren, um die VIEL teureren Alphablending Operationen zu sparen für Pixel, die ohnehin ganz oder fast ganz transparent sind...



  • Ishildur schrieb:

    Ich kriege langsam den Eindruck das Alphatesting langsamer als Alphablending ist? Also ich erinnere mich noch Aussagen, wo empfohlen wurde Alphatesting IMMER zu aktivieren, um die VIEL teureren Alphablending Operationen zu sparen für Pixel, die ohnehin ganz oder fast ganz transparent sind...

    Ja das deckt sich mit meiner Erfahrung (ich sagte ja schon dass Alphatesting ziemlich reinhauen kann). Das Problem ist dass die GPU evtl. Early-Z-Culling und Double-Speed Z-Only Rendering nicht verwenden kann wenn Alphatesting aktiv ist (ich gehe davon aus dass dein PixelShader weder die Tiefe von Pixeln modifiziert noch clip() verwendet, beides wäre der endgültige Todesstoß für diese beiden Optimierungen). Deswegen ja auch mein Rat anfangs es mal nur mit Alphablending zu versuchen. Wie gesagt interessant wäre jetzt noch die Performance von normalem Back-To-Front mit Alphablending...


Anmelden zum Antworten