2009-08-27 10 views
1

Dans une application Direct3D remplie d'objets Sprite de D3DX, j'aimerais pouvoir ajuster globalement la luminosité et le contraste. Le contraste est important, si possible.Ajuster la luminosité/contraste/gamma de la scène dans DirectX?

Je l'ai vu ici cette question à propos de OpenGL: Tweak the brightness/gamma of the whole scene in OpenGL

Mais cela ne me donne pas ce que je aurais besoin dans un contexte de DirectX. Je sais que c'est quelque chose que je pourrais probablement faire avec un pixel shader, mais cela ressemble à une mouche avec un bazooka et je m'inquiète de la rétrocompatibilité avec les anciens GPU qui devraient faire des shaders dans les logiciels. Il semble que cela devrait être possible, je me souviens même des jeux beaucoup plus anciens comme le Half Life original ayant des réglages comme celui-ci bien avant les jours de shaders. EDIT: Notez également qu'il ne s'agit pas d'une application en plein écran, ce qui devrait affecter uniquement le périphérique Direct3D et ne constitue pas un paramètre global pour le moniteur.

+0

Cela ne résoudra pas votre problème, mais je pense que tout le monde en utilisant le mot gamma dans le contexte de traitement d'image devrait lire ceci: http://www.alvyray.com/Memos/9_gamma.pdf – Laserallan

Répondre

4

Beaucoup de jeux augmentent la luminosité en appliquant, littéralement, un poly plein écran sur l'écran avec un mélange additif. à savoir

SRCBLEND = ONE 
DESTBLEND = ONE 

puis appliquer une texture avec une couleur de (1, 1, 1, 1) augmenter la luminosité (ish) de chaque pixel par 1.

Pour régler le contraste, alors vous devez faire semblable mais MULTIPLIER par un facteur constant. Cela nécessite des paramètres de mélange comme suit

SRCBLEND = DESTCOLOR 
DESTBLEND = ZERO 

De cette façon, si vous mélangez un pixel avec une valeur de (2, 2, 2, 2), alors vous allez changer le contraste. Gamma est une bête beaucoup plus compliquée et je ne suis pas au courant d'une manière que vous pouvez simuler comme ci-dessus.

Aucune de ces solutions n'est entièrement précise, mais elle vous donnera un résultat qui semble "légèrement" correct. C'est beaucoup plus compliqué à faire de toute façon, mais en utilisant ces méthodes, vous verrez des effets qui ressembleront INCROYABLEMENT aux différents jeux auxquels vous avez joué, et c'est parce que c'est EXACTEMENT ce qu'ils font;)

+0

Cela semble très prometteur - je vais expérimenter cela le matin et voir comment cela fonctionne en pratique. Merci! – x4000

+0

D'accord, en fait, j'ai déjà vérifié et c'est parfait! Évidemment, ce n'est pas 100% précis, comme vous le dites, mais il est plus ancien - GPU amical, assez efficace dans l'ensemble, et donne un résultat qui est assez bon. Encore merci! – x4000

+0

Vous êtes les bienvenus :) – Goz

1

Vous n'avez pas spécifié quelle version de DirectX que vous utilisez, donc je vais supposer 9. Probablement le meilleur que vous pouvez faire est d'utiliser le gamma-ramp functionality. Pousser la rampe de haut en bas augmente ou diminue la luminosité. Augmenter ou diminuer le gradient modifie le contraste.

+0

Fonctionne uniquement en mode plein écran, mode exclusif, malheureusement. Peut-être que ce n'est pas possible pour les applications non-plein écran sans pixel shader, je ne sais pas. – x4000

+0

Les docs impliquent qu'il pourrait fonctionner en mode fenêtré. En pratique, je pense que cela dépendra de votre carte graphique et de vos pilotes. – Kylotan

+0

Malheureusement non: "Lors de la définition de nouveaux niveaux de rampe, gardez à l'esprit que les niveaux que vous définissez dans les tableaux ne sont utilisés que lorsque votre application est en mode exclusif plein écran." (à partir du lien) – x4000

1

Une autre approche est de éditez toutes vos textures. Ce serait essentiellement la même approche que la carte gamma, sauf que vous appliquez manuellement la rampe aux données de pixels dans chacun de vos fichiers image pour générer les textures.

1

Utilisez simplement un shader. Tout ce qui ne supporte pas au moins SM 2.0 est ancien à ce stade.

2

Pour un jeu que j'ai fait en XNA, j'ai utilisé un pixel shader. Voici le code. [disclaimer] Je ne suis pas entièrement sûr que la logique est bonne et certains paramètres peuvent avoir des effets étranges (!) [/ Disclaimer]

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

pouvez-vous expliquer comment définir les offsets de façon dynamique? Ou recompilez-vous le code shader à chaque fois après avoir changé? – Ulterior