# Draw on top of shader?

**URL:** <https://discourse.processing.org/t/draw-on-top-of-shader/20764>\
**Category:** Coding Questions\
**Created:** [May 11, 2020, 11:34pm UTC](https://discourse.processing.org/t/draw-on-top-of-shader/20764 "2020-05-11T23:34:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![toom](https://avatars.discourse-cdn.com/v4/letter/t/919ad9/32.png) [@toom](https://discourse.processing.org/u/toom)\
**Post date:** [May 11, 2020, 11:34pm UTC](https://discourse.processing.org/t/draw-on-top-of-shader/20764/1 "2020-05-11T23:34:04Z")

</div>

Hi there, how can I draw text or a primitive shape on top of a shader? resetShader() doesn’t appear to do anything. Every shape drawn after the shader is started is somehow under the shader.

I’m capturing video from the webcam, applying effects with a shader, and want to put text and shapes on top of the result.

```auto

let testCapture;
let stream;

function setup() {

  createCanvas(640, 480, WEBGL);

  //capture from webcam
  testCapture = createCapture(VIDEO);
  testCapture.size(640, 480);
  //hide raw capture video to be replaced with shader below
  testCapture.hide();

  //for capturing and recording the whole canvas later
  canvas = document.querySelector('canvas');
  stream = canvas.captureStream(); 
  console.log('Started stream capture from canvas element: ', stream);

}

function draw() {
  background(200);

  shader(theShader);

  theShader.setUniform('tex0', testCapture);
  theShader.setUniform('resolution', [640, 480]);

  rect(0,0,1,1);

  resetShader();

  fill(0,0,255);
  stroke(0,255,0);
  rect(0,0,10,10);
  //no rectangle visible, only the shader
}

```

If you comment out

```auto
rect(0,0,1,1);

```

which is the moment the shader is “applied”, the subsequent rectangle is visible underneath.

So how can it be drawn on top of the shader instead?

---

<div class="post-metadata">

**Author:** ![Sven](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sven/32/8293_2.png) [@Sven](https://discourse.processing.org/u/Sven)\
**Post date:** [May 12, 2020, 7:21am UTC](https://discourse.processing.org/t/draw-on-top-of-shader/20764/2 "2020-05-12T07:21:39Z")

</div>

Hello @toom,

It sounds like you want something similar to layers in an image editing software, right? Do the shader magic in one layer and, in another layer on top of that, draw text and other shapes. I can think of at least a couple of ways to accomplish that. p5.js is just HTML, CSS, and JavaScript, after all, so you could stack multiple canvases on top of each other. You could stack any elements, really, like position a `<p>Hello World!</p>`element on top of your canvas.

Another approach is to render the result of the shader to an off-screen graphics buffer, using `createGraphics`, and then combine that with text and other shapes on your canvas.

I tweaked the [Basic Shader example](https://p5js.org/examples/3d-basic-shader.html) a bit to illustrate this:

```javascript
// this variable will hold our shader object
let theShader;
// this variable will hold our createGraphics layer
let shaderGraphics;

function preload() {
  // load the shader
  theShader = loadShader('assets/basic.vert', 'assets/basic.frag');
}

function setup() {
  createCanvas(710, 400);

  fill('white');
  textAlign(CENTER)
  textSize(36);

  // shaders require WEBGL mode to work
  shaderGraphics = createGraphics(710, 400, WEBGL);
  shaderGraphics.noStroke();
}

function draw() {
  // shader() sets the active shader with our shader
  shaderGraphics.shader(theShader);
  // rect gives us some geometry on the screen
  shaderGraphics.rect(0, 0, width, height);

  image(shaderGraphics, 0, 0, width, height);
  text('Hello World!', width / 2, height / 2)
}

```

 ![Hello World! written in large text on top of a gradient.](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/b/b3a50b9c8af2145bc63262514f8389e9fcce874d.png)

---

<div class="post-metadata">

**Author:** ![toom](https://avatars.discourse-cdn.com/v4/letter/t/919ad9/32.png) [@toom](https://discourse.processing.org/u/toom)\
**Post date:** [May 12, 2020, 6:20pm UTC](https://discourse.processing.org/t/draw-on-top-of-shader/20764/3 "2020-05-12T18:20:35Z")

</div>

Ahhhh thank you! This works. It seems very counter-intuitive that you can’t call resetShader() and continue drawing things, but I am very glad for the solution. 😄

---

<div class="post-metadata">

**Author:** ![JulesFouchy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/julesfouchy/32/9246_2.png) [@JulesFouchy](https://discourse.processing.org/u/JulesFouchy)\
**Post date:** [May 18, 2020, 1:07am UTC](https://discourse.processing.org/t/draw-on-top-of-shader/20764/4 "2020-05-18T01:07:59Z")

</div>

Hello there ! I’ve just run into the same issue. Interestingly enough, the following Processing code works just fine

```auto
PShader myShader;

void setup() {
  size(800, 800, P2D);
  myShader = loadShader("myShader.frag"); 
}

void draw() {
  shader(myShader);
  rect(0, 0, width, height);
  resetShader();
  rect(0, 0, 200, 200);
}

```

 ![Processing](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/7/772d10955c87d879842f4ef6cbdfb966045ad1fc.png)  
While the equivalent p5 code fails

```auto
let myShader;

function preload() {
  myShader = loadShader('myShader.vert', 'myShader.frag');
}

function setup() {
  createCanvas(800, 800, WEBGL);
}

function draw() {
  shader(myShader);
  rect(0, 0, width, height);
  resetShader();
  rect(0, 0, 200, 200);
}

```

[https://editor.p5js.org/JulesFouchy/sketches/qVKIHqkdD](https://editor.p5js.org/JulesFouchy/sketches/qVKIHqkdD)

So either I missed something in the p5 API, or this is a bug 😕

---

<div class="post-metadata">

**Author:** ![Sven](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sven/32/8293_2.png) [@Sven](https://discourse.processing.org/u/Sven)\
**Post date:** [May 18, 2020, 6:57am UTC](https://discourse.processing.org/t/draw-on-top-of-shader/20764/5 "2020-05-18T06:57:47Z")

</div>

Hey @JulesFouchy,

Nice digging! It may well be a bug (I don’t know what the intended behavior is) and if you suspect so you should definitely open an issue in the GitHub repository:

> **[processing/p5.js](https://github.com/processing/p5.js/issues)**
>
> p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Proces...

---

<div class="post-metadata">

**Author:** ![JulesFouchy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/julesfouchy/32/9246_2.png) [@JulesFouchy](https://discourse.processing.org/u/JulesFouchy)\
**Post date:** [May 18, 2020, 12:08pm UTC](https://discourse.processing.org/t/draw-on-top-of-shader/20764/6 "2020-05-18T12:08:32Z")

</div>

Hello again !  
After some more digging, I think I understand a little better what’s going on 🙂  
Because we are using WEBGL mode, everything is 3D (unlike in Processing where there is both P2D and P3D modes that are compatible with shaders).  
Therefore, deciding what is on top of what depends on the z (depth) value, and not on the order of drawing anymore !  
If you want to recover the default behavior, you can disable the glDepthTest with these two lines after createCanvas :

```auto
const gl = canvas.getContext('webgl')
gl.disable(gl.DEPTH_TEST)

```

Here is a simple example : [https://editor.p5js.org/JulesFouchy/sketches/beiJNt342](https://editor.p5js.org/JulesFouchy/sketches/beiJNt342)

Hope this helps !
