MJW

Hot Metal Glow

Recommended Posts

HotMetalGlowExample_zpsmtmc6nwh.png
 
This is a rather minor plugin, but it might be useful. It's in the Effects>Color menu. (It was developed for creating my SOTW fire image.)
 
Quoting the Help menu:

Hot Metal Glow converts each pixel's color value into a color intended to mimic incandescent heated metal. The colors go from black, to red, to orange, to yellow, and finally to white. The color transition is only approximate. No attempt is made to imitate actual physics.

An input pixel's color value is simply the largest of its RGB components. Brighter pixels are considered to be hotter, unless the Invert Color Range option is selected.

The controls are:
Celsius Temperature at Zero Value is the temperature assigned to 0 value pixels.
Celsius Temperature at Maximum Value is the temperature assigned to 255 value pixels.
Incandescence Threshold Temperature is the temperature at which the pixel will begin to turn red.
Red Temperature is the temperature at which the pixel will be full-intensity red. (The behavior is modified by Red to Orange Shift.)
Yellow Temperature is the temperature at which the hue of the pixel will be yellow.
White Temperature is the temperature at which the pixel will be white.
Red to Orange Shift specifies the point at which red shifts towards orange as the intensity increases. When 0, the hue remains red until the red is full intensity. When 1, the hue immediately begins to shift towards orange. (This control is useful for producing fire colors.)
Orange Desaturation specifies the point at which orange will be desaturated. When 0, orange and yellow are fully saturated. When 1, orange begins to be desaturated at the Red Temperature.
Invert Color Range specifies that the range of color values should be inverted, so black pixels are hottest.

The Threshold, Red, Yellow, and White Temperature values must be in increasing order. If not, the values are clamped to force the order to increase, but the resulting colors are not likely to be useful.

The user interface looks like this:
 
HotMetalGlowUI_zps5pedtpa6.png
 
Here is the DLL: HotMetalGlow.zip

 

There's also 3.5.11 version, courtesy of Maximilian.
 
Here is the CodeLab code:

Hidden Content:


// Name: Hot Metal Glow
// Submenu: Color
// Author: MJW
// Title: Hot Metal Glow
// Version: 1.2.*
// Desc: Convert pixel color values into incandescence colors
// Keywords: incandescence colors
// URL: 
// Help:
#region UICode
IntSliderControl Amount1 = 500; // [0,1400] Celsius Temperature at Zero Value
IntSliderControl Amount2 = 1315; // [0,1400] Celsius Temperature at Maximum Value
IntSliderControl Amount3 = 425; // [0,1400] Incandescence Threshold Temperature
IntSliderControl Amount4 = 825; // [0,1400] Red Temperature
IntSliderControl Amount5 = 1175; // [0,1400] Yellow Temperature
IntSliderControl Amount6 = 1315; // [0,1400] White Temperature
DoubleSliderControl Amount7 = 0.0; // [0,1] Red to Orange Shift
DoubleSliderControl Amount8 = 0; // [0,1] Yellow Desaturation
CheckboxControl Amount9 = false; // [0,1] Invert Color Range
#endregion

// This could be done with a 255 entry color table, but it doesn't work especially
// well for CodeLab.
int cMask;

