Text archives Help
- From: bigler@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r1349 - in trunk: Model/Materials Model/Primitives SwigInterface
- Date: Wed, 18 Apr 2007 15:23:57 -0600 (MDT)
Author: bigler
Date: Wed Apr 18 15:23:56 2007
New Revision: 1349
Modified:
trunk/Model/Materials/Dielectric.cc
trunk/Model/Materials/Dielectric.h
trunk/Model/Primitives/Cylinder.cc
trunk/SwigInterface/runmanta.py
Log:
Model/Materials/Dielectric.cc
Model/Materials/Dielectric.h
Added an interface to switch between using Schlick's approximation
to the Fresnel reflectance or not.
Made some variable names more consistent with Steve's notes (and
other references).
Model/Primitives/Cylinder.cc
Fix normal computation. It was transforming the hit location as a
vector instead of a point.
SwigInterface/runmanta.py
Some slight changes for my crazy debug scene.
Modified: trunk/Model/Materials/Dielectric.cc
==============================================================================
--- trunk/Model/Materials/Dielectric.cc (original)
+++ trunk/Model/Materials/Dielectric.cc Wed Apr 18 15:23:56 2007
@@ -48,22 +48,63 @@
Dielectric::Dielectric(const Texture<Real>* n, const Texture<Real>* nt,
const Texture<Color>* sigma_a,
Real cutoff)
- : n(n), nt(nt), sigma_a(sigma_a)
+ : n(n), nt(nt), sigma_a(sigma_a), doSchlick(false)
{
-
}
Dielectric::~Dielectric()
{
}
+// Given eta = eta_t/eta_i (or eta2/eta1)
+// eta_inverse = eta_i/eta_t (or eta1/eta2)
+// r0 = (1 - eta_inverse) / (1 + eta_inverse);
+// r0 = (eta - 1) / (1 + eta);
+// r0 = (eta_t - eta_i) / (eta_t - eta_i);
+//
+// Note that because r0 is squared, eta_t and eta_i can be swapped and
+// get the same result.
+//
+// (eta_t - eta_i)^2 = eta_t^2 - 2*eta_t*eta_i + eta_i^2
+// (eta_i - eta_t)^2 = eta_i^2 - 2*eta_i*eta_t + eta_t^2
+//
+// We can conclude that the reflection coefficient is not dependent on
+// wether the ray is entering or leaving the dielectric, but rather
+// the relative angles.
+
+static inline Real SchlickReflection(Real costheta, Real costheta2,
+ Real eta_inverse)
+{
+ Real k = 1 - SCIRun::Min(costheta, costheta2);
+ Real k5 = (k*k)*(k*k)*k;
+ Real r0 = (1 - eta_inverse) / (1 + eta_inverse);
+ r0 *= r0;
+ return r0*(1-k5) + k5;
+}
+
+// Similarly to the Schlick approximation to the reflection, eta1 and
+// eta2 can be swapped and get the same result.
+static inline Real FresnelReflection(Real costheta, Real costheta2,
+ Real eta1, Real eta2)
+{
+ Real r_parallel = (((eta2 * costheta) - (eta1 * costheta2)) /
+ ((eta2 * costheta) + (eta1 * costheta2)));
+ Real r_perp = (((eta1 * costheta) - (eta2 * costheta2)) /
+ ((eta1 * costheta) + (eta2 * costheta2)));
+ return (Real)(.5)*(r_parallel*r_parallel + r_perp*r_perp);
+}
+
void Dielectric::shade(const RenderContext& context, RayPacket& rays) const
{
+ int debugFlag = rays.getAllFlags() & RayPacket::DebugPacket;
if(rays.getDepth() >= context.scene->getRenderParameters().maxDepth) {
for(int i=rays.begin();i<rays.end();i++)
rays.setColor(i, Color::black());
return;
}
+ if (debugFlag) {
+ cerr << "Dielectric::shade: depth = "<< rays.getDepth() << "\n";
+ }
rays.computeHitPositions();
rays.normalizeDirections();
@@ -81,14 +122,9 @@
RayPacketData refracted_data;
RayPacket reflected_rays(reflected_data, RayPacket::UnknownShape,
- 0, 0, rays.getDepth()+1,
RayPacket::NormalizedDirections);
+ 0, 0, rays.getDepth()+1,
RayPacket::NormalizedDirections | debugFlag);
RayPacket refracted_rays(refracted_data, RayPacket::UnknownShape,
- 0, 0, rays.getDepth()+1,
RayPacket::NormalizedDirections);
-
- if (rays.getFlag(RayPacket::DebugPacket)) {
- reflected_rays.setFlag(RayPacket::DebugPacket);
- refracted_rays.setFlag(RayPacket::DebugPacket);
- }
+ 0, 0, rays.getDepth()+1,
RayPacket::NormalizedDirections | debugFlag);
Color results[RayPacket::MaxSize];
Color refl_attenuation[RayPacket::MaxSize];
@@ -107,65 +143,91 @@
Vector rayD = rays.getDirection(i);
Vector normal = rays.getNormal(i);
- Real n_dot_v = Dot(normal, rayD);
- Real eta_tmp_inv;
- bool was_incoming = ( n_dot_v < 0 );
+ Real costheta = -Dot(normal, rayD);
+ if (debugFlag) {
+ cerr << "ray = "<<rayD<<"\n";
+ cerr << "normal = "<<normal<<"\n";
+ cerr << "costheta = "<<costheta<<"\n";
+ }
+ Real eta_inverse;
Color beers_color;
- if ( was_incoming ) {
- eta_tmp_inv = nt_values.data[i]/n_values.data[i];
- n_dot_v = -n_dot_v;
- beers_color = Color::white();
- } else {
+ bool exiting;
+ if ( costheta < 0 ) {
+ // Exiting surface
normal = -normal;
- eta_tmp_inv = n_values.data[i]/nt_values.data[i];
+ costheta = -costheta;
+ eta_inverse = n_values.data[i]/nt_values.data[i];
+ exiting = true;
beers_color = sigma_a_values.get(i).Pow(rays.getMinT(i));
+ } else {
+ eta_inverse = nt_values.data[i]/n_values.data[i];
+ exiting = false;
+ beers_color = Color::white();
}
- Real cosine_sq = 1 + (n_dot_v*n_dot_v - 1) * (eta_tmp_inv*eta_tmp_inv);
+ Vector refl_dir = rayD + 2*costheta*normal;
+ Real costheta2squared =
1+(costheta*costheta-1)*(eta_inverse*eta_inverse);
Color in_importance = rays.getImportance(i);
Vector hitpos = rays.getHitPosition(i);
- if ( cosine_sq <= 0 ) {
+ if ( costheta2squared < 0 ) {
// total internal reflection - no attenuation
+#if 1
Color refl_importance = in_importance * beers_color;
if(refl_importance.luminance() > cutoff){
reflected_rays.setImportance(num_refl, refl_importance);
- Vector refl_dir = rayD + 2*n_dot_v*normal;
reflected_rays.setRay(num_refl, hitpos, refl_dir);
refl_source[num_refl] = i;
refl_attenuation[num_refl] = beers_color;
num_refl++;
}
+#endif
+ if (debugFlag) cerr << "Total internal reflection: " <<
costheta2squared << "\n";
} else {
- Real cosine = Sqrt(cosine_sq);
- Real k = 1 - cosine;
- k*=(k*k)*(k*k);
-
- Real r0 = (n_values.data[i] - nt_values.data[i]) / (n_values.data[i] +
nt_values.data[i]);
- r0 *= r0;
- Real R = r0*(1-k) + k;
- if (rays.getFlag(RayPacket::DebugPacket)) cerr << "r0 = "<<r0<<"\n";
+ Real costheta2 = Sqrt(costheta2squared);
+ Real refl;
- // Possibly create refraction ray
- refr_attenuation[num_refr] = beers_color * (1-R);
- Color refr_importance = in_importance * refr_attenuation[num_refr];
- if(refr_importance.luminance() > cutoff){
- refracted_rays.setImportance(num_refr, refr_importance);
- Vector refr_dir = rayD*eta_tmp_inv +
- (n_dot_v*eta_tmp_inv - cosine) * normal;
- refracted_rays.setRay(num_refr, hitpos, refr_dir);
- refr_source[num_refr] = i;
- num_refr++;
+ if (doSchlick) {
+ refl = SchlickReflection(costheta, costheta2, eta_inverse);
+ } else {
+ refl = FresnelReflection(costheta, costheta2,
+ n_values.data[i], nt_values.data[i]);
+ }
+ if (debugFlag) {
+ Real schlick_refl, fresnel_refl;
+ if (doSchlick) {
+ schlick_refl = refl;
+ fresnel_refl = FresnelReflection(costheta, costheta2,
+ n_values.data[i],
+ nt_values.data[i]);
+ } else {
+ schlick_refl = SchlickReflection(costheta, costheta2, eta_inverse);
+ fresnel_refl = refl;
+ }
+ cerr << "schlick_refl = "<<schlick_refl<<", fresnel_refl =
"<<fresnel_refl<<", refl = "<<refl<<"\n";
}
+#if 1
// Possibly create reflection ray
- refl_attenuation[num_refl] = beers_color * R;
+ refl_attenuation[num_refl] = beers_color * refl;
Color refl_importance = in_importance * refl_attenuation[num_refl];
if(refl_importance.luminance() > cutoff){
reflected_rays.setImportance(num_refl, refl_importance);
- Vector refl_dir = rayD + (2*n_dot_v)*normal;
reflected_rays.setRay(num_refl, hitpos, refl_dir);
refl_source[num_refl] = i;
num_refl++;
+ }
+#endif
+
+ // Possibly create refraction ray
+ refr_attenuation[num_refr] = beers_color * (1-refl);
+ Color refr_importance = in_importance * refr_attenuation[num_refr];
+ if(refr_importance.luminance() > cutoff){
+ refracted_rays.setImportance(num_refr, refr_importance);
+ Vector refr_dir = (eta_inverse * rayD +
+ (eta_inverse * costheta - costheta2) * normal);
+ refracted_rays.setRay(num_refr, hitpos, refr_dir);
+ refr_source[num_refr] = i;
+ num_refr++;
}
}
}
Modified: trunk/Model/Materials/Dielectric.h
==============================================================================
--- trunk/Model/Materials/Dielectric.h (original)
+++ trunk/Model/Materials/Dielectric.h Wed Apr 18 15:23:56 2007
@@ -46,8 +46,9 @@
Real localCutoffScale = 1)
: n(new Constant<Real>(n)),
nt(new Constant<Real>(nt)),
- sigma_a(new Constant<Color>(sigma_a)),
- localCutoffScale(localCutoffScale)
+ sigma_a(new Constant<Color>(sigma_a)),
+ localCutoffScale(localCutoffScale),
+ doSchlick(false)
{ }
Dielectric(const Texture<Real>* n, const Texture<Real>* nt,
@@ -58,12 +59,14 @@
void shade(const RenderContext& context, RayPacket& rays) const;
virtual void attenuateShadows(const RenderContext& context,
RayPacket& shadowRays) const;
-
+
+ void setDoSchlick(bool new_val) { doSchlick = new_val; }
private:
const Texture<Real>* n;
const Texture<Real>* nt;
const Texture<Color>* sigma_a;
Real localCutoffScale;
+ bool doSchlick;
};
}
Modified: trunk/Model/Primitives/Cylinder.cc
==============================================================================
--- trunk/Model/Primitives/Cylinder.cc (original)
+++ trunk/Model/Primitives/Cylinder.cc Wed Apr 18 15:23:56 2007
@@ -83,12 +83,14 @@
{
rays.computeHitPositions();
for(int i=rays.begin(); i < rays.end(); i++) {
- Vector xn(xform.multiply_vector(rays.getHitPosition(i)));
+ Vector xn(xform.multiply_point(rays.getHitPosition(i)));
xn[2]=0.0;
Vector v=ixform.multiply_vector(xn);
v.normalize();
rays.setNormal(i, v);
}
+ // We either need to set the flag here or don't normalize the normals.
+ rays.setFlag(RayPacket::HaveUnitNormals);
}
Modified: trunk/SwigInterface/runmanta.py
==============================================================================
--- trunk/SwigInterface/runmanta.py (original)
+++ trunk/SwigInterface/runmanta.py Wed Apr 18 15:23:56 2007
@@ -206,7 +206,7 @@
objs = Array1_ObjectP()
#
checker1 = manta_new(CheckerTexture_Color(Color(RGBColor(.6,.6,.6)),
- Color(RGBColor(0.3,0.3,0.3)),
+ Color(RGBColor(0.1,0.6,0.1)),
Vector(1,0,0),
Vector(0,1,0)))
groundmatl = manta_new(Lambertian(checker1))
@@ -216,7 +216,8 @@
#
lenscale = 2.5
glass = Color(RGBColor(pow(0.80, lenscale), pow(0.93, lenscale),
pow(0.87, lenscale)))
- transp_matl = manta_new(Dielectric(1.5, 1, glass))
+ transp_matl = manta_new(Dielectric(1.1, 1.0, glass))
+# transp_matl.setDoSchlick(True)
print transp_matl
objs.add(manta_new(Cube(transp_matl,
Vector(-5, -2, 2.95 ),
@@ -225,8 +226,8 @@
# Vector(-5, -2, 2.95 ),
# Vector(-1, 2, 3.05))))
-# objs.add(manta_new(Sphere(transp_matl,
-# Vector( -3, 0, 4.5), 0.5)))
+ objs.add(manta_new(Sphere(transp_matl,
+ Vector( -3, 0, 4.5), 0.5)))
ringmatl = manta_new(Lambertian(Color(RGBColor(.9, .3, .2))))
print ringmatl
@@ -234,13 +235,13 @@
inner_radius = r*0.5
center = Vector(-6, 0, 3.5+r)
offset = Vector(2.25*r, 0, 0)
- for i in range(9):
- objs.add(manta_new(Ring(ringmatl,
- center+offset*i,
- Vector(0, 0, 1),
- inner_radius, r-inner_radius)))
+# for i in range(9):
+# objs.add(manta_new(Ring(ringmatl,
+# center+offset*i,
+# Vector(0, 0, 1),
+# inner_radius, r-inner_radius)))
- #addDebugRays(objs, "raytree", 0.05)
+ #addDebugRays(objs, "raytree", 0.025)
# Create a BVH
world.add(manta_new(RealisticBvh(objs.get_objs(), objs.size())))
scene.setObject(world)
@@ -307,8 +308,9 @@
#defaultCamera = factory.createCamera("pinhole(-eye 3 3 2 -lookat 0 0 0.3
-up 0 0 1 -fov 60)")
#defaultCamera = factory.createCamera("pinhole(-eye 8 -18 8.5 -lookat -4.7
2.5 2.5 -up 0 0 1 -fov 15)")
-defaultCamera = factory.createCamera("pinhole(-eye 8.3 -18 7 -lookat -4.7
2.5 3 -up 0 0 1 -fov 15)")
+#defaultCamera = factory.createCamera("pinhole(-eye 8.3 -18 7 -lookat -4.7
2.5 3 -up 0 0 1 -fov 15)")
#defaultCamera = factory.createCamera("pinhole( -eye 8.06072 -17.7429
8.73358 -lookat -4.98977 2.23422 2.74486 -up -0.0793095 0.0464671 0.995767
-fov 15 )")
+defaultCamera = factory.createCamera("pinhole( -eye 7.92503 -16.4782 12.1826
-lookat -4.42502 2.59203 2.7444 -up -0.216459 0.129008 0.967731 -fov 15 )")
addXInterface(engine, defaultCamera, 512, 512)
#addNullInterface(engine, defaultCamera, 512, 512)
- [MANTA] r1349 - in trunk: Model/Materials Model/Primitives SwigInterface, bigler, 04/18/2007
Archive powered by MHonArc 2.6.16.