How can I get Half Blur effect?

Hello, everyone.

I want to ask how can I get an effect called “Depth of Filed” with Processing.

What I mean saying “Depth of Field” shown below:

I appreciate every help, thanks !

You could try the blur() function for this. For example:

text("hello", 10, 10); // most blur
filter(BLUR);
text("hello", 10, 30); // medium blur
filter(BLUR);
text("hello", 10, 50); // no blur

I’m not sure how important the noise is? Is there some rolling/barrel effect? If so, you can add animation that responds to the mouseY value.

void setup() {
  size(400, 50);
  textSize(40);
}

void draw() {
  background(0);
  fill(255); 
  text("HELLO", 10, 40); 
  filter(BLUR, mouseX/60);
}

@noel @tabreturn Hi, Thank you for your reply.

I write this code:

void setup() {
  fullScreen(P3D);
  textAlign(CENTER, CENTER);
  textSize(200);
}

void draw() {
  background(0);
 
  for(int i = 0; i < 360; i += 24) {

    text("NOISE", width/2, height/2 - sin(radians(frameCount - i)) * 700,  -cos(radians(frameCount - i)) * 700);
    //filter(BLUR);
  }
}

But I have two issues.

  1. I can’t get that BLUR effect.
  2. When they are scrolling, some of the text’s back filled with black rectangle.

How can I solve these ?

Love the sketch!
But Blur is really slow, so I would use a PGraphics.
Just a simple example to which you maybe could apply your math magic.

PGraphics pg;
float y, z, t;

void setup() {
  size(1200, 800, P3D);
  background(0); 
  pg = createGraphics(650, 170);
  pg.beginDraw();
  pg.textSize(200);
  pg.text("NOISE", 10, 150);
  pg.filter(BLUR);
  pg.filter(BLUR);
  pg.endDraw();
}

void draw() {
  background(0); 
  t += .009;
  z += 2*sin(t);
  y += 2*sin(t);
  translate(300, y, z);
  image(pg, 0, 0);
}

Edit: Oh, just now I saw the image above. You want a heavy blur in the background.
I would try it with multiple PGraphics then, each with a stronger blur.
Because I don’t see a way for an easy dynamic blur.

1 Like

I have an idea that may work.
In your loop you use, let’s say, five times the text, but each with slightly bigger text sizes.
For each of these texts you also give an increasing white transparency. This will give a blur effect.
Then you place these transparent layers in an if block to just show them at a further z value.

@noel Sorry, I didn’t really understand. How to give them white transparency ?

It didn’t increase the size as I expected. In the center the blur effect is less.

void setup() {
  size(800, 300);
  //size(750, 300, P3D);
  background(0);
  textSize(200);
  text("NOISE", 100, 230);
  int transparency = 200;
  int x = 100;
  int y = 230;
  for(int i = 200; i < 250; i += 5) {
    textSize(i);
    fill(255, transparency);
    transparency -= 15;
    text("NOISE", x, y);
    x -= 7;
    y += 2;
  }
}

@noel Thank you for your trying, but it is not what I wanted. But I learned how to good effects, Thanks !

I started to test my first suggestion because it is far simpler to give a nice blur on a prepared pgraphics.
But soon I encountered the same transparency problem as you had. One of the pgraphic’s isn’t transparent.
Could that be a bug?

PGraphics pg1, pg2;
float ang1, ang2, x, z1, y1, z2, y2, d = 150;

void setup() {
  size(380, 450, P3D);
  background(0); 
 
  pg1 = createGraphics(300, 60);
  pg1.beginDraw();
  pg1.textSize(55);
  pg1.text("N.O.I.S.E", 50, 45);
  pg1.endDraw();

  pg2 = createGraphics(300, 60);
  pg2.beginDraw();
  pg2.textSize(55);
  pg2.text("N.O.I.S.E", 50, 45);
  pg2.endDraw();
  ang2 = PI/2;
}

void draw() {
  background(0);  
  z1 = d*sin(ang1);
  y1 = d*cos(ang1)+200;
  ang1 += .03;
  z2 = d*sin(ang2);
  y2 = d*cos(ang2)+200;
  ang2 += .03;
  if (ang1 > TWO_PI)ang1 = 0;
  if (ang2 > TWO_PI)ang2 = 0;
  push();
  translate(30, y1, z1);
  image(pg1, 0, 0);
  pop();
  translate(30, y2, z2);
  image(pg2, 0, 0);
}

crop1 crop2

1 Like

I posted to fast. I forgot about it. You need to use hint(DISABLE_DEPTH_MASK); in setup();

@noel Thank you man ! You solved my second problem ! I appreciate it !

In this code java and JS, a part of the ‘cylinder’ gets a slightly transparent text, and I can’t figure out why. Any idea?

PGraphics pg, pgb1, pgb2;
float ang, a, dy = 170, dz = 100, y, z;
PFont fnt;

