[DX10]: Deffered Lightning CLear G-Buffer Frage

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

[DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

Hi

Ich beschäftige mich zur Zeit mit der Deferred Lightning Technik und hab dazu ein paar Artikel/Tutorials durchgelesen. Ich fand dieses (http://www.ziggyware.com/readarticle.ph ... rowstart=1) ziemlich gut verständlich und hab dazu eine Frage

In dem Tutorial steht das man vorm Rendern der Szene ind en einzelnen render Targets ersteinmal den G-Buffer clearen soll

dazu gab es diesen code

Code: Alles auswählen

struct VertexShaderInput
    {
        float3 Position : POSITION0;
    };

    struct VertexShaderOutput
    {
        float4 Position : POSITION0;
    };

    VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
    {
        VertexShaderOutput output;
        output.Position = float4(input.Position,1);
        return output;
    }
    struct PixelShaderOutput
    {
        float4 Color : COLOR0;
        float4 Normal : COLOR1;
        float4 Depth : COLOR2;
    };

    PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
    {
        PixelShaderOutput output;
        //black color
        output.Color = 0.0f;
        output.Color.a = 0.0f;
        //when transforming 0.5f into [-1,1], we will get 0.0f
        output.Normal.rgb = 0.5f;
        //no specular power
        output.Normal.a = 0.0f;
        //max depth
        output.Depth = 1.0f;
        return output;
    }
Da ich aber kein XNA verwende und das ganze unter DirectX10 machen will würde ich nun gerne Wissen ob ob man den PixelShader code auch ohne einen VertexShader laufen lassen kann. Also ich will meinem .fx File das diesen Code enthält an sich keien Vertex Daten übergeben sonder einfach nur meine 3 Render Targets "clearn" bzw mit den farben vom Pixel Shader füllen

Ist das irgendwie möglich?
Benutzeravatar
Zudomon
Establishment
Beiträge: 2254
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Zudomon »

Soweit ich weiß, geht das nicht... du musst zum Clearen schon Dreiecke zeichnen.
marcjulian
Beiträge: 6
Registriert: 12.09.2004, 18:36

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von marcjulian »

Du musst folgend vorgehen:

Deferred MRTs binden
Clear Shader setzen
Ein Quad in der Größe deiner Rendertargets rendern

Modell Shader setzen
Alle Geometrie zeichnen

Standard RT binden
MRTs verwenden um den Lighting Pass zu machen
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Krishty »

beuschl hat geschrieben:… würde ich nun gerne Wissen ob ob man den PixelShader code auch ohne einen VertexShader laufen lassen kann.
Nein.
beuschl hat geschrieben:… sonder einfach nur meine 3 Render Targets "clearn" bzw mit den farben vom Pixel Shader füllen

Ist das irgendwie möglich?
Was spricht gegen ClearRenderTargetView()?

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

was mir eingefallen ist:

kann ich nicht einfaach um die verschiedenen RenderTargets mit den entsprechenden Farben zu clearen

pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.4f, 0.4f, 0.9f, 1.0f)); //irgendeine farbe

machen?

@marcjulian: wieso muss ich nach Clear Shader ein Quad in der größ0e des Rendertargets rendern?
hab gedacht es geht: Rendertargets clearen, geometry mit dem mdoell shader zeichnen und im pixel shader die verschiedenen farben gleich in die MRTs zeichnen, .... und dann halt weiter (bin noch nicht viel weiter gekommen bisher, da mir doch etwas die Zeit fehlt derzeit ;)


edit: oh grad gesehn das jemand geantwortet hatbzgl dem clearen^^ thx
marcjulian
Beiträge: 6
Registriert: 12.09.2004, 18:36

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von marcjulian »

Um zu Clearen musst du das Quad zeichnen - so werden ja alle Pixel in den Rendertargets modifiziert.

ClearRenderTargetView funktioniert nur solange wie du deine float4 Rendertargets behälst, was allerdings etwas verschwenderisch ist da man ohne Probleme
mit folgendem Setup einen Bruchteil des Speichers bräuchte:

