Beispiel #1
0
// if this function changes, please also check SupportsReShading, PreShade and PostShade
// end - ke/mjm - 03.16.00 - merge reshading code
// [attilas|29.5.2000] if this function changes, please also check EvalColorStdChannel
void Matte::Shade(ShadeContext& sc)
{
   Color c,t, shadowClr;
   float atten;
   float reflA;

   // > 6/15/02 - 11:12am --MQM-- 
   // for renderer prepass, we need to at least call
   // illuminate so that Light Tracer can cache shading
   if ( SHADECONTEXT_IS_PREPASS( sc ) )
   {
      Color    lightCol;
      Point3   L;
      float    NL = 0.0f, diffCoef = 0.0f;
      LightDesc *l = NULL;
      for ( int i = 0;  i < sc.nLights;  i++ )
      {
         l = sc.Light( i );
         if ( NULL != l )
            l->Illuminate( sc, sc.Normal(), lightCol, L, NL, diffCoef );
      }
      return;
   }

#ifdef _DEBUG
   IPoint2 sp = sc.ScreenCoord();
   if ( sp.x == stopX && sp.y == stopY )
      sp.x = stopX;
#endif

   if (gbufID) sc.SetGBufferID(gbufID);
   IllumParams ip( 1, &shadowIllumOutStr);
   IllumParams ipNS(0, NULL);
   ip.ClearInputs(); ip.ClearOutputs();
   ipNS.ClearInputs(); ipNS.ClearOutputs();
   ip.hasComponents = ipNS.hasComponents = HAS_MATTE_MTL; 
   
   // get background color & transparency
   if (!opaque) sc.Execute(0x1000); // DS: 6/24/99:use black bg when AA filtering (#192348)
   sc.GetBGColor(c, t, fogBG&&(!fogObjDepth) );
   if (!opaque) sc.Execute(0x1001); // DS: 6/24/99:use black bg when AA filtering (#192348)

   if (shadowBG && sc.shadow) {
      /********
      sc.shadow = 0;
      Color col0 = sc.DiffuseIllum();
      sc.shadow = 1;
      Color scol = sc.DiffuseIllum();
      float f = Intens(col0);
      atten = (f>0.0f)?Intens(scol)/f:1.0f;
      if (atten>1.0f) atten = 1.0f/atten;
      ********/
      atten = IllumShadow( sc, shadowClr );
      atten = amblev + (1.0f-amblev) * atten; 

      // key on black user-set shadow clr
      if( gUseLocalShadowClr || col.r != 0.0f || col.g != 0.0f || col.b != 0.0f )
            shadowClr = col;

      ipNS.finalC = ipNS.diffIllumOut = c;
      c *= atten;
      ip.diffIllumOut = c;

      shadowClr *= 1.0f - atten;
      ip.finalC = sc.out.c = c + shadowClr;

      ip.SetUserIllumOutput( 0, shadowClr );

      if (shadowAlpha)
         t *= atten;
   } else {
      sc.out.c  = 
      ipNS.finalC = ipNS.diffIllumOut = ip.finalC = ip.diffIllumOut = c;
   }


   // add the reflections
   if (reflmap && useReflMap) {
      AColor rcol;
      if (reflmap->HandleOwnViewPerturb()) {
         sc.TossCache(reflmap);
         rcol = reflmap->EvalColor(sc);
      } else 
         rcol = sc.EvalEnvironMap(reflmap, sc.ReflectVector());

      Color rc;
      rc = Color(rcol.r,rcol.g,rcol.b)*reflAmt;
      ip.reflIllumOut = ipNS.reflIllumOut = rc;

      if( additiveReflection ) {
         // additive compositing of reflections
         sc.out.c += rc; ip.finalC += rc; ipNS.finalC += rc;
      } else {
         reflA = Intens( rc );
         // over compositing of reflections 
         sc.out.c = (1.0f - reflA) * sc.out.c + rc; 
         ip.finalC = (1.0f - reflA) * ip.finalC + rc;
         ipNS.finalC = (1.0f - reflA) * ipNS.finalC + rc;
      }
   }

   // render elements
   Clamp( t );
   Clamp( reflA );
   ip.finalT = ipNS.finalT = sc.out.t = opaque ? black: additiveReflection? t : Color(reflA,reflA,reflA) ; 
   int nEles = sc.NRenderElements();
   if( nEles != 0 ){
      ip.pShader = ipNS.pShader = NULL; // no shader on matte mtl
      ip.stdIDToChannel = ipNS.stdIDToChannel = NULL;
      ip.pMtl = ipNS.pMtl = this;
      ip.finalAttenuation = ipNS.finalAttenuation = 1.0f;

      for( int i=0; i < nEles; ++i ){
         IRenderElement* pEle = sc.GetRenderElement(i);
         if( pEle->IsEnabled() ){
            MaxRenderElement* pMaxEle = (MaxRenderElement*)pEle->GetInterface( MaxRenderElement::IID );
            if( pEle->ShadowsApplied() )
               pMaxEle->PostIllum( sc, ip );
            else
               pMaxEle->PostIllum( sc, ipNS );
         }
      }
   }

}
// if this function changes, please also check SupportsReShading, PreShade and PostShade
// end - ke/mjm - 03.16.00 - merge reshading code
// [attilas|29.5.2000] if this function changes, please also check EvalColorStdChannel
void CompositeMat::Shade(ShadeContext& sc)
{
	Mtl *sm1 = NULL;
	int id =0; 
//	float gamount;
	if (gbufID){
		sc.SetGBufferID(gbufID);
		id = gbufID;
	}

	Interval iv;
	int first = 1;
	ShadeOutput out1;
	int nEles = sc.NRenderElements();
	
	for (int i = 0; i < MAX_NUM_MTLS; i++){
		BOOL enabled;
		float amount;
		if (i==0) enabled = 1;
		else pblock2->GetValue(compmat_map_on,sc.CurTime(),enabled,iv,i-1);
		if (enabled){
			pblock2->GetValue(compmat_mtls,sc.CurTime(),sm1,iv,i);
			if (sm1 != NULL){
				if (i==0) amount = 100.f;
				else pblock2->GetValue(compmat_amount,sc.CurTime(),amount,iv,i-1);
				amount = amount*0.01f;
				int type;
				if (i==0) type = 2;
				else pblock2->GetValue(compmat_type,sc.CurTime(),type,iv,i-1);

				if (first ==1){	// first material
					first = 0;
					sm1->Shade(sc); // sc.out already reset for first
					out1 = sc.out;
					if (type == 0){
						out1.t.r += 1.0f-amount;
						out1.t.g += 1.0f-amount;
						out1.t.b += 1.0f-amount;
						out1.c *= amount;
						out1.t.ClampMinMax();

						// render elements
						for( int i = 0; i < nEles; ++i )
							out1.elementVals[i] *= amount;

					}
					out1.ior *= amount;

//					gamount = 1.0f-(out1.t.r + out1.t.g + out1.t.b)/3.0f;
				
				} else {	// not first material
//					pblock2->GetValue(compmat_mtls,sc.CurTime(),sm2,iv,i);
//					sc.out.ior = s*a.ior + f*ior;
//					if (f<=0.5f) gbufId = a.gbufId;
					sc.ResetOutput();
					sm1->Shade(sc);
					ShadeOutput out2 = sc.out;

					if (type == 0){  // additive
						out2.t.r += 1.0f-amount;
						out2.t.g += 1.0f-amount;
						out2.t.b += 1.0f-amount;
						out2.c *= amount;
						out2.t.ClampMinMax();

						out2.ior *= amount;

						float f1 = 1.0f-(out1.t.r + out1.t.g + out1.t.b)/3.0f; 
						float f2 = 1.0f-(out2.t.r + out2.t.g + out2.t.b)/3.0f; 

						out1.c =  out1.c *(1.0f-f2) + out2.c * (f1); 
						out1.t =  out1.t- (1.0f-out2.t);
						out1.ior = out1.ior + out2.ior;
//						if (f2 > gamount) {
//							gamount = f2;
//							out1.gbufId = out1.gbufId;//?? ke 6.13.00
//						}
						out1.t.ClampMinMax();
			
						// render elements
						for( int i = 0; i < nEles; ++i )
							out1.elementVals[i] = out1.elementVals[i] * (1.0f-f2) + out2.elementVals[i] * f1;
				
					} else if (type == 1) { // subtractive
						//NB: as of 6.13.00 this is SAME as additive case
						out2.t.r += 1.0f-amount;
						out2.t.g += 1.0f-amount;
						out2.t.b += 1.0f-amount;
						out2.c *= amount;

						out2.t.ClampMinMax();

						out2.ior *= amount;

						float f1 = 1.0f-(out1.t.r + out1.t.g + out1.t.b)/3.0f; 
						float f2 = 1.0f-(out2.t.r + out2.t.g + out2.t.b)/3.0f; 

						out1.c =  out1.c *(1.0f-f2) - out2.c * f1; 
						out1.t =  out1.t- (1.0f-out2.t);
						out1.ior = out1.ior + out2.ior;
//						if (f2 > gamount){
//							gamount = f2;
//							out1.gbufId = out1.gbufId;	//?? ke 6.13.00
//						}
						out1.t.ClampMinMax();

						// render elements
						for( int i = 0; i < nEles; ++i )
							out1.elementVals[i] = out1.elementVals[i] * (1.0f-f2) + out2.elementVals[i] * f1;
					
					} else { //mix

						// mixIn handles render elements
						out1.MixIn(out2,1.0f-amount);
					}
				}// end, not first mtl
			} // end, sm1 not null
		}// end, enabled
	} // end, for each material

	sc.out = out1;
}