Text outline neon

Hi all,

I am trying to play a little with lettering, outline and lights and I am trying to simulate some neon letters that can light up and appear to glow.
I used the blur filter to achieve the glow effect. However, the frame rate decreases considerably when I use the filter. Is there anyway around this?
This is what I have done so far:

boolean on = true;
PGraphics pg;
void setup() {
  size(400, 400, P3D);

}
void draw() {
  background(240); 
  println(frameRate);
  
  color outglow = on ? color(255, 0, 0) : color(150);
  fill(outglow);
  int p = 50;
  textFont(createFont("Comic Sans MS", 30));
  for (int x = -2; x < 2; x++) {
    text("LIKE THIS A!", p+x, p);
    text("LIKE THIS A!", p, p+x);
  }
  int blurAmount = on ? 4 : 2;
  filter(BLUR, blurAmount);

  color inLight = on ? color(255) : color(200);
  fill(inLight);
  text("LIKE THIS A!", p, p);
}

void keyPressed() {
  on = !on;
  println("ON = " + on);
}

Thanks in advance! :slight_smile:

@PhySan Hi, have a look at the examples in menu, its under topics, shaders, blur, its a far more efficient blurring shader than the default blur filter

Hi @PhySan ,

First start by using P2D and move this to setup

textFont(createFont("Comic Sans MS", 30));

Maybe it would be better to use a shader for that which processing example could be found under File → examples on topic shader.

Cheers
— mnse

In the example file, youll have to goto the sketch folder and grab the file blur.glsl and paste that into your sketch folder in order for the filter to work otherwise you’ll get an error when trying to load the shader

2 Likes

Try this code with Thomas Diewald’s PixelFlow library. This is the best Processing library for this kind of task:

import com.thomasdiewald.pixelflow.java.DwPixelFlow;
import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;

DwPixelFlow context;
DwFilter filter;

PGraphics2D pg_a, pg_b; // just another buffer for temporary results

void setup() {
    size(900, 600, P2D);

    context = new DwPixelFlow(this);
    filter = DwFilter.get(context);

    pg_a = (PGraphics2D) createGraphics(width, height, P2D);
    pg_b = (PGraphics2D) createGraphics(width, height, P2D);
    
    pg_a.beginDraw();
    pg_a.textSize(150);
    pg_a.textAlign(CENTER, TOP);
    pg_a.endDraw();
}

void draw() {
    pg_a.beginDraw();
    {
        pg_a.background(0);
        pg_a.fill(0, 255, 255);
        pg_a.text("hello", width/2, 150);
        pg_a.fill(255, 255, 0);
        pg_a.text("world", width/2, 300);
    }
    pg_a.endDraw();

    pg_b.beginDraw();
    pg_b.clear();
    pg_b.endDraw();

    float val = oscillate(5, 10, frameCount * 0.01);
    filter.bloom.param.mult = val;//map(mouseX, 0, width, 0, 10);
    filter.bloom.param.radius = 1; //map(mouseY, 0, height, 0, 1);

    filter.luminance_threshold.param.threshold = 0.3f;
    filter.luminance_threshold.param.exponent = 10;

    filter.luminance_threshold.apply(pg_a, pg_b);
    filter.bloom.apply(pg_b, pg_b, pg_a);

    image(pg_a, 0, 0);
    surface.setTitle("FPS: " + (int)frameRate);
}

float oscillate(float mean, float range, float step) {
    return (float)(Math.cos(step) * range/2 + mean);
}

You can download this library in the Contributions Manager.
ezgif.com-gif-maker

3 Likes

Still some tweaking to do and clean up, I like the final effect :slight_smile:

import com.thomasdiewald.pixelflow.java.DwPixelFlow;
import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwFilter;

DwPixelFlow context;
DwFilter filter;

PGraphics2D pg_a, pg_b; // just another buffer for temporary results

float val = 0;
float range = 10;
float mean = 5;

boolean on = false;
PFont font;
String txt = "HELLO";
void setup() {
  size(200, 200, P2D);
  
  font = createFont("Comic Sans MS", 40);

  context = new DwPixelFlow(this);
  filter = DwFilter.get(context);

  pg_a = (PGraphics2D) createGraphics(width, height, P2D);
  pg_b = (PGraphics2D) createGraphics(width, height, P2D);

  pg_a.beginDraw();
  pg_a.textFont(font);
  pg_a.textAlign(CENTER, TOP);
  pg_a.endDraw();
}

void draw() {
  background(0);
  pg_a.beginDraw();
  {
    pg_a.background(0);
    pg_a.fill(0, 255, 255);
    pg_a.text(txt, width/2, height/2);
    //pg_a.fill(255, 255, 0);
    //pg_a.text("world", width/2, 300);
  }
  pg_a.endDraw();

  pg_b.beginDraw();
  pg_b.clear();
  pg_b.endDraw();

  if (on) {
    if (val < 2) {
      val += 0.04;
      //val = oscillate(mean, range, step);
    }

    filter.bloom.param.mult = val;//map(mouseX, 0, width, 0, 10);
    filter.bloom.param.radius = 1; //map(mouseY, 0, height, 0, 1);

    filter.luminance_threshold.param.threshold = 0.3f;
    filter.luminance_threshold.param.exponent = 10;

    filter.luminance_threshold.apply(pg_a, pg_b);
    filter.bloom.apply(pg_b, pg_b, pg_a);

    image(pg_a, 0, 0);
    
    
    textFont(font);
    textAlign(CENTER, TOP);
    fill(255, val * 128);
    text(txt, width/2, height/2);
    
  
  }

  
  surface.setTitle("FPS: " + (int)frameRate);
}

float oscillate(float mean, float range, float step) {
 return (float)(Math.cos(step) * range/2 + mean);
}

void keyPressed() {
  on = !on;
  if (!on) val = 0;
}
1 Like