void Render(Surface dst, Surface src, Rectangle rect)
{
    int minTemp = Amount1;
    int maxTemp = Amount2;
    if (minTemp >= maxTemp)
        maxTemp = minTemp + 1;
          
    int minRedTemp = Amount3;
    int redTemp = Math.Max(Amount4, minRedTemp+ 1);
    int yellowTemp = Math.Max(Amount5, redTemp + 1);  
    int whiteTemp = Math.Max(Amount6, yellowTemp + 1);
    double redOrangeShift = Amount7;
    double yellowDesat = Amount8;
         
    double colorScale = 255.0 / (double)(maxTemp - minTemp);
    
    // (The "min" values are where the value is zero, but will change to non-zero.)
    int minRed = (int)(colorScale * (double)(minRedTemp - minTemp) + 0.5);
    int fullRed = (int)(colorScale * (double)(redTemp - minTemp) + 0.5);
    int minGreen = (int)(fullRed + redOrangeShift * (minRed - fullRed) + 0.5);
    double fullGreen = Math.Round(colorScale * (double)(yellowTemp - minTemp));
    int minBlue = (int)(fullGreen + yellowDesat * (fullRed - fullGreen) + 0.5);
    int fullBlue = (int)(colorScale * (double)(whiteTemp - minTemp) + 0.5);

    double scaleRed = 255.0 / (double)(fullRed - minRed);
    double scaleGreen = 255.0 / (double)(fullGreen - minGreen);
    double scaleBlue = 255.0 / (double)(fullBlue- minBlue);
    
    cMask = Amount9 ? 255 : 0;  // Optionally invert tohe color range
    
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
        {        
            // Get the value, which is just the maximum RGB value.
            int value = ColorValue(src[x, y]);
            byte r = 0, g = 0, b = 0;
            
            if (value > minRed)
            {
                r = (byte)Math.Min(scaleRed * (double)(value - minRed) + 0.5, 255);
            }
            
            if (value > minGreen)
            {
                g = (byte)Math.Min(scaleGreen * (double)(value - minGreen) + 0.5, 255);
            }
            
            if (value > minBlue)
            {
                b = (byte)Math.Min(scaleBlue * (double)(value - minBlue) + 0.5, 255);
            }
                
            dst[x, y] = ColorBgra.FromBgra(b, g, r, src[x, y].A);
        }
    }
}

int ColorValue(ColorBgra color)
{
    return Math.Max(Math.Max(cMask ^ color.R, cMask ^ color.G), cMask ^ color.;
}


 
EDIT: Added Desaturate Yellow feature. I noticed in many examples of hot metal, the yellow was never fully saturated.
EDIT 2: Fixed Help Menu to match UI. Control is called "Yellow Desaturation" not "Desaturate Yellow."
EDIT 3: Added Red to Orange Shift feature.

EDIT 4: In plugin, renamed Yellow Desaturation to Orange Desaturation. (Man, do I get tired of all the updates I have to make each time I change the interface!)

Edited by MJW
  • Upvote 8

Share this post


Link to post
Share on other sites

This is cool.  Have to figure out how to effectively use it, though.  Doesn't work on solid colors...need something varying or gradient-like perhaps.  Or use layers.   I need to experiment.

 

Thank you, MJW!!     :)     :beer:  :pizza:

 

 

EDIT:  Works great on textures!                  hotmetalglow_01.png

Edited by lynxster4
re-hosted image
  • Upvote 5

Share this post


Link to post
Share on other sites

Thank you for the creation, this looks very good :)

 

Edit-

Works great on gradients.

23jg0er.png

Edited by sashwilko
  • Upvote 1

Share this post


Link to post
Share on other sites

I added a new feature which allows the yellow to be desaturated. I think it often produces more realistic results.

Share this post


Link to post
Share on other sites

Added Red to Orange Shift. This adds a bit more flexibilty by allowing the plugin to be used to produce flame-like colors

Share this post


Link to post
Share on other sites

This may be a rather far-fetched application, but I've found that this plugin produces nifty tweaks on skies, particularly if I want to turn a sky into a bloody sky or maybe if I just want to turn a few clouds into bloody clouds. Follows an example of what I mean (source image in the top left corner of this collage is a 100% PdN landscape, plus three results obtained after applying the effect on the sky layer and playing a little with blend modes). Click on thumbnail for a full-size picture:

 

Hot_Metal_Glow_test_collage.jpg

 

Very many thanks, MJW! You're definitely an A+ coder! Laie_54.gif

 

Here's the plugin for users of Paint.NET 3.5.11

HotMetalGlow 1.2 for PdN 3.5.11.zip

  • Upvote 4

Share this post


Link to post
Share on other sites

Thanks for the 3.5.11 version Maximilian! I'll link to your comment in the initial comment.

  • Upvote 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now