RGBA (4 * ubyte norm) - 32 bit - Farbe, man könnte LogLuv Kodierung verwenden um HDR zu ermöglichen
Depth (1 * float) - 32 bit - Tiefen Wert
Normals (2 * float16) - 32 bit - Kodierung mittels Polarkoordinaten so das nur zwei Komponenten gebraucht werden

Und wenn du dann noch Werte für Specular, Emissive und Co brauchst nimmst du halt noch eine RGBA RT dazu..

Mit deinem Setup bräuchtest du auf 1280x720 schon knapp 42MB nur für deine Rendertargets an VRAM - mit dem anderem Setup nur 10.5.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Krishty »

marcjulian hat geschrieben:ClearRenderTargetView funktioniert nur solange wie du deine float4 Rendertargets behälst …
Überprüf das lieber nochmal.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
marcjulian
Beiträge: 6
Registriert: 12.09.2004, 18:36

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von marcjulian »

Krishty hat geschrieben:
marcjulian hat geschrieben:ClearRenderTargetView funktioniert nur solange wie du deine float4 Rendertargets behälst …
Überprüf das lieber nochmal.
Naja, die Microsoft Dokumentation warnt ja schon "Applications that wish to clear a render target to a specific integer value bit pattern should render a screen-aligned quad instead of using this method." - Man müsste schauen wie es sich zum Beispiel mit R16G16F RenderTargets verhält und mit ARGB 32 Bit RTs.

Wenn ClearRenderTargetView() da richtig arbeitet, wäre es natürlich zu bevorzugen - wäre mal gut wenn das jemand ausprobieren könnte :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Krishty »

Die Warnung bezieht sich auf Integer-Puffer; die Funktion funktioniert mit allen üblichen Render-Target-Formaten.
Alles, was man da übergibt, wird selbstverständlich in das richtige Format konvertiert, bevor das RT damit gefüllt wird.

Noch was am Rande: Diese ganze ×0.5+0.5-Frickelei kann man sich sparen, wenn man ein SNorm-Format benutzt – die wurden schließlich extra für Normalen eingeführt :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

Habe noch eine Frage
Bin jetzt soweit ein paar Objekte darstellen zu können mit Directional Light
Jetzt wollte ich meine (einfache) Skybox hinzufügen so wie bei meinem vorherigen Renderer. Nur klappt das bsiher nicht.. am End ehabe ich meien beleuchteten Objekte mit schwarzen Hintergrund. Evtl hab ich irgendwas nicht beachtet? Hier meine Renderabfolge:

1. Meine 3 Rendertargets setzen (Colo, Normal, Depth) und mit entsprechenden Farben clearen (Schwarz, Grau, Weiß)

2. G-Buffer mit den Objekten füllen und zum Schluss Skybox zeichnen... in meinem rendertarget Color hab ich laut PIX nun folgende Ausgabe http://s5.directupload.net/file/d/1896/3kycj72j_jpg.htm
sieht soweit richtig aus

3. Ich setze die 3 Rendertargets auf 0 mittels

Code: Alles auswählen

ID3D10RenderTargetView* renderTargets[3] = {0,0,0};
mD3DDevice->OMSetRenderTargets(3, renderTargets, NULL);
Und setze danach mein Light RenderTarget als aktives. (clear mit Farbe schwarz) Ich mache die Lichtberechnung und habe in dem rendertarget dann folgendes ergebnis: http://s2.directupload.net/file/d/1896/7e4jdrso_jpg.htm

4. Ich setze das mit dem SwapChainDevice verbundene Rendertarget als aktives. zeichne nochmal einen Fluu Screenquad und kombiniere in einem Shader die colorMap (1.Bild) mit der lightMap (2.Bild)


Als Ergebnis erhalte ich die 2 Beleuchteten Objekte mit schwarzem Hintergrund (an einer Stelle gibt es einen weißen Hintergrund) anstatt der Skybox

