# Paint an image with transparency on a quad via a fragment shader

**URL:** <https://discourse.processing.org/t/paint-an-image-with-transparency-on-a-quad-via-a-fragment-shader/34189>\
**Category:** p5.js\
**Created:** [December 18, 2021, 11:20pm UTC](https://discourse.processing.org/t/paint-an-image-with-transparency-on-a-quad-via-a-fragment-shader/34189 "2021-12-18T23:20:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![stewart](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/stewart/32/15269_2.png) [@stewart](https://discourse.processing.org/u/stewart)\
**Post date:** [December 18, 2021, 11:20pm UTC](https://discourse.processing.org/t/paint-an-image-with-transparency-on-a-quad-via-a-fragment-shader/34189/1 "2021-12-18T23:20:58Z")

</div>

Hi I would appreciate help implementing this feature for an art project I’m working on. Functionally it would be similar to a p5.Image filter() but using my own fragment shader instead of the built in filters.

So what I have is a “sprite sheet” image, which is multiple images packed into a larger image.  
I want to draw a subsection of the sprite sheet image and run it through a fragment shader so I can modify the colors on the fly. That means I need to set the texture uv components.

shader.vert:

```auto
attribute vec3 aPosition;
attribute vec2 aTexCoord;

varying vec2 vTexCoord;

void main() {
    vTexCoord = aTexCoord;
    vec4 positionVec4 = vec4(aPosition, 1.0);
    gl_Position = positionVec4;
}

```

shader.frag

```auto
precision mediump float;

// ranges from 0..1
varying vec2 vTexCoord;
uniform sampler2D texture;

void main() {
    vec2 uv = vTexCoord;
    uv = 1.0 - uv;
    vec4 tex = texture2D(texture, uv);
    // just invert the texture color to demonstrate the fragement shader is running
    gl_FragColor = vec4(1.0-tex.rgb, tex.a);
}

```

implementation 1-- the shader is ignored

```auto
p5.shader(shader);
p5.image(image, x+ss.x, y+ss.y, frame.w, frame.h, xOffset, yOffset, frame.w, frame.h);

```

ss and frame and xOffset(s) are values that come from the image location on the larger sprite sheet image.

implementation 2-- shader is ignored.

```auto
p5.shader(shader);
p5.beginShape();
p5.texture(image);
p5.vertex(x+ss.x, y+ss.y, xOffset, yOffset);
p5.vertex(x+ss.x + frame.w, y+ss.y, xOffset+frame.w, yOffset);
p5.vertex(x+ss.x + frame.w, y+ss.y+frame.h, xOffset+frame.w, yOffset+frame.h);
p5.vertex(x+ss.x, y+ss.y+frame.h, xOffset, yOffset+frame.h);
p5.endShape();

```

I have tried other more in depth implementations but none work very well. Any help would be appreciated!

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [December 19, 2021, 12:14am UTC](https://discourse.processing.org/t/paint-an-image-with-transparency-on-a-quad-via-a-fragment-shader/34189/2 "2021-12-19T00:14:56Z")

</div>

Two issues: The first is that there is a bug in p5.js where user defined shaders are never recognized as supporting textures, so the WEBGL renderer falls back to the built in shader; The second is that your shader needs to conform to the completely undocumented conventions for attribute and uniform naming in p5.js and apply some boilerplate transformation matrices to the vertex coordinates.

Fix for issue #1:

```javascript
  shader.samplerIndex = 1;

```

Fix for issue #2:

shader.vert

```auto
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;

attribute vec3 aPosition;
attribute vec2 aTexCoord;

varying vec2 vTexCoord;

void main() {
  vTexCoord = aTexCoord;

  // You need to apply these matrices for your shape to show up in the correct location
  vec4 viewModelPosition = uModelViewMatrix * vec4(aPosition, 1.0);
  gl_Position = uProjectionMatrix * viewModelPosition;
}

```

frag.vert

```auto
precision mediump float;

// ranges from 0..1
varying vec2 vTexCoord;

// Your texture uniform must use this name
uniform sampler2D uSampler;

void main() {
    vec4 tex = texture2D(uSampler, vTexCoord);
    // just invert the texture color to demonstrate the fragement shader is running
    gl_FragColor = vec4(1.0-tex.rgb, tex.a);
}

```

https://openprocessing.org/sketch/1406878/embed/?plusEmbedHash=NjQyOWM3NTk0MjViMWMyZWYzYWYwOTQ2MDM1MTY0NmZkMjc4MWUyZDI0MDdkODljZjJjNDcwYmUxNjA0Y2UwNzg5ZTNlNjFhYjJmODU5NTYyNDdjYzNlZTBjNmQ3NGE0YzJkNGNjMDU5ZDY0ZDQ2ZmRjZjJiNmY1ZWFkYmQwNDBMS0llMWtKZWVoL1VpMVlzYy9PeWlXTHVpTUlSQ2VnT2tFSjgzT2FYa29uL2ZuNTErVU1Eb2F0ZlpiM0Voc3hzTzRmZVQ0akt6RlRKbVZyRGxZUEQ2UT09

Note: I couldn’t make heads or tails of your vertex coordinates, so I just made that part up for my example. The documentation indicates that if you want to specify UV coordinates you need to specify x y and z first (it appeared you were trying `vertex(x, y, u, v)` and I’m not sure if that will work).

---

<div class="post-metadata">

**Author:** ![stewart](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/stewart/32/15269_2.png) [@stewart](https://discourse.processing.org/u/stewart)\
**Post date:** [December 19, 2021, 12:24am UTC](https://discourse.processing.org/t/paint-an-image-with-transparency-on-a-quad-via-a-fragment-shader/34189/3 "2021-12-19T00:24:40Z")

</div>

KumuPaul, thank you very much this is very helpful. I also encountered that bug you described, now I know why the shader was toggled on and off when I comment and uncomment the `texture` call.

This convention ought to be documented! Well thanks for sharing it with me.

The vertex coordinates aren’t important, you understood what I was trying to do perfectly. In `vertex()` documentation is says `vertex(x, y, [z], u, v)` in which the brackets imply that `z` is optional. I’ll try setting the z to zero.

Thanks.

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [December 19, 2021, 12:29am UTC](https://discourse.processing.org/t/paint-an-image-with-transparency-on-a-quad-via-a-fragment-shader/34189/4 "2021-12-19T00:29:38Z")

</div>

Oh, my bad, you’re absolutely right about that `[z]`.

I’ve opened an issue on GitHub regarding the `samplerIndex` issue: [User defined shaders are never used when a texture is specified because isTextureShader always returns false. · Issue #5507 · processing/p5.js · GitHub](https://github.com/processing/p5.js/issues/5507)

I agree about the documentation for custom shaders, it is something I have been meaning to contribute.

---

<div class="post-metadata">

**Author:** ![aferriss](https://avatars.discourse-cdn.com/v4/letter/a/ea5d25/32.png) [@aferriss](https://discourse.processing.org/u/aferriss)\
**Post date:** [December 20, 2021, 2:12am UTC](https://discourse.processing.org/t/paint-an-image-with-transparency-on-a-quad-via-a-fragment-shader/34189/5 "2021-12-20T02:12:00Z")

</div>

I answered [here](https://github.com/processing/p5.js/issues/5507#issuecomment-997531981) but the short answer is that when using the shader() function, you are expected to pass your own uniforms with `.setUniform()`.

So in this case, you could remove the call to `texture()` and add `shdr.setUniform("uSampler", img);` after `shader(shdr);`

---

<div class="post-metadata">

**Author:** ![aferriss](https://avatars.discourse-cdn.com/v4/letter/a/ea5d25/32.png) [@aferriss](https://discourse.processing.org/u/aferriss)\
**Post date:** [December 20, 2021, 2:21am UTC](https://discourse.processing.org/t/paint-an-image-with-transparency-on-a-quad-via-a-fragment-shader/34189/6 "2021-12-20T02:21:12Z")

</div>

Also FWIW, there was an issue where some work had started on documenting the existing uniforms, but it never finished up. I reached out to see if it was still ongoing but I’m unsure of the current status.

> <https://github.com/processing/p5.js-website/issues/1017>
>
> \*\*Actual Behaviour\*\*
> 
> There is currently no documentation on the attributes an…d uniforms that are available when writing shaders in p5. For example, the \`aPosition\` attribute is used in all vertex shader examples, but there is no associated documentation on the Reference page. Similarly, there are a lot of useful attributes and uniforms (such as \`uProjectionMatrix\`), which do not appear in any of the available examples. The only way to learn about them is to dig into the p5 source code.
> 
> \*\*Expected Behaviour\*\*
> 
> Ideally, a list of the available uniforms would be listed in the \[\`setUniform()\` documentation page\]\[0\]. Each listing would have a brief description of what the uniform does. (This would have the added bonus of giving the user a hint as to which uniform names are unavailable for use).
> 
> Similarly, a list of available attributes would be listed. If a \`setAttribute()\` method existed in p5, its documentation page would be the ideal place to list them. However, they can be (together with the default uniforms for consistency) be listed in the \[\`p5.Shader\` documentation page\]\[1\].
> 
> Since a lot of these default attributes and uniforms are used for the \[default shaders\]\[2\], not all are immediately relevant to outside use. Here is a list of the most useful I have been able to identify so far (\[source1\]\[3\], \[source2\]\[4\]):
> 
> \- Attributes
> - aPosition
> - aTexCoord
> - aNormal
> - aMaterialColor (aVertexColor might be a better name)
> \- Uniforms
> - uProjectionMatrix
> - uModelViewMatrix
> - uViewMatrix
> - uNormalMatrix
> 
> Ideally, \[additional examples\]\[5\] (such as this one (\[live\]\[6\], \[src\]\[7\] by aferriss ) would be added to demonstrate the usage of some of these attributes and uniforms.
> 
> \*\*Would you like to work on the issue?\*\*
> 
> Yes
> 
> \[0\]: https://p5js.org/reference/#/p5.Shader/setUniform
> \[1\]: https://p5js.org/reference/#/p5.Shader/
> \[2\]: https://github.com/processing/p5.js/tree/main/src/webgl/shaders
> \[3\]: https://github.com/processing/p5.js/blob/e68179c247ef64b1e056007f0202abf005fb369b/src/webgl/p5.RendererGL.js#L144
> \[4\]: https://github.com/processing/p5.js/blob/e68179c247ef64b1e056007f0202abf005fb369b/src/webgl/p5.Shader.js#L263
> \[5\]: https://p5js.org/examples/
> \[6\]: https://aferriss.github.io/p5jsShaderExamples/6\_3d/6-2\_vertexDisplacement/
> \[7\]: https://github.com/aferriss/p5jsShaderExamples/tree/gh-pages/6\_3d/6-2\_vertexDisplacement
