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::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 ); } }