Jump to content
  • Advertisement
Sign in to follow this  
Fibonacci One

Simple ray tracer refraction problem

This topic is 4832 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This seems like such a simple thing for me to have already spent nearly a day trying to fix, but refraction in my raytracer does not currently work. Every time I try to render an object that is completly refractive I just end up with a black circle on the screen. I have used multiple sources from books to the internet, but everything I try has similiar result. This leads me to believe that the problem may be because of the code that uses the refraction rather then the refraction code itself, but I have checked that rather thoroughly and it seems OK. So I'll start by showing the source from two of the algorithms I have already tried. This first one I got from the book Real-Time Rendering. l is the incoming vector and n is the normal, the function expects both of them to point away from the surface and already be normalized.
        Vector i = -l;	// The incoming vector points at the surface for this formula
	float r = Nl / Nt;
	float w =  - (i.Dot(n)) * r;
	float k = 1 + (w - r) * (w + r);
	if (k < 0.0f)
		return Reflect(l, n);
	
	k = sqrt(k);
	Vector result = r*i + (w - k)*n;
	return result; // This is already normalized

This second formula is from Realistic Image Synthesis Using Photon Mapping.
// Formula from realistic image synthesis using photon mapping
	float index = Nl / Nt;
	float ldotn = l.Dot(n);
	float root = 1 - ( (index*index) * (1 - (ldotn*ldotn)) );
	if (root < 0.0f)
		return Reflect(l, n);

	Vector result = -index * (l - ldotn*n) - sqrt(root)*n;
	result.Normalize(); // May not be necessary... investigate once it works.
	return result;

I have tried several other similiar formulas from various sources on the internet, but I assumed these two would be the most reliable. Thanks in advance for your help.

Share this post


Link to post
Share on other sites
Advertisement
In your second block of code, everything looks right except the line that computes result. It should look like this:

Vector result = (index * ldotn - sqrt(root)) * n - index * l;

This assumes that the light direction l points away from the surface.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hey, I'm stuck implementing my Perspective Camera in my ray tracer. And since you're up to refraction in your ray tracer. I was thinking you can help me.

May I ask you to post your Perspective Camera class?

Many thanks...

Share this post


Link to post
Share on other sites
Quote:
Original post by Eric Lengyel
In your second block of code, everything looks right except the line that computes result. It should look like this:

Vector result = (index * ldotn - sqrt(root)) * n - index * l;

This assumes that the light direction l points away from the surface.


Thanks for your help. I tossed a simple triangle into the scene and gave it an index of refraction of 1.3333 and it seems to work. The bad news is that my sphere is still showing up as solid black. It looks like the photons are bouncing around inside the sphere. Do I need to include some special case when ldotn < 0?

Quote:
Original post by Anonymous Poster
Hey, I'm stuck implementing my Perspective Camera in my ray tracer. And since you're up to refraction in your ray tracer. I was thinking you can help me.

May I ask you to post your Perspective Camera class?

Many thanks...

When you trace a ray from the center of projection through the frame buffer the perspective is "built in." If that's not enough to set you on the right path, PM me and I'll try to help some more.

Edit: As timw mentioned, I would have to check ldotn and not the indices of refraction. 4AM post are a bad idea.

[Edited by - Fibonacci One on August 24, 2005 11:09:32 AM]

Share this post


Link to post
Share on other sites
it doesn't matter if n's are greater or what order they're in. the equation should take care of it. let me just dump my code on you rather then checking yours if you really want I'll read it tomorrow


Vector3 *getRefractionV(Vector3 *pNormal, Vector3 *pDirection, float fN, float fNt, Vector3 *pTransmition) {

double fNdotD = (*pNormal)^(*pDirection);

double fRad = 1 - (((fN*fN)/(fNt*fNt))*(1 - (fNdotD*fNdotD)));

if(fRad < 0)
return NULL;

*pTransmition = (fN/fNt)*((*pDirection) - (*pNormal)*(fNdotD)) - (*pNormal)*(sqrt(fRad));
pTransmition->Normalize();

return pTransmition;
}

if the function returns null you have total internal reflection, and you should trace a reflection vector only. if it returns non null it returns the transmision direction and you should trace two rays in proportion using the fresnel equations. here fN is the index of refraction that the ray is LEAVING and fNt is the index of refraction that the ray is ENTERING. also the operator ^ is a dot product.

Share this post


Link to post
Share on other sites
oh re-reading your post taking care of ordering you simply check to see how the ray is entering the surface. if the dir^normal < 0 it's entering else it's exiting the surface. dir is the direction of the ray of course. ordering does matter in the equation, read the fun above. in my material classes each dielectric surface has two index of refraction, one for entering and one for leaving, in this way we don't have to "fake" interface's that don't have air as the exiting index.

Share this post


Link to post
Share on other sites
Quote:
Original post by timw
it doesn't matter [stuff] what order they're in. the equation should take care of it.

That's all I needed. I'll start searching through the rest of my code and try to figure out what's wrong.
Thanks.

Share this post


Link to post
Share on other sites
np man. the order does determin what order the refraction is taking place in tho. like air to water or water to air these situations would have the order of the index of refractions reversed, but I figure you know that, just making sure.

peace

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!