How to apply two textures to the same PShape?

Hi, I have created some code that takes a polyline and creates a mesh surrounding the polyline (in the image there’s a bunch of them). Next I want to add a second texture to control the transparency.

I want this mask to be independent from the color texture, so I can change their uv coordinates without affecting each other.

I could write my own shader, pass the alpha texture as a uniform, but what I’m not sure about is about the second set of uv coordinates. I see PShape has a setAttrib method. Can I use that to define my own vertex attributes? In other environments you can define specular maps, bump maps, etc. In Processing, would I need to switch to low level OpenGL to achieve such features?

I figured out a “hack”: since I’m not using normals in my shapes I can abuse them as a second texture coordinates, so I can call shp.normal(uv2.x, uv2.y, 0). Then I must make use of those values in the shader. That should work.

Update: or even easier: I could put uv2.x into the red component and uv2.y into the green component of the color.

I’m still curious about attrib() and setAttrib() and if I can define my own attributes for vertices. I’ll try and see what happens.

Update 2: I made it work using normal to store the second uv coordinates. color would not work, because you set vertex color values as an integer even if they end up being floats in the shader.
Still need to polish it a bit, but I’m happy to see the partial transparency working :slight_smile:

Have you ever found out how to use setAttrib and attrib method to create your own attributes in the shader? It seems that it does not work properly in the recent version of processing.

If I setup a new vertex attribute with shape.attrib("intensity", 0.5f);, the value is not stored in the attribute. Also if I later update each vertex with shape.setAttrib("intensity", i, intensity);. The attribute is always 0.0.

Hi! I didn’t try. Could you share a small test program to try?

Of course, there you go (download the full repository to execute with the shaders). The sketch creates random vertices in 3d and render them as points. The pont size can be set through a uniform, and the idea was to use more attributes. As an example I’ve just added a simple pointIndex attribute, which represents the id of the vertex (normalized) and is used to control the red channel of the color.

This is how it looks (no red at all):

If you only need the vertex id, you could maybe use https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_VertexID.xhtml ?

I suggest calling hint(DISABLE_OPTIMIZED_STROKE); to avoid unexpected effects caused by Processing optimizations.

No, the final goal is not to have the vertex index :slight_smile: This is just a simple test, to see if it works or not. In threejs and plain opengl it is straightforward to add new vertex attributes, but it seems that it is broken in processing. Thanks for the optimization hint, but does it even affect the rendering if there are only points?

The hint would change the value of gl_VertexID if there were more than one shape, as all shapes would be sent in one batch (if I understood it correctly).

I already knew this thread, but the code was not working for me. I’ve adapted the shader now, so it runs under MacOS too. It seems that if I change the shape mode to POINTS and adapting the shader breaks it. The vert_color attribute is always just black vec4(0.0, 0.0, 0.0, 0.0).

PShape shape;
PShader shader;

public void setup() {
  size(500, 500, P3D);

  shape = createShape();
  shape.beginShape(POINTS);

  // Visual
  shape.noFill();
  shape.stroke(255, 0, 0);

  // Custom Attribute
  shape.attrib("vert_color", 1.0, 0.5, 0.0, 1.0); // Supposed to be Orange

  shape.vertex(-100, -100);
  shape.vertex(100, -100);
  shape.vertex(100, 100);
  shape.vertex(-100, 100);

  shape.endShape();

  // Exemple shader
  shader = createShader();
}

public void draw() {
  background(255);

  shader(shader, POINTS);
  translate(width/2, height/2);
  shape(shape);
}

public PShader createShader() {
  String[] vert = new String[] {
    "#version 150", 
    "", 
    "uniform mat4 projection;", 
    "uniform mat4 modelview;", 
    "", 
    "in vec4 position;", 
    "in vec4 color;", 
    "in vec2 offset;", 
    "in vec4 vert_color;", 
    "", 
    "out vec4 vertColor;", 
    "", 
    "void main() {", 
    "vec4 pt = position;", 
    "pt /= 10.0;", 
    "vec4 pos = modelview * pt;", 
    "vec4 clip = projection * pos;", 
    "gl_Position = clip + projection * vec4(offset, 0, 0);", 
    "", 
    // setting the vert color
    "vertColor = vert_color;", 
    "}"
  };

  String[] frag = new String[] {
    "#version 150", 
    "in vec4 vertColor;", 
    "out vec4 fragColor;", 
    "", 
    "void main() {", 
    "  fragColor = vertColor;", 
    "}"
  };

  return new PShader(this, vert, frag);
}
1 Like

Unfortunately I don’t know how to fix it. Maybe open an issue? In the issues I see https://github.com/processing/processing/issues/5091 somewhat related…

Or use a different framework with working custom attributes? :slight_smile:

1 Like

Haha I already thought to switch to openrndr for this project…but it is not possible. Thank you for the issue, it really seems comparable. But I opened an own one for this specific problem, because a bit of research in the tessellation code of processing shows, that the custom attributes on PShape are just processed if the shape is of type POLYGON.

1 Like