We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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
edit post, highlight code, press ctrl-o
AND CHECK IT!
Sorry, I've just corrected it
your sphere isn't a sphere. it's an approximation of a sphere...
add this
sphereDetail(10);
line 27.5, and you'll seeis 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)