bypass P5 renderers "added geometry" ...

edited June 2014 in GLSL / Shaders

Hello everyone, I want to know if its possible to bypass the P5 renderers "added geometry" so that your shader does not have to account for it? i.e. say you have a simple shader where the fragment shader just colors every pixel blue and the vertex shader moves the vertices according the sine function and the ellapsed time, if I understand correctly this would qualify as a "LINES" shader in P5 and I guess in order for the strokeWeight function to work correctly with a shader the P5 renderer converts a line (which is 2 points) into 4 points(which basically turns a line into a rectangle) and passes it to the shader where you'd have to perform a technique called billboarding so that this line (now rectangle) always faces the camera right?? how would I go about implementing such shader if I didnt care about using billboarding in my shader (this would make the shader shorter and simpler) and just want to use one pixel width lines (not ever using strokeWeight function in my sketch) ?

I think my question is a bit convoluted but just ask me what part you'd like me to clarify

Saludos Everyone!

JLafarga

Answers

  • Answer ✓

    Hola JLafarga, you're entirely right in your description of how the line rendering works in Processing. Since it is not possible to change the way the line geometry is computed by the renderer before sending it to the shader (unless you write your own renderer, or at least subclass PGraphicsOpenGL and override the methods involved in line rendering :-)), a line shader will always receive 4 points per line segment. Also, by default the geometry is interpreted as triangles... The simplest way I can imagine to change this behavior in order render lines without billboarding would be by subclassing the PShader class and overriding its draw() method, like so:

    PShape cube;
    LineShader lineShader;
    float angle;
    
    float weight = 10;
    
    void setup() {
      size(640, 360, P3D);
    
      lineShader = new LineShader(this, "linevert.glsl", "linefrag.glsl");
    
      cube = createShape(BOX, 150);
      cube.setFill(false);
      cube.setStroke(color(255));
      cube.setStrokeWeight(1);
    }
    
    void draw() {
      background(0);
    
      translate(width/2, height/2);
      rotateX(angle);
      rotateY(angle);
    
      shader(lineShader, LINES);
      shape(cube);
    
      angle += 0.01;
    }
    
    class LineShader extends PShader { 
      public LineShader(PApplet parent, String vertFilename, String fragFilename) {
        super(parent, vertFilename, fragFilename);
      }
    
      void draw(int idxId, int count, int offset) {
        pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, idxId);
        pgl.drawElements(PGL.LINES, count, PGL.UNSIGNED_SHORT, offset * Short.SIZE / 8);
        pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0);
      }
    }
    

    with the following corresponding shader code for the vertex stage:

    #define PROCESSING_LINE_SHADER
    
    uniform mat4 transform;
    
    attribute vec4 vertex;
    attribute vec4 color;
    
    varying vec4 vertColor;
    
    void main() {
      gl_Position = transform * vertex;
      vertColor = color;  
    }
    

    and the fragment:

    varying vec4 vertColor;
    
    void main() {
      gl_FragColor = vertColor;
    }
    

    By doing this, the shader will interpret the geometry elements simply as GL_LINES, and the additional direction attribute would be ignored altogether.

  • awesome thanks!

Sign In or Register to comment.