Simon Brown has created a similar plugin here. Mine is different.
For my plugin, the user (that's you) will need to draw a black to white gradient in the general shape you want the flames before running the effect.
Download here: http://forums.getpai...hp?/topic/8318-
How to install plugins: http://boltbait.goog...ges.com/install
If that doesn't work, post your troubles here:

This plugin shows up under the Effects > Distort menu as "Burninate". I believe Trogdor would approve.
Source code here:
using System;
using System.Text;
using System.Reflection;
using PaintDotNet;
using PaintDotNet.Effects;
using PaintDotNet.IndirectUI;
using PaintDotNet.PropertySystem;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("BurninatePlugin")]
[assembly: AssemblyDescription("Burninate Plugin for Paint.NET. Based on Tom Jackson's excellent Fire Tutorial.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BoltBait")]
[assembly: AssemblyProduct("BurninatePlugin")]
[assembly: AssemblyCopyright("Copyright © BoltBait")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.0.*")]
namespace BurninateEffect
{
public class PluginSupportInfo : IPluginSupportInfo
{
public string Author
{
get
{
return "BoltBait";
}
}
public string Copyright
{
get
{
return ((AssemblyCopyrightAttribute)base.GetType().Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false)[0]).Copyright;
}
}
public string DisplayName
{
get
{
return ((AssemblyProductAttribute)base.GetType().Assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0]).Product;
}
}
public Version Version
{
get
{
return base.GetType().Assembly.GetName().Version;
}
}
public Uri WebsiteUri
{
get
{
return new Uri("http://www.BoltBait.com/pdn");
}
}
}
[PluginSupportInfo(typeof(PluginSupportInfo), DisplayName = "Burninate")]
public class BurninateEffectPlugin : PropertyBasedEffect
{
public static string StaticName
{
get
{
return "Burninate";
}
}
public static Image StaticIcon
{
get
{
return new Bitmap(typeof(BurninateEffectPlugin), "burninate.png");
}
}
public BurninateEffectPlugin()
: base(StaticName, StaticIcon, SubmenuNames.Distort, EffectFlags.Configurable)
{
}
public enum PropertyNames
{
Amount1,
Amount2,
Amount3,
Amount4
}
protected override PropertyCollection OnCreatePropertyCollection()
{
List<Property> props = new List<Property>();
props.Add(new Int32Property(PropertyNames.Amount1, 100, 2, 1000));
props.Add(new DoubleProperty(PropertyNames.Amount2, 0.5, 0, 1));
props.Add(new BooleanProperty(PropertyNames.Amount4, false));
props.Add(new Int32Property(PropertyNames.Amount3, 0, 0, 255));
return new PropertyCollection(props);
}
protected override ControlInfo OnCreateConfigUI(PropertyCollection props)
{
ControlInfo configUI = CreateDefaultConfigUI(props);
configUI.SetPropertyControlValue(PropertyNames.Amount1, ControlInfoPropertyNames.DisplayName, "Scale");
configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.DisplayName, "Roughness");
configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.SliderLargeChange, 0.25);
configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.SliderSmallChange, 0.05);
configUI.SetPropertyControlValue(PropertyNames.Amount2, ControlInfoPropertyNames.UpDownIncrement, 0.01);
configUI.SetPropertyControlValue(PropertyNames.Amount4, ControlInfoPropertyNames.DisplayName, string.Empty);
configUI.SetPropertyControlValue(PropertyNames.Amount4, ControlInfoPropertyNames.Description, "Black and White");
configUI.SetPropertyControlValue(PropertyNames.Amount3, ControlInfoPropertyNames.DisplayName, string.Empty);
configUI.SetPropertyControlType(PropertyNames.Amount3, PropertyControlType.IncrementButton);
configUI.SetPropertyControlValue(PropertyNames.Amount3, ControlInfoPropertyNames.ButtonText, "Randomize");
configUI.SetPropertyControlValue(PropertyNames.Amount3, ControlInfoPropertyNames.Description, "HINT: Start by drawing a gradient from black to white before running this effect. Try different gradient shapes to vary the flames.");
return configUI;
}
protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs)
{
this.Amount1 = newToken.GetProperty<Int32Property>(PropertyNames.Amount1).Value;
this.Amount2 = newToken.GetProperty<DoubleProperty>(PropertyNames.Amount2).Value;
this.Amount3 = newToken.GetProperty<Int32Property>(PropertyNames.Amount3).Value;
this.Amount4 = newToken.GetProperty<BooleanProperty>(PropertyNames.Amount4).Value;
// setup for calling the clouds effect
cloudsProps = cloudsEffect.CreatePropertyCollection();
PropertyBasedEffectConfigToken CloudsParameters = new PropertyBasedEffectConfigToken(cloudsProps);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Scale, Amount1);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Power, Amount2);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.BlendOp, normalOp);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Seed, Amount3);
cloudsEffect.SetRenderInfo(CloudsParameters, dstArgs, srcArgs);
base.OnSetRenderInfo(newToken, dstArgs, srcArgs);
}
protected override unsafe void OnRender(Rectangle[] rois, int startIndex, int length)
{
if (length == 0) return;
for (int i = startIndex; i < startIndex + length; ++i)
{
Render(DstArgs.Surface, SrcArgs.Surface, rois[i]);
}
}
protected override void OnCustomizeConfigUIWindowProperties(PropertyCollection props)
{
// Change the effect's window title
props[ControlInfoPropertyNames.WindowTitle].Value = "BoltBait's Fire Effect v1.0";
base.OnCustomizeConfigUIWindowProperties(props);
}
int Amount1 = 100; // [2,1000] Scale
double Amount2 = 0.5; // [0,1] Roughness
int Amount3 = 0; // [255] Reseed
bool Amount4 = false; // Black and White
// Setup for calling the Render Clouds effect
private CloudsEffect cloudsEffect = new CloudsEffect();
private PropertyCollection cloudsProps;
// Setup for using Desaturate pixel op
private UnaryPixelOps.Desaturate desaturateOp = new UnaryPixelOps.Desaturate();
// Setup for using various blend ops
private UserBlendOps.OverlayBlendOp overlayOp = new UserBlendOps.OverlayBlendOp();
private UserBlendOp normalOp = new UserBlendOps.NormalBlendOp(); // Blend Mode
unsafe void Render(Surface dst, Surface src, Rectangle rect)
{
// Call the Render Clouds function
cloudsEffect.Render(new Rectangle[1] { rect }, 0, 1);
// Now in the main render loop, the dst canvas has a render of clouds
for (int y = rect.Top; y < rect.Bottom; y++)
{
ColorBgra* srcPtr = src.GetPointAddressUnchecked(rect.Left, y);
ColorBgra* dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
for (int x = rect.Left; x < rect.Right; x++)
{
ColorBgra CurrentPixel = *srcPtr;
// Make the source layer black and white
CurrentPixel = desaturateOp.Apply(CurrentPixel);
// Mix it with the clouds layer to create flames
CurrentPixel = overlayOp.Apply(CurrentPixel, *dstPtr);
// Now, make the curves adjustment to give the flames color
if (!Amount4)
{
CurrentPixel.G = Utility.ClampToByte((CurrentPixel.G - 140) * 2.2173);
CurrentPixel.B = Utility.ClampToByte((CurrentPixel.G - 204) * 5);
}
*dstPtr = CurrentPixel;
srcPtr++;
dstPtr++;
}
}
}
}
}
Note: This is NOT a CodeLab script. VS 2005+ is required to compile.
Enjoy.





















