# Shader as texture for primitive

**URL:** <https://discourse.processing.org/t/shader-as-texture-for-primitive/13680>\
**Category:** Coding Questions\
**Created:** [August 29, 2019, 7:43am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680 "2019-08-29T07:43:16Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![lnp](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lnp/32/4911_2.png) [@lnp](https://discourse.processing.org/u/lnp)\
**Post date:** [August 29, 2019, 7:43am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/1 "2019-08-29T07:43:17Z")

</div>

Is it possible to use a shader as a texture on a 3d primitive? When I invoke shader the effect is to render the sphere as a flat 2d object with the shader as a fill rather than a texture.

I thought I could call texture(myshader) but it appears to demand a PImage.

---

<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 29, 2019, 9:44am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/2 "2019-08-29T09:44:01Z")

</div>

see listing 2.1

in [https://processing.org/tutorials/pshader/](https://processing.org/tutorials/pshader/)

---

<div class="post-metadata">

**Author:** ![lnp](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lnp/32/4911_2.png) [@lnp](https://discourse.processing.org/u/lnp)\
**Post date:** [August 29, 2019, 10:02am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/3 "2019-08-29T10:02:05Z")

</div>

Thanks! That makes a lot of sense.

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [August 29, 2019, 10:07am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/4 "2019-08-29T10:07:24Z")

</div>

If your shader looks like a 2D fill it’s because when the shader calculates the color of a pixel it only takes into account the screen 2D position of each vertex.

If the shader calculations use the x, y and z components of the vertex to calculate the color, then it will no longer be a flat sticker.

Here a [simple example](http://shdr.bkcore.com/#1/hZAxa8MwFIT/ykOTXYzq0HRJyFToVujUpSlBlWVFwdYTkpzaCfnvfXLiUgylk+Du0+lOZ1ah7FplY2Crd+a8kiYYtLA3eu+gblDE9dYehR+M1XBU8gEcCSShqaAVxmY5nLcWrixoLwbYQIjKZSV/LKD2QsbM8R7uYFHyMs/XidbN7tkL/YQNeuIpeJml9CwF5AUsiCTwwoo/S4kYvfnsorrVwmAiUeR01tToW6oXl9BipZo3o75eBPH93HYeD0qmiz/+f3vHuY5aT0/yfjhNq15vWrJn0fQDszKkjMunoF+7Pwo2wmx1PcN96E7CWrVLv8APgV2+AQ==).

A question is then how to use the 3D vertices to calculate a texture in the shader?

ps. To use model space coordinates you will need to call `hint(DISABLE_OPTIMIZED_STROKE)` in your program, otherwise the position attribute is the shader is no longer in model space, and the shader generated texture would not rotate when rotating the object in 3D.

But maybe you wanted a simple example instead of all these details? 🙂

```java
import peasy.PeasyCam;
PeasyCam cam;
PShader fx;

void setup() {
  size(600, 600, P3D);
  cam = new PeasyCam(this, 400);
  fx = loadShader("fx.frag", "fx.vert");
  shader(fx);  
  noStroke();
  hint(DISABLE_OPTIMIZED_STROKE);
}

void draw() {
  background(0);
  sphere(150);
}

```

```auto
// fx.vert
uniform mat4 transformMatrix;
attribute vec4 position;

varying vec3 p;

void main() {
  gl_Position = transformMatrix * position;
    
  p = position.xyz;
}

```

```auto
// fx.frag
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec3 p;

void main() {
  float gray = step(0.5, fract(p.x * 0.05));
  gl_FragColor = vec4(vec3(gray), 1.0);
}

```

Try remove the `hint()`, run the program and rotate the sphere.

---

<div class="post-metadata">

**Author:** ![lnp](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lnp/32/4911_2.png) [@lnp](https://discourse.processing.org/u/lnp)\
**Post date:** [August 29, 2019, 10:19am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/5 "2019-08-29T10:19:46Z")

</div>

Haha… I’d be lying if I didn’t want a simpler way but you know it’s all learning and I’m grateful for the full answers. I kind of expected the 2d shader to be treated like a PImage and just ‘wrap’ the 3d primitive like texture() seems to work.

So as I understand it the .vert file takes the (let’s say 2d shader) and transforms it for 3d space?

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [August 29, 2019, 10:22am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/6 "2019-08-29T10:22:48Z")

</div>

The vert and frag shaders work together. vert runs first, then frag. If you only use the fragment shader, Processing provides a default vertex shader for you. The vertex shaders main goal is to decide where in the screen each vertex should be drawn, depending on translations, rotations and the 3D shape you are using. Then, once the screen location is known, the fragment shader decides the color for all the pixels that form a triangle (made out of 3 vertices). More or less 🙂

You can probably do what you are asking: use a PGraphics with a shader and render the texture there, then call texture(…) with your PGraphics (containing the shader texture) as an argument. Basically it’s splitting the problem in two steps: since you can not call `texture()` with a shader, render the shader to an image first, then call `texture()`.

---

<div class="post-metadata">

**Author:** ![lnp](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lnp/32/4911_2.png) [@lnp](https://discourse.processing.org/u/lnp)\
**Post date:** [August 29, 2019, 10:32am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/7 "2019-08-29T10:32:27Z")

</div>

What you’re describing in the second paragraph does seem more straight forward. But I am but a shader padawan. Thanks!

---

<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 29, 2019, 10:45am UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/8 "2019-08-29T10:45:23Z")

</div>

Is there a resource for free shaders?

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [August 29, 2019, 3:11pm UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/9 "2019-08-29T15:11:53Z")

</div>

There’s many places where one can find shaders online. 4 examples:

- [shadertoy.com](http://shadertoy.com)
- [http://stack.gl/packages/](http://stack.gl/packages/) (from [https://github.com/glslify/glslify](https://github.com/glslify/glslify))
- [https://github.com/neilmendoza/ofxPostProcessing/tree/master/src](https://github.com/neilmendoza/ofxPostProcessing/tree/master/src)
- [https://github.com/mrdoob/three.js/tree/dev/src/renderers/shaders](https://github.com/mrdoob/three.js/tree/dev/src/renderers/shaders)

but they must be made compatible with Processing. For Shadertoy there’s an [library](https://github.com/SableRaf/Shadertoy2Processing). The shader language is usually the same (GLSL) but the names of the uniforms and the attributes used in each platform vary, and the architectures also change a bit.

Most shaders you find online tend to be fragment shaders. There’s not many examples of vertex shaders.

Afaik there’s no database of free shaders for Processing, but we could make one 🙂

---

<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 29, 2019, 4:24pm UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/10 "2019-08-29T16:24:05Z")

</div>

> [@hamoid](#):
>
> Afaik there’s no database of free shaders for Processing, but we could make one

Sounds very interesting. What did you have in mind – like an organized list of links, or like a repo that compiles many example files from different sources, or something else?

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [August 29, 2019, 6:11pm UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/11 "2019-08-29T18:11:00Z")

</div>

Many of the [GLSL Sandbox](http://glslsandbox.com/) shaders are compatible. although it’s a very hit and miss collection! 😄

There are a couple of PraxisLIVE nodes supporting live shader editing that might be useful even if you want to use them in a vanilla Processing project later.

---

<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 29, 2019, 8:29pm UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/12 "2019-08-29T20:29:42Z")

</div>

> [@jeremydouglass](#):
>
> like a repo that compiles many example files from different sources

Actually I could imagine this for game sprites / sounds, svgs… as well…

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [August 29, 2019, 9:08pm UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/13 "2019-08-29T21:08:26Z")

</div>

I thought of providing a bunch of 2D and 3D shader effects to use in projects. When I have time I can start by populating the list on the right side of the [Processing Shader Tool](https://discourse.processing.org/t/processing-shader-tool/5476)

I thought it would be cool to show examples of using shaders as materials, even if people can’t write those shaders, they can activate them to render 2D and 3D shapes with strange (non flat) colors.

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [August 29, 2019, 9:18pm UTC](https://discourse.processing.org/t/shader-as-texture-for-primitive/13680/14 "2019-08-29T21:18:26Z")

</div>

## Using a shader as a texture

```auto
PShader fx;
PShape cube;
PGraphics tex;

void setup() {
  size(640, 360, P3D);
  tex = createGraphics(200, 200, P3D);
  
  fx = loadShader("frag.glsl");
  tex.beginDraw();
  tex.shader(fx);
  tex.noStroke();
  tex.rect(0, 0, tex.width, tex.height);
  tex.endDraw();
  
  cube = makeCube();
  cube.setTexture(tex);
  fill(255);
  noStroke();
}

// We need a 3D model, ideally with UV coordinates for the shader texture.
// In this case we create a 3D cube, but we could replace this function just by
// loadShape() to load a 3D model from disk.
PShape makeCube() {
  PShape s = createShape();
  s.beginShape(QUADS);

  // +Z "front" face
  s.vertex(-1, -1, 1, 0, 0);
  s.vertex( 1, -1, 1, 1, 0);
  s.vertex( 1, 1, 1, 1, 1);
  s.vertex(-1, 1, 1, 0, 1);

  // -Z "back" face
  s.vertex( 1, -1, -1, 0, 0);
  s.vertex(-1, -1, -1, 1, 0);
  s.vertex(-1, 1, -1, 1, 1);
  s.vertex( 1, 1, -1, 0, 1);

  // +Y "bottom" face
  s.vertex(-1, 1, 1, 0, 0);
  s.vertex( 1, 1, 1, 1, 0);
  s.vertex( 1, 1, -1, 1, 1);
  s.vertex(-1, 1, -1, 0, 1);

  // -Y "top" face
  s.vertex(-1, -1, -1, 0, 0);
  s.vertex( 1, -1, -1, 1, 0);
  s.vertex( 1, -1, 1, 1, 1);
  s.vertex(-1, -1, 1, 0, 1);

  // +X "right" face
  s.vertex( 1, -1, 1, 0, 0);
  s.vertex( 1, -1, -1, 1, 0);
  s.vertex( 1, 1, -1, 1, 1);
  s.vertex( 1, 1, 1, 0, 1);

  // -X "left" face
  s.vertex(-1, -1, -1, 0, 0);
  s.vertex(-1, -1, 1, 1, 0);
  s.vertex(-1, 1, 1, 1, 1);
  s.vertex(-1, 1, -1, 0, 1);

  s.endShape();

  s.setStroke(false);
  s.setTextureMode(NORMAL);

  return s;
}

void draw() {
  // the shader has a uniform called time
  // to make change on every frame, otherwise we might
  // as well just use an image loaded from disk instead of a shader :)
  fx.set("time", millis()*0.01);
  tex.beginDraw();
  tex.rect(0, 0, tex.width, tex.height);
  tex.endDraw();
  // notice that for the tex pgraphics we just draw a rectangle
  // covering it. The colors of that rectangle come from the shader.

  background(255);
  translate(width/2, height/2, -100);
  rotateX(millis() * 0.001);
  rotateY(millis() * 0.0005);
  scale(90);
  shape(cube);
}

```

A simple shader doing some rgb wavy nonsense

```auto
// frag.glsl
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

uniform float time;

void main() {
  vec2 p = (gl_FragCoord.xy - 100.0) * 0.03;
  float r = 0.5 + 0.5 * sin(p.x * p.y * 1.1 + time);
  float g = 0.5 + 0.5 * sin(p.x * p.y * 1.2 + time);
  float b = 0.5 + 0.5 * sin(p.x * p.y * 1.3 + time);
  gl_FragColor = vec4(r, g, b, 1.0);
}

```

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