Sign in to follow this  
fnm

raytracing: does this look right?

Recommended Posts

I'm trying to implement refraction in my basic raytracer. I got something working, but I'm not sure I got it right, if my renderings look natural. Here's a simple scene: - the camera is at (0, 0, -500) - a red sphere, radius = 100, at (0, 0, 200) - a green sphere, radius = 50, at (0, 0, 400) - a yellow plane, normal = (0, 1, 0), distance = -100 Now, if I put a light source at (0, 0, -500), the rendering look like: which looks pretty right to me. The same scene, with a light source at (0, 500, -500): This looks ok too. The same scene, with a light source at (0, 200, -500): I'm not sure about the last one. Does it looks natural? If not, what the problem can be? The TIR is not implemented. Thanks.

Share this post


Link to post
Share on other sites
It is not easy to spot mistakes in refraction from such pictures, maybe you could post your refraction code. Be sure to invert the normal when you intersect the inside surface of the sphere (when the ray leaves it). You could add a simple texture to the plane to help.
Anyway, they look ok (even the last one).

Share this post


Link to post
Share on other sites
Thanks for the reply. Here's the code:

//refraction
if (closest->refraction() == 0) return;
if (refractionDepth-- > 0) {
float n = 1.; //for testing purpose only
if(ray.direction().dot(normal) >= 0)normal = -normal;
float c1 = -normal.dot(ray.direction());
float c2 = n * n * (1.f - c1 * c1);
if (c2 <= 1.) {
Vector t = ray.direction() * n + (n * c1 - sqrt(1.0f - c2*c2)) * normal;
Vector rc;
shootRay(Ray(point + t * 0.1f, t), rc, reflectionDepth, refractionDepth);
color = color + rc;
}
else;//TIR here?
}



About the TIR, is my assumption correct? If c2 > 1 I should reflect all the rays, with not-inverted normal?

Share this post


Link to post
Share on other sites
That's my code for reference (I suppose it is correct, but I never extensively tested it):

const vector4 Refract(const vector4<T>& n, T ior_i, T ior_r, bool& tir) const
{
tir = false;
if(ior_i == ior_r) return *this; //The two indexes of refraction are equals

// calculate refraction
const T eta = ior_i / ior_r;
const T cos_i = -(n.Dot(*this));
const T cos_t = T(1) - eta * eta * (T(1) - cos_i * cos_i);
if (cos_t > T(0))
{
vector4 res = (*this * eta) + (n * (eta * cos_i - sqrt( cos_t )));
tir = false;

return res.Direction();
}

tir = true;
return Reflect(*this);
}





In addition, if you have not yet read this, then give it a look.

EDIT: now that I look at it, I fear that there is something wrong with my code: when I go home I will make a test, then I will report it here.

EDIT 2:
Quote:

I should reflect all the rays, with not-inverted normal?

The normal must be always be in the same hemisphere where the ray is coming from. If it is not, then
-The shape is not closed (i.e. a simple triangle seen from the back). If you use backface culling then the intersection must have never been reported. Since it was, then in order to compute shading the normal must be inverted.
-The ray just traversed the shape, due to transparency, and intersects the surface from the inside. Again, the normal must be inverted.

I do this just after the intersection, before applying shading.

Share this post


Link to post
Share on other sites
Just for fun, I post what I got trying to implement the Fresnel effect



Maybe we should start a bug and glitch pictures thread.

Observe the cross in the middle of the image; maybe its a sign...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this