Text archives Help
- From: "Thiago Ize" <thiago@sci.utah.edu>
- To: manta@sci.utah.edu
- Subject: [Manta] r2045 - trunk/Model/Primitives
- Date: Sun, 10 Feb 2008 23:04:57 -0700 (MST)
Author: thiago
Date: Sun Feb 10 23:04:56 2008
New Revision: 2045
Modified:
trunk/Model/Primitives/Sphere.cc
Log:
Removed an old #ifdef'd out sphere intersection code that
wouldn't even compile and replaced it with another #ifdef'd
out version that is more robust to the self intersection
that causes surface acne. This is a bit slower since it has
to do a few more adds, multiplies, and branches (still just
one sqrt, which is the dominant cost), but in the
default manta scene it's slower by only a few percent. If
people like this, then this can be converted to SSE and the
specialized cases.
Modified: trunk/Model/Primitives/Sphere.cc
==============================================================================
--- trunk/Model/Primitives/Sphere.cc (original)
+++ trunk/Model/Primitives/Sphere.cc Sun Feb 10 23:04:56 2008
@@ -50,32 +50,36 @@
void Sphere::intersect(const RenderContext&, RayPacket& rays) const
{
-#if VERSION1
- rays.normalizeDirections();
- for(int i = 0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- Vector OC=center-e.ray.origin();
- Real tca=Dot(OC, e.ray.direction());
- Real l2oc=OC.length2();
- Real rad2=radius*radius;
- if(l2oc <= rad2){
- // Inside the sphere
- Real t2hc=rad2-l2oc+tca*tca;
- Real thc=Sqrt(t2hc);
- Real t=tca+thc;
- e.hitInfo.hit(t, getMaterial(), this, getTexCoordMapper());
- } else {
- if(tca < 0){
- // Behind ray, no intersections...
- } else {
- Real t2hc=rad2-l2oc+tca*tca;
- if(t2hc <= 0){
- // Ray misses, no intersections
- } else {
- Real thc=Sqrt(t2hc);
- e.hitInfo.hit(tca-thc, getMaterial(), this, getTexCoordMapper());
- e.hitInfo.hit(tca+thc, getMaterial(), this, getTexCoordMapper());
- }
+#if 0
+ //This version will find a t value close to the actual value
+ //(actually finds the midpoint between the two intersections), and
+ //then uses that initial t to cast a ray from there in order to get
+ //a more exact t value. This is more robust and allows for a smaller
+ //T_EPSILON.
+ for(int i = rays.begin();i<rays.end();i++){
+ Vector O(rays.getOrigin(i)-center);
+ const Vector D(rays.getDirection(i));
+ const Real A = Dot(D, D);
+ const Real A_inv = static_cast<Real>(1)/A;
+ Real B = Dot(O, D);
+ Real C = Dot(O, O) - radius*radius;
+ Real disc = B*B-A*C;
+ if(disc >= 0){
+ Real t = -B*A_inv; //average of two t intersections.
+ O += D*t;
+ Real B = Dot(O, D);
+ Real C = Dot(O, O) - radius*radius;
+ disc = B*B-A*C;
+
+ if (disc >= 0) {
+ const Real r = Sqrt(disc);
+ const Real t1 = t + -(r+B)*A_inv;
+ if (t1 <= T_EPSILON)
+ t += (r-B)*A_inv;
+ else
+ t = t1;
+
+ rays.hit(i, t, getMaterial(), this, getTexCoordMapper());
}
}
}
- [Manta] r2045 - trunk/Model/Primitives, Thiago Ize, 02/11/2008
Archive powered by MHonArc 2.6.16.