VFB+ v2.51

VFB+ v2.51 is now available for download.
This latest update fixes a few bugs reported by our users.


  • Deleting all images and then rendering would cause an exception.
  • Fixed batch CC UI quirks.
  • VFB+ could fail to initialize when trying to load a corrupted .VFB cache file.
  • [3dsmax 2013 & above] 3dsmax would crash when using render element names with more than 32 characters.
  • [3dsmax 2013 & above] Images loaded from a previous session of 3dsmax had garbled render element names.
  • [3dsmax 2013 & above] The batch CC feature was broken.
  • [3dsmax 2013 & above] Loading an image into VFB+ using MAXScript was broken.

Thanks again to all those who take the time to send me bug reports and feature requests!

Download VFB+ v2.51

VFB+ v2.5 Now Available

A new version of VFB+ is now available for download!

In this version, the main new feature is a noise reduction filter suited for high frequency noise often found in CG renderings. This filter aims to reduce fine grain, while keeping textural details as sharp as possible. For previews (and often for final renders), this lets you get away with higher levels of noise in your original rendering, while still saving a smooth image out of the frame buffer.

In addition, many bugs have been fixed. See the change log for complete details.

As always, this upgrade is free for all existing users.
Thanks to everyone for sending me continuous feedback, bug reports and feature requests, and for making VFB+ a part of your workflow!

VFB+ v2.45 Available for Download

An updated version of VFB+ has been released!
Version 2.45 supports 3dsmax 2015, as well as support for layered PSD export; VFB+ now allows you to export your image as a PSD, with each element of the image in a separate layer, and Stamper data in a separate layer as well.

Download here or see the change log for a complete rundown of new features and bug fixes.

VFB+ v2.4 Has Arrived

Fashionably late (well, at least according to my initial plans :)), I’m proud to present an all new release of VFB+. A lot of effort has gone into this release, both in terms of new features added, and the number of bugs fixes.
The image processing engine has been completely rewritten to better leverage SIMD optimizations.
New features like image filters, composition guides, view-dependent CC settings and overall stability improvements make sure that you get the most out of the tool, and the greatest improvement to your workflow.

Needless to say, the upgrade is free for existing users!

Be sure to check out the full change log for a comprehensive list.

Thanks to everyone for the continuous feedback and the overall support!

version 2.41 Update!

An update has been released fixing the following bugs:

  • ‘Send To’ was broken for command-line based applications.
  • Opening the preferences panel would reset the last used ‘Send To’ application.
  • If ‘Output Folder’ was set to ‘Permanent’ in output preferences, and annoying message would pop up whenever a user opens the preferences dialog.
  • Using ‘Sent to Photoshop’ could result in a MAXScript exception being raised.

A big thanks to Shawn Olson for letting me know about all of these bugs, and my sincere apology to those who have already taken the time to download v2.4.

mmMaxControls : .NET Controls with a 3dsmax Style

Lately I’ve seen several posts on the CGTalk MAXScript forum asking how one could make the standard .Net WinForms controls look like the standard 3dsmax UI elements.

Towards this end, I’ve written a collection of some commonly used controls that imitate the 3dsmax look and feel to the pixel, thus maintaining uniformity in your scripted or compiled interface, but giving you the high level of control that DotNet offers.

The package is called mmMaxControls, and is freely available for personal or commercial use. It targets version 2.0 of the DotNet framework, which should make is backwards compatible many versions (the earliest I’ve tested is 3dsmax 2009, theoretically it may work on as far back as 3dsmax 9).

General Features:

  • Look exactly like 3dsmax controls.
  • Control colors update when 3dsmax colors update.
  • No keyboard focus issues that plague standard DotNet controls in 3dsmax (EnableAccelerators is automatically managed by the library).
  • All the customization options of DotNet controls.
  • Can be used in any DotNet language. e.g. if you are developing a 3dsmax plugin in c# without referencing the 3dsmax SDK (for example, for versions earlier than 3dsmax 2012SAP), this is your best bet for native-looking 3dsmax controls.
  • Can be used in both a MAXScript Rollout as a DotNetControl or in a WinForms Form.

Download mmMaxControls v1.02 (12k)

The library is fully documented: Online | Zipped HTML.

Below is the code used for creating the MAXScript rollout at the top of this post.

