static int print(const Spectrum &s) { Float rgb[3]; s.ToRGB(rgb); int np = print(rgb[0]); np += print(rgb[1]); return np + print(rgb[2]); }
void SubsurfaceFromDiffuse(const Spectrum &Kd, float meanPathLength, float eta, Spectrum *sigma_a, Spectrum *sigma_prime_s) { float A = (1.f + Fdr(eta)) / (1.f - Fdr(eta)); float rgb[3]; Kd.ToRGB(rgb); float sigma_prime_s_rgb[3], sigma_a_rgb[3]; for (int i = 0; i < 3; ++i) { float alphap = RdToAlphap(rgb[i], A); float sigma_tr = 1.f / meanPathLength; float sigma_prime_t = sigma_tr / sqrtf(3.f * 1.f - alphap); sigma_prime_s_rgb[i] = alphap * sigma_prime_t; sigma_a_rgb[i] = sigma_prime_t - sigma_prime_s_rgb[i]; } *sigma_a = Spectrum::FromRGB(sigma_a_rgb); *sigma_prime_s = Spectrum::FromRGB(sigma_prime_s_rgb); }
void testMaterial(DifferentialGeometry &dg) { float c1[] = {1.f,1.f,1.f}; Spectrum spec1 = RGBSpectrum::FromRGB(c1, SpectrumType::SPECTRUM_REFLECTANCE); MatteMaterial *matte = new MatteMaterial( new ConstantTexture<Spectrum>(spec1), new ConstantTexture<float>(0.0f), NULL); MemoryArena m; BSDF* bsdf = matte->GetBSDF(dg, dg, m); Vector woW = Point(-10,0,0) - dg.p; Vector wiW = Point(-7,2,2) - dg.p; // world vectors Spectrum spec = bsdf->f(woW, wiW); float rgb[3]; spec.ToRGB(rgb); printf("spectrum %g %g %g\n", rgb[0], rgb[1], rgb[2]); }
// Integrator Utility Functions Spectrum UniformSampleAllLights(const Scene *scene, const Renderer *renderer, MemoryArena &arena, const Point &p, const Normal &n, const Vector &wo, float rayEpsilon, float time, BSDF *bsdf, const Sample *sample, RNG &rng, const LightSampleOffsets *lightSampleOffsets, const BSDFSampleOffsets *bsdfSampleOffsets) { Spectrum L(0.); Spectrum zero(0.); Vector wi; // Normal vector to sample PBRT's BRDF wi.x = n.x; wi.y = n.y; wi.z = n.z; vector<cutvertex> cut; // Heap (based on error) of vertices in the cut cutvertex v; Spectrum total; // Store the total illumination for the current cut v.l = scene->lighttree; // Initial cut consists only the root SetError(v); // Compute it's error Factor(v); // Compute it's factor Illuminate(v); // Compute it's illumination total = v.illumination; cut.push_back(v); while(cut.size() < MAXCUT) { pop_heap(cut.begin(), cut.end()); // Get the vertex in the cut with the maximum error v = cut[cut.size() - 1]; float err[3]; float intensity[3]; v.error.ToRGB(err); total.ToRGB(intensity); // Check if error is below the threshold. If so, we are done if(err[0] >= 0 && err[1] >= 0 && err[2] >= 0 && err[0] <= THRESHOLD * intensity[0] && err[1] <= THRESHOLD * intensity[1] && err[2] <= THRESHOLD * intensity[2]) break; // If not, refine the cut by subdividing this vertex cut.pop_back(); // Remove the vertex from the cut total = total - v.illumination; // Remove the illumination due to this vertex cutvertex v1, v2; // We will add the vertex's children to the cut v1.l = v.l->leftChild; v2.l = v.l->rightChild; // Compute their errors and illumination SetError(v1); SetError(v2); if(v1.l != v.l) { Factor(v1); } else { v1.factor = v.factor; } if(v2.l != v.l) { Factor(v2); } else { v2.factor = v.factor; } Illuminate(v1); Illuminate(v2); // Add them to the cut and update the total illumination cut.push_back(v1); push_heap(cut.begin(), cut.end()); total += v1.illumination; cut.push_back(v2); push_heap(cut.begin(), cut.end()); total += v2.illumination; } return total; }