// specular reflectivity, no colors yet, all vectors assumed normalized float GaussHighlight( float gloss, float aniso, float orient, Point3& N, Point3& V, Point3& L, Point3& T, float* pNL ) { float out = 0.0f; float asz = (1.0f - gloss) * ALPHA_SZ; float ax = ALPHA_MIN + asz; float ay = ALPHA_MIN + asz * (1.0f-aniso); // DbgAssert( ax >= 0.0f && ay >= 0.0f ); LBound( ax ); LBound( ay ); Point3 H = Normalize(L - V); // (L + -V)/2 float NH = DotProd(N, H); if (NH > 0.0f) { float axy = /* normalizeOn ? ax * ay : */ DEFAULT_GLOSS2; float norm = 1.0f / (4.0f * PI * axy ); float NV = -DotProd(N, V ); if ( NV <= 0.001f) NV = 0.001f; float NL = pNL ? *pNL : DotProd( N, L ); float g = 1.0f / (float)sqrt( NL * NV ); if ( g > 3.0f ) g = 3.0f; // Apply Orientation rotation here float or = orient * 180.0f; Point3 T1 = T; if ( or != 0.0f ) T1 = RotateVec( T, N, DegToRdn(or)); // get binormal Point3 B = CrossProd( T1, N ); float x = Dot( H, T1 ) / ax; float y = Dot( H, B ) / ay; float e = (float)exp( -2.0 * (x*x + y*y) / (1.0+NH) ); out = norm * g * e; } return SPEC_MAX * out; // does not have speclev or light color or kL }
////////////////////////////////////////////////////////////////////////////// // // transpColor utility // Color transpColor( ULONG type, float opac, Color& filt, Color& diff ) { // Compute the color of the transparent filter color if ( type == TRANSP_ADD ) { // flags & STDMTL_ADD_TRANSP) { float f = 1.0f - opac; return Color(f, f, f); } else if ( type == TRANSP_FILTER ) { //flags & STDMTL_FILT_TRANSP ){ // Transparent Filter color mapping if (opac>0.5f) { // darken as opac goes ( 0.5--> 1.0) // so that max component reaches 0.0f when opac reaches 1.0 // find max component of filt float m = Max(filt); float d = 2.0f*(opac-.5f)*m; Color fc = filt-d; fc = LBound( fc ); return fc; } else { // lighten as opac goes ( 0.5--> 0.0) // so that min component reaches 1.0f when opac reaches 1.0 // find min component of filt float m = Min(filt); float d = (1.0f-2.0f*opac)*(1.0f-m); Color fc = filt+d; fc = UBound( fc ); return fc; } } else { // original 3DS transparency Color f = (1.0f-diff); return (1.0f-opac)*f; } }
// returns shadow fraction & shadowClr // move this util to shade context at first opportunity float IllumShadow( ShadeContext& sc, Color& shadowClr ) { IlluminateComponents illumComp; IIlluminationComponents* pIComponents = NULL; Color illumClr(0,0,0); Color illumClrNS(0,0,0); shadowClr.Black(); Point3 N = sc.Normal(); // scale the sums so we don't overflow // float scaleFactor = 1.0; // if( sc.nLights ) // scaleFactor = 1.0f / float( sc.nLights ); // > 9/24/02 - 2:30pm --MQM-- // poke flag to let Light Tracer/Radiosity so they will // separate out the shadow value. int oldXID = sc.xshadeID; sc.xshadeID |= SHADECONTEXT_GUESS_SHADOWS_FLAG; for (int i = 0; i < sc.nLights; i++) { LightDesc* l = sc.Light( i ); pIComponents = (IIlluminationComponents*)l->GetInterface( IID_IIlluminationComponents ); if( pIComponents ){ // use component wise illuminate routines if (!pIComponents->Illuminate( sc, N, illumComp )) continue; // illumClr += (illumComp.finalColor - illumComp.shadowColor ) * illumComp.geometricAtten * scaleFactor; LBound( illumComp.shadowColor ); illumClr += (illumComp.finalColor - illumComp.shadowColor ) * illumComp.geometricAtten; // illumClrNS += illumComp.finalColorNS * illumComp.geometricAtten * scaleFactor; illumClrNS += illumComp.finalColorNS * illumComp.geometricAtten; if( illumComp.rawColor != illumComp.filteredColor ){ // light is filtered by a transparent object, sum both filter & user shadow color shadowClr += illumComp.finalColor * illumComp.geometricAtten; //attenuated filterColor } else { // no transparency, sum in just the shadow color shadowClr += illumComp.shadowColor * illumComp.geometricAtten; } } else { // no component interface, shadow clr is black Color lightCol; Point3 L; register float NL, diffCoef; if (!l->Illuminate(sc, N, lightCol, L, NL, diffCoef)) continue; if (diffCoef <= 0.0f) continue; // illumClr += diffCoef * lightCol * scaleFactor; illumClr += diffCoef * lightCol; if( sc.shadow ){ sc.shadow = FALSE; l->Illuminate(sc, N, lightCol, L, NL, diffCoef); // illumClrNS += diffCoef * lightCol * scaleFactor; illumClrNS += diffCoef * lightCol; sc.shadow = TRUE; } else { illumClrNS = illumClr; } } }// end, for each light // > 9/24/02 - 2:31pm --MQM-- // restore xshadeID sc.xshadeID = oldXID; float intensNS = Intens(illumClrNS); // Clamp( intensNS ); float intens = Intens(illumClr); // Clamp( intens ); float atten = (intensNS > 0.01f)? intens/intensNS : 1.0f; if (atten > 1.0f) atten = 1.0f/atten; return atten; }