dotnet.loadAssembly @"C:\mmMaxControls.dll"
try(destroyDialog mmMaxControls)catch()
rollout mmMaxControls "mmMaxControls" width:235
	groupBox grpBtn "Button" width:225 height:55 pos:[5,5]
	dotNetControl mmBtn1 "mmMaxControls.Button" width:62 height:25 pos:[15,25]
	dotNetControl mmBtn2 "mmMaxControls.Button" width:60 height:25 pos:[80,25]
	dotNetControl mmBtn3 "mmMaxControls.Button" width:25 height:25 pos:[143,25]
	dotNetControl mmBtn4 "mmMaxControls.Button" width:50 height:25 pos:[171,25]
	groupBox grpChk "CheckButton" width:225 height:55 pos:[5,65]
	dotNetControl mmChk1 "mmMaxControls.CheckButton" width:25 height:25 pos:[15,85]
	dotNetControl mmChk2 "mmMaxControls.CheckButton" width:70 height:25 pos:[45,85]
	dotNetControl mmChk3 "mmMaxControls.CheckButton" width:72 height:25 pos:[120,85]
	dotNetControl mmChk4 "mmMaxControls.CheckButton" width:25 height:25 pos:[195,85]
	groupBox grpFlyBtn "FlyoutButton" width:110 height:60 pos:[5,125]
	dotNetControl mmFlyBtn "mmMaxControls.FlyoutButton" width:32 height:32 pos:[43,145]
	groupBox grpFlyChk "FlyoutCheckButton" width:110 height:60 pos:[120,125]
	dotNetControl mmFlyChk "mmMaxControls.FlyoutCheckButton" width:32 height:32 pos:[157,145]
	groupBox grpDrop "DropDownList" width:225 height:50 pos:[5,190]
	dotNetControl mmDrop "mmMaxControls.DropDownList" width:200 height:21 pos:[15,210]
	groupBox grpTxt "TextBox" width:225 height:120 pos:[5,245]
	dotNetControl mmText1 "mmMaxControls.TextBox" width:200 height:21 pos:[15,265]
	dotNetControl mmText2 "mmMaxControls.TextBox" width:200 height:63 pos:[15,290]
	groupBox grpSpn "Spinner" width:225 height:65 pos:[5,370]
	label mmSpn1Lab "That's draggable" pos:[15,390]
	dotNetControl mmSpn1 "mmMaxControls.Spinner" width:80 height:16 pos:[140,390]
	label mmSpn2Lab "And screen-wrapping" pos:[15,412]
	dotNetControl mmSpn2 "mmMaxControls.Spinner" width:80 height:16 pos:[140,412]
	on mmMaxControls open do
		local logoImg = dotnetObject "System.Drawing.Bitmap" @"C:\logo.png"
		local blueImg = dotnetObject "System.Drawing.Bitmap" @"C:\logoBlue.png"
		local flyoutStrip = dotnetObject "System.Drawing.Bitmap" @"C:\imageStrip.png"
		mmBtn1.text = "DotNet"
		mmBtn1.image = logoImg
		mmBtn1.imageAlign = mmBtn1.imageAlign.MiddleLeft
		mmBtn1.TextAlign = mmBtn1.textAlign.MiddleRight
		mmBtn2.text = "Controls"
		mmBtn3.image = logoImg
		mmBtn3.ShowFocusFrame = off
		mmBtn4.text = "With"
		mmBtn4.FrameOnMouseOverOnly = on
		mmChk1.text = "A"
		mmChk2.text = "3dsmax"
		mmChk2.image = blueImg
		mmChk2.imageAlign = mmChk1.imageAlign.MiddleLeft
		mmChk2.TextAlign = mmChk1.textAlign.MiddleRight
		mmChk2.ShowFocusFrame = off
		mmChk3.text = "Look"
		mmChk3.ShowFocusFrame = off
		mmChk3.FrameOnMouseOverOnly = on
		mmChk4.image = blueImg
		mmChk4.ShowFocusFrame = off
		mmChk4.FrameOnMouseOverOnly = on
		mmText2.multiLine = on
		mmSpn1.minimum = 0.1
		mmSpn1.maximum = 1
		mmSpn1.increment = .001
		mmspn1.value = mmspn1.defaultValue = 0.5
		mmSpn1.decimalPlaces = 3
		mmSpn2.increment = 1
		mmSpn2.maximum = 10000
		mmSpn2.value = mmSpn2.defaultValue = 100
		mmSpn2.decimalPlaces = 0
		mmDrop.items.addRange #("A", "DropDownList", "control", "that", "inherits", "from", "Combobox")
		mmDrop.selectedIndex = 0
		mmFlyBtn.setImageStrip flyoutStrip 4
		mmFlyBtn.toolTips = #("Easily", "Set", "Button", "Tooltips")
		mmFlyChk.setImageStrip flyoutStrip 4
		mmFlyChk.toolTips = #("Same", "Thing", "But", "Checkable")
		mmFlyChk.flyoutTime = 100
createDialog mmMaxControls

These are the bitmaps used in the example code:

Update: v1.01

