// Seed random number generator void BerconGradient::seedRandomGen(ShadeContext& sc) { int seed = 1; if (previewMatIDMode) { seed = sc.mtlNum; } else { if (p_randMat) { seed += sc.mtlNum; } if (p_randObj) { int hand = (int)sc.Node()->GetHandle(); seed += hand*(hand*hand*15731 + 789221); } if (p_randPar) { Object *ob = sc.GetEvalObject(); if (ob && ob->IsParticleSystem()) { ParticleObject *obj = (ParticleObject*)ob; IChkMtlAPI* chkMtlAPI = static_cast<IChkMtlAPI*>(obj->GetInterface(I_NEWMTLINTERFACE)); if ((chkMtlAPI && chkMtlAPI->SupportsParticleIDbyFace())) { int id = chkMtlAPI->GetParticleFromFace(sc.FaceNumber()); seed += id*(id*id*571 + 789221); } } } if (p_randTile) { seed += (int)(sc.UVW(99).z); } } seed *= p_seed; srand(seed*(seed*seed*15731 + 789221)); }
// Calculates 0..1 value which is given to the gradient float BerconGradient::getGradientValue(ShadeContext& sc) { switch (p_type) { case 0: { // UVW break; // Handled in main evaluation } case 1: { // Normal switch (p_normalFunction) { case 0: { // Perpendicular / Parallel return fabs(getGradientValueNormal(sc)); } case 1: { // Towards / Away return (getGradientValueNormal(sc) + 1.f) / 2.f; } case 2: { // Fresnel // NOTE: Should this get IOR from sc.GetIOR()? // I think not since its just a map, not material. // You get more predictable behaviour with constant 1.f. static float n1 = 1.0f; float cti = fabs(getGradientValueNormal(sc)); float stt = (n1 / p_ior) * sqrt(1 - cti * cti); float ctt = sqrt(1 - stt * stt); float rs = (p_ior * ctt - n1 * cti ) / (p_ior * ctt + n1 * cti); rs = rs * rs; float rp = (n1 * ctt - p_ior * cti ) / (n1 * ctt + p_ior * cti); rp = rp * rp; return 1.f - 0.5f * (rs + rp); } } } case 2: { // Distance return getGradientValueDist(sc); } case 3: { // Light return Intens(sc.DiffuseIllum()); } case 4: { // Map return p_maptex?p_maptex->EvalMono(sc):0.f; // TODO: Evaluate submaps color, bump is tougher DELTA shift with BerconSC? } case 5: { // Random seedRandomGen(sc); return (float)sfrand(); break; } case 6: { // Particle age Object *ob = sc.GetEvalObject(); if (ob && ob->IsParticleSystem()) { ParticleObject *obj = (ParticleObject*)ob; TimeValue t = sc.CurTime(); TimeValue age = obj->ParticleAge(t,sc.mtlNum); TimeValue life = obj->ParticleLife(t,sc.mtlNum); if (age>=0 && life>=0) return float(age)/float(life); } break; } case 7: { // Particle speed Object *ob = sc.GetEvalObject(); if (ob && ob->IsParticleSystem()) { ParticleObject *obj = (ParticleObject*)ob; /*IChkMtlAPI* chkMtlAPI = static_cast<IChkMtlAPI*>(obj->GetInterface(I_NEWMTLINTERFACE)); if ((chkMtlAPI&&chkMtlAPI->SupportsParticleIDbyFace())) return (Length(obj->ParticleVelocity(sc.CurTime(),chkMtlAPI->GetParticleFromFace(sc.FaceNumber()))) - p_rangeMin) / (p_rangeMax - p_rangeMin); else*/ return Length(obj->ParticleVelocity(sc.CurTime(),sc.mtlNum)); } break; } case 8: { // Particle size Object *ob = sc.GetEvalObject(); if (ob && ob->IsParticleSystem()) { ParticleObject *obj = (ParticleObject*)ob; return obj->ParticleSize(sc.CurTime(),sc.mtlNum); } break; } default: break; } return 0.f; }