Category : C Source Code
Archive   : MTVSRC.ZIP
Filename : SHADE.C

 
Output of file : SHADE.C contained in archive : MTVSRC.ZIP
/***********************************************************************
* $Author: markv $
* $Revision: 1.2 $
* $Date: 88/09/12 12:58:01 $
* $Log: shade.c,v $
* Revision 1.2 88/09/12 12:58:01 markv
* Added specular reflections and shadow caching. When a object
* is found between a light source and the current point we are trying
* to shade, that object is cached (indexed by recursion level) in the
* lightsource. Next time we test a shadow against the light source,
* we test this object first. If it is between us and the light source,
* we can correctly shadow the object without calling Intersect().
*
* Note: specular highlights call the unix pow() function, which seems
* to be REALLY expensive. Optimizations could be made here.
*
* Revision 1.1 88/09/11 11:00:44 markv
* Initial revision
*
***********************************************************************/

#include
#include
#include "defs.h"
#include "extern.h"

/***********************************************************************
* Shade(level, weight, P, N, I, hit, col)
*
* Wow! Too many parameters!
*
* Shade is the driving force of the raytracer. It calculates the actual
* luminance at point P, given N, the normal, and I the incident vector.
* We also pass in the hit, because the normal generating code might need it.
* The color is returned in col.
***********************************************************************/

Shade(level, weight, P, N, I, hit, col)
int level ;
Flt weight ;
Vec P, N, I ;
Isect * hit;
Color col ;
{
Ray tray ;
Color tcol ;
Vec L, H, R ;
Flt t ;
Flt diff ;
Flt spec ;
#ifdef SHADOW_CACHING
Object * cached ;
#endif /* SHADOW_CACHING */
Isect nhit ;
Surface * surf ;
int l ;

col[0] = col[1] = col[2] = 0.0 ;
surf = hit -> isect_prim -> o_surf ;

for (l = 0; l < nLights; l++) {
VecSub(Lights[l].light_pos, P, L);
if (VecDot(N,L) >= 0.0) {
t = VecNormalize(L);
VecCopy(P, tray.P);
VecCopy(L, tray.D);
nShadows ++ ;
#ifdef SHADOW_CACHING
cached = Lights[l].light_obj_cache[level] ;
if (cached
&& (cached -> o_procs -> intersect)
(cached, &tray, &nhit)
&& nhit.isect_t < t) {
/*
* we are in shadow, continue...
*/
nShadowCacheHits ++ ;
continue ;
}
#endif /* SHADOW_CACHING */
if (Shadow(&tray, &nhit, t)) {
diff = VecDot(N,L) * surf -> surf_kd
* Lights[l].light_brightness ;
#ifdef SHADOW_CACHING
Lights[l].light_obj_cache[level] = NULL ;
#endif /* SHADOW_CACHING */
VecAddS(diff, surf -> surf_color, col, col) ;
SpecularDirection(I, N, R) ;
VecNormalize(R) ;
if (surf -> surf_shine > rayeps) {
spec = VecDot(R,L) ;
if (spec > rayeps) {
spec = pow(spec, surf -> surf_shine ) * Lights[l].light_brightness ;
col[0] += spec ;
col[1] += spec ;
col[2] += spec ;
}
}
} else {
#ifdef SHADOW_CACHING
Lights[l].light_obj_cache[level] =
nhit.isect_prim ;
#endif /* SHADOW_CACHING */
}

}
}

VecCopy(P, tray.P);

if(surf -> surf_ks * weight > minweight) {
SpecularDirection(I, N, tray.D);
VecNormalize(tray.D);
Trace(level + 1, surf -> surf_ks * weight, &tray, tcol, &nReflected);
VecAddS(surf -> surf_ks, tcol, col, col);
}

if (surf -> surf_kt * weight > minweight) {
if (hit -> isect_enter)
TransmissionDirection(NULL, surf, I, N, tray.D) ;
else
TransmissionDirection(surf, NULL, I, N, tray.D) ;
Trace(level + 1, surf -> surf_kt * weight, &tray, tcol, &nRefracted) ;
VecAddS(surf -> surf_kt, tcol, col, col) ;
}
}

/***********************************************************************
* SpecularDirection(I, N, R)
*
* Given an incident vector I, and the normal N, calculate the
* direction of the reflected ray R.
***********************************************************************/

SpecularDirection(I, N, R)
Vec I, N, R;
{
#ifndef DIVIDE
VecComb(1.0/fabs(VecDot(I,N)), I, 2.0, N, R);
#else
VecComb(divide('Q' , 1.0,fabs(VecDot(I,N))), I, 2.0, N, R);
#endif
VecNormalize(R);
}

/***********************************************************************
* TransmissionDirection(m1, m2, I, N, T)
*
* calculates the direction of the transmitted ray
***********************************************************************/

TransmissionDirection(m1, m2, I, N, T)
Surface *m1, *m2;
Vec I, N, T ;
{
Flt n1, n2, eta, c1, cs2 ;
n1 = (m1!=NULL) ? m1 -> surf_ior : 1.0 ;
n2 = (m2!=NULL) ? m2 -> surf_ior : 1.0 ;
#ifndef DIVIDE
eta = n1/n2 ;
#else
eta = divide('R',n1,n2) ;
#endif

c1 = -VecDot(I,N);
cs2 = 1.0 - eta * eta*(1.0 - c1*c1);
if (cs2 < 0.0)
return 0;
VecComb(eta, I, eta*c1-sqrt(cs2), N, T);
return(1);
}



  3 Responses to “Category : C Source Code
Archive   : MTVSRC.ZIP
Filename : SHADE.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/