void setup() {
  size(380, 450, P3D);
  background(0); 
  fnt = createFont("Bulette-Bold.ttf", 100);

  pg = createGraphics(300, 60);
  pg.beginDraw();
  pg.textFont(fnt, 100);
  pg.textSize(35);
  pg.text("N.O.I.S.E", 90, 40);
  pg.endDraw();

  pgb1 = createGraphics(300, 60);
  pgb1.beginDraw();
  pgb1.textFont(fnt, 100);
  pgb1.textSize(35);
  pgb1.text("N.O.I.S.E", 90, 40);
  pgb1.filter(BLUR, 4);
  pgb1.endDraw();

  pgb2 = createGraphics(300, 60);
  pgb2.beginDraw();
  pgb2.textFont(fnt, 100);
  pgb2.textSize(35);
  pgb2.text("N.O.I.S.E", 90, 40);
  pgb2.filter(BLUR, 7);
  pgb2.endDraw();

  hint(DISABLE_DEPTH_MASK);
  frameRate(25);
}

void draw() {
  background(0);  
  ang += .03; 
  if (ang > TWO_PI) ang = 0;
  for (a = 0; a < TWO_PI; a += TWO_PI/16) {
    y = dy*cos(ang+a)+200;
    z = dz*sin(ang+a);
    push();
    translate(25, y, z);
    if (z < -1 && z < -25) image(pgb1, 0, 0);
    else if (z < -25 && z < -40) image(pgb2, 0, 0);
    else image(pg, 0, 0);
    pop();
  }
}

If we create graphics everytime in draw with controlling their blur effect, will it be so slow ?

You’d probably be better creating the graphics once with the unblurred text, then using a shader to blur it as you draw - something along the lines of the BlurFilter and SepBlur examples in Topics / Shaders (or at https://github.com/processing/processing-docs/tree/master/content/examples/Topics/Shaders ). Separate blur will require a second scratch graphics (make sure to create it the same size and also as P2D, with both big enough to contain the blur, and it should do for this).

1 Like

I’ve done some tests now. One with the filter(BLUR,i) and one manipulating the pixels in the pixel array. It’s just too time-consuming to be used in draw(), and the processor gets over charged with this.

Yes, absolutely, when you want to blur fast in draw() dynamically, shaders are the way to go, but you still need pgraphics otherwise you will blur the whole canvas. You can use the blur shaders from the ide examples, or find others on the forum which are all adaptions from code on this blog. (there are other nice examples there). Anyway, if you want to try here is a basic example of blurring in draw().

  • blur.glsl
 #ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
 
#define PROCESSING_TEXTURE_SHADER
 
 
uniform sampler2D texture;
 
uniform vec4 o=vec4(0, 0, 0, 0); 
uniform lowp mat4 colorMatrix = mat4(1, 0.0, 0.0, 0.0, 
                                     0.0, 1, 0.0, 0.0, 
                                     0.0, 0.0, 1, 0.0, 
                                     0, 0.0, 0.0, 60.0); //Alpha contrast set to 60
 
 
varying vec2 center;
 
// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;
 
varying vec4 vertColor;
varying vec4 vertTexCoord;
 
uniform int blurSize;       
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma;        // The sigma value for the gaussian function: higher value means more blur
                            // A good value for 9x9 is around 3 to 5
                            // A good value for 7x7 is around 2.5 to 4
                            // A good value for 5x5 is around 2 to 3.5
                            // ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>
 
const float pi = 3.14159265;
 
void main() {  
  float numBlurPixelsPerSide = float(blurSize / 2); 
 
  vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
 
  // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
  vec3 incrementalGaussian;
  incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
 
  vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
  float coefficientSum = 0.0;
 
  // Take the central sample first...
  avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
  coefficientSum += incrementalGaussian.x;
  incrementalGaussian.xy *= incrementalGaussian.yz;
 
  // Go through the remaining 8 vertical samples (4 on each side of the center)
  for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { 
    avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * 
                          blurMultiplyVec) * incrementalGaussian.x;         
    coefficientSum += 2.0 * incrementalGaussian.x;
    incrementalGaussian.xy *= incrementalGaussian.yz;
  }
  gl_FragColor = (avgValue / coefficientSum )  * colorMatrix;
}
  • blur.pde
PShader blur;
PGraphics pg;
PFont fnt;

void setup() {
  size(380, 450, P3D);
  background(0); 
  imageMode(CENTER);
  pg = createGraphics(width, height, P2D);
  blur = loadShader("blur.glsl");
  blur.set("sigma", 5.0);
  blur.set("blurSize", 39);
  textSize(90);
}

void draw() {
  background(0);
  pg.beginDraw();
  pg.background(0, 0); 
  pg.noStroke();
  pg.fill(255);
  pg.textSize(90);
  pg.text("N.O.I.S.E", mouseX-width/2, mouseY);
  blur.set("horizontalPass", 1);
  pg.filter(blur);
  pg.endDraw();
  image(pg, width/2, height/2);
}

I am not sure about this, because even when you rotate with plain text, and just fill the 'background (negative z) with gray text color, you will find the same I had mentioned above. See here that when the cylinder rotates from 0 to PI, the background text is drawn in front of the white text.

noise1

Image 3

The solution I found is to draw just a part (PI/6) of the rotation, in a loop that gives the illusion that the cylinder fully rotates. Below the sketch with just two pgraphics. The next step is to give a more glow-like blur in multiple stages, like in the first image you posted.

1 Like