2009-08-27 6 views
1

In einer Direct3D-Anwendung mit Sprite-Objekten von D3DX möchte ich die Helligkeit und den Kontrast global anpassen können. Der Kontrast ist wichtig, wenn überhaupt möglich.Helligkeit/Kontrast/Gamma der Szene in DirectX anpassen?

ich hier, um diese Frage zu OpenGL gesehen habe: Tweak the brightness/gamma of the whole scene in OpenGL

Aber das gibt mir nicht, was ich in einem DirectX Kontext benötigen würde. Ich weiß, dass dies etwas ist, was ich wahrscheinlich auch mit einem Pixelshader machen könnte, aber das scheint eine Fliege mit einer Bazooka zu sein, und ich mache mir Sorgen über die Rückwärtskompatibilität mit älteren GPUs, die Shader in der Software machen müssten. Es scheint so, als ob das möglich sein sollte, ich erinnere mich sogar an viel ältere Spiele wie das ursprüngliche Half Life mit solchen Einstellungen lange vor den Tagen der Shader.

BEARBEITEN: Bitte beachten Sie auch, dass dies keine Vollbild-Anwendung ist, also müsste dies etwas sein, das nur das eine Direct3D-Gerät betreffen würde und das ist keine globale Einstellung für den Monitor insgesamt.

+0

Dies wird Ihr Problem nicht lösen, aber ich denke, dass jeder diese verwenden, sollten das Wort Gamma in Bildverarbeitungskontext lesen: http://www.alvyray.com/Memos/9_gamma.pdf – Laserallan

Antwort

4

Viele Spiele erhöhen die Helligkeit, indem sie buchstäblich einen Vollbild-Poly über den Bildschirm mit additivem Mischen anwenden.

dh
SRCBLEND = ONE 
DESTBLEND = ONE 

und dann eine Textur mit einer Farbe der Anwendung (1, 1, 1, 1) wird die Helligkeit (ish) jedes Pixels erhöhen, indem 1.

Kontrast einstellen, dann müssen Sie Machen Sie ähnlich, aber MULTIPLY durch einen konstanten Faktor. Dies wird Mischung Einstellungen benötigt als

SRCBLEND = DESTCOLOR 
DESTBLEND = ZERO 

Auf diese Weise folgt, wenn Sie ein Pixel mit einem Wert von mischen (2, 2, 2, 2), dann werden Sie den Kontrast ändern.

Gamma ist ein viel komplizierteres Biest und ich bin mir nicht bewusst, wie man es wie oben vortäuschen kann.

Keine dieser Lösungen ist völlig korrekt, aber sie geben Ihnen ein Ergebnis, das "leicht" korrekt aussieht. Es ist viel komplizierter, so oder so zu tun, aber mit diesen Methoden werden Sie Effekte sehen, die UNGLAUBLICH ähnlich zu verschiedenen Spielen aussehen, die Sie gespielt haben, und das ist genau das, was sie tun;)

+0

Das hört sich sehr vielversprechend an - ich werde morgens damit experimentieren und sehen, wie es in der Praxis funktioniert. Vielen Dank! – x4000

+0

Okay, eigentlich habe ich es schon überprüft und es ist perfekt! Natürlich ist es nicht 100% genau wie du sagst, aber es ist älter - GPU freundlich, ziemlich effizient insgesamt und gibt ein Ergebnis, das genug gut genug ist. Noch einmal vielen Dank! – x4000

+0

Gern geschehen :) – Goz

1

Sie hat nicht angegeben, welche Version von DirectX Sie verwenden, so werde ich 9. Wahrscheinlich nehme an, das Beste, was Sie tun können, ist die gamma-ramp functionality zu verwenden. Durch Drücken der Rampe nach oben oder unten wird die Helligkeit erhöht oder verringert. Das Erhöhen oder Verringern des Gradienten ändert den Kontrast.

+0

Funktioniert nur im Vollbild, Exklusivmodus, leider. Vielleicht ist das nicht möglich für Anwendungen ohne Vollbild ohne einen Pixelshader, ich weiß es nicht. – x4000

+0

Die Dokumentation deutet an, dass es im Fenstermodus funktionieren könnte. In der Praxis erwarte ich, dass es von deiner Grafikkarte und deinen Treibern abhängt. – Kylotan

+0

Leider nicht: "Beachten Sie beim Festlegen neuer Rampenstufen, dass die in den Arrays festgelegten Ebenen nur verwendet werden, wenn sich Ihre Anwendung im exklusiven Vollbildmodus befindet." (von der Verbindung) – x4000

1

Ein anderer Ansatz ist es bearbeite alle deine Texturen. Es wäre im Grunde der gleiche Ansatz wie die Gammakarte, außer dass Sie die Rampe manuell auf die Pixeldaten in jeder Ihrer Bilddateien anwenden, um die Texturen zu erzeugen.

1

Verwenden Sie einfach einen Shader. Alles, was SM 2.0 nicht zumindest unterstützt, ist an dieser Stelle alt.

2

Für ein Spiel, das ich in XNA gemacht habe, habe ich einen Pixel-Shader verwendet. Hier ist der Code. [Haftungsausschluss] Ich bin nicht ganz sicher ist die Logik richtig und einige Einstellungen können seltsame Auswirkungen haben (!) [/ Haftungsausschluss]

float offsetBrightness = 0.0f; //can be set from my C# code, [-1, 1] 
float offsetContrast = 0.0f; //can be set from my C# code [-1, 1] 

sampler2D screen : register(s0); //can be set from my C# code 

float4 PSBrightnessContrast(float2 inCoord : TEXCOORD0) : COLOR0 
{ 
    return (tex2D(screen, inCoord.xy) + offsetBrightness) * (1.0 + offsetContrast); 
} 

technique BrightnessContrast 
{ 
    pass Pass1 { PixelShader = compile ps_2_0 PSBrightnessContrast(); } 
} 
+0

Können Sie erklären, wie Sie die Offsets dynamisch einstellen? Oder kompilierst du den Shader-Code jedes Mal neu, nachdem du ihn geändert hast? – Ulterior