Make Thing Glowing!

To glow thing, you can do various ways. this time, i will show you how to glow thing by manipulating Pixels and using Texture (PImage).

  1. Using loadPixels and updatePixels (Slow but best)
    by calculating distance between the source and pixel, we can determine how bright the spread at that pixel.
    we updating pixels in given boundary. bigger boundary, nice looking glowing, but costs computing power, slows down frame updating.

these simple codes determine how far any given pixel to the center of the source

//bright multiplier
const multiplier = 100;

//calculating the distance using euclidean formula
dx = centerX - x;
dy = centerY - y;
d = sqrt(sq(dx) + sq(dy));

// convert to brightness
col = 1/d * multiplier; 

to prevent current pixels color overwritten, we can use lerpColor() function
meaning, if there is an object behind it, it will be overlapped

Method 1:

// updating the pixels from the center source to the circle edges
//
// Pros
// Circle boundary
// Stable Pixels Update
//
// Cons
// Step-like bright radials
// Rough spreads

void glow(PVector gPos, float gSize, float spread, color spreadColor) {
  loadPixels();
  float distance = gSize;
  float rot = 0;
  while (rot < TWO_PI) { // spin the starting pixel draw by full rotation (360 degree = Two Pi)
    for (int len = 0; len < distance; len++) { //update pixels from center toward the current angle*boundary radius
      int x = floor(cos(rot) * len + gPos.x);
      int y = floor(sin(rot) * len + gPos.y);
      int index = x + y * width;
      float dx = gPos.x - x;
      float dy = gPos.y - y;
      float d = sqrt(sq(dx) + sq(dy));
      float col = spread/d;
      
     // drawing at the edges of the window? here is the solution
      if (index < height * width && index > 0)
        // update pixel
        pixels[index] = lerpColor(pixels[index], spreadColor, sq(col));
    }
   // next starting angle
    rot += 0.01;
  }
  updatePixels();
}

Method 2

// updating the pixels from circle edges to another circle edges
//
// Pros
// Circle boundary
// Smooth Spread
//
// Cons
// Unstable Spread
// Changing distance leads to spread interference
// minor spread error 

void glow(PVector gPos, float gSize, float spread, color spreadColor) {
loadPixels();
 float k = 0;
  float distance = 100// = gSize;
  while (k < HALF_PI) { //
    int yPlus = floor(sin(TWO_PI-k) * distance + gPos.y); // for top part glows
    int yMinus = floor(sin(PI-(k+0.01)) * distance + gPos.y); // for bottom part glows
    float aStart = PI+k; // starting angle
    float aEnd = TWO_PI - k; // ending angle
    int xStart = round(cos(aStart) * distance + gPos.x); // starting point.x 
    int xEnd  = round(cos(aEnd) * distance + gPos.x); // ending point x
    for (int i = xStart; i < xEnd; i++) { 
      float dx = gPos.x - i;
      float dy = gPos.y - yPlus;
      float d = sqrt(sq(dx) + sq(dy));
      float col = 1/d * spread;
     
     //draw the top part
      int index = i + yMinus * width;
      if (index < height * width && index > 0)
        pixels[index] = lerpColor(pixels[index], spreadColor, sq(col));
     
     //draw the bottom part
      index = i + yPlus * width;
      if (index < height * width && index > 0)
        pixels[index] = lerpColor(pixels[index], spreadColor, sq(col));
    }
    k += 0.01;
  }
  updatePixels();
}

Method 3

// updating pixels in given Rectangle boundary
//
// Pros
// Stable Spread
// Smooth Spread
//
// Cons
// Rectangle boundary leads to bounded-like spread if boundary not quite big

void glow(PVector gPos, float gSize, float spread, color spreadColor) {
  loadPixels();
  for (int x = int(gPos.x-gSize); x < int(gPos.x + gSize); x++) {
    for (int y = int(gPos.y-gSize); y < int(gPos.y+gSize); y++) { 
      int index = x + y * width;
      float dx = gPos.x - x;
      float dy = gPos.y - y;
      float d = sqrt(sq(dx) + sq(dy));
      float col = 1/d * spread;
      if (index < height * width && index > 0)
        pixels[index] = lerpColor(pixels[index], spreadColor, sq(col));
    }
  }
  updatePixels();
}
  1. Using texture (Fast but Fake)
    by applying glowing texture, we can get instant result!

fast!

but

it is fake.

PImage img;
void setup(){
     img = loadImage("texture.png"); //your glowing texture
     size(640, 480, P2D);
}

void draw(){
    blendMode(ADD);
    glow(50, 100);
}

void glow(float x, float y) {
    imageMode(CENTER);
    image(img,x,y);
  }

edit: adding image
22028

btw, i have that in video:

bit.ly/2FZQRDY
:stuck_out_tongue:

Anyone can help me improve my dirty Code!
Thank you!

3 Likes

you should post examples for those of us (me) who are too lazy to run the code.

edit: it does seem like it’s just a gradient though. another good cheat for glow is to draw the object multiple times with increasing alpha at decreasing sizes.\ :stuck_out_tongue:

1 Like

wow, i have learned a new way:smiley:
thank you!

1 Like