void StraussShader::Illum(ShadeContext &sc, IllumParams &ip) { LightDesc *l; Color lightClr; #ifdef _DEBUG IPoint2 sp = sc.ScreenCoord(); if ( sp.x == stopX && sp.y == stopY ) sp.x = stopX; #endif float opac = ip.channels[ S_TR ].r; float g = ip.channels[ S_GL ].r; float m = ip.channels[ S_MT ].r; Color Cd = ip.channels[ S_DI ]; // BOOL dimDiffuse = ip.hasComponents & HAS_REFLECT; BOOL dimDiffuse = ip.hasComponents & HAS_REFLECT_MAP; float rd; float g3 = Cube( g ); if ( dimDiffuse ) rd = (1.0f - g3) * opac; else rd = (1.0f - m * g3) * opac; //ke 10/28/98 float rn = opac - (1.0f - g3) * opac; float h = (g == 1.0f ) ? 600.0f : 3.0f / (1.0f - g ); float d = 1.0f - m * g; for (int i=0; i<sc.nLights; i++) { l = sc.Light(i); float NL, Kl; Point3 L; if (l->Illuminate( sc, sc.Normal(), lightClr, L, NL, Kl)) { if (l->ambientOnly) { ip.ambIllumOut += lightClr; continue; } if (NL<=0.0f) continue; // diffuse if (l->affectDiffuse){ ip.diffIllumOut += Kl * d * rd * lightClr; } // specular if (l->affectSpecular) { // strauss uses the reflected LIGHT vector Point3 R = L - 2.0f * NL * sc.Normal(); R = Normalize( R ); float RV = -Dot(R, sc.V() ); float s; if (RV < 0.0f) { // soften if ( NL < softThresh ) RV *= SoftSpline2( NL / softThresh ); // specular function s = SpecBoost * (float)pow( -RV, h); } else continue; float a, b; a = (float)acos( NL ) * OneOverHalfPi; b = (float)acos( -Dot(sc.Normal(), sc.V()) ) * OneOverHalfPi; float fa = F( a ); float j = fa * G( a ) * G( b ); float rj = rn > 0.0f ? Bound( rn + (rn+kj)*j ) : rn; Color Cl = lightClr; // normalize the light color in case it's really bright float I = NormClr( Cl ); Color Cs = Cl + m * (1.0f - fa) * (Cd - Cl); ip.specIllumOut += s * rj * I * Cs; } // end, if specular } // end, illuminate } // for each light // now we can multiply by the clrs, except specular, which is already done ip.ambIllumOut *= 0.5f * rd * Cd; ip.diffIllumIntens = Intens(ip.diffIllumOut); ip.diffIllumOut *= Cd; // next due reflection if ( ip.hasComponents & HAS_REFLECT ){ Color rc = ip.channels[ ip.stdIDToChannel[ ID_RL ] ]; AffectReflection(sc, ip, rc); ip.reflIllumOut = rc * ip.reflectAmt; } // last do refraction/ opacity if ( (ip.hasComponents & HAS_REFRACT) ){ // Set up attenuation opacity for Refraction map. dim diffuse & spec by this ip.finalAttenuation = ip.finalOpac * (1.0f - ip.refractAmt); // Make more opaque where specular hilite occurs: float max = Max(ip.specIllumOut); if (max > 1.0f) max = 1.0f; float newOpac = ip.finalAttenuation + max - ip.finalAttenuation * max; // Evaluate refraction map, filtered by filter color. // Color tClr = ((StdMat2*)(ip.pMtl))->TranspColor( newOpac, ip.channels[filtChan], ip.channels[diffChan]); Color tClr = transpColor( TRANSP_FILTER, newOpac, Cd, Cd ); ip.transIllumOut = ip.channels[ ip.stdIDToChannel[ ID_RR ] ] * tClr; // no transparency when doing refraction ip.finalT.Black(); } else { // no refraction, transparent? ip.finalAttenuation = opac; if (ip.hasComponents & HAS_OPACITY) { // ip.finalT = Cd * (1.0f-opac); Cd = greyVal * Color( 1.0f, 1.0f, 1.0f ) + clrVal * Cd; ip.finalT = transpColor( TRANSP_FILTER, opac, Cd, Cd ); } } if (sc.globContext != NULL && sc.globContext->pToneOp != NULL) { if (isInvertSelfIllum()) sc.globContext->pToneOp->RGBToScaled(ip.selfIllumOut); if (isInvertReflect() && (ip.hasComponents & HAS_REFLECT)) sc.globContext->pToneOp->RGBToScaled(ip.reflIllumOut); if (isInvertRefract() && (ip.hasComponents & HAS_REFRACT)) sc.globContext->pToneOp->RGBToScaled(ip.transIllumOut); } CombineComponents( sc, ip ); }
void OrenNayarBlinnShader::Illum(ShadeContext &sc, IllumParams &ip) { LightDesc *l; Color lightCol; #ifdef _DEBUG IPoint2 sp = sc.ScreenCoord(); if ( sp.x == stopX && sp.y == stopY ) sp.x = stopX; #endif // Blinn style phong BOOL isShiny= (ip.channels[ID_SS].r > 0.0f) ? 1 : 0; double phExp = 0.0; if (isShiny) phExp = pow(2.0, ip.channels[ID_SH].r * 10.0) * 4.0; for (int i=0; i<sc.nLights; i++) { l = sc.Light(i); float NL, kL; Point3 L; if (l->Illuminate( sc, sc.Normal(), lightCol, L, NL, kL)) { if (l->ambientOnly) { ip.ambIllumOut += lightCol; continue; } if (NL<=0.0f) continue; // specular Color spec( 0.0f, 0.0f, 0.0f ); if (isShiny && l->affectSpecular) { Point3 H = Normalize(L-sc.V() ); // (L + -V)/2 float c = DotProd(sc.Normal(), H); if (c>0.0f) { if (softThresh != 0.0 && kL < softThresh) { c *= Soften(kL/softThresh); } c = (float)pow((double)c, phExp); // could use table lookup for speed spec = c * ip.channels[ID_SS].r * lightCol; ip.specIllumOut += spec; } } // diffuse if (l->affectDiffuse){ float diffIntens; Color d = OrenNayarIllum( sc.Normal(), L, sc.V(), ip.channels[ID_DIFF_ROUGH].r * Pi*0.5f, ip.channels[ID_DI], &diffIntens, NL ); d = d * ip.channels[ID_DIFF_LEV].r; ip.diffIllumOut += kL * d * lightCol; ip.diffIllumIntens += kL * diffIntens * Intens(lightCol); } } } // for each light // Apply mono self illumination if ( ! selfIllumClrOn ){ float si = 0.3333333f * (ip.channels[ID_SI].r + ip.channels[ID_SI].g + ip.channels[ID_SI].b); // float si = ip.channels[ID_SI].r; //DS: 4/23/99 if ( si > 0.0f ) { si = Bound( si ); ip.selfIllumOut = si * ip.channels[ID_DI]; ip.diffIllumOut *= (1.0f - si); // fade the ambient down on si: 5/27/99 ke ip.ambIllumOut *= 1.0f-si; } } else { // colored self illum, ip.selfIllumOut += ip.channels[ID_SI]; } // get the diffuse intensity...unscramble the wavelength dependence // float rho, diffIntens; // rho = ip.channels[ID_DI].r == 0.0f ? 1.0f : 1.0f / ip.channels[ID_DI].r; // diffIntens = ip.diffIllumOut.r * rho; // rho = ip.channels[ID_DI].g == 0.0f ? 1.0f : 1.0f / ip.channels[ID_DI].g; // diffIntens += ip.diffIllumOut.g * rho; // rho = ip.channels[ID_DI].b == 0.0f ? 1.0f : 1.0f / ip.channels[ID_DI].b; // diffIntens += ip.diffIllumOut.b * rho; // ip.diffIllumIntens = diffIntens * 0.5f; // now we can multiply by the clrs ip.specIllumOut *= ip.channels[ID_SP]; ip.ambIllumOut *= ip.channels[ID_AM]; int chan = ip.stdIDToChannel[ ID_RR ]; ShadeTransmission(sc, ip, ip.channels[chan], ip.refractAmt); chan = ip.stdIDToChannel[ ID_RL ]; ShadeReflection( sc, ip, ip.channels[chan] ); if (sc.globContext != NULL && sc.globContext->pToneOp != NULL) { if (isInvertSelfIllum()) sc.globContext->pToneOp->RGBToScaled(ip.selfIllumOut); if (isInvertReflect() && (ip.hasComponents & HAS_REFLECT)) sc.globContext->pToneOp->RGBToScaled(ip.reflIllumOut); if (isInvertRefract() && (ip.hasComponents & HAS_REFRACT)) sc.globContext->pToneOp->RGBToScaled(ip.transIllumOut); } CombineComponents( sc, ip ); }
void WardShader::Illum(ShadeContext &sc, IllumParams &ip) { LightDesc *l; Color lightCol; #ifdef _DEBUG IPoint2 sp = sc.ScreenCoord(); if ( sp.x == stopX && sp.y == stopY ) sp.x = stopX; #endif BOOL isShiny= (ip.channels[W_SL].r > 0.0f) ? 1 : 0; for (int i=0; i<sc.nLights; i++) { l = sc.Light(i); float NL, Kl; Point3 L; if (l->Illuminate( sc, sc.Normal(), lightCol, L, NL, Kl)) { if (l->ambientOnly) { ip.ambIllumOut += lightCol; continue; } if (NL<=0.0f) continue; // diffuse if (l->affectDiffuse){ ip.diffIllumOut += Kl / Pi * ip.channels[W_DL].r * lightCol; } // specular if (isShiny && l->affectSpecular) { float gx = ip.channels[W_GX].r; float gy = ip.channels[W_GY].r; assert( gx >= 0.0f && gy >= 0.0f ); Point3 H = Normalize(L - sc.V() ); // (L + -V)/2 float NH = DotProd(sc.Normal(), H); if (NH > 0.0f) { float g2 = normalizeOn ? gx * gy : DEFAULT_GLOSS2; float norm = 1.0f / (4.0f * PI * g2); float NV = -DotProd(sc.Normal(), sc.V() ); if ( NV <= 0.001f) NV = 0.001f; float g = 1.0f / (float)sqrt( NL * NV ); if ( g > 6.0f ) g = 6.0f; //Point3 basisVecs[ 3 ]; //sc.DPdUVW( basisVecs, uvChan ); // 0 is vtxclr, 1..n is uv channels, max_meshmaps in mesh.h //basisVecs[0] = Normalize( basisVecs[0] ); // This is the new preferred method for getting bump basis vectors -- DS 5/22/00 Point3 basisVecs[2]; sc.BumpBasisVectors(basisVecs, 0, uvChan); // the line between the tip of vec[0] and its projection on N is tangent Point3 T = basisVecs[0] - sc.Normal() * Dot( basisVecs[0], sc.Normal() ); Point3 B = CrossProd( sc.Normal(), T ); float x = DotProd( H, T ) / gx; float y = DotProd( H, B ) / gy; float e = (float)exp( -2.0 * (x*x + y*y) / (1.0+NH) ); ip.specIllumOut += Kl * ip.channels[W_SL].r * norm * g * e * lightCol; } } } } // for each light // now we can multiply by the clrs, ip.ambIllumOut *= ip.channels[W_AM]; ip.diffIllumIntens = Intens(ip.diffIllumOut); ip.diffIllumOut *= ip.channels[W_DI]; ip.specIllumOut *= ip.channels[W_SP]; int chan = ip.stdIDToChannel[ ID_RR ]; ShadeTransmission(sc, ip, ip.channels[chan], ip.refractAmt); chan = ip.stdIDToChannel[ ID_RL ]; ShadeReflection( sc, ip, ip.channels[chan] ); if (sc.globContext != NULL && sc.globContext->pToneOp != NULL) { if (isInvertSelfIllum()) sc.globContext->pToneOp->RGBToScaled(ip.selfIllumOut); if (isInvertReflect() && (ip.hasComponents & HAS_REFLECT)) sc.globContext->pToneOp->RGBToScaled(ip.reflIllumOut); if (isInvertRefract() && (ip.hasComponents & HAS_REFRACT)) sc.globContext->pToneOp->RGBToScaled(ip.transIllumOut); } CombineComponents( sc, ip ); }