// 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; }