Bitmap Gamma and MAXScript

The handling of Bitmap Gamma in MAXScript has been overhauled in 3ds Max 2014 to solve several long-standing issues.

The Past Problems

In versions prior to 3ds Max 2014, MAXScript had limited access to the Gamma settings of the Bitmap Values loaded from files, created by a script, or saved to disk bitmap files in various formats.

Here is a list of some of the problems:

To solve the above issues, MAXScript was extended in 3ds Max 2014 to let scripts properly handle the Gamma of Bitmap Values.

In all cases, the additions have been implemented as extensions, in other words old scripts will remain syntactically correct.

Gamma Modes - Auto, Override and Default

In 3ds Max 2014 and higher, the Gamma of a Bitmap Value can be controlled in three ways - as #auto , #default or an override.

The following extensions have been implemented:

The openBitmap() function now accepts an optional gamma: keyword argument, so you can say

FOR EXAMPLE:

   a = openBitmap "test.jpg" gamma:#auto -- auto mode 
   b = openBitmap "test.exr" gamma:1.0 -- an override

Similarly, the bitmap save() method has been extended with an optional gamma: keyword, so you can say:

save a gamma:#auto -- auto mode 
save b gamma:1.0 -- an override

In addition, the save() function now provides a metadata: optional keyword which can be used to pass the dialog settings acquired from the various bitmap filename picking functions - SelectSaveBitmap() , getBitmapSaveFilename() and getBitmapOpenFilename() . See further on this page for details.

If you render to a file using the render() function, you can also set the Gamma using the optional gamma: keyword:

FOR EXAMPLE:

   render filename:"something.exr" gamma:#auto -- auto mode 
   render filename:"somotherthing.jpg" gamma:1.0 -- an override

New and Modified Bitmap Value Gamma Properties

The existing .gamma property has been modified to represent the ACTUAL gamma of the bitmap. In the past, it confused output and input gamma into one parameter, which was problematic.

For this reason, two new properties have been added to explicitly address the input gamma, and how that gamma was obtained:

.inputGamma will inform you of the gamma of the file that was loaded. It will return either #auto, #default or the override value. This can be used to display e.g. where the gamma info comes from. It can also be used to make sure to save a bitmap the same as it was loaded, for example.

.inputGammaValue just returns the actual value that was used, e.g. for #auto it would return 1.0 or 2.2 depending on file type, for #default it would return 2.2, and for an override it returns the override value.

Bitmap File Open and Save Dialogs Meta-Data Access

Features have been added to the MAXScript bitmap file dialogs to return as an optional by-reference output parameters the Gamma values, as well as the dialog's setup data.

When these optional parameters are used, the gamma options are visible and work. When they are not used, the Gamma options will be grayed out in the file dialog.

The functions that have been extended are:

getBitmapOpenFilename()
getBitmapSaveFilename() 
SelectSaveBitmap()

In each one of these functions, an optional keyword argument gamma: can refer to a by-reference variable that will return #auto , #default or a numeric value:

FOR EXAMPLE:

   x = SelectSaveBitmap caption:"Select a file" gamma:&gma

If the function returns successfully, the variable 'gma' will contain the gamma value from the dialog.

Similarly, bitmap Save dialogs can return the meta-data stored by the "Setup" button, by requesting it via the metadata: by-reference optional argument:

FOR EXAMPLE:

   x = SelectSaveBitmap caption:"Select a file" gamma:&gma metadata:&data

Upon success, the 'gma' variable will contain the gamma, and the 'data' variable will contain an array of data stored by the bitmap plugin. This data can then be used in bitmap save operations, for example:

   bitmap.filename = SelectSaveBitmap caption:"Select a file" gamma:&gma metadata:&data
   if (bitmap.filename) do save bitmap gamma:gma metadata:data

Pixels Access - Linear vs. Raw

The function getPixels() have been extended with the optional linear: boolean parameter:

FOR EXAMPLE:

   a = openBitmap "hello.jpg" gamma:#auto --this will set gamma to 2.2
   p = getPixels a [0,0] 50 linear:true  --get the linear pixel values (gamma 1.0)
   p[1].r *= 2.0 --make first pixel twice as red...

The following example script goes through all Bitmap Textures and if they are set to #default (legacy mode), changes the Gamma to an override of 2.2.

Note that you cannot change the Gamma of a bitmap value (this gets burned in when loading it), but you can simply re-load it with the new Gamma from the original source file.

SCRIPT:

   for tmap in (getClassInstances BitmapTexture) where (tmap.bitmap.inputGamma == #default) do 
     tmap.bitmap = openBitmap tmap.bitmap.filename gamma:2.2