3DMAX Plugins

Maps

Released

BozoNoise
ColorNoise
CompositeMode
Confetti
CrossTile

MultiColor
Vector Noise

In Development

Oak
SuperCell
Turbulent


Brazil Shaders

CarPaint
GlowWorm

Gooch
Velvet

XSpecs

MaxScripts

Experiments

 


CompositeMode

After having used PhotoShop for several years I've come to really appreciate the power of the various blending modes it offers. That being said, I've often wanted the same kind of control in the Max material editor. Though it allows for simple linear blends and some of the other compositing types it doesn't have nearly the amount of versatility found in Photoshop. It seemed like a fairly doable deal, so I cobbled together CompositeMode which emulates all of the PhotoShop blending modes in map form. While not as sexy as some of the other procedurals I've built, it is quite possibly the most useful of all the maps I've put together so far. It can be used anyplace you would normally use a map including bump and displacement. This can generate some very cool effects though not all of the modes make sense in all cases. The teapot image above for example uses the Cellular map and my Turbulent map in difference mode for both the diffuse and displacement.

Also, a big thanks to Jens Gruschel, for documenting many of the functions found here and also allowing me to use his sample images which nicely illustrate the results.

Samples

To give a better idea for those not familiar with all the modes and what they look like, here are two sample images and the subsequent result using the various functions.

Additive

Additive simply adds the values of Layer1 and the Base Map. Values greater than 1 are clamped.

colorout = Layer1 + BaseMap;

 

Normal

Normal produces the same result as the blend map. It is a simple linear interpolation between Layer1 and the Base Map. At 100% Opacity only Layer1 will be shown. If the Opacity is less than 100% or a map is used that contains values less than white,Layer1 will be blended with the Base Map.

colorout = Layer1;

 

Subtractive

Subtractive is the opposite of additive mode. Values less than 0.0 are clampled to black.

one = Color(1,1,1);
colorout = Layer1 + BaseMap - one;

 

Dissolve

Dissolve takes the value of Layer1 and uses it as a parameter for randomly choosing either Layer1or the Base Map. A Layer1 value that is lighter in value is more likely to be replaced by the information in the Base Map.

if ( ((float)(rand()%255))/255.0f < Intens(Layer1))
colorout = Layer1;
else
colorout = BaseMap;

 

Multiply

For Multiply, Layer1 and the Base Map are multiplied by each other. This forces the result to be darker than either of the input maps except if either of the values are equal to 1.0. By the same logic if either of the values are black the result will be black also.

colorout = BaseMap * Layer1;

 

Screen

Screen can be thought of as the opposite of Multiply. Both layers are inverted, multiplied by each other, the result is inverted again. The result is generally lighter than the input layers except when one of them equals 0.0. Black does not change the composite. White input remains white in the composite.

one = Color(1,1,1);
colorout = one - ( one - BaseMap) * (one - Layer1);

 

Overlay

The result of Overlay is between multiply and screen. It either multiplies or screens, depending on the value of the Base Map. Overall the effect is that the Base Map is not replaced by Layer1, but is mixed with it, weighted by the value of the Base Map. Overlay treats 50% grey as an identity. Any value multiplied by grey is the original value.

one = Color(1,1,1);
colorout = Layer1 < 0.5f ? 2.0f * (Layer1 * BaseMap) : one - 2.0f * ( one - Layer1) * (one - BaseMap);

 

SoftLight

If the value of Layer1 is greater/less than 50% grey, the Base Map value is lightened/darkened. SofLlight treats 50% grey as an identity any value multiplied by grey remains its original value.

scl() maps the value or function f from its normal range (il, ih) to a new range(ol,oh)

zero = Color(0.0f,0.0f,0.0f);
one = Color(1.0f,1.0f,1.0f);
lo = Color(0.25f,0.25f,0.25f);
hi = Color(0.75f,0.75f,0.75f);
colorout = BaseMap< 0.5f ? 2.0f * scl(Layer1,zero,one,lo,hi) * BaseMap : one - (2.0f * (one - scl(Layer1,zero,one,lo,hi)) * (one - BaseMap));

 

HardLight

HardLight looks at the value of Layer1. If it is greater/less than 50% grey, the Base Map is either screened/ multiplied. Hard light treats 50% grey as an identity (any pixel value multiplied by grey is the original value).

one = Color(1,1,1);
colorout = BaseMap> 0.5f ? 2.0f * (Layer1 * BaseMap) : one - 2.0f * ( one - Layer1) * (one - BaseMap);

 

ColorDodge

Colordodge evaluates the color information in each channel and brightens the Base Map to reflect the color of Layer1. Colordodge treats black as the identity thus; any pixel value multiplied by black is the original value.

one = Color(1,1,1);
colorout = BaseMap / (one - Layer1);

 

ColorBurn

Color burn evaluates the color information in each channel and darkens the Base Map to reflect the color of Layer1. Color burn treats white as identity thus; any pixel value multiplied by white is the original value.

