简体   繁体   中英

Basic Specular Shading

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

  • 思考
  • 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|; 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*(qp)-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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM