stroke glitches in 3.0

edited October 2015 in Questions about Code

hello there...

have been working on a particular sketch for a while... and I'm starting to get random stroke glitches...

the code is pretty basic... so i can't really see why or how it could be happening given the parameters

(see example below)

Answers

  • edited October 2015

    I think it's a glitch with stroke, when StrokeWeight is something else other than 1.

    void setup() {
      size(1000, 1000, P3D);
      smooth();
    }
    
    void draw() { 
      background(255);
      translate(width/2, height/2);
      lights();
      rotateX(map(mouseX, 0, width, 0, radians(360)));
      for (int i = 250; i < 500; i++) {
        noFill();
        strokeWeight(2);
        stroke(map(i, 250, 500, 0, 255), 0, 100, 255);
        ellipse(0, 0, i, i);
      } 
    }
    
  • edited October 2015

    when you say 'glitch' what do you mean?

    i've run the code but nothing jumps out at me as wrong

  • u cant see glitchy lines crossing across the ellipses?

  • nope.

    i'm using v 1.5.1

  • i'm using 3.0

  • it's also ok in v2

    but i do see the glitches in v3

  • its even worse if there are other objects in the scene

  • this is probably worth raising as a proper bug as it seems wrong (especially those times when the glitch lines seem to come from a point outside the plane of the disk)

    it does seem to occur at specific angles, i wonder if that's a clue.

  • This behavior is caused by Processing's "stroke optimization", just add hint(DISABLE_OPTIMIZED_STROKE); to your setup() function and you should be fine.

  • edited October 2015

    @poersch that does indeed get rid of the lines, but at a massive cost to performance. not really a useable solution. did some reading and doesn't sound like there's a fix, sounds like its normal expected behaviour based on the renderer. a bit of a shame, but i guess i'll have to figure out other ways of doing what i'm trying to do

  • edited October 2015

    that does indeed get rid of the lines, but at a massive cost to performance. not really a useable solution.

    From rendering this one circle? If you are rendering more than one of those I wouldn't use strokes at all. Strokes are basically a heap of polygons, meaning you are rendering thousands of polygons just to display one colored circle. Taking an image of the circle and rotating that around would probably look the same. Alternatively you could create a disk like object (which of course has a higher poly count than an image but still far less than your stroke solution) and use a gradient texture or a simple shader to color it.

    We need more information about your actual project or how and when these circles are rendered to the screen to help you find a more sophisticated workaround for the new "stroke optimization".

  • I have experienced the same problem with the Shapes3D library and the solution suggested by @Poersch worked for me too.

    that does indeed get rid of the lines, but at a massive cost to performance. not really a useable solution.

    Unless you need wire frames then turn the stroke off. It is much faster to draw fills than strokes. The following data is from drawing two spheres where each sphere comprises 2500 quads.

    1-2ms to render solid (fill only) spheres
    4-5ms to render wireframe (stroke only) with ENABLE_OPTIMIZED_STROKE.
    5-6ms to render wireframe (stroke only) with DISABLE_OPTIMIZED_STROKE

    You can see the biggest impact is drawing the stroke (wire) and although disabling optimised stroke impacted on performance it not as great as you might expect.

  • edited October 2015

    Thanks for the responses guys.

    To be specific I'm trying to create some rings with a gradient fill, as you can see in the images and code.

    As far as I'm aware ellipse() does not have settings for an inner radius, something like the Segment node in vvvv.

    I did find some examples here: https://processing.org/discourse/beta/num_1221179611.html

    I managed to copy the code easy enough and call the ring function as needed.

    I then attempted to apply the code for a radial gradient which I find here https://processing.org/examples/radialgradient.html but which is glitchy also.

    I assume this is because this gradient code is optimized for a fill of an ellipse, rather than custom curveVertex shapes.

    It does seem to work when you run the sketch, but when you rotate it, it goes all haywire... (also I'm not sure how to reconcile the two radii while the second radius is in the hue for loop)...

    I can't say I know how to make the leap between the two.

    Perhaps there is a better way to go about it all that someone can enlighten me on?

    That's why I jumped to strokes - iterate some strokes and the stroke color - job done. Then I was met with the stroke glitch. But point taken its not efficient to work with strokes in this manner and fill is obviously much more desirable for this purpose (albeit unknown to me how to achieve such a thing)...

    Anyway, without being a troll, it has to be said this is mind-blowingly hard, for, what is to my mind, a very simple task.

    color a = color(random(255), random(255), random(255)); 
    color b = color(random(255), random(255), random(255)); 
    color c = color(random(255), random(255), random(255)); 
    
      int radius = 360;
      float h = 120;
    
    void setup()
    {
      size(800,800, P3D);
      smooth(8);
    
        ellipseMode(RADIUS);
        colorMode(HSB, 360, 100, 100);
    }
    
    void draw()
    {
      background(0); 
    
      noStroke();
      translate(width/2, height/2);
        rotateX(map(mouseX, 0, width, 0, radians(359)));
    
    
      for (int r = radius; r > 0; --r) {
        fill(h, 100, 100);
      ring(0,0, r*2, 0, 0, r);
        h = (h + 1) % 360;
      }
    }
    
    // Create a ring by drawing an outer cicle clockwise and an inner circle anticlo
    
    void ring(float cx1, float cy1, float r1, float cx2, float cy2, float r2)
    {
      beginShape();
       buildCircle(cx1,cy1,r1,true);
       buildCircle(cx2,cy2,r2,false); 
      endShape();
    }
    
    // Creates a circle using spline curves. Can be drawn either clockwise
    // which creates a solid circle, or anticlockwise that creates a hole.
    void buildCircle(float cx, float cy, float r, boolean isClockwise)
    {
      int numSteps = 10;
      float inc = TWO_PI/numSteps;
    
      if (isClockwise)
      {
        // First control point should be penultimate point on circle.
        curveVertex(cx+r*cos(-inc),cy+r*sin(-inc));
    
        for (float theta=0; theta<TWO_PI-0.01; theta+=inc)
        {
          curveVertex(cx+r*cos(theta),cy+r*sin(theta));
        }
        curveVertex(cx+r,cy);
    
        // Last control point should be second point on circle.
        curveVertex(cx+r*cos(inc),cy+r*sin(inc));
    
        // Move to start position to keep curves in circle.
        vertex(cx+r,cy);
      }
      else
      {
        // Move to start position to keep curves in circle.
        vertex(cx+r,cy);
    
        // First control point should be penultimate point on circle.
        curveVertex(cx+r*cos(inc),cy+r*sin(inc));
    
        for (float theta=TWO_PI; theta>0.01; theta-=inc)
        {
          curveVertex(cx+r*cos(theta),cy+r*sin(theta));
        }
        curveVertex(cx+r,cy);
    
        // Last control point should be second point on circle.
        curveVertex(cx+r*cos(TWO_PI-inc),cy+r*sin(TWO_PI -inc));
      }  
    }
    
  • Here's a screen grab that describes how it looks (cool effect tho - but not what I want)...

    Screen Shot 2015-10-09 at 11.19.51 AM

  • Answer ✓

    This might help you get started.

    int nbr = 91;
    float delta = TWO_PI/(nbr-1);
    int c1, c2;
    float r1 = 180, r2=50;
    
    void setup(){
      size(400,400,P3D);
      c1 = color(255,0,0);
      c2 = color(0,255,0);
    }
    
    void draw(){
      background(0);
      translate(width/2, height/2);
      noStroke();
      beginShape(QUAD_STRIP);
      for(int i = 0; i < nbr; i++){
        float sa = sin(i * delta);
        float ca = cos(i * delta);
        fill(c1);
        vertex(r1*ca, r1*sa, 0);
        fill(c2);
        vertex(r2*ca, r2*sa, 0);
      }
      endShape();
    }
    
  • @quark - brilliant. Perfect.

  • @quark again, thanks so much!

  • And a little shader based example:

    void setup() {
        size(600, 600, P3D);
        textureMode(NORMAL);
        noStroke();
        smooth();
        String[] vertSource = {
            "uniform mat4 transform;",
            "attribute vec4 vertex;",
            "attribute vec2 texCoord;",
            "varying vec2 vertTexCoord;",
            "void main() {",
                "vertTexCoord = texCoord;",
                "gl_Position = transform * vertex;",
            "}"
        };
        String[] fragSource = {
            "uniform vec4 colorA;",
            "uniform vec4 colorB;",
            "varying vec2 vertTexCoord;",
            "void main() {",
                "float dist = distance(vertTexCoord, vec2(0.5, 0.5));",
                "if(dist > 0.2 && dist < 0.5)",
                    "gl_FragColor = mix(colorA, colorB, (dist - 0.2) * 3.33);",
            "}"
        };
        PShader gradientFill = new PShader(this, vertSource, fragSource);
        shader(gradientFill);
        gradientFill.set("colorA", 0.0, 0.0, 0.392, 1.0); // red, green, blue, alpha
        gradientFill.set("colorB", 1.0, 0.0, 0.392, 1.0); // (normalized in shader world)
    }
    
    void draw() { 
        background(255);
        translate(width / 2, height / 2);
        rotateX(map(mouseX, 0, width, 0, radians(360)));
        texturedRect();
    }
    
    void texturedRect() {
        beginShape(QUADS);
        vertex(-250, -250, 0.0, 0.0);
        vertex(+250, -250, 1.0, 0.0);
        vertex(+250, +250, 1.0, 1.0);
        vertex(-250, +250, 0.0, 1.0);
        endShape();
    }
    
  • @poersch - its been a little while, but i never did get that example to run ~

Sign In or Register to comment.