• Advertisement
Sign in to follow this  

Refraction in a raytracer

This topic is 4949 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

to anyone who has ever done this before: can you spot any obvious flaws in the following code snippet? it looks almost right. in most cases it looks great, but somehow lenses dont enlarge and never-ending internal reflection seems to occur way too often resulting in completely black spots in an object. ive spent a lot of time doublechecking my formulas and code, but to no avail... besides im sure its not because of fucked up normals.
			if (hit.e.Stuff.transparent && depth < MaxRecursions){
				newray.infinite = true;

				float alpha, beta;

				float ci;
				
				if (!hit.e.Volume.iv.state){		//refract inwards
					ci = -(ray.dir.x*normal.x + ray.dir.y*normal.y + ray.dir.z*normal.z);
					alpha = 1 / hit.e.Stuff.refractionindex;
					beta = alpha*ci - sqrt(1+alpha*alpha*(ci*ci-1));
assert(beta<0);					
					newray.dir.x = alpha*ray.dir.x + beta*normal.x;
					newray.dir.y = alpha*ray.dir.y + beta*normal.y;
					newray.dir.z = alpha*ray.dir.z + beta*normal.z;

//printf("in:%f\n",newray.dir.Length);
					newray.state = true;
					
					Vector3 l = TraceRay(newray, depth+1).light;
					hit.light.x = hit.light.x + l.x;
					hit.light.y = hit.light.y + l.y;
					hit.light.z = hit.light.z + l.z;
				}else{
					ci = -(ray.dir.x*normal.x + ray.dir.y*normal.y + ray.dir.z*normal.z);
					alpha = hit.e.Stuff.refractionindex;
					beta = 1+alpha*alpha*(ci*ci-1);
					if (beta < 0){			//total inner reflection
						dp = (ray.dir.x*normal.x + ray.dir.y*normal.y + ray.dir.z*normal.z) * 2;
						newray.dir.x = ray.dir.x - normal.x * dp;
						newray.dir.y = ray.dir.y - normal.y * dp;
						newray.dir.z = ray.dir.z - normal.z * dp;

//						if (newray.dir.Length()==1f) printf("ref:%f\n",newray.dir.Length);
						newray.state = true;
						
						Vector3 l = TraceRay(newray, depth+1).light;
						hit.light.x = hit.light.x + l.x * pow(hit.e.Stuff.color.x, first);
						hit.light.y = hit.light.y + l.y * pow(hit.e.Stuff.color.y, first);
						hit.light.z = hit.light.z + l.z * pow(hit.e.Stuff.color.z, first);
											
					}else{					//refract outwards
						beta = alpha*ci - sqrt(beta);
assert(beta>0);
						newray.dir.x = alpha*ray.dir.x + beta*normal.x;
						newray.dir.y = alpha*ray.dir.y + beta*normal.y;
						newray.dir.z = alpha*ray.dir.z + beta*normal.z;

//printf("out:%f\n",newray.dir.Length);

						newray.state = false;
											
						Vector3 l = TraceRay(newray, depth+1).light;
						float t = pow(hit.e.Stuff.transparency, first);
						hit.light.x = hit.light.x + l.x * pow(hit.e.Stuff.color.x, first+1);
						hit.light.y = hit.light.y + l.y * pow(hit.e.Stuff.color.y, first+1);
						hit.light.z = hit.light.z + l.z * pow(hit.e.Stuff.color.z, first+1);
					}
				}
			}

anyone?

Share this post


Link to post
Share on other sites
Advertisement
I haven't got time to go through your code, but have a few things you should be doing...

* Flip the normals if you hit a back-facing triangle.

* Keep track of all refractive indices, the indices of the material you are in and are going into. Consider the use of a stack to keep track of the materials you are in - this allows transparent objects within transparent objects etc. etc.

Ignore these if you've done them.

Share this post


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

  • Advertisement