The handling of Bitmap Gamma in MAXScript has been overhauled in 3ds Max 2014 to solve several long-standing issues.
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:
.gamma
property of the MAXScript bitmap value attempted to represent both the loading and saving gamma, which was incorrect or misleading in many cases.getPixels()
function was always working with the raw data and had no way to respect the Gamma settings.compareBitmaps()
function would produce false when comparing a JPG (which loads with a gamma of 2.2) to its own copy with would have a gamma of 1.0.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.
In 3ds Max 2014 and higher, the Gamma of a Bitmap Value can be controlled in three ways - as #auto
, #default
or an override.
#auto
is the new, intelligent mode. It uses the file information when present, or intelligently chooses gamma based on whether the file is Floating point or not. This is the default behavior.#default
is actually the old legacy mode which only exists for completeness and for loading old files.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
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.
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
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