def test_finite_difference(test_name, make_scene, diff_integrator, diff_spp, diff_passes, fd_integrator, fd_spp, fd_passes, fd_eps): print("Running test:", test_name) path = "output/" + test_name + "/" if not os.path.isdir(path): os.makedirs(path) print("Rendering finite differences...") scene_fd0 = make_scene(fd_integrator, fd_spp, 0) scene_fd1 = make_scene(fd_integrator, fd_spp, fd_eps) fsize = scene_fd0.sensors()[0].film().size() for i in range(fd_passes): print("pass:"******"Writing " + path + 'radiance_fd0.exr') Bitmap(values_fd0).write(path + 'radiance_fd0.exr') print("Writing " + path + 'radiance_fd1.exr') Bitmap(values_fd1).write(path + 'radiance_fd1.exr') gradient_fd = (values_fd1 - values_fd0) / fd_eps gradient_fd = gradient_fd[:, :, [0]] scale = np.abs(gradient_fd).max() write_gradient_image(gradient_fd / scale, path + 'gradient_fd', fsize) del scene_fd0, scene_fd1, values_fd0, values_fd1, channels, gradient_fd print("Rendering gradients... ({} spp, {} passes)".format( diff_spp, diff_passes)) scene = make_scene(diff_integrator, diff_spp, None) assert scene is not None params = traverse(scene) params.keep(['SDF.data']) gradient_rp_np = render_gradient(scene, diff_spp, diff_passes, scale, path, params, fd_eps)
def render_offset(offset): scene = make_scene(integrator, spp, offset) fsize = scene.sensors()[0].film().size() values = render(scene) for i in range(passes-1): values += render(scene) values /= passes return values.numpy().reshape(fsize[1], fsize[0], -1)
def render_gradient(scene, spp, pass_count, scale, path, params, eps): sensor = scene.sensors()[0] fsize = sensor.film().size() for i in range(pass_count): print("grad:", i, end='\r') set_requires_gradient(params['SDF.data']) y_i = render(scene) set_gradient(params['SDF.data'], np.sign(eps), backward=False) Float32.forward() #i == pass_count - 1 nb_channels = len(y_i) // (fsize[1] * fsize[0]) grad_i = gradient(y_i).numpy().reshape(fsize[1], fsize[0], nb_channels) grad_i = grad_i[:, :, 0] grad_i[grad_i != grad_i] = 0 if i == 0: y = y_i.numpy() y[y != y] = 0 grad = grad_i else: temp = detach(y_i).numpy() temp[temp != temp] = 0 y += temp del y_i grad += grad_i grad /= pass_count y /= pass_count if (scale == 0.0): scale = np.abs(grad).max() grad = grad.reshape(fsize[1], fsize[0], 1) write_gradient_image(grad / scale, path + 'gradient', fsize) y_np = y.reshape(fsize[1], fsize[0], nb_channels) print('Writing ' + path + 'radiance.exr') Bitmap(y_np).write(path + 'radiance.exr') return grad
def render_gradient(scene, passes, diff_params): """Render radiance and gradient image using forward autodiff""" from mitsuba.python.autodiff import render fsize = scene.sensors()[0].film().size() img = np.zeros((fsize[1], fsize[0], 3), dtype=np.float32) grad = np.zeros((fsize[1], fsize[0], 1), dtype=np.float32) for i in range(passes): img_i = render(scene) ek.forward(diff_params, i == passes - 1) grad_i = ek.gradient(img_i).numpy().reshape(fsize[1], fsize[0], -1)[:, :, [0]] img_i = img_i.numpy().reshape(fsize[1], fsize[0], -1) # Remove NaNs grad_i[grad_i != grad_i] = 0 img_i[img_i != img_i] = 0 grad += grad_i img += img_i return img / passes, grad / passes
# Load example scene Thread.thread().file_resolver().append('bunny') scene = load_file('bunny/bunny.xml') # Find differentiable scene parameters params = traverse(scene) # Make a backup copy param_res = params['my_envmap.resolution'] param_ref = Float(params['my_envmap.data']) # Discard all parameters except for one we want to differentiate params.keep(['my_envmap.data']) # Render a reference image (no derivatives used yet) image_ref = render(scene, spp=16) crop_size = scene.sensors()[0].film().crop_size() write_bitmap('out_ref.png', image_ref, crop_size) # Change to a uniform white lighting environment params['my_envmap.data'] = ek.full(Float, 1.0, len(param_ref)) params.update() # Construct an Adam optimizer that will adjust the parameters 'params' opt = Adam(params, lr=.02) time_a = time.time() iterations = 100 for it in range(iterations): # Perform a differentiable rendering of the scene
time_a = time.time() outpath = os.path.join('outputs/invert_infloasion/', outimg_dir) os.makedirs(outpath, exist_ok=True) out_config(outpath, render_config) # Write out config file losses = np.array([]) film = scene.sensors()[0].film() crop_size = film.crop_size() iterations = render_config['num_iteration'] for it in range(iterations): # Perform a differentiable rendering of the scene image = render(scene, optimizer=opt, unbiased=True, spp=4) if it % 10 == 0: write_bitmap(os.path.join(outpath, 'out_%04i.png' % it), image, crop_size) write_bitmap(os.path.join(outpath, 'texture_%04i.png' % it), params[opt_param_name], (param_res[1], param_res[0])) # Objective : MSE between 'image' and 'image_ref' ob_val = ek.hsum(ek.sqr(image - image_ref)) / len(image) # Back-propropagate errors to input parameters ek.backward(ob_val) # Optimizer : take a gradient step opt.step()
from mitsuba.python.autodiff import render, write_bitmap # Load the Cornell Box Thread.thread().file_resolver().append('cbox') scene = load_file( 'C:/MyFile/code/ray tracing/misuba2/test/gpu_autodiff/cbox/cbox.xml') # Find differentiable scene parameters params = traverse(scene) # Keep track of derivatives with respect to one parameter param_0 = params['red.reflectance.value'] ek.set_requires_gradient(param_0) # Differentiable simulation image = render(scene, spp=4) # Assign the gradient [1, 1, 1] to the 'red.reflectance.value' input ek.set_gradient(param_0, [1, 1, 1], backward=False) # Forward-propagate previously assigned gradients Float.forward() # The gradients have been propagated to the output image image_grad = ek.gradient(image) # .. write them to a PNG file crop_size = scene.sensors()[0].film().crop_size() fname = 'C:/MyFile/code/ray tracing/misuba2/test/gpu_autodiff/output/out.png' write_bitmap(fname, image_grad, crop_size) print('Wrote forward differentiation image to: {}'.format(fname))
# width and height determines the resolution of rendered image width = 128 height = 128 # spp: samples per pixel spp_ref = 64 spp_opt = 8 # Prepare output folder output_path = 'output/diffuser_smooth/' + task + '/' if not os.path.isdir(output_path): os.makedirs(output_path) # Generate the scene and image with a plain glass panel scene = make_scene(path_str, spp_ref, width, height) image_plain = render(scene) write_bitmap(output_path + "out_plain.png", image_plain, (width, height)) print("Writing " + "out_plain.png") params = traverse(scene) print(params) positions_buf = params['grid_mesh.vertex_positions_buf'] positions_initial = ravel(positions_buf) normals_initial = ravel(params['grid_mesh.vertex_normals_buf']) vertex_count = ek.slices(positions_initial) filename = 'scene/diffuser_surface_1.jpg' Thread.thread().file_resolver().append(os.path.dirname(filename)) # Create a texture with the reference displacement map disp_tex_1 = xml.load_dict({
import os test = list() test.append(10.00) test.append(100.00) test.append(259.00) mitsuba.set_variant('gpu_autodiff_rgb') from mitsuba.core import Thread from mitsuba.core.xml import load_file from mitsuba.python.util import traverse # Absolute or relative path to the XML file filename = 'scenes/cboxwithdragon/cboxwithdragon.xml' dump_path = 'results/BSDFTest/' try: os.makedirs(dump_path) except: pass # Add the scene directory to the FileResolver's search path Thread.thread().file_resolver().append(os.path.dirname(filename)) # Load the scene scene = load_file(filename) # Render a reference image (no derivatives used yet) from mitsuba.python.autodiff import render, write_bitmap image_ref = render(scene, spp=8) crop_size = scene.sensors()[0].film().crop_size() write_bitmap(dump_path + 'out_ref.png', image_ref, crop_size)