I am playing around with a simple code that generates a shaded sphere. I don't yet fully understand the math but I am figuring it out as I play with the code. I was wondering how one might implement specular shading into this based on this code. Any suggestions?
for (y=0;y<screenHeight;y++)
for (x=0;x<screenWidth;x++)
if (sqr((x-xcenter)*(x-xcenter)+(y-ycenter)*(y-ycenter))<radius)
{
vx=(x-xcenter);
vy=(y-xcenter);
vz=sqr(radius*radius-vx*vx-vy*vy);
vl=sqr(vx*vx+vy*vy+vz*vz);
co_angle=(lx*vx+ly*vy+lz*vz)/(ll*vl);
pixel=co_angle*255;
}
I was looking at this thread and the second image is what I am after. But I also don't fully understand the math there either: Trouble with Phong Shading
Thanks in advance.
To add reflection first you need mirror light vector by surface normal
![](https://www.manongdao.com/static/images/pcload.jpg)
- all these are unit vectors:
l
- (yellow) to light source
n
- (aqua) surface normal
r
- (green) reflected light direction
e
- (orange) to eye/camera direction
- points:
p
- (red) - rendered pixel position
q
- (magenta) - reflection midpoint
- axises:
- brown - reflection midpoint
- yellow - to light
- gray - to eye/camera
So how to do it?
n,p,e,l
are knowns or can be easily computed
- if light is directional then
l
is constant for all pixels
- if light source is a point then
l=light_pos-p; l/=|l|;
e=eye_pos-p; e/=|e|;
- now you need to find point
q
I use dot product for this q=p+(n*dot(l,n));
- now the
r
vector is easy r=(p+l)+2*(q-(p+l))-p=2*(q-p)-l;
- hope I did not make a silly math mistake/typo somewhere but it should be clear how I obtain the equations
now you have reflection vector r
- so add shading by multiplying pixel color by
m=light_color*dot(r,e)+ambient_light;
- to add specular spots you need add to m the maximal reflections which are present only near
r
- so
ca=cos(ang)=dot(r,e);
you do not need ang
directly cosine is fine
- now to limit the specular cone size do
ca=pow(ca,5.0)
can use any exponent
- this will lower the values below one so it is much much less then raw cosine
- the bigger the exponent the smaller spot cone size so now:
m=(light_color*0.5*(ca+dot(r,e)))+ambient_light;
- you can also add mixing coefficients to change the ratio between specular and normal reflection light strength
- now render pixel
p
with color=surface_color*m;
Hope I didn't forget something it is a while I coded something like this...