I’ve updated the library to v1.01, fixing a few bugs and adding a few small methods.

  • Spinner: Backspace key was not working.
  • Spinner: now behaves correctly for resetting and cancelling a spin operation.
  • Spinner: now goes faster/slower with control/alt buttons pressed, as native 3dsmax spinner.
  • Spinner: text area would not accept the enter key when used as a DotNetControl.
  • Spinner: now shows the correct mouse cursor when dragging.
  • Spinner: ‘dragging’ behavior now only begins when the mouse has left the control area.
  • Spinner: Added .Clear() method for setting the control in an indeterminate state.
  • Spinner: Added events for ButtonDown and ButtonUp, similar to the native 3dsmax events.
  • Button: Contents are now corrently moved 1 pixel to the right and down when pressed.
  • CheckButtons: Frame is now always shown when button is checked, even if FrameOnMouseOverOnly is on.
  • Flyout controls: Opening the flyout no longer steals focus from the host dialog.
  • Flyout controls: Added .ShowFlyout() method for programmatically opening the flyout, e.g. – when you want another button to open the flyout.

Thanks to DenisT from CGTalk for catching most of these bugs.

Another Update: v1.02

I’ve fixed some more bugs and inaccuracies:

  • Spinner: Very minor change of point of transitioning from click to drag behavior, now completely matches 3dsmax.
  • CheckButton: Now shows checked background on mouse down, instead of mouse up.
  • FlyoutButton and FlyoutCheckButton: Flyout items are now correctly shifted 1 pixel right and down on mouse over.
  • FlyoutButton: ItemSelected is now also triggered when the button is clicked without the flyout opening.

Introducing VFB+ v2.3

First of all, I must apologize for not updating this blog more often. Virtually all of my free time in the past six months has gone towards making sure the next update of VFB+ will be as powerful, stable and convenient as possible.

This release is packed full of new features, almost all of them requested by users! A considerable number of bugs has also been fixed, and performance greatly improved.

Amongst the new features you will find:

  • Chromatic aberration!
  • VFB+ now supports rendering via Backburner. This means that you can install VFB+ on your render nodes (no license required for this mode), and get your network renders come back with your color correction and stamps.
  • sRGB color space toggle.
  • Estimated render time display. Yes, even if your renderer does not report this data natively (e.g. – Mental Ray).
  • Save all elements of current image with one click.
  • And much much more… I recommend taking a look at the complete change log, and the new video which demonstrates some of the new features.

    I’ve also made the help files available online as well as the compiled .CHM.

    Thanks to all users for your requests, bug reports and general feedback.

    Oh, and of course, this upgrade is free for all existing users. Simply download the trial from this page and replace VFBPlus2.dlx in your \plugins\ folder, your license should work as usual.

VFB+ v2.2 Released

Check out the latest version of VFB+, which brings new and improved features such as a vignette effect, enhanced support for Render-To-Texture, extended MAXScript interfaces, editable image titles and the ability to open VFB+ in any 3dsmax image viewer window, as well as a few bug fixes.

The upgrade is, as usual, free for all existing users.

Color Correction
Check out the complete Change Log.

If you’ve evaluated VFB+ in the past and would like to re-evaluate a newer version, please don’t hesitate to contact me.

mmTransformTypein: A hotkey-compatible TTI launcher

VFB+ user and architect Maxim Borisov has recently suggested a script to help make his transform-intensive work easier:

“Very often I have to move, rotate or scale my objects for some exact numbers of units, and I hate to move mouse pointer to Transform Type-in window, select the slot were to put numbers and move mouse back to objects on other side of my second screen… Idea is to get the Offset part of Transform Type-In dialog near by the mouse pointer or by hitting 4th or 5th button on mouse, or by some keyboard shortcut.”

This tiny MacroScript does exactly this. When executed, it opens the 3dsmax Transform Type-In dialog exactly where the mouse cursor is and sets keyboard focus to spinners. This allows rapid manipulation of scene objects for those users who rely on a fast-paced scene workflow.

edit (01/19/15) – the tool now takes the current axis constraints into consideration and focuses the relevant text field in the dialog.

Rigging a Sprite Sheet in 3dsmax

A user recently asked on CGTalk:

i want to use max to create something like this :

basically i want to have a controller like this one :

but instead of it controlling morph targets , i want it to control a texture on a plane object
so it will cycle or load different images for set values in the controller position.

This article will demostrate a method of hooking up a sprite sheet to a two-dimensional joystick controller.

This will be our sprite sheet for the example:

It may not be much to look at, but for testing purposes it will be the easiest way of determining if we’re getting the right image or not.

You can download the initial and final scene files here:
Download Sprite Sheet Rigging Scene Files (3dsmax 2009)

As a starting point, we have a teapot and a joystick controller. Notice that both the joystick frame and the joystick controller itself have their pivot set to their bottom left corner. This will make it easier to extract the normalized value from the controller. The joystick controller is also parented to the frame.
As you might expect, the joystick has a limit controller applied to it’s X and Y axes to keep it within the frame.

