How Processing shaders works EXACTLY ?

Hello !

I just create some classes to be able to write GLSL directly inside a java class to be able to create OOP-shader-structure. Everything works fine but I would like to represents exactly the 6 processing shaders, then I'll just have to extend it to create my own shader (as Processing works actually)

I follow that great tutorial https://www.processing.org/tutorials/pshader/

And I rebuild the shaders I found in the tutorial using my tool. Everythings worked just fine, the GLSL code generated is exactly the same than the one found in the tutorial but the results on the screen are almost the results I got with "true-processing-shader" but not exactly.

For example, the quality of the lineShader described in the tutorial is ugly. Or, in the light-shader, the inner-part of the mesh doesn't look like to be illuminate in a correct way.

The problem doesn't come from my tool because at the end the GLSL I'm using is the exact same as the one given in the tutorials.

I suppose that the GLSL given in the tutorials are just an approximation of the true GLSL code.

Then my question is "Where can I find the true GLSL code for the 6 shaders used in Processing ?"

Thanks a lot by advance !

Answers

  • edited March 2015

    just to be sure, maybe I'm missing something....

    Here is the glsl of my vertexShader

    #define PROCESSING_LINE_SHADER
    attribute vec4 vertex;
    attribute vec4 color;
    attribute vec4 direction;
    uniform mat4 transform;
    uniform vec4 viewport;
    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 * vertex;
    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; 
    }
    

    the one of my fragmentShader :

    #ifdef GL_ES
    precision mediump float;
    precision mediump int;
    #endif
    varying vec4 vertColor;
    void main(){
    gl_FragColor = vertColor;
    }
    

    And the (eclipse-)processing-code I'm using

    public class Example07 implements IExample{

    PApplet applet;
    PShape can;
    float angle;
    PShader shader;
    
    public Example07(PApplet appletObj){
        applet = appletObj;
        ProcessingLineShader s = new ProcessingLineShader();
        shader = s.compileShader(appletObj);
        can = createCan(100, 200, 32);
    }
    PShape createCan(float r, float h, int detail) {
      applet.textureMode(applet.NORMAL);
      PShape sh = applet.createShape();
      sh.beginShape(applet.QUAD_STRIP);
      sh.stroke(0);
      for (int i = 0; i <= detail; i++) {
        float angle = applet.TWO_PI / detail;
        float x = applet.sin(i * angle);
        float z = applet.cos(i * angle);
        float u = (float)(i) / detail;
        sh.normal(x, 0, z);
        sh.vertex(x * r, -h/2, z * r, u, 0);
        sh.vertex(x * r, +h/2, z * r, u, 1);    
      }
      sh.endShape(); 
      return sh;
    }
    
    public void update(){ 
         applet.background(255);
         applet.stroke(0);
         applet.shader(shader);
         applet.translate(applet.width/2, applet.height/2);
         applet.rotateX(angle);  
         applet.rotateY(angle);  
         applet.rotateZ(angle);  
         applet.shape(can);  
          angle += 0.01;
    
    }
    

    }

    (the left picture was done with a "true-processing-shader" and the right picture uses the pointShader GLSL code given in the tutorial)

    And, if you are curious to see how looks like the ProcessingLineShader class

    package kosmos.shader.shaders.processing;
    import kosmos.shader.GLSLFunction;
    import kosmos.shader.GLSLShader;
    import kosmos.shader.uniforms.VariableType;
    
    public class ProcessingLineShader extends GLSLShader {
    
        public ProcessingLineShader(){
            super();
    
            GLSLFunction clipToWindow = new GLSLFunction(this,"clipToWindow");
            clipToWindow.setReturnType(VariableType.FLOAT_3);
            clipToWindow.addParameter(VariableType.FLOAT_4, "clip");
            clipToWindow.addParameter(VariableType.FLOAT_4, "viewport");
            clipToWindow.addGlsl("vec3 dclip = clip.xyz / clip.w;");
            clipToWindow.addGlsl("vec2 xypos = (dclip.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw;");
            clipToWindow.addGlsl("return vec3(xypos, dclip.z * 0.5 + 0.5);");
    
            vertexShader.addGLSLFunction(clipToWindow);
    
    
            vertexShader.newMat4Uniform("transform");
            vertexShader.newVec4Uniform("viewport");
            vertexShader.newVec4Attribute("vertex");
            vertexShader.newVec4Attribute("color");
            vertexShader.newVec4Attribute("direction");
            vertexShader.newVec4Varying("vertColor");
    
            vertexShader.setProcessingShaderType(ProcessingShaderType.PROCESSING_LINE_SHADER);
            vertexShader.addGlsl("vec4 clip0 = transform * vertex;");
            vertexShader.addGlsl("vec4 clip1 = clip0 + transform * vec4(direction.xyz, 0);");
            vertexShader.addGlsl("float thickness = direction.w;");
            vertexShader.addGlsl("vec3 win0 = clipToWindow(clip0, viewport);");
            vertexShader.addGlsl("vec3 win1 = clipToWindow(clip1, viewport); ");
            vertexShader.addGlsl("vec2 tangent = win1.xy - win0.xy;");
            vertexShader.addGlsl("vec2 normal = normalize(vec2(-tangent.y, tangent.x));");
            vertexShader.addGlsl("vec2 offset = normal * thickness;");
            vertexShader.addGlsl("gl_Position.xy = clip0.xy + offset.xy;");
            vertexShader.addGlsl("gl_Position.zw = clip0.zw;");
            vertexShader.addGlsl("vertColor = color; ");
    
            //----
    
            fragmentShader.newVec4Varying("vertColor");
            fragmentShader.addGlsl("gl_FragColor = vertColor;");
    
        }
    }
    
  • Nice research! If you will find a way for simplify the coding for beginner user of GLSL shader as me, it will be great!

  • I'm working on it :) The main obstacle with Shader come from the division of the code in differents individual part (vertexShader / fragmentShader / buffer creation / top-level usage of the shader )

    I would like to join every part of the shader-process in a single java class, then the shader will contains its own buffers and it becomes possible to extends the shader to another shader without buffer-missing-issue.

    I already did it in JS/WebGL , it's a bit more tricky in Java but I think I will get it working soon :)

Sign In or Register to comment.