Home Up Tutorials FAQs Downloads Web Links Newsgroups About Me Search


Simple Gamma Correction

Written By Microsoft MVP: Eric DeBrosse
Content may not be duplicated without permission.
Updated: 2-8-2002

In this article, I will briefly explain gamma correction. More importantly, I will show you how to implement a simple corrective function using good'ol Visual Basic code. The DirectX SDK documentation does a great job of describing gamma correction, so I suggest you have a look at the expert Microsoft advice.

But first, let me try to give you a quick description of gamma correction. Most people confuse gamma correction with the ability to control the brightness and/or contrast of a display. In scaling all of the color values by the same factor, this is essentially what is happening. True gamma correction is where the individual color values are independently scaled, to give uniform color on arbitrary display devices. If you desire a better explanation than mine, query your favorite search engine; you will find many results.

I will be implementing a simple linear graph, like the following, in the sample code. All color values will be scaled by the same factor.


Gamma Ramp Graphs

The graph on the left shows the default gamma ramp. In this graph, the color value "out" is the same as the color value "in". For example, if 32,000 is input, 32,000 comes out. i.e. no gamma correction. With the graph on the right, all color values are dampened by a linear factor. In this case, the color values coming out would be scaled by about half. The output seen on the screen would be much darker than normal. If you were to increase the ramp values, the display would of course be much brighter.

In the sample code, we make sure all of the ramp values are clamped to a maximum of 65535. The strange bit manipulation logic is required because we are dealing with unsigned integers. The code pretty much says it all.

Have a look at the function:

Public Sub SetGamma(Optional ByVal GammaFactor As Single = 1!)
    Dim d3dCaps As D3DCAPS8
    Dim NewRamp As D3DGAMMARAMP
    Dim NewValue As Long
    Dim ui As Long
    Dim i As Long

    'see if this device can do fullscreen gamma
    Call g_oDevice.GetDeviceCaps(d3dCaps)

    If (d3dCaps.Caps2 And D3DCAPS2_FULLSCREENGAMMA) _
            <> D3DCAPS2_FULLSCREENGAMMA Then
        'device does not support gamma correction
        Exit Sub
    End If

    'create linear gamma ramp
    For i = 0 To 255
        NewValue = i * GammaFactor * 255: ui = 0
        If NewValue > 32767 Then NewValue = NewValue - 32767: ui = 1
        If NewValue > 32767 Then NewValue = 32767

        'manipulate bits to handle unsigned integers
        NewRamp.red(i) = NewValue Or (&H8000 * ui)
        NewRamp.green(i) = NewValue Or (&H8000 * ui)
        NewRamp.blue(i) = NewValue Or (&H8000 * ui)
    Next i

    'send gamma ramp to device
    Call g_oDevice.SetGammaRamp(D3DSGR_NO_CALIBRATION, NewRamp)
End Sub

The above function assumes g_oDevice is a valid Direct3DDevice8 object.

You might ask, what values can I pass in the optional GammaFactor parameter? To create a default gamma ramp, pass 1 in the GammaFactor parameter (or leave the parameter empty). A value of 2 should make the display fairly bright. Passing 0 would cause all of the colors to become black! Not good. Just do a little experimenting, all monitors are different. Just please keep in mind, if you need your scene to fade to black, there are better ways to accomplish it! I would only allow users to make subtle changes to the gamma, enabling them to make basic contrast adjustments.

Well that's it! Just plug the above code into your application and off you go! You should note that most devices will not allow you to set the gamma of a windowed application. Actually, the gamma of the entire desktop would need to be set. The above code merely checks to see if fullscreen gamma correction is available before proceeding.

2009 Eric DeBrosse


Hit Counter
Visitors since 5/21/2002