Hat jemand eine Idee? Mac ich irgendetwas grundsätzliches Falsch vond er Reihenfolge oder so oder liegt der Fehler irgendwo in einem Shader?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4858
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Schrompf »

Na ist doch ganz klar. Du multiplizierst den Himmel (irgendne Farbe) mit dem Licht (schwarz an dieser Stelle). Da muss schwarz rauskommen. Von Licht unbeeinflusste Sachen wie den Himmel würde ich erst nach der Kombination von Colormap und LightMap zeichnen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

mhm logisch ;)

Nur jetzt hab ich ein Problem: wie genau amch ich das ganze dann? Ich bin noch nicht so firm mit DirectX

Ich hab jetzt auf meinem HauptRenderTarget das kombinierte Color/Light Rendertarget gezeichnet. Wenn ich jetzt auf diesem Rendertarget meine Skybox zeichne überdeckt sie natürlich den Rest.
Muss ich da irgendwie die Skybox reinblenden oder sowas in der art?Mit Blending und dem ganzen Depth/Stencil Buffer Zeug kenn ich mich leider noch nicht so gut aus. Gibts es irgendwelche guten Quellen für DX10 dazu? (außer der Doku^^)
Benutzeravatar
Schrompf
Moderator
Beiträge: 4858
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Schrompf »

Du hast doch noch den DepthBuffer vom Ausrendern des GBuffers. Wenn der Pixel für Pixel auf das Ziel-Rendertarget passt (also auch in Sachen AA-Einstellungen), kannst Du den weiterverwenden. Aktiviere einfach den DepthTest, wie Du ihn brauchst, und fertig. Der Himmel müsste dann automatisch nur an den Pixeln durchscheinen, wo er nicht verdeckt wird. Natürlich vorausgesetzt, Deine Himmel-Geometrie hat einen vernünftigen Tiefenwert.

Bye, Thomas
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

Mhm ich habs mal versucht...

1. Zuerst render ich meine 3 Rendertargets (gbuffer) mit aktivierten Depth Buffer: mD3DDevice->OMSetRenderTargets(3, renderTargets, engine->pDepthStencilView);
2. Ich render mein Light RT OHNE den depth Buffer mD3DDevice->OMSetRenderTargets(1, lightTarget, NULL);
3. ich setze meinen Hauptbuffer als aktuelles RT mit depth buffer m->OMSetRenderTargets(1, &engine->pRenderTargetView, engine->pDepthStencilView);
4. Ich zeichne meine Skybox mit folgenden DepthStencilState DepthFunc = LESS_EQUAL; und erhalte laut PIX bei diesem Schritt folgende Ausgabe (sieht richtig aus, also genau dort wo die Würfel sind ist das Bild "ausgeschnitten")
http://s4.directupload.net/file/d/1896/fzrjux2p_jpg.htm

5. Ich zeichne einen Fullscreen quad und kombiniere color RT + light RT und erhalte http://s3.directupload.net/file/d/1896/fjlpk7k9_jpg.htm
Danach zeige ich den Buffer an

Bei Schritt 5 überschreibe ich also wieder irgendwie die Skybox... ich weiß nicht was ich falsch mache
Benutzeravatar
Schrompf
Moderator
Beiträge: 4858
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Schrompf »

Jetzt verstehe ich Dich allerdings nicht mehr ganz. Du hast mir exakt beschrieben, was Du tust, warum Du es tust und warum es deswegen schief geht - und dann fragst Du mich, warum es schiefgeht? Du hast doch schon hingeschrieben, was das Problem ist: Du überschreibst den Himmel, wenn Du den Light Buffer anwendest. Und die Lösung ist dann simpel: erst den Light Buffer anwenden, danach den Himmel hinterherpinseln.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

*gg* ja schon aber das ist ja rigendwie das problem weswegen ich den fehler nicht finde... für mich erscheint das alles richtig und trotzdem gehts nicht...

