AColor plLayerTex::EvalColor(ShadeContext& sc) { if (!sc.doMaps) return AColor(0.0f, 0.0f, 0.0f, 1.0f); AColor color; if (sc.GetCache(this, color)) return color; if (gbufID) sc.SetGBufferID(gbufID); // // Evaluate the Bitmap // if (fBitmapPB->GetInt(kBmpUseBitmap) && fBM) { plBMSampler mysamp(this, fBM); color = fUVGen->EvalUVMap(sc, &mysamp, FALSE); // We'd like to pass TRUE and actually filter the image, but that seems to be // tripping an odd crash in Max internals. *shrug* } else color.White(); // Invert color if specified if (fBitmapPB->GetInt(kBmpInvertColor)) { color.r = 1.0f - color.r; color.g = 1.0f - color.g; color.b = 1.0f - color.b; } // Discard color if specified if (fBitmapPB->GetInt(kBmpDiscardColor)) color.r = color.g = color.b = 1.0f; // Invert alpha if specified if (fBitmapPB->GetInt(kBmpInvertAlpha)) color.a = 1.0f - color.a; // Discard alpha if specified if (fBitmapPB->GetInt(kBmpDiscardAlpha)) color.a = 1.0f; // If RGB output is set to alpha, show RGB as grayscale of the alpha if (fBitmapPB->GetInt(kBmpRGBOutput) == 1) color = AColor(color.a, color.a, color.a, 1.0f); sc.PutCache(this, color); return color; }
void plPassMtl::ShadeWithBackground(ShadeContext &sc, Color background, bool useVtxAlpha /* = true */) { #if 1 // old #if 0 Color lightCol,rescol, diffIllum0; RGBA mval; Point3 N0,P; BOOL bumped = FALSE; int i; if (gbufID) sc.SetGBufferID(gbufID); if (sc.mode == SCMODE_SHADOW) { float opac = 0.0; for (i=0; i < NumSubTexmaps(); i++) { if (SubTexmapOn(i)) { hsMaxLayerBase *hsmLay = (hsMaxLayerBase *)GetSubTexmap(i); opac += hsmLay->GetOpacity(t); } } float f = 1.0f - opac; sc.out.t = Color(f,f,f); return; } N0 = sc.Normal(); P = sc.P(); #endif TimeValue t = sc.CurTime(); Color color(0, 0, 0); float alpha = 0.0; // Evaluate Base layer Texmap *map = fLayersPB->GetTexmap(kPassLayBase); if (map && ( map->ClassID() == LAYER_TEX_CLASS_ID || map->ClassID() == STATIC_ENV_LAYER_CLASS_ID ) ) { plLayerTex *layer = (plLayerTex*)map; AColor evalColor = layer->EvalColor(sc); color = evalColor; alpha = evalColor.a; } // Evaluate Top layer, if it's on if (fLayersPB->GetInt(kPassLayTopOn)) { Texmap *map = fLayersPB->GetTexmap(kPassLayTop); if (map && ( map->ClassID() == LAYER_TEX_CLASS_ID || map->ClassID() == STATIC_ENV_LAYER_CLASS_ID || map->ClassID() == ANGLE_ATTEN_LAYER_CLASS_ID) ) { plPlasmaMAXLayer *layer = (plPlasmaMAXLayer*)map; AColor evalColor = layer->EvalColor(sc); // Blend layers if( !layer->DiscardColor() ) { int blendType = fLayersPB->GetInt(kPassLayBlend); switch (blendType) { case kBlendAdd: color += evalColor * evalColor.a; break; case kBlendAlpha: color = (1.0f - evalColor.a) * color + evalColor.a * evalColor; break; case kBlendMult: color *= evalColor; break; default: // No blend... color = evalColor; break; } } if( !layer->DiscardAlpha() ) { int alphaType = fLayersPB->GetInt(kPassLayOutputBlend); switch( alphaType ) { case kAlphaMultiply: alpha *= evalColor.a; break; case kAlphaAdd: alpha += evalColor.a; break; case kAlphaDiscard: default: break; } } } } #if 1 AColor black; black.Black(); AColor white; white.White(); SIllumParams ip; if (fBasicPB->GetInt(kPassBasEmissive)) { // Emissive objects don't get shaded ip.diffIllum = fBasicPB->GetColor(kPassBasColorAmb, t) * color; ip.diffIllum.ClampMinMax(); ip.specIllum = black; } else { // // Shading setup // // Setup the parameters for the shader ip.amb = fBasicPB->GetColor(kPassBasColorAmb, t); ip.diff = fBasicPB->GetColor(kPassBasColor, t) * color; ip.diffIllum = black; ip.specIllum = black; ip.N = sc.Normal(); ip.V = sc.V(); // // Specularity // if (fBasicPB->GetInt(kPassBasUseSpec, t)) { ip.sh_str = 1.f; ip.spec = fBasicPB->GetColor( kPassBasSpecColor, t ); ip.ph_exp = (float)pow(2.0f,float(fBasicPB->GetInt(kPassBasShine, t)) / 10.0f); ip.shine = float(fBasicPB->GetInt(kPassBasShine, t)) / 100.0f; } else { ip.spec = black; ip.sh_str = 0; ip.ph_exp = 0; ip.shine = 0; } ip.softThresh = 0; // // Do the shading Shader *myShader = GetShader(SHADER_BLINN); myShader->Illum(sc, ip); // Override shader parameters if (fAdvPB->GetInt(kPBAdvNoShade)) { ip.diffIllum = black; ip.specIllum = black; } if (fAdvPB->GetInt(kPBAdvWhite)) { ip.diffIllum = white; ip.specIllum = black; } ip.specIllum.ClampMinMax(); ip.diffIllum = ip.amb * sc.ambientLight + ip.diff * ip.diffIllum; ip.diffIllum.ClampMinMax(); } // AColor returnColor = AColor(opac * ip.diffIllum + ip.specIllum, opac) #endif // Get opacity and combine with alpha float opac = float(fBasicPB->GetInt(kPassBasOpacity, t)) / 100.0f; alpha *= opac; float vtxAlpha = 1.0f; if (useVtxAlpha && GetOutputBlend() == plPassMtlBase::kBlendAlpha) { Point3 p; GetInterpVtxValue(MAP_ALPHA, sc, p); vtxAlpha = p.x; } alpha *= vtxAlpha; // MAX will do the additive/alpha/no blending for us based on what Requirements() // we tell it. However, since MAX's formula is bgnd*sc.out.t + sc.out.c, // we have to multiply our output color by the alpha. // If we ever need a more complicated blending function, you can request the // background color via Requirements() (otherwise it's just black) and then do // the blending yourself; however, if the transparency isn't set, the shadows // will be opaque, so be careful. Color outC = ip.diffIllum + ip.specIllum; sc.out.c = ( outC * alpha ); sc.out.t = Color( 1.f - alpha, 1.f - alpha, 1.f - alpha ); #endif }
AColor plStaticEnvLayer::EvalColor(ShadeContext& sc) { if (!sc.doMaps) return AColor(0.0f, 0.0f, 0.0f, 1.0f); AColor color; if (sc.GetCache(this, color)) return color; if (gbufID) sc.SetGBufferID(gbufID); // Evaluate the Bitmap // Point3 v = sc.VectorTo( sc.V(), REF_OBJECT );//WORLD ); Point3 v = sc.VectorTo( sc.Normal(), REF_OBJECT ); float wx,wy,wz; Color rcol; Bitmap *refmap = NULL; Point3 rv; Point2 uv; int size; wx = (float)fabs( v.x ); wy = (float)fabs( v.y ); wz = (float)fabs( v.z ); if( wx >= wy && wx >= wz ) { if( v.x < 0 ) { refmap = fBitmaps[ kLeftFace ]; uv = CompUV( -v.y, -v.z, v.x ); } else { refmap = fBitmaps[ kRightFace ]; uv = CompUV( v.y, -v.z, -v.x ); } } else if( wy >= wx && wy >= wz ) { if( v.y > 0 ) { refmap = fBitmaps[ kBackFace ]; uv = CompUV( -v.x, -v.z, -v.y ); } else { refmap = fBitmaps[ kFrontFace ]; uv = CompUV( v.x, -v.z, v.y ); } } else if( wz >= wx && wz >= wy ) { if( v.z < 0 ) { refmap = fBitmaps[ kBottomFace ]; uv = CompUV( -v.x, -v.y, v.z ); } else { refmap = fBitmaps[ kTopFace ]; uv = CompUV( -v.x, v.y, -v.z ); } } if( refmap == NULL ) color.White(); else { if( uv.x < 0.0f ) uv.x = 0.0f; else if( uv.x > 1.0f ) uv.x = 1.0f; if( uv.y < 0.0f ) uv.y = 0.0f; else if( uv.y > 1.0f ) uv.y = 1.0f; size = refmap->Width(); int x = (int)( uv.x * (float)( size - 1 ) ); int y = (int)( ( 1.0f - uv.y ) * (float)( size - 1 ) ); BMM_Color_64 c; refmap->GetLinearPixels( x, y, 1, &c ); color = AColor( c.r / 65535.f, c.g / 65535.f, c.b / 65535.f, c.a / 65535.f ); } // Invert color if specified if( fBitmapPB->GetInt( kBmpInvertColor ) ) { color.r = 1.0f - color.r; color.g = 1.0f - color.g; color.b = 1.0f - color.b; } // Discard color if specified if( fBitmapPB->GetInt( kBmpDiscardColor ) ) color.r = color.g = color.b = 1.0f; // Invert alpha if specified if( fBitmapPB->GetInt( kBmpInvertAlpha ) ) color.a = 1.0f - color.a; // Discard alpha if specified if( fBitmapPB->GetInt( kBmpDiscardAlpha ) ) color.a = 1.0f; // If RGB output is set to alpha, show RGB as grayscale of the alpha if( fBitmapPB->GetInt( kBmpRGBOutput ) == 1 ) color = AColor( color.a, color.a, color.a, 1.0f ); sc.PutCache(this, color); return color; }
void plParticleMtl::ShadeWithBackground(ShadeContext &sc, Color background) { #if 1 TimeValue t = sc.CurTime(); Color color(0, 0, 0); float alpha = 0.0; // Evaluate Base layer Texmap *map = fBasicPB->GetTexmap(kTexmap); if (map && map->ClassID() == LAYER_TEX_CLASS_ID) { plLayerTex *layer = (plLayerTex*)map; AColor evalColor = layer->EvalColor(sc); color = evalColor; alpha = evalColor.a; } #if 1 AColor black; black.Black(); AColor white; white.White(); SIllumParams ip; if( fBasicPB->GetInt( kNormal ) == kEmissive ) { // Emissive objects don't get shaded ip.diffIllum = fBasicPB->GetColor(kColorAmb, t) * color; ip.diffIllum.ClampMinMax(); ip.specIllum = black; } else { // // Shading setup // // Setup the parameters for the shader ip.amb = black; ip.diff = fBasicPB->GetColor(kColor, t) * color; ip.spec = white; ip.diffIllum = black; ip.specIllum = black; ip.N = sc.Normal(); ip.V = sc.V(); // // Specularity // ip.sh_str = 0; ip.ph_exp = 0; ip.shine = 0; ip.softThresh = 0; // Do the shading Shader *myShader = GetShader(SHADER_BLINN); myShader->Illum(sc, ip); ip.diffIllum.ClampMinMax(); ip.specIllum.ClampMinMax(); ip.diffIllum = ip.amb * sc.ambientLight + ip.diff * ip.diffIllum; } // AColor returnColor = AColor(opac * ip.diffIllum + ip.specIllum, opac) #endif // Get opacity and combine with alpha float opac = float(fBasicPB->GetInt(kOpacity, t)) / 100.0f; //float opac = 1.0f; alpha *= opac; // MAX will do the additive/alpha/no blending for us based on what Requirements() // we tell it. However, since MAX's formula is bgnd*sc.out.t + sc.out.c, // we have to multiply our output color by the alpha. // If we ever need a more complicated blending function, you can request the // background color via Requirements() (otherwise it's just black) and then do // the blending yourself; however, if the transparency isn't set, the shadows // will be opaque, so be careful. Color outC = ip.diffIllum + ip.specIllum; sc.out.c = ( outC * alpha ); sc.out.t = Color( 1.f - alpha, 1.f - alpha, 1.f - alpha ); #endif }