// specular reflectivity, no colors yet, all vectors assumed normalized 
float GaussHighlight( float gloss, float aniso, float orient,  
                 Point3& N, Point3& V, Point3& L, Point3& T, float* pNL )
{
   float out = 0.0f;

   float asz = (1.0f - gloss) * ALPHA_SZ;
   float ax = ALPHA_MIN + asz;
   float ay = ALPHA_MIN + asz * (1.0f-aniso);
// DbgAssert( ax >= 0.0f && ay >= 0.0f );
   LBound( ax ); LBound( ay );

   Point3 H = Normalize(L - V); // (L + -V)/2
   float NH = DotProd(N, H);   
   if (NH > 0.0f) {
      float axy = /* normalizeOn ? ax * ay : */ DEFAULT_GLOSS2;
      float norm = 1.0f / (4.0f * PI * axy );
      float NV = -DotProd(N, V );
      if ( NV <= 0.001f)
         NV = 0.001f;

      float NL = pNL ? *pNL : DotProd( N, L );
      float g = 1.0f / (float)sqrt( NL * NV );
      if ( g > 3.0f ) g = 3.0f;

      // Apply Orientation rotation here
      float or = orient * 180.0f;
      Point3 T1 = T;
      if ( or != 0.0f )
         T1 = RotateVec( T, N, DegToRdn(or));

      // get binormal
      Point3 B = CrossProd( T1, N );

      float x = Dot( H, T1 ) / ax;
      float y = Dot( H, B ) / ay;
      float e = (float)exp( -2.0 * (x*x + y*y) / (1.0+NH) );

      out = norm * g * e;
   }
   return SPEC_MAX * out;  // does not have speclev or light color or kL
}
//////////////////////////////////////////////////////////////////////////////
//
// transpColor utility
//
Color transpColor( ULONG type, float opac, Color& filt, Color& diff )
{
   // Compute the color of the transparent filter color
   if ( type == TRANSP_ADD ) { // flags & STDMTL_ADD_TRANSP) {
      float f = 1.0f - opac;
      return Color(f, f, f);   

   } else if ( type == TRANSP_FILTER ) { //flags & STDMTL_FILT_TRANSP ){
      // Transparent Filter color mapping
      if (opac>0.5f) {
         // darken as opac goes ( 0.5--> 1.0)
         // so that max component reaches 0.0f when opac reaches 1.0
         // find max component of filt
         float m = Max(filt);
         float d = 2.0f*(opac-.5f)*m;
         Color fc = filt-d;
         fc = LBound( fc );
         return fc;
      } else {
         // lighten as opac goes ( 0.5--> 0.0)
         // so that min component reaches 1.0f when opac reaches 1.0
         // find min component of filt
         float m = Min(filt);
         float d = (1.0f-2.0f*opac)*(1.0f-m);
         Color fc = filt+d;
         fc = UBound( fc );
         return fc;
      }

   } else {
      // original 3DS transparency 
      Color f = (1.0f-diff);  
      return  (1.0f-opac)*f;
   }

}
Exemple #3
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;
}