Orange Book Code to Processing

edited November 2016 in GLSL / Shaders

Hi guys, I'm new with the shaders and I'm starting to read the Orange Book to understand something about it. I'm managed to translate the first example of the book, following the Processing Andreas Colubri's shaders tutorial (https://processing.org/tutorials/pshader/) but it presents strange issue although it's quite similar to the final output shown. If you run the code below, you should notice a strange issue with rotate() that makes the sphere blobby, it seems that the function affects the vertex shader but not the fragment shader and I don't understand why. Anyone can help me?

Processing Code:

PShader shader;

float a = 0.0;

void setup() {
  size(600, 600, P3D);
  noStroke();


  shader = loadShader("OBfrag1.glsl","OBver1.glsl");

  shader.set("BrickColor", 0.5, 0.1, 0.1);
  shader.set("MortarColor", 0.5, 0.5, 0.5);
  shader.set("BrickSize", 0.1, 0.1);
  shader.set("BrickPct", 0.9, 0.9);
}

void draw() {
  background(255);
  shader(shader);

  pointLight(255, 255, 255, width/2, height/2, 500);

  translate(width/2, height/2);
  rotateY(a);

  fill(255);
  sphere(200);

  a += 0.01;
}

Vertex Shader ( OBver1.glsl ):

#define PROCESSING_LIGHT_SHADER

uniform mat4 modelview;
uniform mat4 transform;
uniform mat3 normalMatrix;
uniform vec4 lightPosition;

const float SpecularContribution = 0.2;
const float DiffuseContribution = 1.0 - SpecularContribution;

attribute vec4 vertex;
attribute vec4 color;
attribute vec3 normal;

varying vec4 vertColor;
varying float LightIntensity;
varying vec2 MCposition;

void main() {
    vec3 ecPosition = vec3(modelview * vertex);
    vec3 tNorm = normalize(normalMatrix * normal);

    vec3 lightVec = normalize(lightPosition.xyz - ecPosition);
    vec3 reflectVec = reflect(-lightVec, tNorm);
    vec3 viewVec = normalize(-ecPosition);

    float diffuse = max(dot(lightVec, tNorm), 0.0);
    float spec = 0.0;

    if (diffuse > 0.0) {
        spec = max(dot(reflectVec, viewVec), 0.0);
        spec = pow(spec, 16.0);
    }

    LightIntensity = DiffuseContribution * diffuse +
                     SpecularContribution * spec;

    MCposition = tNorm.xy;
    vertColor = vec4(LightIntensity, LightIntensity, LightIntensity, 1) * color;
    gl_Position = transform * vertex;
}

Fragment Shader ( OBfrag1.glsl ):

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

uniform vec3 BrickColor, MortarColor;
uniform vec2 BrickSize;
uniform vec2 BrickPct;

varying vec4 vertColor;
varying float LightIntensity;
varying vec2 MCposition;


void main() {

    vec3 color;
    vec2 position, useBrick;
    position = MCposition / BrickSize;

    if (fract(position.y * 0.5) > 0.5) {
        position.x += 0.5;
    }

    position = fract(position);
    useBrick = step(position, BrickPct);

    color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y);
    color *= LightIntensity;

    gl_FragColor = vec4(color, 1.0) * vertColor;
}

Answers

  • Answer ✓

    edit post, highlight code, press ctrl-o

    AND CHECK IT!

  • Sorry, I've just corrected it

  • Answer ✓

    your sphere isn't a sphere. it's an approximation of a sphere...

    add this sphereDetail(10); line 27.5, and you'll see

  • Answer ✓
    noFill();
    stroke(0);
    sphereDetail(10);
    sphere(200);
    

    is even clearer 8)

  • Ok, now this is clearer, but why the bricks (the fragment shader) don't rotate with the shape? If you run the code, you know what I mean.

    Thanks for the answers anyway.

  • I don't think the rotation of the sphere has anything to do with the painting done by the shader. Is it even wrapping the texture around the sphere? (I can't remember and can't run the example here). From my limited knowledge that frag shader looks like it's just applying a brick pattern to all the drawn pixels. (The vert shader is mostly lighting, frag shader is pattern)

Sign In or Register to comment.