# Refraction in a raytracer

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

## 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 on other sites
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.

1. 1
2. 2
3. 3
4. 4
5. 5
Rutin
18

• 11
• 12
• 9
• 12
• 37
• ### Forum Statistics

• Total Topics
631420
• Total Posts
2999990
×