How to deal with refraction when rays start inside a nested object

I am creating a simple raytracer for educational purposes and want to add refraction to objects. Using Snells' Law, I can create a new ray recursively at intersection points. Currently, raytracer only supports spheres, and I am using a scene where I have several spheres embedded in each other with different refractive indices.

If I start a ray from outside the spheres, everything seems simple. You start with the refractive index of the scene, and as soon as you get into the first sphere, refract the beam using the refractive index to and the refractive index of the material of the sphere until you click on the next sphere and so on. Using the intersection normals, I can determine if I am entering or leaving the sphere.

However, I do not understand how I should process the leaves of the sphere and what to do if the ray does not start in the outer part of the scene.

  • Is it possible to take a stack of refractive indices and go to one level as soon as I leave the sphere?
  • How can I determine with what index of refraction should I start if I start inside the spheres?

Example

You have three spheres with refractive indices of 0.9, 1.1, and 0.8 from external to internal. Air Index 1.0

  • Your camera is outside the sphere and points to the center of the sphere:

    • start index 1.0, you first fall into the outer sphere with an index of 0.9 and refract from 1.0 to 0.9 and save that your ray is now in 0.9 material.
    • you fall into the middle sphere and notice the material constant 1.1, since you saved 0.9, you know that you need to refract from 0.9 to 1.1 and save 1.1 in addition to 0.9
    • 1,1 0,8, 0,9, 1,1 0,8
    • ( , , 1.1)
    • ...
  • , . , .

+5
2

, : P.

, .

, , , , , , , , .

, , .

, , , , .

, , , (theta1)/sin (theta2) = [ 2]/[ 1]. , , , , .

, , , !

+1

( Python) : . , , /:

1) - ( ), , , . .

:

  • intersection_points(ray) - , .
  • intersection_objects(ray) - , .
  • containing_object(ray) - , .
  • objects() - .

. : Scene_Boundary. ( ), , .

2) . (, ).

:

  • contains(ray) - - , False, False,
  • ray_is_on_surface(ray) - True - , False.
  • intersection_points(ray) - () ,
  • surface_normal(ray) - , ( )

.

:

  • refractive_index

, : (n1) (n2) ? :

1) :

sphere # origin = (0,0,0), radius = 1
ray  # origin = (0,0,0), direction = (0,0,1) Note: the ray is inside the sphere
scene.add_object(sphere)
ipoints = scene.intersection_points(ray) #  [ (0,0,1), (0,0,10) ]
iobjects = scene.intersection_objects(ray) # [ Sphere, Scene_Boundary]

, . ipoints iobjects - , . !

2) n1 , :

obj1 = scene.containing_object(ray) # Scene_Boundary
n1 = obj1.refractive_index() # n1 = 1. Scene_Boundary always has refractive index of Air

3) n2 iobject, . :

index = iobjects.index_of_object(obj1)
obj2 = iobjects[index+1]
n2 = obj2.refractive_index() # n2 = 1.5 e.g. Glass

4) :

normal = obj1.surface_normal(ray)

. , , , , !

, . Python numpy ,

def reflect_vector(normal, vector):
   d = numpy.dot(normal, vector)
   return vector - 2 * d * normal

( ) n1 n2:

def fresnel_refraction(normal, vector, n1, n2):
    n = n1/n2
    dot = np.dot(norm(vector), norm(normal))
    c = np.sqrt(1 - n**2 * (1 - dot**2))
    sign = 1
    if dot < 0.0:
        sign = -1
    refraction = n * vector + sign*(c - sign*n*dot) * normal
    return norm(refraction)

, , - ( , "" ). 0 1, , .

def fresnel_reflection(angle, n1, n2):
    assert 0.0 <= angle <= 0.5*np.pi, "The incident angle must be between 0 and 90 degrees to calculate Fresnel reflection."
    # Catch TIR case
    if n2 < n1:
        if angle > np.arcsin(n2/n1):
            return 1.0

    Rs1 = n1 * np.cos(angle) - n2 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2)
    Rs2 = n1 * np.cos(angle) + n2 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2)
    Rs = (Rs1/Rs2)**2
    Rp1 = n1 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2) - n2 * np.cos(angle)
    Rp2 = n1 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2) + n2 * np.cos(angle)
    Rp = (Rp1/Rp2)**2
    return 0.5 * (Rs + Rp)

Python, (!), : http://daniel.farrell.name/freebies/pvtrace. Python! Python, http://groups.google.com/group/python-ray-tracing-community/web/list-of-python-statistical-ray-tracers. , , .

, , http://github.com/danieljfarrell/pvtrace alt text

+9

All Articles