Seite 1 von 1
[DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 14:51
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?
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 15:15
von Zudomon
Soweit ich weiß, geht das nicht... du musst zum Clearen schon Dreiecke zeichnen.
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 17:05
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
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 17:16
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
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 17:19
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
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 17:33
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.
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 17:37
von Krishty
marcjulian hat geschrieben:ClearRenderTargetView funktioniert nur solange wie du deine float4 Rendertargets behälst …
Überprüf das lieber nochmal.
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 17:41
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 :)
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 22.08.2009, 17:51
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 :)
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 24.08.2009, 11:37
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?
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 24.08.2009, 13:00
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.
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 24.08.2009, 13:48
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^^)
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 24.08.2009, 13:51
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
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 24.08.2009, 14:35
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
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 24.08.2009, 18:28
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.
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 24.08.2009, 18:45
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
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 24.08.2009, 19:20
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
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 25.08.2009, 07:42
von beuschl
hi
Danke für den tipp!! es geht nun.
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 26.08.2009, 15:02
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)
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 26.08.2009, 16:53
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.
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 27.08.2009, 13:50
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)
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 27.08.2009, 16:24
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:
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 28.08.2009, 17:26
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
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 28.08.2009, 18:00
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.
Re: [DX10]: Deffered Lightning CLear G-Buffer Frage
Verfasst: 28.08.2009, 18:09
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