public Vector3D untransform(Vector3D a, Vector3D dest) { dest.X = a.dot(u); dest.Y = a.dot(v); dest.Z = a.dot(w); return(dest); }
// Lambertian! Replace with general BSDF. public virtual void radianceEstimate(RGBColor rad, Vector3D position, Vector3D normal, float maxDist, int noPhotons) { //float ALPHA = 0.918f; float MBETA = -1.953f; float DENOMFACTOR = 1.0f / (1.0f - (float)System.Math.Exp(MBETA)); NearestPhotons np = new NearestPhotons(noPhotons, maxDist, position); rad.set(0.0f); // locate the nearest photons locatePhotons(np, 1); // if less than MINPHOTONS return if (np.found < photontracer.SceneConstants.MIN_PHOTONS) { return; } Vector3D direction = new Vector3D(); //float mittrs = MBETA / (2.0f * (float) np.dist2[0]); float kdenom = (float)(1.0 / (1.1 * Math.Sqrt(np.dist2[0]))); // sum irrandiance from all photons for (int i = 1; i <= np.found; i++) { float cosNL; Photon p = getPhoton(np.indices[i]); // the toCartesian call and following if can be omitted (for speed) // if the scene does not have any thin surfaces p.toCartesian(direction); cosNL = (float)direction.dot(normal); //cosNL = -1.0f; if (cosNL < 0.0) { //float gaussWeight = 1.0f - (1.0f - (float) System.Math.Exp((float) p.position.distanceSqr(position) * mittrs)) * DENOMFACTOR; float coneWeight = 1.0f - (float)(p.position.distance(position) * kdenom); //rad.add(p.power.scaleNew((- cosNL) * gaussWeight)); //rad.add(p.power.scaleNew((- cosNL))); rad.add(p.power.scaleNew(coneWeight)); } } // estimate of density //rad.scale(ALPHA / (float) (System.Math.PI * np.dist2[0])); //rad.scale(1.0f / (float) (System.Math.PI * np.dist2[0])); rad.scale(1.0f / (float)((1.0f - 2.0f / (3.0f * 1.1f)) * System.Math.PI * np.dist2[0])); }
public override bool intersect(Ray ray, Intersection intersection) { double vd; double vx; double vy; Vector3D orig = ray.Location.subNew(position());; Vector3D dir = ray.direction(); /* Check if the ray lies parallel to the plane */ vd = ng.dot(dir); if ((vd > -photontracer.SceneConstants.EPSILON) && (vd < photontracer.SceneConstants.EPSILON)) { return(false); } /* Check if ray intersects plane */ double t = -((ng.x() * orig.x()) + (ng.y() * orig.y()) + (ng.z() * orig.z()) + d) / vd; if (t < photontracer.SceneConstants.EPSILON) { return(false); } /* Check if intersection is inside the triangle */ switch (dropAxis) { case 0: vx = (orig.y() + (dir.y() * t)) - v0.p.y(); vy = (orig.z() + (dir.z() * t)) - v0.p.z(); break; case 1: vx = (orig.x() + (dir.x() * t)) - v0.p.x(); vy = (orig.z() + (dir.z() * t)) - v0.p.z(); break; default: vx = (orig.x() + (dir.x() * t)) - v0.p.x(); vy = (orig.y() + (dir.y() * t)) - v0.p.y(); break; } double u = (edge2x * vy) - (edge2y * vx); if ((u < 0.0) || (u > 1.0)) { return(false); } double v = (edge1y * vx) - (edge1x * vy); if ((v < 0.0) || ((u + v) > 1.0)) { return(false); } Vector3D intersectionPoint; intersectionPoint = ray.direction().scaleNew(t); intersectionPoint.add(ray.Location); intersection.IntersectionPoint = intersectionPoint; intersection.IntersectedObject = this; intersection.Lambda = t; return(true); }
public virtual void locatePhotonsPrecomputed(Vector3D normal, NearestPhotons np, int index) { double dist1, dist2; Photon p = getPhoton(index); if (index < halfStoredPhotons) { dist1 = np.position.get(p.plane) - p.position.get(p.plane); if (dist1 > 0.0) { // if dist1 is positive search right plane locatePhotonsPrecomputed(normal, np, (2 * index) + 1); if (dist1 * dist1 < np.dist2[0]) { locatePhotonsPrecomputed(normal, np, (2 * index)); } } else { // dist1 is negative search left first locatePhotonsPrecomputed(normal, np, (2 * index)); if (dist1 * dist1 < np.dist2[0]) { locatePhotonsPrecomputed(normal, np, (2 * index) + 1); } } } // compute squared distance between current photon and np.position dist2 = p.position.distanceSqr(np.position); //assert(p.precomputedIrradiance); //assert(np.max == 1); Vector3D surfaceDirection = new Vector3D(); p.surfaceToCartesian(surfaceDirection); //System.out.println(normal.dot(surfaceDirection)); if (dist2 < np.dist2[0] && normal.dot(surfaceDirection) > 0.0) { // we found a photon :) Insert it in the candidate list if (np.found < 1) { // heap is not full; use array np.found++; np.dist2[np.found] = dist2; np.indices[np.found] = index; } else { // exchange element if necessary if (np.dist2[0] > dist2) { np.dist2[1] = dist2; np.indices[1] = index; np.dist2[0] = dist2; } } } }