Ejemplo n.º 1
0
// returns shadow fraction & shadowClr
// move this util to shade context at first opportunity
float IllumShadow( ShadeContext& sc, Color& shadowClr ) 
{ 
   IlluminateComponents illumComp;
   IIlluminationComponents* pIComponents = NULL; 
   Color illumClr(0,0,0);
   Color illumClrNS(0,0,0);
   shadowClr.Black();
   Point3 N = sc.Normal();

   // scale the sums so we don't overflow
// float scaleFactor = 1.0;
// if( sc.nLights )
//    scaleFactor = 1.0f / float( sc.nLights );

   // > 9/24/02 - 2:30pm --MQM-- 
   // poke flag to let Light Tracer/Radiosity so they will
   // separate out the shadow value.   
   int oldXID = sc.xshadeID;
   sc.xshadeID |= SHADECONTEXT_GUESS_SHADOWS_FLAG;
   
   for (int i = 0; i < sc.nLights; i++) {
      LightDesc* l = sc.Light( i );
      pIComponents = (IIlluminationComponents*)l->GetInterface( IID_IIlluminationComponents );
      if( pIComponents ){
         // use component wise illuminate routines
         if (!pIComponents->Illuminate( sc, N, illumComp ))
            continue;

//       illumClr += (illumComp.finalColor - illumComp.shadowColor ) * illumComp.geometricAtten * scaleFactor;
         LBound( illumComp.shadowColor );
         illumClr += (illumComp.finalColor - illumComp.shadowColor ) * illumComp.geometricAtten;
//       illumClrNS += illumComp.finalColorNS * illumComp.geometricAtten * scaleFactor;
         illumClrNS += illumComp.finalColorNS * illumComp.geometricAtten;
         if( illumComp.rawColor != illumComp.filteredColor ){
            // light is filtered by a transparent object, sum both filter & user shadow color
            shadowClr += illumComp.finalColor * illumComp.geometricAtten; //attenuated filterColor 
         } else {
            // no transparency, sum in just the shadow color
            shadowClr += illumComp.shadowColor * illumComp.geometricAtten;
         }

      } else {
         // no component interface, shadow clr is black
         Color lightCol;
         Point3 L;
         register float NL, diffCoef;
         if (!l->Illuminate(sc, N, lightCol, L, NL, diffCoef))
            continue;
         if (diffCoef <= 0.0f)     
            continue;
//       illumClr += diffCoef * lightCol * scaleFactor;
         illumClr += diffCoef * lightCol;

         if( sc.shadow ){
            sc.shadow = FALSE;
            l->Illuminate(sc, N, lightCol, L, NL, diffCoef);
//          illumClrNS += diffCoef * lightCol * scaleFactor;
            illumClrNS += diffCoef * lightCol;
            sc.shadow = TRUE;
         } else {
            illumClrNS = illumClr;
         }
      }
   }// end, for each light

   // > 9/24/02 - 2:31pm --MQM-- 
   // restore xshadeID
   sc.xshadeID = oldXID;

   float intensNS = Intens(illumClrNS);
// Clamp( intensNS );
   float intens = Intens(illumClr);
// Clamp( intens );
   float atten = (intensNS > 0.01f)? intens/intensNS : 1.0f;
   if (atten > 1.0f)
      atten = 1.0f/atten;

   return atten;
}