Ich zeichne das color RT + light RT zusammen auf den backpufer und DANACH zeichne ich die Skybox und gebe dann den Buffer aus... und trotzdem bleibt der Hintergrund schwarz

Änder ich beim Skybox shader den DepthStencilState von LESS_EQUAL auf GREATER_EQUAL seh ich die skybox(mit extremen grafikfehlern bei der kamerabewegung), bei GREATER seh ich nur dieses Standardblau von DirectX und bei LESS und LESS_EQUAL nur das color RT+lightRT mit schwarzen Hintergrund
Dirk Schulz
Establishment
Beiträge: 130
Registriert: 01.03.2009, 14:21
Alter Benutzername: frittentuete

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Dirk Schulz »

Hi,

da muss ich Schrompf rechtgeben, in deinem Aufzählungspost renderst du bei 4. die Skybox und bei 5. kombinierst du die beiden RTs.

Ich würde ja die Skybox zuerst rendern, ohne Depth, im Lighting-Pass deines Skybox-Shaders einfach weiß übergeben (oder ganz einfach mit weiß clearen, da überall mindestens deine Skybox sichtbar ist), sollte ja dadurch, dass keine Depth für die Skybox übergeben wird, eigentlich überschrieben werden, oder?

Dirk Schulz
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

hi

Danke für den tipp!! es geht nun.
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

mhm es funktioniert doch nicht :( Keine ahnung ich hab wieder die ursprüngliche Lichtberechnung genommen im Shader und nun hab ich wieder den schwarzen Hintergrund anstatt der Skybox (wenn ich die Skybox als erstes Rendere)

@Schrompf: es wär auch für mich logisch die Skybox erst zu rendern NACHDEM ich das color RT mit dem light RT kombiniert habe. Nur leider funktioniert es nicht (schwarzer Hintergrund)
Evtl hat das etwas mit meinem Depth Buffer zu tun? Weil nach jedem Draw call seh ich mir den in PIX an und er ist imemr komplett schwarz! Selbst nach einem Aufruf von

mD3DDevice->ClearDepthStencilView(engine->pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0 )

ist der Buffer nicht weiß sodner schwarz. Müsste er da nicht komplett weiß sein? (1.0f)
Benutzeravatar
Zudomon
Establishment
Beiträge: 2254
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Zudomon »

Ich benutze für den Himmel einfach den Stencil Buffer. Einfach alles im Stencil markieren, wo gezeichnet wurde und dann beim Rest den Himmel rendern.
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

ok ich hab den stencil buffer noch nie benutzt und mich in das Thema mal bisschen eingelesen..

Hier mal meine Theorie wie ich das ganze amchen würde. Pls mitteilen falls irgendwas daran falsch ist oder so

1. Ich zeichne zeurst meine ganze szene+Skybox ganz normal und cleare den Stencil Buffer mit 0
2. Ich aktiviere für mein Light RT den Stencil test (depth test nicht... braucht man da nicht oder?). Alle Pixel die in das Light RT gezeichnet werden bekommen im Stencil Buffer eine 1
3. Jetzt render ich die Pixel aus dem Light RT in den Backpuffer und zwar nur die die den Stencil Test bestehen (D3D10_COMPARISON_EQUAL) mit Referenzwert 1

könnte das so klappen (komme grad nicht zum programmieren und möchte das ganze erstmal theoretisch überlegen)
Benutzeravatar
Zudomon
Establishment
Beiträge: 2254
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Zudomon »

1. Alles clearen, Stencil mit 0
2. Szene zeichenn mit aktiviertem Stencil. Einfach Stencil auf Always setzen, also so, das der Wert des Stencils immer überschrieben wird. Als Reference nimmste dann z.B. 1...
3. Dann hast du alles 1, außer da, wo keine Geometrie war. Jetzt einfach über die ganze Szene den Himmel zeichnen, aber nur da, wo der Stencil 0 hat.

Vorsicht, Delphi-Quellcode ;)

Für Nr. 2:

