Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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 );
	}
}