// 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; }
void M3Mat::PostShade(ShadeContext& sc, IReshadeFragment* pFrag, int& nextTexIndex, IllumParams* ip) { int i; IReshading* pReshading; TimeValue t = sc.CurTime(); Interval valid = FOREVER; pblockMat->GetValue(100,t,i,FOREVER); Mtl *sm1 = mTex[100]; float total(0.0f); ShadeOutput sDatabase[100]; float u[100]; ShadeOutput sFinal; // handle no base mat if(!sm1) { sc.ResetOutput(); sc.out.c = black; sc.out.t = black; return; } if(i==0 || (i==1 && inRender) ) { for( i=0; i<100; i++) { pblockMat->GetValue(i,t,u[i],valid); u[i] /= 100.0f; if( mTex[i]!=NULL && u[i]!=0 && mapOn[i] ) { Mtl *comb = mTex[i]; pReshading = (IReshading*)(comb->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PostShade(sc, pFrag, nextTexIndex, ip ); sDatabase[i] = sc.out; sc.ResetOutput(); total += u[i]; } } sc.ResetOutput(); pReshading = (IReshading*)(sm1->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PostShade(sc, pFrag, nextTexIndex, ip ); sFinal.c = black; sFinal.t = black; sFinal.ior = 0.0f; for( i=0;i<100;i++) { if(mTex[i]!=NULL && u[i]!=0 && mapOn[i]) { sc.out.flags |= sDatabase[i].flags; if(total>1.0f){ sFinal.c += u[i]/total * sDatabase[i].c; sFinal.t += u[i]/total * sDatabase[i].t; sFinal.ior += u[i]/total * sDatabase[i].ior; } else{ sFinal.c += u[i] * sDatabase[i].c; sFinal.t += u[i] * sDatabase[i].t; sFinal.ior += u[i] * sDatabase[i].ior; } } } if(total) { sc.out.MixIn(sFinal, 1.0f-total); } } else { pReshading = (IReshading*)(sm1->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PostShade(sc, pFrag, nextTexIndex, ip ); } }
void CompositeMat::PostShade(ShadeContext& sc, IReshadeFragment* pFrag, int& nextTexIndex, IllumParams* ) { int i(0), type(2); Mtl* submtl = NULL; BOOL enabled(TRUE); ShadeOutput out1, out2; float amount(100.0f); // , gamount(0.0f); char texLengths[12]; int* pI = (int*)&texLengths[0]; pI[0] = pFrag->GetIntChannel(nextTexIndex++); pI[1] = pFrag->GetIntChannel(nextTexIndex++); pI[2] = pFrag->GetIntChannel(nextTexIndex++); // postshade any submaterials for ( i=0; i<MAX_NUM_MTLS; i++) { if( i>0 ) pblock2->GetValue(compmat_map_on, sc.CurTime(), enabled, FOREVER, i-1); else enabled = TRUE; pblock2->GetValue(compmat_mtls, sc.CurTime(), submtl, FOREVER, i); if ( enabled && submtl ){ if( i > 0 ){ pblock2->GetValue(compmat_amount, sc.CurTime(), amount, FOREVER, i-1); pblock2->GetValue(compmat_type, sc.CurTime(), type, FOREVER, i-1); } amount = amount * 0.01f; sc.ResetOutput(); IReshading* pReshading = (IReshading*)(submtl->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PostShade(sc, pFrag, nextTexIndex); // first check for base material if( i > 0 ) { // not base material, composite the next material 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; out1.t.ClampMinMax(); } else if (type == 1) // subtractive { 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; out1.t.ClampMinMax(); } else //mix { out1.MixIn(out2, 1.0f-amount); } }// end, not base mtl else { // base material. out1 = sc.out; out1.ior *= amount; } }// end, if has submtl & enabled else { nextTexIndex += texLengths[i]; } }// end, for each mtl sc.out = out1; }
void M3Mat::Shade(ShadeContext& sc) { int i; TimeValue t = sc.CurTime(); Interval valid = FOREVER; pblockMat->GetValue(100,t,i,FOREVER); Mtl *sm1 = mTex[100]; float total(0.0f); ShadeOutput sFinal( sc.out.nElements ); // get nElements correctly ShadeOutput sDatabase[100]; // for( i = 0; i < 100; ++i ) // sDatabase[i] = sFinal; float u[100]; // handle no base mat if(!sm1) { sc.ResetOutput(); sc.out.c = black; sc.out.t = black; return; } if(i==0||(i==1&&inRender)) { for( i=0;i<100;i++) { pblockMat->GetValue(i,t,u[i],valid); u[i] /= 100.0f; if(mTex[i]!=NULL&&u[i]!=0&&mapOn[i]) { Mtl *comb = mTex[i]; comb->Shade(sc); sDatabase[i] = sc.out; sc.ResetOutput(); total += u[i]; } } sc.ResetOutput(); sm1->Shade(sc); sFinal.c = black; sFinal.t = black; sFinal.ior = 0.0f; for( i=0;i<100;i++) { if(mTex[i]!=NULL&&u[i]!=0&&mapOn[i]) { sc.out.flags |= sDatabase[i].flags; if(total>1.0f){ sFinal.c += u[i]/total * sDatabase[i].c; sFinal.t += u[i]/total * sDatabase[i].t; sFinal.ior += u[i]/total * sDatabase[i].ior; } else{ sFinal.c += u[i] * sDatabase[i].c; sFinal.t += u[i] * sDatabase[i].t; sFinal.ior += u[i] * sDatabase[i].ior; } } } if(total) { sc.out.MixIn(sFinal, 1.0f-total); } } else { sm1->Shade(sc); } }