Code: Alles auswählen

      SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE  );
      SetRenderState( D3DRS_STENCILFAIL,  D3DSTENCILOP_KEEP  );
      SetRenderState( D3DRS_STENCILZFAIL,  D3DSTENCILOP_KEEP  );
      SetRenderState( D3DRS_STENCILREF, CARDINAL( 1 ) );
      SetRenderState( D3DRS_STENCILFUNC,  D3DCMP_ALWAYS  );
Für Nr. 3:

Code: Alles auswählen

      SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP  );
      SetRenderState( D3DRS_STENCILFAIL,  D3DSTENCILOP_KEEP  );
      SetRenderState( D3DRS_STENCILZFAIL,  D3DSTENCILOP_KEEP  );
      SetRenderState( D3DRS_STENCILFUNC,  D3DCMP_EQUAL  );
      SetRenderState( D3DRS_STENCILREF, CARDINAL( 0 ) );
Musst mal schauen, bzw. die anderen mal sagen, falls es bei DX10 da noch einen Unterschied gibt.

Und nicht vergessen, den Stenciltest zu aktivieren:

Code: Alles auswählen

      SetRenderState(D3DRS_STENCILENABLE, cardinal(true));
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

hi... ich hab den Stencil jetzt genauso umgesetzt. im Prinzip funktioniert er auch nur hab ich im Endeffekt wieder einen schwarzen Hintergrund anstatt der Skybox

Also in meinem color RT zeichne ich Geometry, dann die Skybox und das Ergebnis hier stimmt.
Füg ich das coloRT jetzt mit dem lightRT zusammen ist der Hintergrund wieder schwarz, was wohl an dem PixelShader liegt der die beiden RTs zusammenfügt
Hier der PixelSahder code der die zwei RTs zusammenfügt

Code: Alles auswählen

float4 PS(PS_INPUT psInput) : SV_Target
{
    float3 diffuseColor = colorMap.Sample(samLinear2, psInput.Tex).rgb;
    float4 light = lightMap.Sample(samLinear2, psInput.Tex);
    float3 diffuseLight = light.rgb;
   // float specularLight = light.a;
   float specularLight = 0.0f;
    return float4((diffuseColor * diffuseLight + specularLight),1);
}
kann man das ganze irgendwie umgehen indem man beim Zusammenfügen der beiden RTs wieder einen Stencil Test einbaut? Sonst fällt mir dazu leider nicht viel mehr ein
Benutzeravatar
Zudomon
Establishment
Beiträge: 2254
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von Zudomon »

Wenn ich das jetzt richtig verstanden habe, liegt es an folgendem: Du renderst zuerst Geometry + Skybox in verschiedene RTs. Wenn du nun deinen Lichtshader darüber anwendest, hast du bei der Skybox keine Normalen oder irgendwas, was dir die korrekte beleuchtung ermöglicht, deswegen wird das dann schwarz.

Ich meinte das auch etwas anders, also zuerst zeichnest du Geometry in verschiedene RTs, dann wendest du alles was du brauchst, darauf an, z.B. Lichtberechnungen usw. Am Ende hast du somit die fertige Szene OHNE Skybox. Allerdings, ist im Stencil überall, wo Geometry gezeichnet wurde markiert. Jetzt kannst du schließlich die Skybox über das komplette Bild zeichnen. Somit wäre im Endergebnis NUR noch die Skybox da, weil die Geometry bzw, also was vorher gemacht wurde, übermalt wird. Um das nun zu vermeiden nutzt du halt wieder den Stencil und sagst, nur da, wo keine Geometry war, soll die Skybox gezeichnet werden.
beuschl
Beiträge: 34
Registriert: 26.07.2009, 08:47

Re: [DX10]: Deffered Lightning CLear G-Buffer Frage

Beitrag von beuschl »

ok da hab ich mich etwas dumm angestellt^^ Hab jetzt wie du geschrieben hast die Skybox einfach NACH dem zusammenfügen des colorRT und des lightRt gezeichnet und jetzt passts. Ich kann endlich meien Skybox sehen!

danke dir
Antworten