The teapot has a material applied with our sprite sheet loaded as a texture.

First we must scale our UV space. We do this so we get a UV space in the range of 0 to 1 for each sprite. This has the advantage of decoupling the object’s UV mapping from the sprite sheet, allowing us to think in normal terms when mapping our object.
So, if we have 7 sprites on the X axis and 3 sprites on the Y axis, our UV space, centered at [0,0], will range from -3 to 3 on the X and -1 to 1 on the Y.

To scale our current UV space we simply divide the U and V tiling parameters by the number of sprites in each axis.

U tiling: 1.0 / 7 = 0.142857
V tiling: 1.0 / 3 = 0.333333

Now we must write code that will snap the position of the joystick controller to the correct values. We will add float script controllers to the U offset and V offset parameters of our texture.
This is most easily done from track view.
Select the tracks in track view and from the controller menu choose ‘Assign…‘. Select ‘Float Script‘ as the controller type.

First we must create variables for the relevant joystick position controller, and a constant value for the number of sprites in this axis.
Create a variable named xCtrl and use ‘Attach Controller‘ to connect it to the Float Limit controller of the joystick’s X position.
Then create a variable named NumSpritesX and use ‘Assign Constant…‘ to assign it a value of 7.

This is the complete code for the U offset controller:

local normalizedX = xCtrl.value / XCtrl.upper_limit
local xIndex = (normalizedX * NumSpritesX - 0.001) as integer + 1
NumSpritesX / 2. + 0.5 - xIndex

The first line normalizes the position of the joystick by dividing it by the upper limit of the limit controller. because the pivots are aligned as mentioned before, and the joystick is parented to the frame, we get a normalized value in the range of 0.0 to 1.0.
We then use this value to determine the index of the sprite we need to retrieve.
We do this by multiplying the normalized position by the number of sprites on the X axis (in this case, 7) and casting to an integer. This cast is what provides the ‘snap’ behavior. Otherwise we would get a smooth movement across the UV space, which we are trying to avoid.
We subtract -0.001 from the value before casting to integer so that a normalized position of 1.0 (when the controller is farthest to the right) will not loop back to the first sprite. As the result we get is 0-based, we add 1 to convert it to 1-based.
The final line converts the index of the sprite to its valid U offset value. Because our U space is centered at [0,0] and ranges from -3 to 3, we must subtract the index from half of the total number of sprites, and add 0.5 so we end up on the correct boundary.

Do exactly the same for the V offset parameter.

Now everything should be hooked up. You can move the joystick around and the correct sprite should appear on the teapot.

If we want to change the number of sprites in the sprite sheet, all we need to do is:

  • Change the U and V tiling parameters on the bitmap texture.
  • Change the NumSpritesX and NumSpritesY variables in the script controllers of the U and V offset parameters.

Everything else will adjust automatically. The frame can also be resized to whatever we want, as long as the pivot alignment is maintained and the limits are updated.

In a proper production environment, or just to take it a step further, we could also put a custom attribute on the joystick controller with spinners for inputting the dimensions of the sprite sheet, making the rig more animator friendly. The U and V tiling paremeters as well as the variables in the script controllers would then be linked to these custom attribute parameters.

mmRegions: A Handly Little Script for Render Region Management

Lately I’ve been seeing several requests on forums for a way to easily ‘save’ coordinates of regions in a 3dsmax scene. mmRegions is a small free script which does just that. It can store the current render region, restore previously saved regions, and even batch render several regions with one button.

All coordinates are saved as percentages, so they scale linearly with the image size. The regions can also be given a descriptive name are are visualized inside the tool. They are saved automatically inside the scene.

To use it:

  • Install the script by dragging mmRegions.mcr into a viewport.
  • Assign it to a toolbar or a keyboard shortcut from the Customize User Interface dialog. It will be found under the Monotone Minimal category.
  • Open the tool.
  • Set a render region as you normally would.
  • Press the Store Region button (first button from the left) to save the coordinates of the region.
  • Press the Restore Region button (third button from the left) to restore the saved region to the current render region of 3dsmax.
  • To batch-render several regions, use the Batch Render button (last button from the left).

UPDATE: Fixed a bug which would cause the Mental Ray VFB controls window to go blank after batch-rendering multiple regions. Thanks to Spacefrog for the report!

UPDATE #2: Updated to v1.1! New features:

  • Preview window now correctly matches render aspect
  • Now works with V-Ray Frame Buffer regions. If the V-Ray VFB region mode is enabled, creating a new region, restoring a region or batch-rendering will affect that instead of the standard 3dsmax render region.
  • Added spinners for editing the dimensions of the currently selected region.
  • Added option to export/import region data. Data can be exported either as plain text, or as Adobe After Effects keyframe data.
  • Added a confirmation window when ‘delete region’ is pressed.

Download mmRegions