I'm working on a raytracer implementation in Python, and I want to ensure that only the front faces of 3D objects are rendered. Currently, the raytracer renders both the front and back faces, and I would like to modify the code to only accumulate color for the front faces.
Here's the relevant portion of my code:
def extract(cond, x):
if isinstance(x, (int, float, complex)):
return x
return np.extract(cond, x)
class Ray:
def __init__(self,origin, dir, depth, n, reflections, transmissions, diffuse_reflections):
self.origin = origin
self.dir = dir
self.depth = depth
self.n = n
self.reflections = reflections
self.transmissions = transmissions
self.diffuse_reflections = diffuse_reflections
def extract(self,hit_check):
return Ray(self.origin.extract(hit_check), self.dir.extract(hit_check), self.depth, self.n.extract(hit_check), self.reflections, self.transmissions,self.diffuse_reflections)
class Hit:
def __init__(self, distance, orientation, material, collider,surface):
self.distance = distance
self.orientation = orientation
self.material = material
self.collider = collider
self.surface = surface
self.u = None
self.v = None
self.N = None
self.point = None
def get_uv(self):
if self.u is None:
return self.collider.assigned_primitive.get_uv(self)
return self.u, self.v
def get_normal(self):
if self.N is None:
return self.collider.get_N(self)
return self.N
def get_raycolor(ray, scene):
distances, hit_orientation = zip(*[s.intersect(ray.origin, ray.dir) for s in scene.collider_list])
nearest = np.minimum.reduce(distances)
color = vec3(0., 0., 0.)
for (coll, dis , orient) in zip(scene.collider_list, distances, hit_orientation):
hit_check = (nearest != FARAWAY) & (dis == nearest)
if np.any(hit_check):
color += coll.assigned_primitive.material.get_color(scene, ray.extract(hit_check), Hit(extract(hit_check,dis) , extract(hit_check,orient), coll.assigned_primitive.material, coll, coll.assigned_primitive)).place(hit_check)
return color
Your code already has this feature.
if you do this you will find out your code gets slower.
From:
def get_raycolor(ray, scene):
distances, hit_orientation = zip(*[s.intersect(ray.origin, ray.dir) for s in scene.collider_list])
nearest = np.minimum.reduce(distances)
color = vec3(0., 0., 0.)
for (coll, dis , orient) in zip(scene.collider_list, distances, hit_orientation):
hit_check = (nearest != FARAWAY) & (dis == nearest)
if np.any(hit_check):
color += coll.assigned_primitive.material.get_color(scene, ray.extract(hit_check), Hit(extract(hit_check,dis) , extract(hit_check,orient), coll.assigned_primitive.material, coll, coll.assigned_primitive)).place(hit_check)
return color
To:
def get_raycolor(ray, scene):
distances, hit_orientation = zip(*[s.intersect(ray.origin, ray.dir) for s in scene.collider_list])
nearest = np.minimum.reduce(distances)
color = vec3(0., 0., 0.)
for (coll, dis , orient) in zip(scene.collider_list, distances, hit_orientation):
hit_check = (nearest != FARAWAY) & (dis == nearest)
color += coll.assigned_primitive.material.get_color(scene, ray.extract(hit_check), Hit(extract(hit_check,dis) , extract(hit_check,orient), coll.assigned_primitive.material, coll, coll.assigned_primitive)).place(hit_check)
return color