Render LINES on PShapes loaded with External Obj Files?

edited March 2017 in GLSL / Shaders

Is it possible to render lines using the line shader code from this tutorial

https://processing.org/tutorials/pshader/

on PShapes loaded with .obj files?

The following code based on the tutorial produces the lines for the cube fine but not the Satellite (obj attached)

Processing code:

PShape satellite;
float angle;
PShader colorShader;

PShape cube;

float weight = 2;

void setup() {
  size(1280, 720, P3D);

  satellite = loadShape("Satellite.obj");
  satellite.setStroke(color(255,0,0));
  satellite.setStrokeWeight(weight);

  cube = createShape(BOX, 150);
  cube.setFill(false);
  cube.setStroke(color(255,0,0));
  cube.setStrokeWeight(weight);

  colorShader = loadShader("colorfrag.glsl", "colorvert.glsl");  

  shader(colorShader, LINES);
}

void draw() {
  background(0);
  translate(width/2, height/2);
  rotateY(angle);
  angle += 0.01;

  shape(satellite);  
  shape(cube);

}

colorvert.glsl:

uniform mat4 transform;
uniform vec4 viewport;

attribute vec4 position;
attribute vec4 color;
attribute vec4 direction;

varying vec4 vertColor;

vec3 clipToWindow(vec4 clip, vec4 viewport) {
    vec3 dclip = clip.xyz / clip.w;
    vec2 xypos = (dclip.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw;
    return vec3(xypos, dclip.z * 0.5 + 0.5);
}

void main() {
    vec4 clip0 = transform * position;
    vec4 clip1 = clip0 + transform * vec4(direction.xyz, 0);
    float thickness = direction.w;

    vec3 win0 = clipToWindow(clip0, viewport);
    vec3 win1 = clipToWindow(clip1, viewport);
    vec2 tangent = win1.xy - win0.xy;

    vec2 normal = normalize(vec2(-tangent.y, tangent.x));
    vec2 offset = normal * thickness;
    gl_Position.xy = clip0.xy + offset.xy;
    gl_Position.zw = clip0.zw;
    vertColor = color;  
}

colorfrag.glsl:

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec4 vertColor;

void main() {

    gl_FragColor = vertColor;

}

Is there something particular about loading external obj files into PShape that means the same functions (setStroke(), etc) don't work the same or variables aren't passed to the shaders correctly?

Or in general, is Processing really not suited to using shaders with .obj files?

Thanks.

(edit: attachment doesn't seem to have worked, here's the link)

https://www.dropbox.com/s/6c6mn63cnwcrtte/Satellite.obj?dl=0

Answers

  • maybe you can use this line (which is a thin rect)

    void setup() {
      size(640, 360, P3D);
    }
    
    void draw() {
      background(0);
      lights();
      depth(260);
    }
    
    void depth(float z1) {
    
      pushMatrix();
    
      // A vector that points to the mouse location
      PVector mouse = new PVector(mouseX, mouseY, 0);
      stroke(255);
      drawLine(220, 220, -220, 
        mouse.x, mouse.y, mouse.z, 
        22, 
        color(255, 0, 0));
    
      popMatrix();
    }
    // 
    
    // -----------------------------------------------
    
    void drawLine(float x1, float y1, float z1, 
      float x2, float y2, float z2, 
      float weight, 
      color strokeColour)
      // was called drawLine; programmed by James Carruthers
      // see http://processing.org/discourse/yabb2/YaBB.pl?num=1262458611/0#9
    {
      PVector p1 = new PVector(x1, y1, z1);
      PVector p2 = new PVector(x2, y2, z2);
      PVector v1 = new PVector(x2-x1, y2-y1, z2-z1);
      float rho = sqrt(pow(v1.x, 2)+pow(v1.y, 2)+pow(v1.z, 2));
      float phi = acos(v1.z/rho);
      float the = atan2(v1.y, v1.x);
      v1.mult(0.5);
    
      pushMatrix();
      translate(x1, y1, z1);
      translate(v1.x, v1.y, v1.z);
      rotateZ(the);
      rotateY(phi);
      noStroke();
      fill(strokeColour);
      // box(weight,weight,p1.dist(p2)*1.2);
      box(weight, weight, p1.dist(p2)*1.0);
      popMatrix();
    }
    
    //
    
  • Thanks for the suggestion. My question is really specifically asking about the process of rendering a PShape based on an obj file though..

    Shapes made using Processing's inbuilt functions work fine.

  • You are missing the setStroke(true) call after loading the OBJ, try this:

     satellite = loadShape("rocket.obj");
     satellite.setStroke(true);
     satellite.setStroke(color(255,0,0));
     satellite.setStrokeWeight(weight);
    
     cube = createShape(BOX, 150);
     cube.setFill(false);
     cube.setStroke(false);
     cube.setStroke(color(255,0,0));
     cube.setStrokeWeight(weight);
    
  • Thanks, that solved it. The lines are rendering perfectly now.

Sign In or Register to comment.