uniform vec3 cam; /* camera location, world coordinates */After compiling, from C++ you can set this uniform variable. You do this by passing it's string name to "glGetUniformLocationARB", which returns an integer index (into a table of variables somewhere in the guts of your graphics card). You can then set a "vec3" uniform's value by passing the uniform's location to glUniform3fvARB (or set a vec4 with glUniform4fvARB, etc). Here I'm passing one (1) float-pointer as the camera location, which I've named "camera" in C++ ogl/minicam.h:
glUseProgramObjectARB(prog);Calling "glGetUniformLocation" every frame is somewhat expensive, and it's rather annoying to call. So I've got a wrapper macro (in ogl/glsl.h) that caches the uniform's location in a static variable, for faster execution and a simpler interface:
glUniform3fvARB( /* set the GLSL uniform variable named "cam" */
glGetUniformLocationARB(prog, "cam"),
1, /* <- number of variables to set (just one vec3) */
camera /* C++ variable new uniform value is read from */
);
glFastUniform3fv(prog,"cam",1,camera);Make sure your program is still bound in use before you try to set uniform variables; the "glUseProgramObjectARB" above is only needed once, but it is needed!
vec3 N = normalize(gradient); // Points away from surfaceYou may need to flip the normal vector to point toward the camera, typically this is just a "dot(N,cameraDir)" test followed by an "N=-N;" flip if the normals are backwards. Then you need to compute (clamped) dot products between these vectors:
vec3 L1 = normalize(vec3(0.0,0.0,1.0)); // Points toward light 1
vec3 T = normalize(vec3(cam)-P); // Points from intersection Toward camera
vec3 H1 = normalize(T+L1); // Blinn's 'halfway vector' for light 1
float a=0.2; // Ambient illuminationAnd finally you just combine these together--you can get lots of different effects by combining them in different ways. Here I've added in "M" for the object ("Material") color, and "K" for a checkerboard pattern.
float d=clamp(dot(N,L1),0.0,1.0); // Diffuse light fraction
float s=pow(clamp(dot(N,H1),0.0,1.0),50.0); // Specular fraction. Constant controls highlight size
a- Ambient, 0.2 |
d- Diffuse, dot(N,L) |
M- Material Color, gl_Color |
s- Specular, pow(dot(N,H),...) |
M*a Typical Pure Ambient |
M*d Typical Pure Diffuse |
M*(d+a) Typical Lambertian |
M*(d+a)+s Classic Phong Lighting |
K- Checkerboard, using step(fract(position)) |
K*M*(d+a)+s Checkerboard controls overall diffuse color. |
M*(d+a)+K*s Checkerboard controls shininess. |
M*(d+a)+s+0.5*K Gently glowing checkerboard. |