Text archives Help
- From: boulos@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r445 - branches/itanium2/Model/Materials
- Date: Thu, 28 Jul 2005 01:02:21 -0600 (MDT)
Author: boulos
Date: Thu Jul 28 01:02:20 2005
New Revision: 445
Modified:
branches/itanium2/Model/Materials/Dielectric.cc
branches/itanium2/Model/Materials/Dielectric.h
Log:
A ray-packeted version of Dielectric.
Modified: branches/itanium2/Model/Materials/Dielectric.cc
==============================================================================
--- branches/itanium2/Model/Materials/Dielectric.cc (original)
+++ branches/itanium2/Model/Materials/Dielectric.cc Thu Jul 28 01:02:20
2005
@@ -52,13 +52,10 @@
}
-Dielectric::Dielectric(const Color& diffuse, const Color& specular, const
Color &minusC_,
- int specpow, double n, double nt)
- : diffuse(diffuse), specular(specular), specpow(specpow),
- n(n), nt(nt), minusC( minusC_ )
+Dielectric::Dielectric(const Texture<double>* n, const Texture<double>* nt,
const Texture<Color>* sigma_a)
+ : n(n), nt(nt), sigma_a(sigma_a)
{
- r0 = (n - nt) / (n + nt);
- r0 *= r0;
+
}
Dielectric::~Dielectric()
@@ -67,15 +64,6 @@
void Dielectric::shade(const RenderContext& context, RayPacket& rays) const
{
- rays.normalizeDirections();
- rays.computeNormals(context);
- if (!(rays.getFlags() & rays.HaveUnitNormals)) {
- // I would like to replace this with a call to
- // rays.normalizeNormals() but need to add it.
- fprintf(stderr, "Dielectric assumes unit normals\n");
- exit(-1);
- }
-
if(rays.getDepth() >= context.scene->getRenderParameters().maxDepth)
{
for(int i=0;i<rays.getSize();i++)
@@ -83,86 +71,155 @@
}
else
{
- rays.computeHitPositions();
- for(int i=0;i<rays.getSize();i++)
- {
- RayPacket::Element& e = rays.get(i);
- double cosine = -Dot(e.normal, e.ray.direction());
- Vector refl_dir, refr_dir;
- bool from_outside = (cosine > 0);
- bool total_internal_reflection;
- refr_dir = e.ray.direction();
- refl_dir = e.ray.direction() + 2 * cosine * e.normal;
- if (from_outside) {
- total_internal_reflection = !Refract(e.normal, n, nt,
refr_dir);
- }
- else
- {
- total_internal_reflection = !Refract(-e.normal, nt, n,
refr_dir);
+ rays.computeHitPositions();
+ rays.normalizeDirections();
+ rays.computeNormals(context);
+ if (!(rays.getFlags() & rays.HaveUnitNormals))
+ {
+ // I would like to replace this with a call to
+ // rays.normalizeNormals() but need to add it.
+ fprintf(stderr, "Dielectric assumes unit normals\n");
+ exit(-1);
+ }
+
+ double n_values[RayPacket::MaxSize];
+ double nt_values[RayPacket::MaxSize];
+ Color sigma_a_values[RayPacket::MaxSize];
+
+ n->mapValues(context, rays, n_values);
+ nt->mapValues(context, rays, nt_values);
+ sigma_a->mapValues(context, rays, sigma_a_values);
+
+ bool internally_reflected[RayPacket::MaxSize];
+ Vector refl_dirs[RayPacket::MaxSize];
+ Vector refr_dirs[RayPacket::MaxSize];
+ float fresnel_coeffs[RayPacket::MaxSize]; // might be better to compute
+ int num_internal = 0;
+ int num_branch = 0;
+
+ for(int i=0;i<rays.getSize();i++)
+ {
+ RayPacket::Element& e = rays.get(i);
+ double cosine = -Dot(e.normal, e.ray.direction());
+ Vector refl_dir, refr_dir;
+ bool from_outside = (cosine > 0);
+ bool total_internal_reflection;
+ refr_dir = e.ray.direction();
+ refl_dir = e.ray.direction() + 2 * cosine * e.normal;
+
+ if (from_outside)
+ {
+ // refract changes the refr_dir
+ total_internal_reflection = !Refract(e.normal,
+ n_values[i],
+ nt_values[i],
+ refr_dir);
+ }
+ else
+ {
+ total_internal_reflection = !Refract(-e.normal,
+ nt_values[i],
+ n_values[i],
+ refr_dir);
cosine = -cosine;
- }
+ }
- if (total_internal_reflection) {
- // Create a size one ray packet
- int flags = 0;
- int size = 1;
- RayPacketData raydata;
- RayPacket refl_rays(raydata, size, rays.getDepth()+1, flags);
-
- RayPacket::Element& r = refl_rays.get(0);
- r.ray.set(e.hitPosition, refl_dir);
- refl_rays.useLocalColors();
- context.renderer->traceRays(context, refl_rays);
-
- // Apply beer's law
attenuation.
- // (*r.color) =
r.color->attenuate( minusC * r.hitInfo.minT() );
-
- rays.setResult(i, *r.color);
- }
- else // reflection and refraction
- {
+ if (total_internal_reflection)
+ {
+ internally_reflected[i] = true;
+ num_internal++;
+ refl_dirs[i] = refl_dir;
+ }
+ else // reflection and refraction
+ {
float cosine2;
if (from_outside) {
- cosine2 = -Dot(e.normal, refr_dir);
+ cosine2 = -Dot(e.normal, refr_dir);
}
else {
- cosine2 = Dot(e.normal, refr_dir);
+ cosine2 = Dot(e.normal, refr_dir);
}
if (cosine2 < cosine) cosine = cosine2; // for Schlick
float k = 1 - cosine;
k*=k*k*k*k;
- float R = r0*(1-k) + k;
-
- int flags = 0;
- int size = 1;
-
- // Reflected rays.
- RayPacketData raydata;
- RayPacket refl_rays(raydata, size, rays.getDepth()+1, flags);
- RayPacket::Element& r = refl_rays.get(0);
- r.ray.set(e.hitPosition, refl_dir);
- refl_rays.useLocalColors();
- context.renderer->traceRays(context, refl_rays);
-
- // Refracted rays.
- RayPacketData raydata2;
- RayPacket refr_rays(raydata2, size, rays.getDepth()+1, flags);
- RayPacket::Element& r2 = refr_rays.get(0);
- r2.ray.set(e.hitPosition, refr_dir);
- refr_rays.normalizeDirections();
- refr_rays.useLocalColors();
- context.renderer->traceRays(context, refr_rays);
+ double r0 = (n_values[i] - nt_values[i]) / (n_values[i] +
nt_values[i]);
+ r0 *= r0;
+ float R = r0*(1-k) + k;
- // Apply beer's law
attenuation.
- // (*r2.color) *=
minusC.attenuate( r2.hitInfo.minT() );
+ internally_reflected[i] = false;
+ num_branch++;
+ refl_dirs[i] = refl_dir;
+ refr_dirs[i] = refr_dir;
+ fresnel_coeffs[i] = R;
+ }
+ }
- rays.setResult(i, (Color::white()*R)*(*r.color) +
- (Color::white()*(1-R))*(*r2.color) );
+ // okay we've got everything ready now
- }
- }
-
+ RayPacketData total_internal_data;
+ RayPacketData reflected_data;
+ RayPacketData refracted_data;
+
+ RayPacket internal_rays(total_internal_data, num_internal,
rays.getDepth()+1, RayPacket::NormalizedDirections);
+ RayPacket reflected_rays(reflected_data, num_branch,
rays.getDepth()+1, RayPacket::NormalizedDirections);
+ RayPacket refracted_rays(refracted_data, num_branch,
rays.getDepth()+1, RayPacket::NormalizedDirections);
+
+ internal_rays.useLocalColors();
+ reflected_rays.useLocalColors();
+ refracted_rays.useLocalColors();
+
+ // for accessing ray packet elements between the 3 sets (or 2 pairs
really)
+ int internal_counter = 0;
+ int branch_counter = 0;
+ // fill in the raypackets
+ for (int i = 0; i < rays.getSize(); i++)
+ {
+ RayPacket::Element& e = rays.get(i);
+
+ if (internally_reflected[i])
+ {
+ RayPacket::Element& r = internal_rays.get(internal_counter);
+ r.ray.set(e.hitPosition, refl_dirs[i]);
+ internal_counter++;
+ }
+ else
+ {
+ RayPacket::Element& refl = reflected_rays.get(branch_counter);
+ refl.ray.set(e.hitPosition, refl_dirs[i]);
+ RayPacket::Element& refr = refracted_rays.get(branch_counter);
+ refr.ray.set(e.hitPosition, refr_dirs[i]);
+ branch_counter++;
+ }
+ }
+
+ // fire them off
+ context.renderer->traceRays(context, reflected_rays);
+ context.renderer->traceRays(context, refracted_rays);
+ context.renderer->traceRays(context, internal_rays);
+
+ internal_counter = 0;
+ branch_counter = 0;
+ // compute their results
+ for (int i = 0; i < rays.getSize(); i++)
+ {
+ if (internally_reflected[i])
+ {
+ RayPacket::Element& r = internal_rays.get(internal_counter);
+ // TODO: Apply beer's law attenuation to total internal
reflection ray.
+ rays.setResult(i, *r.color);
+ internal_counter++;
+ }
+ else
+ {
+ RayPacket::Element& refl = reflected_rays.get(branch_counter);
+ RayPacket::Element& refr = refracted_rays.get(branch_counter);
+ // TODO: Apply beer's law attenuation to refracted ray
+ rays.setResult(i,
(Color::white()*fresnel_coeffs[i])*(*refl.color) +
+
(Color::white()*(1.-fresnel_coeffs[i]))*(*refr.color) );
+ branch_counter++;
+ }
+ }
}
}
Modified: branches/itanium2/Model/Materials/Dielectric.h
==============================================================================
--- branches/itanium2/Model/Materials/Dielectric.h (original)
+++ branches/itanium2/Model/Materials/Dielectric.h Thu Jul 28 01:02:20
2005
@@ -4,25 +4,23 @@
#include <Model/Materials/LitMaterial.h>
#include <Core/Color/Color.h>
+#include <Interface/Texture.h>
-namespace Manta{
+namespace Manta
+{
class LightSet;
- class Dielectric : public LitMaterial {
+ class Dielectric : public LitMaterial
+ {
public:
- // minusC = log( beersA ) but there isn't an easy way to take
the log of a color.
- Dielectric(const Color& reflected, const Color& specular, const Color
&minusC, int specpow,
- double n, double nt);
-
- virtual ~Dielectric();
+ Dielectric(const Texture<double>* n, const Texture<double>* nt, const
Texture<Color>* sigma_a);
+ ~Dielectric();
- virtual void shade(const RenderContext& context, RayPacket& rays) const;
+ void shade(const RenderContext& context, RayPacket& rays) const;
private:
- Color diffuse;
- Color specular;
- Color minusC; // Beer's law.
- int specpow;
- double n, nt, r0;
+ const Texture<double>* n;
+ const Texture<double>* nt;
+ const Texture<Color>* sigma_a;
};
}
- [MANTA] r445 - branches/itanium2/Model/Materials, boulos, 07/28/2005
Archive powered by MHonArc 2.6.16.