vki.HitShaders(closest_hit=''' struct Payload { float t; vec3 color; }; layout(location = 0) rayPayloadInEXT Payload payload; hitAttributeEXT vec3 hitpoint; void main() { vec3 normal = normalize(hitpoint); payload.t = gl_HitTEXT; payload.color = (normal+vec3(1.0, 1.0, 1.0))*0.5; } ''', intersection=''' hitAttributeEXT vec3 hitpoint; void main() { vec3 origin = gl_ObjectRayOriginEXT; vec3 direction = gl_ObjectRayDirectionEXT; float tMin = gl_RayTminEXT; float tMax = gl_RayTmaxEXT; const float a = dot(direction, direction); const float b = dot(origin, direction); const float c = dot(origin, origin) - 1.0; const float discriminant = b * b - a * c; if (discriminant >= 0) { const float t1 = (-b - sqrt(discriminant)) / a; const float t2 = (-b + sqrt(discriminant)) / a; if ((tMin <= t1 && t1 < tMax) || (tMin <= t2 && t2 < tMax)) { float t = t1; if (tMin <= t1 && t1 < tMax) { hitpoint = origin + direction * t1; } else { t = t2; hitpoint = origin + direction * t2; } reportIntersectionEXT(t, 0); } } } ''')
def trace(self, scene, num_iter=100, interval=-1): if self.m_rng_states == None: print("Initializing RNG states..") self.m_rng_states = vki.SVVector('RNGState', self.m_batch_size) initializer = RNGInitializer() initializer.InitRNGVector(self.m_rng_states) scene.update() sunlight = '' estimate_light = '' for key in scene.m_obj_lists: sublist = scene.m_obj_lists[key] if sublist['is_light_source']: estimate_light += self.template_estimate_light.format( name_list=sublist['name']) if sublist['name'] == 'sun_lights': sunlight = self.sunlight miss = self.payload + self.template_miss.format( sunlight=sunlight) + self.template_update_payload.format( estimate_light='') print("Doing ray-tracing..") lst_param_names = ['camera', 'states', 'sky', 'pdf_lights'] for key in scene.m_obj_lists: sublist = scene.m_obj_lists[key] lst_param_names += [sublist['name']] hit_shaders = [] for key in scene.m_obj_lists: sublist = scene.m_obj_lists[key] if sublist['is_geometry']: closest_hit = self.payload + sublist[ 'closest_hit'] + self.template_update_payload.format( estimate_light=estimate_light) intersection = sublist['intersection'] hit_shaders += [ vki.HitShaders(closest_hit=closest_hit, intersection=intersection) ] ray_tracer = vki.RayTracer(lst_param_names, self.raygen, [miss], hit_shaders) if interval == -1: interval = num_iter lst_params = [ self.m_camera, self.m_rng_states, scene.m_sky, scene.m_pdf_lights ] + scene.m_lst_obj_lsts i = 0 while i < num_iter: end = i + interval if end > num_iter: end = num_iter ray_tracer.launch(self.m_batch_size, lst_params, [scene.m_tlas], tex2ds=scene.m_tex2d_list, tex3ds=scene.m_tex3d_list, cubemaps=scene.m_cubemap_list, times_submission=end - i) self.m_camera.m_film.inc_times_exposure(end - i) i = end if i < num_iter: print('%.2f%%' % (i / num_iter * 100.0))