def _init_globals(self): """ Inits all global bindings. This includes references to the global ShowBase instance, as well as the render resolution, the GUI font, and various global logging and output methods. """ Globals.load(self._showbase) native_w, native_h = self._showbase.win.get_x_size(), self._showbase.win.get_y_size() Globals.native_resolution = LVecBase2i(native_w, native_h) self._last_window_dims = LVecBase2i(Globals.native_resolution) self._compute_render_resolution() RenderTarget.RT_OUTPUT_FUNC = lambda *args: RPObject.global_warn( "RenderTarget", *args[1:]) RenderTarget.USE_R11G11B10 = self.settings["pipeline.use_r11_g11_b10"]
def _init_globals(self): """ Inits all global bindings """ Globals.load(self._showbase) w, h = self._showbase.win.get_x_size(), self._showbase.win.get_y_size() scale_factor = self.settings["pipeline.resolution_scale"] w = int(float(w) * scale_factor) h = int(float(h) * scale_factor) # Make sure the resolution is a multiple of 4 w = w - w % 4 h = h - h % 4 self.debug("Render resolution is", w, "x", h) Globals.resolution = LVecBase2i(w, h) # Connect the render target output function to the debug object RenderTarget.RT_OUTPUT_FUNC = lambda *args: RPObject.global_warn( "RenderTarget", *args[1:]) RenderTarget.USE_R11G11B10 = self.settings["pipeline.use_r11_g11_b10"]
def __init__(self): load_prc_file_data("", """ textures-power-2 none win-size 1600 900 """) ShowBase.__init__(self) Globals.load(self) Globals.resolution = LVecBase2i(1600, 900) sun_vector = Vec3(BAKE_SUN_VECTOR).normalized() diameter = (BAKE_MESH_END - BAKE_MESH_START).length() model_center = (BAKE_MESH_START + BAKE_MESH_END) * 0.5 sun_shadow_map_resolution = 8192 # model = loader.load_model("resources/test-scene.bam") model = loader.load_model("scene/scene.bam") model.reparent_to(render) model.flatten_strong() print("Rendering sun shadow map ..") sun_shadow_cam = Camera("SunShadowCamera") sun_shadow_lens = OrthographicLens() sun_shadow_lens.set_film_size(diameter * 2, diameter * 2) sun_shadow_lens.set_near_far(0, 2 * diameter) sun_shadow_cam.set_lens(sun_shadow_lens) sun_shadow_cam_np = render.attach_new_node(sun_shadow_cam) sun_shadow_cam_np.set_pos(model_center + sun_vector * diameter) sun_shadow_cam_np.look_at(model_center) sun_shadow_target = RenderTarget() sun_shadow_target.size = sun_shadow_map_resolution sun_shadow_target.add_depth_attachment(bits=32) sun_shadow_target.prepare_render(sun_shadow_cam_np) self.graphicsEngine.render_frame() sun_shadow_target.active = False shadow_mvp = self.get_mvp(sun_shadow_cam_np) # Load the dataset dataset = loader.load_texture("raw-bake.png") render.set_shader_input("GIDataTexture", dataset) # Load the display shader shader = Shader.load(Shader.SL_GLSL, "resources/display.vert.glsl", "resources/display.frag.glsl") render.set_shader(shader) render.set_shader_inputs( ShadowMap=sun_shadow_target.depth_tex, shadowMVP=shadow_mvp, sunVector=sun_vector) # Render spheres distributed over the mesh mesh_size = BAKE_MESH_END - BAKE_MESH_START for i in range(11): for j in range(11): for k in range(11): offs_x = i / 10.0 * mesh_size.x + BAKE_MESH_START.x offs_y = j / 10.0 * mesh_size.y + BAKE_MESH_START.y offs_z = k / 10.0 * mesh_size.z + BAKE_MESH_START.z sphere = loader.load_model("resources/sphere.bam") sphere.reparent_to(render) sphere.set_scale(0.02) sphere.set_pos(offs_x, offs_y, offs_z)
def __init__(self): load_prc_file_data( "", """ textures-power-2 none win-size 1600 900 """) ShowBase.__init__(self) Globals.load(self) Globals.resolution = LVecBase2i(1600, 900) sun_vector = Vec3(BAKE_SUN_VECTOR).normalized() diameter = (BAKE_MESH_END - BAKE_MESH_START).length() model_center = (BAKE_MESH_START + BAKE_MESH_END) * 0.5 sun_shadow_map_resolution = 8192 # model = loader.load_model("resources/test-scene.bam") model = loader.load_model("scene/scene.bam") model.reparent_to(render) model.flatten_strong() print("Rendering sun shadow map ..") sun_shadow_cam = Camera("SunShadowCamera") sun_shadow_lens = OrthographicLens() sun_shadow_lens.set_film_size(diameter * 2, diameter * 2) sun_shadow_lens.set_near_far(0, 2 * diameter) sun_shadow_cam.set_lens(sun_shadow_lens) sun_shadow_cam_np = render.attach_new_node(sun_shadow_cam) sun_shadow_cam_np.set_pos(model_center + sun_vector * diameter) sun_shadow_cam_np.look_at(model_center) sun_shadow_target = RenderTarget() sun_shadow_target.size = sun_shadow_map_resolution sun_shadow_target.add_depth_attachment(bits=32) sun_shadow_target.prepare_render(sun_shadow_cam_np) self.graphicsEngine.render_frame() sun_shadow_target.active = False shadow_mvp = self.get_mvp(sun_shadow_cam_np) # Load the dataset dataset = loader.load_texture("raw-bake.png") render.set_shader_input("GIDataTexture", dataset) # Load the display shader shader = Shader.load(Shader.SL_GLSL, "resources/display.vert.glsl", "resources/display.frag.glsl") render.set_shader(shader) render.set_shader_inputs(ShadowMap=sun_shadow_target.depth_tex, shadowMVP=shadow_mvp, sunVector=sun_vector) # Render spheres distributed over the mesh mesh_size = BAKE_MESH_END - BAKE_MESH_START for i in range(11): for j in range(11): for k in range(11): offs_x = i / 10.0 * mesh_size.x + BAKE_MESH_START.x offs_y = j / 10.0 * mesh_size.y + BAKE_MESH_START.y offs_z = k / 10.0 * mesh_size.z + BAKE_MESH_START.z sphere = loader.load_model("resources/sphere.bam") sphere.reparent_to(render) sphere.set_scale(0.02) sphere.set_pos(offs_x, offs_y, offs_z)
def __init__(self): # Load settings load_prc_file_data("", """ win-size 10 10 window-type offscreen win-title GI Bake textures-power-2 none gl-coordinate-system default sync-video #f support-stencil #f framebuffer-stencil #f framebuffer-multisample #f multisamples 0 gl-cube-map-seamless #t gl-force-fbo-color #f """) ShowBase.__init__(self) Globals.load(self) Globals.resolution = LVecBase2i(1600, 900) sun_vector = Vec3(0.2, 0.5, 1.2).normalized() capture_resolution = 32 sun_shadow_map_resolution = 2048 num_probes = LVecBase3i(64) divisor = 128 num_bakers = 8 padding = 0.5 for region in self.win.get_display_regions(): region.set_active(False) print("Loading scene ...") # model = loader.load_model("resources/test-scene.bam") model = loader.load_model("scene/scene.bam") # model = loader.load_model("scene/LivingRoom.egg") model.reparent_to(render) model.flatten_strong() start_point, end_point = model.get_tight_bounds() start_point -= padding end_point += padding diameter = (start_point - end_point).length() * 0.5 model_center = (start_point + end_point) * 0.5 model_size = end_point - start_point print("Rendering sun shadow map ..") sun_shadow_cam = Camera("SunShadowCamera") sun_shadow_lens = OrthographicLens() sun_shadow_lens.set_film_size(diameter * 2, diameter * 2) sun_shadow_lens.set_near_far(0, 2 * diameter) sun_shadow_cam.set_lens(sun_shadow_lens) sun_shadow_cam_np = render.attach_new_node(sun_shadow_cam) sun_shadow_cam_np.set_pos(model_center + sun_vector * diameter) sun_shadow_cam_np.look_at(model_center) sun_shadow_target = RenderTarget() sun_shadow_target.size = sun_shadow_map_resolution sun_shadow_target.add_depth_attachment(bits=32) sun_shadow_target.prepare_render(sun_shadow_cam_np) self.render_frame() sun_shadow_target.active = False shadow_mvp = self.get_mvp(sun_shadow_cam_np) print("Computing first bounce ..") # Target to store all results max_probes = num_probes.x * num_probes.y * num_probes.z if max_probes % divisor != 0: print("WARNING: Bad divisor:", divisor, "for", max_probes) num_rows = (max_probes + divisor - 1) // divisor final_data = Texture("FinalProbeResult") final_data.setup_2d_texture(6 * divisor, num_rows, Texture.T_float, Texture.F_rgba16) final_data.set_clear_color(Vec4(1.0, 0.6, 0.2, 1.0)) worker_handles = [] store_shader = Shader.load(Shader.SL_GLSL, "resources/default.vert.glsl", "resources/copy_cubemap.frag.glsl") convolute_shader = Shader.load(Shader.SL_GLSL, "resources/default.vert.glsl", "resources/convolute.frag.glsl") for worked_id in range(num_bakers): probe_position = Vec3(0, 0, 4) capture_target = RenderTarget() capture_target.size = capture_resolution * 6, capture_resolution capture_target.add_depth_attachment(bits=16) capture_target.add_color_attachment(bits=16, alpha=True) capture_target.prepare_render(None) # Remove all unused display regions internal_buffer = capture_target.internal_buffer internal_buffer.remove_all_display_regions() internal_buffer.disable_clears() internal_buffer.get_overlay_display_region().disable_clears() # Setup the cubemap capture rig directions = (Vec3(1, 0, 0), Vec3(-1, 0, 0), Vec3(0, 1, 0), Vec3(0, -1, 0), Vec3(0, 0, 1), Vec3(0, 0, -1)) capture_regions = [] capture_cams = [] capture_rig = render.attach_new_node("CaptureRig") capture_rig.set_pos(probe_position) # Prepare the display regions for i in range(6): region = capture_target.internal_buffer.make_display_region( i / 6, i / 6 + 1 / 6, 0, 1) region.set_sort(25 + i) region.set_active(True) region.disable_clears() # Set the correct clears region.set_clear_depth_active(True) region.set_clear_depth(1.0) region.set_clear_color_active(True) region.set_clear_color(Vec4(0.0, 0.0, 0.0, 0.0)) lens = PerspectiveLens() lens.set_fov(90) lens.set_near_far(0.05, 2 * diameter) camera = Camera("CaptureCam-" + str(i), lens) camera_np = capture_rig.attach_new_node(camera) camera_np.look_at(camera_np, directions[i]) region.set_camera(camera_np) capture_regions.append(region) capture_cams.append(camera_np) capture_cams[0].set_r(90) capture_cams[1].set_r(-90) capture_cams[3].set_r(180) capture_cams[5].set_r(180) destination_cubemap = Texture("TemporaryCubemap") destination_cubemap.setup_cube_map(capture_resolution, Texture.T_float, Texture.F_rgba16) # Target to convert the FBO to a cubemap target_store_cubemap = RenderTarget() target_store_cubemap.size = capture_resolution * 6, capture_resolution target_store_cubemap.prepare_buffer() target_store_cubemap.set_shader_inputs( SourceTex=capture_target.color_tex, DestTex=destination_cubemap) target_store_cubemap.shader = store_shader # Target to filter the data store_pta = PTALVecBase2i.empty_array(1) target_convolute = RenderTarget() target_convolute.size = 6, 1 # target_convolute.add_color_attachment(bits=16) target_convolute.prepare_buffer() target_convolute.set_shader_inputs( SourceTex=destination_cubemap, DestTex=final_data, storeCoord=store_pta) target_convolute.shader = convolute_shader # Set initial shader shader = Shader.load(Shader.SL_GLSL, "resources/first-bounce.vert.glsl", "resources/first-bounce.frag.glsl") render.set_shader(shader) render.set_shader_inputs( ShadowMap=sun_shadow_target.depth_tex, shadowMVP=shadow_mvp, sunVector=sun_vector) worker_handles.append((capture_rig, store_pta)) print("Preparing to render", max_probes, "probes ..") widgets = [Counter(), " ", Bar(), " ", Percentage(), " ", ETA(), " ", Rate()] progressbar = ProgressBar(widgets=widgets, maxval=max_probes).start() progressbar.update(0) work_queue = [] for z_pos in range(num_probes.z): for y_pos in range(num_probes.y): for x_pos in range(num_probes.x): index = x_pos + y_pos * num_probes.x + z_pos * num_probes.y * num_probes.x # print("Baking", index, "out of", max_probes) offs_x = start_point.x + x_pos / (num_probes.x + 0.5) * model_size.x offs_y = start_point.y + y_pos / (num_probes.y + 0.5) * model_size.y offs_z = start_point.z + z_pos / (num_probes.z + 0.5) * model_size.z store_x = index % divisor store_y = index // divisor work_queue.append((Vec3(offs_x, offs_y, offs_z), LVecBase2i(store_x, store_y))) for i, (pos, store) in enumerate(work_queue): worker_handles[i%num_bakers][0].set_pos(pos) worker_handles[i%num_bakers][1][0] = store if i % num_bakers == num_bakers - 1: self.render_frame() progressbar.update(i) progressbar.finish() self.render_frame() print("Writing out data ..") self.graphicsEngine.extract_texture_data(final_data, self.win.gsg) final_data.write("raw-bake.png") print("Writing out configuration") with open("_bake_params.py", "w") as handle: handle.write("#Autogenerated\n") handle.write("from panda3d.core import LPoint3f, LVecBase3i, LVector3f\n") handle.write("BAKE_MESH_START = " + str(start_point) + "\n") handle.write("BAKE_MESH_END = " + str(end_point) + "\n") handle.write("BAKE_MESH_PROBECOUNT = " + str(num_probes) + "\n") handle.write("BAKE_DIVISOR = " + str(divisor) + "\n") handle.write("BAKE_SUN_VECTOR = " + str(sun_vector) + "\n") with open("_bake_params.glsl", "w") as handle: handle.write("// Autogenerated\n") handle.write("#define LPoint3f vec3\n") handle.write("#define LVector3f vec3\n") handle.write("#define LVecBase3i ivec3\n") handle.write("const vec3 bake_mesh_start = " + str(start_point) + ";\n") handle.write("const vec3 bake_mesh_end = " + str(end_point) + ";\n") handle.write("const ivec3 bake_mesh_probecount = " + str(num_probes) + ";\n") handle.write("const int bake_divisor = " + str(divisor) + ";\n") handle.write("const vec3 sun_vector = " + str(sun_vector) + ";\n")
def __init__(self): # Load settings load_prc_file_data( "", """ win-size 10 10 window-type offscreen win-title GI Bake textures-power-2 none gl-coordinate-system default sync-video #f support-stencil #f framebuffer-stencil #f framebuffer-multisample #f multisamples 0 gl-cube-map-seamless #t gl-force-fbo-color #f """) ShowBase.__init__(self) Globals.load(self) Globals.resolution = LVecBase2i(1600, 900) sun_vector = Vec3(0.2, 0.5, 1.2).normalized() capture_resolution = 32 sun_shadow_map_resolution = 2048 num_probes = LVecBase3i(64) divisor = 128 num_bakers = 8 padding = 0.5 for region in self.win.get_display_regions(): region.set_active(False) print("Loading scene ...") # model = loader.load_model("resources/test-scene.bam") model = loader.load_model("scene/scene.bam") # model = loader.load_model("scene/LivingRoom.egg") model.reparent_to(render) model.flatten_strong() start_point, end_point = model.get_tight_bounds() start_point -= padding end_point += padding diameter = (start_point - end_point).length() * 0.5 model_center = (start_point + end_point) * 0.5 model_size = end_point - start_point print("Rendering sun shadow map ..") sun_shadow_cam = Camera("SunShadowCamera") sun_shadow_lens = OrthographicLens() sun_shadow_lens.set_film_size(diameter * 2, diameter * 2) sun_shadow_lens.set_near_far(0, 2 * diameter) sun_shadow_cam.set_lens(sun_shadow_lens) sun_shadow_cam_np = render.attach_new_node(sun_shadow_cam) sun_shadow_cam_np.set_pos(model_center + sun_vector * diameter) sun_shadow_cam_np.look_at(model_center) sun_shadow_target = RenderTarget() sun_shadow_target.size = sun_shadow_map_resolution sun_shadow_target.add_depth_attachment(bits=32) sun_shadow_target.prepare_render(sun_shadow_cam_np) self.render_frame() sun_shadow_target.active = False shadow_mvp = self.get_mvp(sun_shadow_cam_np) print("Computing first bounce ..") # Target to store all results max_probes = num_probes.x * num_probes.y * num_probes.z if max_probes % divisor != 0: print("WARNING: Bad divisor:", divisor, "for", max_probes) num_rows = (max_probes + divisor - 1) // divisor final_data = Texture("FinalProbeResult") final_data.setup_2d_texture(6 * divisor, num_rows, Texture.T_float, Texture.F_rgba16) final_data.set_clear_color(Vec4(1.0, 0.6, 0.2, 1.0)) worker_handles = [] store_shader = Shader.load(Shader.SL_GLSL, "resources/default.vert.glsl", "resources/copy_cubemap.frag.glsl") convolute_shader = Shader.load(Shader.SL_GLSL, "resources/default.vert.glsl", "resources/convolute.frag.glsl") for worked_id in range(num_bakers): probe_position = Vec3(0, 0, 4) capture_target = RenderTarget() capture_target.size = capture_resolution * 6, capture_resolution capture_target.add_depth_attachment(bits=16) capture_target.add_color_attachment(bits=16, alpha=True) capture_target.prepare_render(None) # Remove all unused display regions internal_buffer = capture_target.internal_buffer internal_buffer.remove_all_display_regions() internal_buffer.disable_clears() internal_buffer.get_overlay_display_region().disable_clears() # Setup the cubemap capture rig directions = (Vec3(1, 0, 0), Vec3(-1, 0, 0), Vec3(0, 1, 0), Vec3(0, -1, 0), Vec3(0, 0, 1), Vec3(0, 0, -1)) capture_regions = [] capture_cams = [] capture_rig = render.attach_new_node("CaptureRig") capture_rig.set_pos(probe_position) # Prepare the display regions for i in range(6): region = capture_target.internal_buffer.make_display_region( i / 6, i / 6 + 1 / 6, 0, 1) region.set_sort(25 + i) region.set_active(True) region.disable_clears() # Set the correct clears region.set_clear_depth_active(True) region.set_clear_depth(1.0) region.set_clear_color_active(True) region.set_clear_color(Vec4(0.0, 0.0, 0.0, 0.0)) lens = PerspectiveLens() lens.set_fov(90) lens.set_near_far(0.05, 2 * diameter) camera = Camera("CaptureCam-" + str(i), lens) camera_np = capture_rig.attach_new_node(camera) camera_np.look_at(camera_np, directions[i]) region.set_camera(camera_np) capture_regions.append(region) capture_cams.append(camera_np) capture_cams[0].set_r(90) capture_cams[1].set_r(-90) capture_cams[3].set_r(180) capture_cams[5].set_r(180) destination_cubemap = Texture("TemporaryCubemap") destination_cubemap.setup_cube_map(capture_resolution, Texture.T_float, Texture.F_rgba16) # Target to convert the FBO to a cubemap target_store_cubemap = RenderTarget() target_store_cubemap.size = capture_resolution * 6, capture_resolution target_store_cubemap.prepare_buffer() target_store_cubemap.set_shader_inputs( SourceTex=capture_target.color_tex, DestTex=destination_cubemap) target_store_cubemap.shader = store_shader # Target to filter the data store_pta = PTALVecBase2i.empty_array(1) target_convolute = RenderTarget() target_convolute.size = 6, 1 # target_convolute.add_color_attachment(bits=16) target_convolute.prepare_buffer() target_convolute.set_shader_inputs(SourceTex=destination_cubemap, DestTex=final_data, storeCoord=store_pta) target_convolute.shader = convolute_shader # Set initial shader shader = Shader.load(Shader.SL_GLSL, "resources/first-bounce.vert.glsl", "resources/first-bounce.frag.glsl") render.set_shader(shader) render.set_shader_inputs(ShadowMap=sun_shadow_target.depth_tex, shadowMVP=shadow_mvp, sunVector=sun_vector) worker_handles.append((capture_rig, store_pta)) print("Preparing to render", max_probes, "probes ..") widgets = [ Counter(), " ", Bar(), " ", Percentage(), " ", ETA(), " ", Rate() ] progressbar = ProgressBar(widgets=widgets, maxval=max_probes).start() progressbar.update(0) work_queue = [] for z_pos in range(num_probes.z): for y_pos in range(num_probes.y): for x_pos in range(num_probes.x): index = x_pos + y_pos * num_probes.x + z_pos * num_probes.y * num_probes.x # print("Baking", index, "out of", max_probes) offs_x = start_point.x + x_pos / (num_probes.x + 0.5) * model_size.x offs_y = start_point.y + y_pos / (num_probes.y + 0.5) * model_size.y offs_z = start_point.z + z_pos / (num_probes.z + 0.5) * model_size.z store_x = index % divisor store_y = index // divisor work_queue.append( (Vec3(offs_x, offs_y, offs_z), LVecBase2i(store_x, store_y))) for i, (pos, store) in enumerate(work_queue): worker_handles[i % num_bakers][0].set_pos(pos) worker_handles[i % num_bakers][1][0] = store if i % num_bakers == num_bakers - 1: self.render_frame() progressbar.update(i) progressbar.finish() self.render_frame() print("Writing out data ..") self.graphicsEngine.extract_texture_data(final_data, self.win.gsg) final_data.write("raw-bake.png") print("Writing out configuration") with open("_bake_params.py", "w") as handle: handle.write("#Autogenerated\n") handle.write( "from panda3d.core import LPoint3f, LVecBase3i, LVector3f\n") handle.write("BAKE_MESH_START = " + str(start_point) + "\n") handle.write("BAKE_MESH_END = " + str(end_point) + "\n") handle.write("BAKE_MESH_PROBECOUNT = " + str(num_probes) + "\n") handle.write("BAKE_DIVISOR = " + str(divisor) + "\n") handle.write("BAKE_SUN_VECTOR = " + str(sun_vector) + "\n") with open("_bake_params.glsl", "w") as handle: handle.write("// Autogenerated\n") handle.write("#define LPoint3f vec3\n") handle.write("#define LVector3f vec3\n") handle.write("#define LVecBase3i ivec3\n") handle.write("const vec3 bake_mesh_start = " + str(start_point) + ";\n") handle.write("const vec3 bake_mesh_end = " + str(end_point) + ";\n") handle.write("const ivec3 bake_mesh_probecount = " + str(num_probes) + ";\n") handle.write("const int bake_divisor = " + str(divisor) + ";\n") handle.write("const vec3 sun_vector = " + str(sun_vector) + ";\n")