one = Color(1,1,1);
colorout = one - (one - Layer1) / BaseMap;

 

Darken

Darken compares the value of Layer1 and the Base Layer1 and chooses the darker one. As a result Layer1 can only darken the composite.

min() compares two values and returns the smaller one.

colorout.r = min(Layer1.r , BaseMap.r);
colorout.g = min(Layer1.g , BaseMap.g);
colorout.b = min(Layer1.b , BaseMap.b);

 

Lighten

Lighten compares the value of Layer1 and the Base Layer1 and chooses the lighter one. Therefore Layer1 can only lighten the composite.

max() compares two values and returns the larger one.

colorout.r = max(Layer1.r , BaseMap.r);
colorout.g = max(Layer1.g , BaseMap.g);
colorout.b = max(Layer1.b , BaseMap.b);

 

Difference

Difference uses the value of Layer1 as a parameter for inverting the Base Map.
If Layer1 is lighter/ darker, the Base Map is more/less inverted. The regions where Layer1 is white, the bottom image is inverted, where Layer1 is black, the Base Map image remain unaffected.

fabs() returns the absolute value.

colorout.r = fabs(Layer1.r - BaseMap.r);
colorout.g = fabs(Layer1.g - BaseMap.g);
colorout.b = fabs(Layer1.b - BaseMap.b);

 

Exclusion

Exclusion does pretty much the same thing as difference, only softer.

colorout = (Layer1 + BaseMap) - (2.0f * (Layer1 * BaseMap));

 

Hue

Hue produces a value with the luminance and saturation of the Base Map but the hue of Layer1. If Layer1 has a value of 0.0, the Base Map will be de-saturated.

RGBtoHLS() method to compute HLS from RGB.
HLStoRGB() method to compute RGB from HLS

RGBtoHLS(Layer1.r, Layer1.g, Layer1.b, hue1, light1, satur1);
RGBtoHLS(BaseMap.r, BaseMap.g, BaseMap.b, hue2, light2, satur2);
HLStoRGB(hue1, light2, satur2, r, g, b);
colorTemp(r, g, b);
colorout = colorTemp;

 

Saturation

Saturation produces a value with the luminance and hue of the Base Map but the saturation of Layer1. If the value of Layer1 is 0.0, the Base Map will be de-saturated. If Layer1 has no saturation (50% grey), then the Base Map will remain unchanged.

RGBtoHLS() method to compute HLS from RGB.
HLStoRGB() method to compute RGB from HLS

RGBtoHLS(Layer1.r, Layer1.g, Layer1.b, hue1, light1, satur1);
RGBtoHLS(BaseMap.r, BaseMap.g, BaseMap.b, hue2, light2, satur2);
HLStoRGB(hue2, light2, satur1, r, g, b);
colorTemp(r, g, b);
colorout = colorTemp;

 

Color

Color takes the luminance of Base map and the hue and saturation of Layer1.

RGBtoHLS() method to compute HLS from RGB.
HLStoRGB() method to compute RGB from HLS

RGBtoHLS(Layer1.r, Layer1.g, Layer1.b, hue1, light1, satur1);
RGBtoHLS(BaseMap.r, BaseMap.g, BaseMap.b, hue2, light2, satur2);
HLStoRGB(hue1, light2, satur1, r, g, b);
colorTemp(r, g, b);
colorout = colorTemp;

 

Luminosity

Luminosity takes the luminance of Layer1 and the hue and saturation of the Base Map. This is the "opposite" effect of the Color mode.

RGBtoHLS() method to compute HLS from RGB.
HLStoRGB() method to compute RGB from HLS

RGBtoHLS(Layer1.r, Layer1.g, Layer1.b, hue1, light1, satur1);
RGBtoHLS(BaseMap.r, BaseMap.g, BaseMap.b, hue2, light2, satur2);
HLStoRGB(hue2, light1, satur2, r, g, b);
Color colorTemp(r, g, b);
colorout = colorTemp;

 

UI

Composite Type: Provides nineteen options for how Layer1 and the Base Map will be composited together.

Opacity: Controls the percentage that layer1 is composited with the Base Map. At 100% the blending mode is used fully. At lower values or with the use of a map, the amount of which Layer1 is combined with the Base Map decreases.

Color swatch: Displays the Color Selector for the layer.

Map buttons: Assigns a map to the Either Layer1 or the Base Map.

Check box: When on, enables the associated map. When off, disables the associated map (the color reverts to the color swatch).

Usage Notes

I'll put in a few notes here shortly. In addition, it's been used in production by a few studios so it feels pretty solid.

Download

Please do not redistribute these files. Changes/bug fixes may be made to the plugin and it makes it much easier to guarantee you have the latest version if it is grabbed it from this site. Thanks.

CompositeMode1.0 for Max6.0

CompositeMode1.0 for Max4.0/5.0

History

The R6 version has been released.

09/05/04

I've finally gotten around to releasing the map.

08/30/03

This map was started late 2002

05/08/03