# Using stencils in P2D / P3D

**URL:** <https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207>\
**Category:** Gallery\
**Created:** [August 6, 2019, 8:38am UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207 "2019-08-06T08:38:01Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [August 6, 2019, 8:38am UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/1 "2019-08-06T08:38:01Z")

</div>

I asked Andres Colubri if he could help me out with getting stencils to work in processing.  
Here it is, and it’s freaking awesome.

 ![12](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/dc08535eac6b0b6698a835f978502006eee62a39.png)

```auto
// Adapted from https://learnopengl.com/Advanced-OpenGL/Stencil-testing
void setup() {
  size(600, 600, P3D);
  noStroke();
}

void draw() {
  PGL pgl = beginPGL();

  pgl.enable(PGL.STENCIL_TEST);
  pgl.stencilOp(PGL.KEEP, PGL.KEEP, PGL.REPLACE); 

  background(100);
  lights();
  
  pgl.stencilMask(0);   
  fill(128);
  drawFloor();
  flush();

  pgl.stencilFunc(PGL.ALWAYS, 1, 255); 
  pgl.stencilMask(255);
  drawBox(1);
  flush(); // Flush the geometry drawn until now to the GPU 

  pgl.stencilFunc(PGL.NOTEQUAL, 1, 255);
  pgl.stencilMask(0);
  pgl.disable(PGL.DEPTH_TEST);
  
  noLights(); // Disable lights because the outline does not have lighting
  fill(255,0,0);
  drawBox(1.1);

  pgl.stencilMask(255);
  pgl.enable(PGL.DEPTH_TEST);   

  endPGL();
}

void drawBox(float scalef) {
  pushMatrix();
  translate(width/2, height/2);
  rotateX(0.01 * frameCount);
  rotateY(0.01 * frameCount);
  scale(scalef);
  box(180);
  popMatrix();
}

void drawFloor() {
  pushMatrix();
  translate(width/2, 0.8 * height);
  scale(1, 0.1, 1);
  box(300);
  popMatrix();
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [August 6, 2019, 11:50am UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/2 "2019-08-06T11:50:31Z")

</div>

> [@clankill3r](#):
>
> stencils

What’s this please? Can you elaborate?

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [August 9, 2019, 11:26pm UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/3 "2019-08-09T23:26:34Z")

</div>

> [@clankill3r](#):
>
> single\_color.glsl

Could you please share single\_color.glsl ?

---

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [August 17, 2019, 3:56pm UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/4 "2019-08-17T15:56:48Z")

</div>

The shader was in the first post, but I changed it so a shader is not needed anymore.  
Stencils can be used to discard fragments (pixels). In the above example the outline is drawn after the box is drawn and not the other way around. I need to use stencils for clipping cause the opengl scissor does not work under an angle.

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [August 17, 2019, 4:04pm UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/5 "2019-08-17T16:04:08Z")

</div>

> [@clankill3r](#):
>
> I changed it so a shader is not needed anymore

I don’t get it. Your code says `sh = loadShader("single_color.glsl");` but you don’t provide a link to a glsl file, or the contents of that file. If you don’t need it, why are you loading it? If you do need it, can you share it?

---

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [August 17, 2019, 4:05pm UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/6 "2019-08-17T16:05:34Z")

</div>

I forgot to remove that line.

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [August 17, 2019, 4:39pm UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/7 "2019-08-17T16:39:37Z")

</div>

Thanks for sharing this! Cool visual effect.

I have never used beginPGL / endPGL in a sketch before – it took me a while to figure out how the sketch builds the scene in three stages (the platform, the box, and the unlit scaled red box to appear “behind” it). Particularly interesting that the outline effect is a 3D object that then aligns correctly through compositing.

If I was diving deeper into this stuff, I would probably begin reading here…

- [https://github.com/processing/processing/wiki/Advanced-OpenGL](https://github.com/processing/processing/wiki/Advanced-OpenGL)
- [https://github.com/processing/processing/wiki/Advanced-OpenGL-in-Processing-2.x](https://github.com/processing/processing/wiki/Advanced-OpenGL-in-Processing-2.x)
- [https://processing.org/tutorials/pshader/](https://processing.org/tutorials/pshader/)

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [August 17, 2019, 4:46pm UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/8 "2019-08-17T16:46:45Z")

</div>

> [@OpenGL processing shader sheet](https://discourse.processing.org/t/opengl-processing-shader-sheet/13432):
>
> I made a google docs about what variables are used in what shader. It might be usefull to someone some day.

Chrisir

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [August 18, 2019, 7:59pm UTC](https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/9 "2019-08-18T19:59:05Z")

</div>

For my own understanding I created an annotated version of this that lets you scale the box and outline interactively using mouseX / mouseY.

The outline is impressive – although the illusion breaks a bit if they both cross too far into the platform and you start seeing them double-intersecting.

```auto
// Adapted from https://learnopengl.com/Advanced-OpenGL/Stencil-testing
// https://discourse.processing.org/t/using-stencils-in-p2d-p3d/13207/7

PGL pgl;
void setup() {
  size(600, 600, P3D);
  noStroke();
}

void draw() {
  background(100);
  lights();
  fill(128);
  
  float boxScaleX = 2*mouseX/(float)width;
  float boxScaleY = boxScaleX - 0.1 + mouseY/(float)height;
  
  // setup
  pgl = beginPGL();
  pgl.enable(PGL.STENCIL_TEST);
  
  // draw floor
  pgl.stencilOp(PGL.KEEP, PGL.KEEP, PGL.REPLACE); 
  pgl.stencilMask(0);   
  drawFloor();
  flush();

  // draw box
  pgl.stencilFunc(PGL.ALWAYS, 1, 255); 
  pgl.stencilMask(255);
  drawBox(boxScaleX);
  flush(); // Flush the geometry drawn until now to the GPU 

  // draw box stencil outline
  pgl.stencilFunc(PGL.NOTEQUAL, 1, 255);
  pgl.stencilMask(0);
  pgl.disable(PGL.DEPTH_TEST);
  noLights(); // Disable lights because the outline does not have lighting
  fill(255, 0, 0);
  drawBox(boxScaleY);

  // teardown
  pgl.stencilMask(255);
  pgl.enable(PGL.DEPTH_TEST);   
  flush();
  endPGL();
}

void drawBox(float scalef) {
  pushMatrix();
  translate(width/2, height/2);
  rotateX(0.01 * frameCount);
  rotateY(0.01 * frameCount);
  scale(scalef);
  box(180);
  popMatrix();
}

void drawFloor() {
  pushMatrix();
  translate(width/2, 0.8 * height);
  scale(1, 0.1, 1);
  box(300);
  popMatrix();
}

```

I’m curious what the difference is between stencilOp and stencilFunc.
