def load_obj(filename, obj_group=True, flip_tex_coords=True): """ Load from a Wavefront obj file as PyTorch tensors. XXX: this is slow, maybe move to C++? """ vertices_pool = [] uvs_pool = [] normals_pool = [] indices = [] vertices = [] normals = [] uvs = [] vertices_map = {} material_map = {} current_mtllib = {} current_material_name = None def create_mesh(indices, vertices, normals, uvs): indices = tf.constant(indices, dtype=tf.int32) vertices = tf.constant(vertices) if len(uvs) == 0: uvs = None else: uvs = tf.constant(uvs) if len(normals) == 0: normals = None else: normals = tf.constant(normals) return TriangleMesh(vertices, indices, uvs, normals) mesh_list = [] light_map = {} f = open(filename, 'r') d = os.path.dirname(filename) cwd = os.getcwd() if d != '': os.chdir(d) for line in f: line = line.strip() splitted = re.split('\ +', line) if splitted[0] == 'mtllib': current_mtllib = load_mtl(splitted[1]) elif splitted[0] == 'usemtl': if len(indices) > 0 and obj_group is True: # Flush mesh_list.append((current_material_name, create_mesh(indices, vertices, normals, uvs))) indices = [] vertices = [] normals = [] uvs = [] vertices_map = {} mtl_name = splitted[1] current_material_name = mtl_name if mtl_name not in material_map: m = current_mtllib[mtl_name] if m.map_Kd is None: diffuse_reflectance = tf.constant(m.Kd, dtype=tf.float32) else: diffuse_reflectance = pyredner.imread(m.map_Kd) if m.map_Ks is None: specular_reflectance = tf.constant(m.Ks, dtype=tf.float32) else: specular_reflectance = pyredner.imread(m.map_Ks) if m.map_Ns is None: roughness = tf.constant([2.0 / (m.Ns + 2.0)], dtype=tf.float32) else: roughness = 2.0 / (pyredner.imread(m.map_Ks) + 2.0) if m.Ke != (0.0, 0.0, 0.0): light_map[mtl_name] = tf.constant(m.Ke, dtype=tf.float32) material_map[mtl_name] = pyredner.Material( diffuse_reflectance, specular_reflectance, roughness) elif splitted[0] == 'v': vertices_pool.append( [float(splitted[1]), float(splitted[2]), float(splitted[3])]) elif splitted[0] == 'vt': u = float(splitted[1]) v = float(splitted[2]) if flip_tex_coords: v = 1 - v uvs_pool.append([u, v]) elif splitted[0] == 'vn': normals_pool.append( [float(splitted[1]), float(splitted[2]), float(splitted[3])]) elif splitted[0] == 'f': def num_indices(x): return len(re.split('/', x)) def get_index(x, i): return int(re.split('/', x)[i]) def parse_face_index(x, i): f = get_index(x, i) if f < 0: if (i == 0): f += len(vertices) if (i == 1): f += len(uvs) else: f -= 1 return f assert (len(splitted) <= 5) def get_vertex_id(indices): pi = parse_face_index(indices, 0) uvi = None if (num_indices(indices) > 1 and re.split('/', indices)[1] != ''): uvi = parse_face_index(indices, 1) ni = None if (num_indices(indices) > 2 and re.split('/', indices)[2] != ''): ni = parse_face_index(indices, 2) key = (pi, uvi, ni) if key in vertices_map: return vertices_map[key] vertex_id = len(vertices) vertices_map[key] = vertex_id vertices.append(vertices_pool[pi]) if uvi is not None: uvs.append(uvs_pool[uvi]) if ni is not None: normals.append(normals_pool[ni]) return vertex_id vid0 = get_vertex_id(splitted[1]) vid1 = get_vertex_id(splitted[2]) vid2 = get_vertex_id(splitted[3]) indices.append([vid0, vid1, vid2]) if (len(splitted) == 5): vid3 = get_vertex_id(splitted[4]) indices.append([vid0, vid2, vid3]) mesh_list.append( (current_material_name, create_mesh(indices, vertices, normals, uvs))) if d != '': os.chdir(cwd) f.close() return material_map, mesh_list, light_map
# The first argument is the shape id of the light light = pyredner.AreaLight(2, light_intensity) area_lights = [light] scene = pyredner.Scene(cam, shapes, materials, area_lights) scene_args = pyredner.serialize_scene(scene=scene, num_samples=256, max_bounces=1) # Alias of the render function # Render our target img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_shadow_receiver/target.exr') pyredner.imwrite(img, 'results/test_shadow_receiver/target.png') target = pyredner.imread('results/test_shadow_receiver/target.exr') # Perturb the scene, this is our initial guess with tf.device(pyredner.get_device_name()): shape_floor.vertices = tf.Variable([[-2.0, -0.2, -2.0], [-2.0, -0.2, 2.0], [2.0, -0.2, -2.0], [2.0, -0.2, 2.0]], trainable=True, use_resource=True) scene_args = pyredner.serialize_scene(scene=scene, num_samples=256, max_bounces=1) # Render the initial guess img = pyredner.render(1, *scene_args) pyredner.imwrite(img, 'results/test_shadow_receiver/init.png') diff = tf.abs(target - img) pyredner.imwrite(diff, 'results/test_shadow_receiver/init_diff.png')
dtype=tf.float32, use_resource=True) look_at = tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32, use_resource=True) up = tf.Variable([0.0, 1.0, 0.0], dtype=tf.float32, use_resource=True) fov = tf.Variable([45.0], dtype=tf.float32, use_resource=True) clip_near = 1e-2 resolution = (256, 256) cam = pyredner.Camera(position=position, look_at=look_at, up=up, fov=fov, clip_near=clip_near, resolution=resolution) with tf.device(pyredner.get_device_name()): checkerboard_texture = pyredner.imread('checkerboard.exr') mat_checkerboard = pyredner.Material( diffuse_reflectance=checkerboard_texture) mat_black = pyredner.Material(diffuse_reflectance=tf.Variable( [0.0, 0.0, 0.0], dtype=tf.float32, use_resource=True)) materials = [mat_checkerboard, mat_black] vertices = tf.Variable([[-1.0, -1.0, 0.0], [-1.0, 1.0, 0.0], [1.0, -1.0, 0.0], [1.0, 1.0, 0.0]], dtype=tf.float32, use_resource=True) indices = tf.constant([[0, 1, 2], [1, 3, 2]], dtype=tf.int32) uvs = tf.Variable([[0.05, 0.05], [0.05, 0.95], [0.95, 0.05], [0.95, 0.95]], dtype=tf.float32, use_resource=True) shape_plane = pyredner.Shape(vertices, indices, uvs, None, 0) light_vertices = tf.Variable([[-1.0, -1.0, -7.0], [1.0, -1.0, -7.0],
# Construct the scene scene = pyredner.Scene(cam, shapes, materials, area_lights) # Serialize the scene # Here we specify the output channels as "radiance" and "alpha" # Render the scene as our target image. scene_args = pyredner.serialize_scene(\ scene = scene, num_samples = 16, max_bounces = 1, channels = [redner.channels.radiance, redner.channels.alpha]) # Render the scene as our target image. # Render. The first argument is the seed for RNG in the renderer. img = pyredner.render(0, *scene_args) background = pyredner.imread('scenes/textures/siggraph.jpg') background = tf.convert_to_tensor(skimage.transform.resize( background.numpy(), (256, 256, 3)), dtype=tf.float32) img = img[:, :, :3] * img[:, :, 3:4] + background * (1 - img[:, :, 3:4]) # Save the images. # The output image is in the GPU memory if you are using GPU. pyredner.imwrite(img, 'results/test_single_triangle_background/target.exr') pyredner.imwrite(img, 'results/test_single_triangle_background/target.png') # Read the target image we just saved. target = pyredner.imread('results/test_single_triangle_background/target.exr') scene_args = pyredner.serialize_scene( scene=scene, num_samples=16,
light_intensity = tf.Variable([1000.0, 1000.0, 1000.0], dtype=tf.float32, use_resource=True) # The first argument is the shape id of the light light = pyredner.AreaLight(2, light_intensity) area_lights = [light] scene = pyredner.Scene(cam, shapes, materials, area_lights) scene_args = pyredner.serialize_scene(scene=scene, num_samples=256, max_bounces=1) # Render our target img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_shadow_blocker/target.exr') pyredner.imwrite(img, 'results/test_shadow_blocker/target.png') target = pyredner.imread('results/test_shadow_blocker/target.exr') # Perturb the scene, this is our initial guess with tf.device(pyredner.get_device_name()): shape_blocker.vertices = tf.Variable([[-0.2, 3.5, -0.8], [-0.8, 3.0, 0.3], [0.4, 2.8, -0.8], [0.3, 3.2, 1.0]], trainable=True, use_resource=True) scene_args = pyredner.serialize_scene(scene=scene, num_samples=256, max_bounces=1) # Render the initial guess img = pyredner.render(1, *scene_args) pyredner.imwrite(img, 'results/test_shadow_blocker/init.png') diff = tf.abs(target - img) pyredner.imwrite(diff, 'results/test_shadow_blocker/init_diff.png')
def load_obj(filename: str, obj_group: bool = True, flip_tex_coords: bool = True, use_common_indices: bool = False, return_objects: bool = False): """ Load from a Wavefront obj file as PyTorch tensors. Args ==== obj_group: bool split the meshes based on materials flip_tex_coords: bool flip the v coordinate of uv by applying v' = 1 - v use_common_indices: bool Use the same indices for position, uvs, normals. Not recommended since texture seams in the objects sharing the same positions would cause the optimization to "tear" the object return_objects: bool Output list of Object instead. If there is no corresponding material for a shape, assign a grey material. Returns ======= if return_objects == True, return a list of Object if return_objects == False, return (material_map, mesh_list, light_map), material_map -> Map[mtl_name, WavefrontMaterial] mesh_list -> List[TriangleMesh] light_map -> Map[mtl_name, torch.Tensor] """ vertices_pool = [] uvs_pool = [] normals_pool = [] indices = [] uv_indices = [] normal_indices = [] vertices = [] uvs = [] normals = [] vertices_map = {} uvs_map = {} normals_map = {} material_map = {} current_mtllib = {} current_material_name = None def create_mesh(indices, uv_indices, normal_indices, vertices, uvs, normals): indices = tf.constant(indices, dtype=tf.int32) if len(uv_indices) == 0: uv_indices = None else: uv_indices = tf.constant(uv_indices, dtype=tf.int32) if len(normal_indices) == 0: normal_indices = None else: normal_indices = tf.constant(normal_indices, dtype=tf.int32) vertices = tf.constant(vertices) if len(uvs) == 0: uvs = None else: uvs = tf.constant(uvs) if len(normals) == 0: normals = None else: normals = tf.constant(normals) return TriangleMesh(indices, uv_indices, normal_indices, vertices, uvs, normals) mesh_list = [] light_map = {} with open(filename, 'r') as f: d = os.path.dirname(filename) cwd = os.getcwd() if d != '': os.chdir(d) for line in f: line = line.strip() splitted = re.split('\ +', line) if splitted[0] == 'mtllib': current_mtllib = load_mtl(splitted[1]) elif splitted[0] == 'usemtl': if len(indices) > 0 and obj_group is True: # Flush mesh_list.append( (current_material_name, create_mesh(indices, uv_indices, normal_indices, vertices, uvs, normals))) indices = [] uv_indices = [] normal_indices = [] vertices = [] normals = [] uvs = [] vertices_map = {} uvs_map = {} normals_map = {} mtl_name = splitted[1] current_material_name = mtl_name if mtl_name not in material_map: m = current_mtllib[mtl_name] if m.map_Kd is None: diffuse_reflectance = tf.constant(m.Kd, dtype=tf.float32) else: diffuse_reflectance = pyredner.imread(m.map_Kd) if m.map_Ks is None: specular_reflectance = tf.constant(m.Ks, dtype=tf.float32) else: specular_reflectance = pyredner.imread(m.map_Ks) if m.map_Ns is None: roughness = tf.constant([2.0 / (m.Ns + 2.0)], dtype=tf.float32) else: roughness = 2.0 / (pyredner.imread(m.map_Ns) + 2.0) if m.Ke != (0.0, 0.0, 0.0): light_map[mtl_name] = tf.constant(m.Ke, dtype=tf.float32) material_map[mtl_name] = pyredner.Material( diffuse_reflectance, specular_reflectance, roughness) elif splitted[0] == 'v': vertices_pool.append([ float(splitted[1]), float(splitted[2]), float(splitted[3]) ]) elif splitted[0] == 'vt': u = float(splitted[1]) v = float(splitted[2]) if flip_tex_coords: v = 1 - v uvs_pool.append([u, v]) elif splitted[0] == 'vn': normals_pool.append([ float(splitted[1]), float(splitted[2]), float(splitted[3]) ]) elif splitted[0] == 'f': def num_indices(x): return len(re.split('/', x)) def get_index(x, i): return int(re.split('/', x)[i]) def parse_face_index(x, i): f = get_index(x, i) if f > 0: f -= 1 return f assert (len(splitted) <= 5) def get_vertex_id(indices): pi = parse_face_index(indices, 0) uvi = None if (num_indices(indices) > 1 and re.split('/', indices)[1] != ''): uvi = parse_face_index(indices, 1) ni = None if (num_indices(indices) > 2 and re.split('/', indices)[2] != ''): ni = parse_face_index(indices, 2) if use_common_indices: # vertex, uv, normals share the same indexing key = (pi, uvi, ni) if key in vertices_map: vertex_id = vertices_map[key] return vertex_id, vertex_id, vertex_id vertex_id = len(vertices) vertices_map[key] = vertex_id vertices.append(vertices_pool[pi]) if uvi is not None: uvs.append(uvs_pool[uvi]) if ni is not None: normals.append(normals_pool[ni]) return vertex_id, vertex_id, vertex_id else: # vertex, uv, normals use separate indexing vertex_id = None uv_id = None normal_id = None if pi in vertices_map: vertex_id = vertices_map[pi] else: vertex_id = len(vertices) vertices.append(vertices_pool[pi]) vertices_map[pi] = vertex_id if uvi is not None: if uvi in uvs_map: uv_id = uvs_map[uvi] else: uv_id = len(uvs) uvs.append(uvs_pool[uvi]) uvs_map[uvi] = uv_id if ni is not None: if ni in normals_map: normal_id = normals_map[ni] else: normal_id = len(normals) normals.append(normals_pool[ni]) normals_map[ni] = normal_id return vertex_id, uv_id, normal_id vid0, uv_id0, n_id0 = get_vertex_id(splitted[1]) vid1, uv_id1, n_id1 = get_vertex_id(splitted[2]) vid2, uv_id2, n_id2 = get_vertex_id(splitted[3]) indices.append([vid0, vid1, vid2]) if uv_id0 is not None: assert (uv_id1 is not None and uv_id2 is not None) uv_indices.append([uv_id0, uv_id1, uv_id2]) if n_id0 is not None: assert (n_id1 is not None and n_id2 is not None) normal_indices.append([n_id0, n_id1, n_id2]) if (len(splitted) == 5): vid3, uv_id3, n_id3 = get_vertex_id(splitted[4]) indices.append([vid0, vid2, vid3]) if uv_id0 is not None: assert (uv_id3 is not None) uv_indices.append([uv_id0, uv_id2, uv_id3]) if n_id0 is not None: assert (n_id3 is not None) normal_indices.append([n_id0, n_id2, n_id3]) mesh_list.append((current_material_name, create_mesh(indices, uv_indices, normal_indices, vertices, uvs, normals))) if d != '': os.chdir(cwd) if return_objects: objects = [] for mtl_name, mesh in mesh_list: if mtl_name in material_map: m = material_map[mtl_name] else: m = pyredner.Material(diffuse_reflectance = \ tf.constant((0.5, 0.5, 0.5))) if mtl_name in light_map: l = light_map[mtl_name] else: l = None objects.append(pyredner.Object(\ vertices = mesh.vertices, indices = mesh.indices, material = m, light_intensity = l, uvs = mesh.uvs, normals = mesh.normals, uv_indices = mesh.uv_indices, normal_indices = mesh.normal_indices)) return objects else: return material_map, mesh_list, light_map
def load_obj(filename, obj_group=True, flip_tex_coords=True, use_common_indices=False): """ Load from a Wavefront obj file as PyTorch tensors. XXX: this is slow, maybe move to C++? Args: obj_group -- split the meshes based on materials flip_tex_coords -- flip the v coordinate of uv by applying v' = 1 - v use_common_indices -- use the same indices for position, uvs, normals. Not recommended since texture seams in the objects sharing the same positions would cause the optimization to "tear" the object. """ vertices_pool = [] uvs_pool = [] normals_pool = [] indices = [] uv_indices = [] normal_indices = [] vertices = [] uvs = [] normals = [] vertices_map = {} uvs_map = {} normals_map = {} material_map = {} current_mtllib = {} current_material_name = None def create_mesh(indices, uv_indices, normal_indices, vertices, uvs, normals): indices = tf.constant(indices, dtype=tf.int32) if len(uv_indices) == 0: uv_indices = None else: uv_indices = tf.constant(uv_indices, dtype=tf.int32) if len(normal_indices) == 0: normal_indices = None else: normal_indices = tf.constant(normal_indices, dtype=tf.int32) vertices = tf.constant(vertices) if len(uvs) == 0: uvs = None else: uvs = tf.constant(uvs) if len(normals) == 0: normals = None else: normals = tf.constant(normals) return TriangleMesh(indices, uv_indices, normal_indices, vertices, uvs, normals) mesh_list = [] light_map = {} f = open(filename, 'r') d = os.path.dirname(filename) cwd = os.getcwd() if d != '': os.chdir(d) for line in f: line = line.strip() splitted = re.split('\ +', line) if splitted[0] == 'mtllib': current_mtllib = load_mtl(splitted[1]) elif splitted[0] == 'usemtl': if len(indices) > 0 and obj_group is True: # Flush mesh_list.append( (current_material_name, create_mesh(indices, uv_indices, normal_indices, vertices, uvs, normals))) indices = [] uv_indices = [] normal_indices = [] vertices = [] normals = [] uvs = [] vertices_map = {} uvs_map = {} normals_map = {} mtl_name = splitted[1] current_material_name = mtl_name if mtl_name not in material_map: m = current_mtllib[mtl_name] if m.map_Kd is None: diffuse_reflectance = tf.constant(m.Kd, dtype=tf.float32) else: diffuse_reflectance = pyredner.imread(m.map_Kd) if m.map_Ks is None: specular_reflectance = tf.constant(m.Ks, dtype=tf.float32) else: specular_reflectance = pyredner.imread(m.map_Ks) if m.map_Ns is None: roughness = tf.constant([2.0 / (m.Ns + 2.0)], dtype=tf.float32) else: roughness = 2.0 / (pyredner.imread(m.map_Ks) + 2.0) if m.Ke != (0.0, 0.0, 0.0): light_map[mtl_name] = tf.constant(m.Ke, dtype=tf.float32) material_map[mtl_name] = pyredner.Material( diffuse_reflectance, specular_reflectance, roughness) elif splitted[0] == 'v': vertices_pool.append( [float(splitted[1]), float(splitted[2]), float(splitted[3])]) elif splitted[0] == 'vt': u = float(splitted[1]) v = float(splitted[2]) if flip_tex_coords: v = 1 - v uvs_pool.append([u, v]) elif splitted[0] == 'vn': normals_pool.append( [float(splitted[1]), float(splitted[2]), float(splitted[3])]) elif splitted[0] == 'f': def num_indices(x): return len(re.split('/', x)) def get_index(x, i): return int(re.split('/', x)[i]) def parse_face_index(x, i): f = get_index(x, i) if f < 0: if (i == 0): f += len(vertices) if (i == 1): f += len(uvs) else: f -= 1 return f assert (len(splitted) <= 5) def get_vertex_id(indices): pi = parse_face_index(indices, 0) uvi = None if (num_indices(indices) > 1 and re.split('/', indices)[1] != ''): uvi = parse_face_index(indices, 1) ni = None if (num_indices(indices) > 2 and re.split('/', indices)[2] != ''): ni = parse_face_index(indices, 2) if use_common_indices: # vertex, uv, normals share the same indexing key = (pi, uvi, ni) if key in vertices_map: vertex_id = vertices_map[key] return vertex_id, vertex_id, vertex_id vertex_id = len(vertices) vertices_map[key] = vertex_id vertices.append(vertices_pool[pi]) if uvi is not None: uvs.append(uvs_pool[uvi]) if ni is not None: normals.append(normals_pool[ni]) return vertex_id, vertex_id, vertex_id else: # vertex, uv, normals use separate indexing vertex_id = None uv_id = None normal_id = None if pi in vertices_map: vertex_id = vertices_map[pi] else: vertex_id = len(vertices) vertices.append(vertices_pool[pi]) vertices_map[pi] = vertex_id if uvi is not None: if uvi in uvs_map: uv_id = uvs_map[uvi] else: uv_id = len(uvs) uvs.append(uvs_pool[uvi]) uvs_map[uvi] = uv_id if ni is not None: if ni in normals_map: normal_id = normals_map[ni] else: normal_id = len(normals) normals.append(normals_pool[ni]) normals_map[ni] = normal_id return vertex_id, uv_id, normal_id vid0, uv_id0, n_id0 = get_vertex_id(splitted[1]) vid1, uv_id1, n_id1 = get_vertex_id(splitted[2]) vid2, uv_id2, n_id2 = get_vertex_id(splitted[3]) indices.append([vid0, vid1, vid2]) if uv_id0 is not None: assert (uv_id1 is not None and uv_id2 is not None) uv_indices.append([uv_id0, uv_id1, uv_id2]) if n_id0 is not None: assert (n_id1 is not None and n_id2 is not None) normal_indices.append([n_id0, n_id1, n_id2]) if (len(splitted) == 5): vid3, uv_id3, n_id3 = get_vertex_id(splitted[4]) indices.append([vid0, vid2, vid3]) if uv_id0 is not None: assert (uv_id3 is not None) uv_indices.append([uv_id0, uv_id2, uv_id3]) if n_id0 is not None: assert (n_id3 is not None) normal_indices.append([n_id0, n_id2, n_id3]) mesh_list.append((current_material_name, create_mesh(indices, uv_indices, normal_indices, vertices, uvs, normals))) if d != '': os.chdir(cwd) f.close() return material_map, mesh_list, light_map
def parse_material(node, two_sided=False): node_id = None if 'id' in node.attrib: node_id = node.attrib['id'] if node.attrib['type'] == 'diffuse': diffuse_reflectance = tf.constant([0.5, 0.5, 0.5]) diffuse_uv_scale = [1.0, 1.0] specular_reflectance = tf.constant([0.0, 0.0, 0.0]) specular_uv_scale = [1.0, 1.0] roughness = tf.constant([1.0]) for child in node: if child.attrib['name'] == 'reflectance': if child.tag == 'texture': for grandchild in child: if grandchild.attrib['name'] == 'filename': diffuse_reflectance = pyredner.imread( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'uscale': diffuse_uv_scale[0] = float( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'vscale': diffuse_uv_scale[1] = float( grandchild.attrib['value']) elif child.tag == 'rgb' or child.tag == 'spectrum': diffuse_reflectance = parse_vector(child.attrib['value']) elif child.attrib['name'] == 'specular': if child.tag == 'texture': for grandchild in child: if grandchild.attrib['name'] == 'filename': specular_reflectance = pyredner.imread( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'uscale': specular_uv_scale[0] = float( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'vscale': specular_uv_scale[1] = float( grandchild.attrib['value']) elif child.tag == 'rgb' or child.tag == 'spectrum': specular_reflectance = parse_vector(child.attrib['value']) elif child.attrib['name'] == 'roughness': roughness = tf.constant([float(child.attrib['value'])]) diffuse_uv_scale = tf.constant(diffuse_uv_scale) specular_uv_scale = tf.constant(specular_uv_scale) return (node_id, pyredner.Material(diffuse_reflectance=pyredner.Texture( diffuse_reflectance, diffuse_uv_scale), specular_reflectance=pyredner.Texture( specular_reflectance, specular_uv_scale), roughness=pyredner.Texture(roughness), two_sided=two_sided)) elif node.attrib['type'] == 'roughplastic': diffuse_reflectance = tf.constant([0.5, 0.5, 0.5]) diffuse_uv_scale = [1.0, 1.0] specular_reflectance = tf.constant([0.0, 0.0, 0.0]) specular_uv_scale = [1.0, 1.0] roughness = tf.constant([1.0]) for child in node: if child.attrib['name'] == 'diffuseReflectance': if child.tag == 'texture': for grandchild in child: if grandchild.attrib['name'] == 'filename': diffuse_reflectance = pyredner.imread( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'uscale': diffuse_uv_scale[0] = float( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'vscale': diffuse_uv_scale[1] = float( grandchild.attrib['value']) elif child.tag == 'rgb' or child.tag == 'spectrum': diffuse_reflectance = parse_vector(child.attrib['value']) elif child.attrib['name'] == 'specularReflectance': if child.tag == 'texture': for grandchild in child: if grandchild.attrib['name'] == 'filename': specular_reflectance = pyredner.imread( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'uscale': specular_uv_scale[0] = float( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'vscale': specular_uv_scale[1] = float( grandchild.attrib['value']) elif child.tag == 'rgb' or child.tag == 'spectrum': specular_reflectance = parse_vector(child.attrib['value']) elif child.attrib['name'] == 'alpha': alpha = float(child.attrib['value']) roughness = tf.constant([alpha * alpha]) diffuse_uv_scale = tf.constant(diffuse_uv_scale) specular_uv_scale = tf.constant(specular_uv_scale) return (node_id, pyredner.Material(diffuse_reflectance=pyredner.Texture( diffuse_reflectance, diffuse_uv_scale), specular_reflectance=pyredner.Texture( specular_reflectance, specular_uv_scale), roughness=pyredner.Texture(roughness), two_sided=two_sided)) elif node.attrib['type'] == 'twosided': ret = parse_material(node[0], True) return (node_id, ret[1]) else: print('Unsupported material type:', node.attrib['type']) assert (False)
def parse_material(node, two_sided=False): node_id = None if 'id' in node.attrib: node_id = node.attrib['id'] if node.attrib['type'] == 'diffuse': diffuse_reflectance = tf.constant([0.5, 0.5, 0.5]) diffuse_uv_scale = [1.0, 1.0] specular_reflectance = tf.constant([0.0, 0.0, 0.0]) specular_uv_scale = [1.0, 1.0] roughness = tf.constant([1.0]) for child in node: if child.attrib['name'] == 'reflectance': if child.tag == 'texture': for grandchild in child: if grandchild.attrib['name'] == 'filename': diffuse_reflectance = pyredner.imread( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'uscale': diffuse_uv_scale[0] = float( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'vscale': diffuse_uv_scale[1] = float( grandchild.attrib['value']) elif child.tag == 'rgb' or child.tag == 'spectrum' or child.tag == 'srgb': diffuse_reflectance = parse_vector(child.attrib['value']) if child.tag == 'srgb': diffuse_reflectance = pyredner.srgb_to_linear( diffuse_reflectance) elif child.attrib['name'] == 'specular': if child.tag == 'texture': for grandchild in child: if grandchild.attrib['name'] == 'filename': specular_reflectance = pyredner.imread( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'uscale': specular_uv_scale[0] = float( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'vscale': specular_uv_scale[1] = float( grandchild.attrib['value']) elif child.tag == 'rgb' or child.tag == 'spectrum' or child.tag == 'srgb': specular_reflectance = parse_vector(child.attrib['value']) if child.tag == 'srgb': specular_reflectance = pyredner.srgb_to_linear( specular_reflectance) elif child.attrib['name'] == 'roughness': roughness = tf.constant([float(child.attrib['value'])]) diffuse_uv_scale = tf.constant(diffuse_uv_scale) specular_uv_scale = tf.constant(specular_uv_scale) return (node_id, pyredner.Material(diffuse_reflectance=pyredner.Texture( diffuse_reflectance, diffuse_uv_scale), specular_reflectance=pyredner.Texture( specular_reflectance, specular_uv_scale), roughness=pyredner.Texture(roughness), two_sided=two_sided)) elif node.attrib['type'] == 'roughplastic': diffuse_reflectance = tf.constant([0.5, 0.5, 0.5]) diffuse_uv_scale = [1.0, 1.0] # Mitsuba defaults specular reflectance to 1.0, but we use Schilick approximation and # use the specular reflectance for representing both index of refraction and color tint # for metal materials simultaneously. # Schilick's appsoximation set R0 to ((n1 - n2) / (n1 + n2))^2. Mitsuba defaults # IOR to n1=1 and n2=1.5, so R0 ~= 0.04 specular_reflectance = tf.constant([0.04, 0.04, 0.04]) specular_uv_scale = [1.0, 1.0] roughness = tf.constant([0.01]) for child in node: if child.attrib['name'] == 'diffuseReflectance' or child.attrib[ 'name'] == 'diffuse_reflectance': if child.tag == 'texture': for grandchild in child: if grandchild.attrib['name'] == 'filename': diffuse_reflectance = pyredner.imread( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'uscale': diffuse_uv_scale[0] = float( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'vscale': diffuse_uv_scale[1] = float( grandchild.attrib['value']) elif child.tag == 'rgb' or child.tag == 'spectrum' or child.tag == 'srgb': diffuse_reflectance = parse_vector(child.attrib['value']) if child.tag == 'srgb': diffuse_reflectance = pyredner.srgb_to_linear( diffuse_reflectance) elif child.attrib['name'] == 'specularReflectance' or child.attrib[ 'name'] == 'specular_reflectance': if child.tag == 'texture': for grandchild in child: if grandchild.attrib['name'] == 'filename': specular_reflectance = pyredner.imread( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'uscale': specular_uv_scale[0] = float( grandchild.attrib['value']) elif grandchild.attrib['name'] == 'vscale': specular_uv_scale[1] = float( grandchild.attrib['value']) elif child.tag == 'rgb' or child.tag == 'spectrum' or child.tag == 'srgb': specular_reflectance = parse_vector(child.attrib['value']) if child.tag == 'srgb': specular_reflectance = pyredner.srgb_to_linear( specular_reflectance) elif child.attrib['name'] == 'alpha': if child.tag == 'texture': roughness, roughness_uv_scale = parse_texture(child) roughness = roughness * roughness else: alpha = float(child.attrib['value']) roughness = tf.constant([alpha * alpha]) diffuse_uv_scale = tf.constant(diffuse_uv_scale) specular_uv_scale = tf.constant(specular_uv_scale) return (node_id, pyredner.Material(diffuse_reflectance=pyredner.Texture( diffuse_reflectance, diffuse_uv_scale), specular_reflectance=pyredner.Texture( specular_reflectance, specular_uv_scale), roughness=pyredner.Texture(roughness), two_sided=two_sided)) elif node.attrib['type'] == 'twosided': ret = parse_material(node[0], True) return (node_id, ret[1]) else: print('Unsupported material type:', node.attrib['type']) assert (False)
# The first argument is the shape id of the light light = pyredner.AreaLight(2, light_intensity) area_lights = [light] scene = pyredner.Scene(cam, shapes, materials, area_lights) scene_args = pyredner.serialize_scene(scene=scene, num_samples=256, max_bounces=1) # Alias of the render function # Render our target img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_shadow_light/target.exr') pyredner.imwrite(img, 'results/test_shadow_light/target.png') target = pyredner.imread('results/test_shadow_light/target.exr') # Perturb the scene, this is our initial guess with tf.device(pyredner.get_device_name()): light_translation = tf.Variable([-0.4, -0.4, -0.4], dtype=tf.float32, trainable=True) shape_light.vertices = light_vertices + light_translation scene_args = pyredner.serialize_scene(scene=scene, num_samples=256, max_bounces=1) # Render the initial guess img = pyredner.render(1, *scene_args) pyredner.imwrite(img, 'results/test_shadow_light/init.png') diff = tf.abs(target - img)
fov = tf.Variable([45.0], dtype=tf.float32) clip_near = 1e-2 # randomly generate distortion parameters tf.random.set_seed(1234) target_distort_params = (tf.random.uniform([8]) - 0.5) * 0.05 resolution = (256, 256) cam = pyredner.Camera(position=position, look_at=look_at, up=up, fov=fov, clip_near=clip_near, resolution=resolution, distortion_params=target_distort_params) checkerboard_texture = pyredner.imread('scenes/teapot.png') mat_checkerboard = pyredner.Material(\ diffuse_reflectance = checkerboard_texture) mat_black = pyredner.Material(\ diffuse_reflectance = tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32)) plane = pyredner.Object(vertices=tf.Variable([[-1.0, -1.0, 0.0], [-1.0, 1.0, 0.0], [1.0, -1.0, 0.0], [1.0, 1.0, 0.0]]), indices=tf.constant([[0, 1, 2], [1, 3, 2]], dtype=tf.int32), uvs=tf.Variable([[0.05, 0.05], [0.05, 0.95], [0.95, 0.05], [0.95, 0.95]]), material=mat_checkerboard) scene = pyredner.Scene(camera=cam, objects=[plane])
materials = [mat_vertex_color] with tf.device(pyredner.get_device_name()): # For the target we randomize the vertex color. vertices, indices, uvs, normals = pyredner.generate_sphere(128, 64) vertex_color = tf.random.uniform(vertices.shape, 0.0, 1.0) shape_sphere = pyredner.Shape(vertices=vertices, indices=indices, uvs=uvs, normals=normals, colors=vertex_color, material_id=0) shapes = [shape_sphere] with tf.device(pyredner.get_device_name()): envmap = pyredner.imread('sunsky.exr') envmap = pyredner.EnvironmentMap(envmap) scene = pyredner.Scene(camera=cam, shapes=shapes, materials=materials, area_lights=[], envmap=envmap) scene_args = pyredner.serialize_scene( scene=scene, num_samples=256, max_bounces=1, channels=[redner.channels.radiance, redner.channels.vertex_color]) img = pyredner.render(0, *scene_args) img_radiance = img[:, :, :3] img_vertex_color = img[:, :, 3:]
# The first argument is the shape id of the light light = pyredner.AreaLight(2, light_intensity) area_lights = [light] scene = pyredner.Scene(cam, shapes, materials, area_lights) scene_args = pyredner.serialize_scene( scene = scene, num_samples = 256, max_bounces = 1) # Alias of the render function # Render our target img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_shadow_camera/target.exr') pyredner.imwrite(img, 'results/test_shadow_camera/target.png') target = pyredner.imread('results/test_shadow_camera/target.exr') # Perturb the scene, this is our initial guess with tf.device(pyredner.get_device_name()): position = tf.Variable([-2.0, 7.0, 2.0], trainable=True) scene.camera = pyredner.Camera(position = position, look_at = look_at, up = up, fov = fov, clip_near = clip_near, resolution = resolution) scene_args = pyredner.serialize_scene( scene = scene, num_samples = 256, max_bounces = 1) # Render the initial guess
############################################### # Scene scene = pyredner.Scene(cam, shapes, materials, area_lights) scene_args = pyredner.serialize_scene(scene=scene, num_samples=1024, max_bounces=1) # Alias of the render function # Render our target img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_shadow_glossy/target.exr') pyredner.imwrite(img, 'results/test_shadow_glossy/target.png') target = pyredner.imread('results/test_shadow_glossy/target.exr') # Perturb the scene, this is our initial guess with tf.device(pyredner.get_device_name()): shape_blocker.vertices = tf.Variable( [[-0.6, 0.9, 0.4], [-0.8, 3.3, 0.7], [0.2, 1.1, 0.6], [0.3, 3.2, 0.4]], dtype=tf.float32, trainable=True) scene_args = pyredner.serialize_scene(scene=scene, num_samples=1024, max_bounces=1) # Render the initial guess img = pyredner.render(1, *scene_args) pyredner.imwrite(img, 'results/test_shadow_glossy/init.png') diff = tf.abs(target - img) pyredner.imwrite(diff, 'results/test_shadow_glossy/init_diff.png')
scene_args = pyredner.serialize_scene(scene=scene, num_samples=16, max_bounces=1) # Render the scene as our target image. # To render the scene, we use our custom PyTorch function in pyredner/render_pytorch.py # First setup the alias of the render function # Render. The first argument is the seed for RNG in the renderer. # Redner automatically maps the devices in the render function, so no need to specify tf.device here. img = pyredner.render(0, *scene_args) # Save the images. pyredner.imwrite(img, 'results/test_single_triangle/target.exr') pyredner.imwrite(img, 'results/test_single_triangle/target.png') # Read the target image we just saved. target = pyredner.imread('results/test_single_triangle/target.exr') if pyredner.get_use_gpu(): target = target.gpu() # Perturb the scene, this is our initial guess. with tf.device(pyredner.get_device_name()): shape_triangle.vertices = tf.Variable( [[-2.0, 1.5, 0.3], [0.9, 1.2, -0.3], [-0.4, -1.4, 0.2]], dtype=tf.float32, trainable=True) # Set trainable to True since we want to optimize this # We need to serialize the scene again to get the new arguments. scene_args = pyredner.serialize_scene(scene=scene, num_samples=16, max_bounces=1) # Render the initial guess. img = pyredner.render(1, *scene_args)
with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())): light_intensity = tf.Variable([30.0, 30.0, 30.0], dtype=tf.float32) light = pyredner.AreaLight(1, light_intensity) area_lights = [light] scene = pyredner.Scene(cam, shapes, materials, area_lights) scene_args = pyredner.serialize_scene(scene=scene, num_samples=16, max_bounces=1) # Render our target img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_single_triangle_camera_fisheye/target.exr') pyredner.imwrite(img, 'results/test_single_triangle_camera_fisheye/target.png') target = pyredner.imread( 'results/test_single_triangle_camera_fisheye/target.exr') # Perturb the scene, this is our initial guess with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())): position = tf.Variable([0.5, -0.5, -3.0], trainable=True) scene.camera = pyredner.Camera(position=position, look_at=look_at, up=up, fov=fov, clip_near=clip_near, resolution=resolution, fisheye=True) scene_args = pyredner.serialize_scene(scene=scene, num_samples=16, max_bounces=1) # Render the initial guess
pyredner.Texture(tf.Variable([0.3, 0.2, 0.2], dtype=tf.float32, use_resource=True)) scene.materials[-1].specular_reflectance = \ pyredner.Texture(tf.Variable([0.6, 0.6, 0.6], dtype=tf.float32, use_resource=True)) scene.materials[-1].roughness = \ pyredner.Texture(tf.Variable([0.05], dtype=tf.float32, use_resource=True)) scene_args = pyredner.serialize_scene( scene = scene, num_samples = 1024, max_bounces = 2) # Render our target. The first argument is the seed for RNG in the renderer. img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_teapot_reflectance/target.exr') pyredner.imwrite(img, 'results/test_teapot_reflectance/target.png') target = pyredner.imread('results/test_teapot_reflectance/target.exr') # Perturb the scene, this is our initial guess cam = scene.camera cam_position = cam.position with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())): cam_translation = tf.Variable([-0.2, 0.2, -0.2], dtype=tf.float32, trainable=True, use_resource=True) with tf.device(pyredner.get_device_name()): diffuse_reflectance = tf.Variable([0.3, 0.3, 0.3], dtype=tf.float32, trainable=True, use_resource=True) specular_reflectance = tf.Variable([0.5, 0.5, 0.5], dtype=tf.float32, trainable=True, use_resource=True) roughness = tf.Variable([0.2], dtype=tf.float32, trainable=True, use_resource=True) scene.materials[-1].diffuse_reflectance = pyredner.Texture(diffuse_reflectance) scene.materials[-1].specular_reflectance = pyredner.Texture(specular_reflectance) scene.materials[-1].roughness = pyredner.Texture(roughness) scene.camera = pyredner.Camera(position = cam_position + cam_translation, look_at = cam.look_at + cam_translation,
specular_reflectance=tf.Variable([0.5, 0.5, 0.5], dtype=tf.float32), roughness=tf.Variable([0.05], dtype=tf.float32)) materials = [mat_grey] with tf.device(pyredner.get_device_name()): vertices, indices, uvs, normals = pyredner.generate_sphere(128, 64) shape_sphere = pyredner.Shape(vertices=vertices, indices=indices, uvs=uvs, normals=normals, material_id=0) shapes = [shape_sphere] with tf.device(pyredner.get_device_name()): envmap = pyredner.imread('sunsky.exr') envmap = pyredner.EnvironmentMap(envmap) scene = pyredner.Scene(camera=cam, shapes=shapes, materials=materials, area_lights=[], envmap=envmap) scene_args = pyredner.serialize_scene(scene=scene, num_samples=256, max_bounces=1) img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_envmap/target.exr') pyredner.imwrite(img, 'results/test_envmap/target.png') target = pyredner.imread('results/test_envmap/target.exr')
# Render. The first argument is the seed for RNG in the renderer. img = pyredner.render(0, *scene_args) # Save the images. depth = img[:, :, 0] normal = img[:, :, 1:4] pyredner.imwrite(depth, 'results/test_g_buffer/target_depth.exr') pyredner.imwrite(depth, 'results/test_g_buffer/target_depth.png', normalize=True) pyredner.imwrite(normal, 'results/test_g_buffer/target_normal.exr') pyredner.imwrite(normal, 'results/test_g_buffer/target_normal.png', normalize=True) # Read the target image we just saved. target_depth = pyredner.imread('results/test_g_buffer/target_depth.exr') target_depth = target_depth[:, :, 0] target_normal = pyredner.imread('results/test_g_buffer/target_normal.exr') with tf.device(pyredner.get_device_name()): # Perturb the teapot by a translation and a rotation to the object translation_params = tf.Variable([0.1, -0.1, 0.1], trainable=True) translation = translation_params * 100.0 euler_angles = tf.Variable([0.1, -0.1, 0.1], trainable=True) # These are the vertices we want to apply the transformation shape0_vertices = tf.identity(shapes[0].vertices) shape1_vertices = tf.identity(shapes[1].vertices) # We can use pyredner.gen_rotate_matrix to generate 3x3 rotation matrices rotation_matrix = pyredner.gen_rotate_matrix(euler_angles) center = tf.math.reduce_mean(tf.concat([shape0_vertices, shape1_vertices],
scene.materials[-1].diffuse_reflectance = \ pyredner.Texture(tf.Variable([0.15, 0.2, 0.15], dtype=tf.float32)) scene.materials[-1].specular_reflectance = \ pyredner.Texture(tf.Variable([0.8, 0.8, 0.8], dtype=tf.float32)) scene.materials[-1].roughness = \ pyredner.Texture(tf.Variable([0.0001], dtype=tf.float32)) scene_args = pyredner.serialize_scene(scene=scene, num_samples=512, max_bounces=2) # Render our target. The first argument is the seed for RNG in the renderer. img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_teapot_specular/target.exr') pyredner.imwrite(img, 'results/test_teapot_specular/target.png') target = pyredner.imread('results/test_teapot_specular/target.exr') # Perturb the scene, this is our initial guess # We perturb the last shape, which is the SIGGRAPH logo ref_pos = scene.shapes[-1].vertices with tf.device(pyredner.get_device_name()): translation = tf.Variable([20.0, 0.0, 2.0], trainable=True) scene.shapes[-1].vertices = ref_pos + translation scene_args = pyredner.serialize_scene(scene=scene, num_samples=512, max_bounces=2) # Render the initial guess img = pyredner.render(1, *scene_args) pyredner.imwrite(img, 'results/test_teapot_specular/init.png') diff = tf.abs(target - img) pyredner.imwrite(diff, 'results/test_teapot_specular/init_diff.png')
material_id_map[key] = count count += 1 materials.append(value) # Setup geometries shapes = [] with tf.device(pyredner.get_device_name()): for mtl_name, mesh in mesh_list: shapes.append( pyredner.Shape(vertices=mesh.vertices, indices=mesh.indices, uvs=mesh.uvs, normals=mesh.normals, material_id=material_id_map[mtl_name])) with tf.device(pyredner.get_device_name()): envmap = pyredner.imread('sunsky.exr') envmap = pyredner.EnvironmentMap(envmap) # Construct the scene scene = pyredner.Scene(cam, shapes, materials, area_lights=[], envmap=envmap) # Serialize the scene # Here we specify the output channels as "depth", "shading_normal" scene_args = pyredner.serialize_scene(scene=scene, num_samples=512, max_bounces=1) img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_compute_uvs/target.exr') pyredner.imwrite(img, 'results/test_compute_uvs/target.png') target = pyredner.imread('results/test_compute_uvs/target.exr')
shapes = [shape_plane, shape_light] with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())): light_intensity = tf.Variable([20.0, 20.0, 20.0], dtype=tf.float32) # The first argument is the shape id of the light light = pyredner.AreaLight(1, light_intensity) area_lights = [light] scene = pyredner.Scene(cam, shapes, materials, area_lights) scene_args = pyredner.serialize_scene(scene=scene, num_samples=16, max_bounces=1) # Render our target img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_svbrdf/target.exr') pyredner.imwrite(img, 'results/test_svbrdf/target.png') target = pyredner.imread('results/test_svbrdf/target.exr') # Our initial guess is three gray textures with tf.device(pyredner.get_device_name()): diffuse_tex = tf.Variable(tf.ones((256, 256, 3), dtype=np.float32) * 0.5, trainable=True) specular_tex = tf.Variable(tf.ones((256, 256, 3), dtype=np.float32) * 0.5, trainable=True) roughness_tex = tf.Variable(tf.ones((256, 256, 1), dtype=np.float32) * 0.5, trainable=True) mat_perlin.diffuse_reflectance = pyredner.Texture(diffuse_tex) mat_perlin.specular_reflectance = pyredner.Texture(specular_tex) mat_perlin.roughness = pyredner.Texture(roughness_tex) scene_args = pyredner.serialize_scene(scene=scene, num_samples=16, max_bounces=1)
with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())): light_intensity = tf.Variable([20.0,20.0,20.0], dtype=tf.float32) # The first argument is the shape id of the light light = pyredner.AreaLight(2, light_intensity) area_lights = [light] scene = pyredner.Scene(cam, shapes, materials, area_lights) scene_args = pyredner.serialize_scene( scene = scene, num_samples = 256, max_bounces = 1) # Render our target img = pyredner.render(0, *scene_args) pyredner.imwrite(img, 'results/test_two_triangles/target.exr') pyredner.imwrite(img, 'results/test_two_triangles/target.png') target = pyredner.imread('results/test_two_triangles/target.exr') # Perturb the scene, this is our initial guess with tf.device(pyredner.get_device_name()): shape_tri0.vertices = tf.Variable( [[-1.3,1.5,0.1], [1.5,0.7,-0.2], [-0.8,-1.1,0.2]], dtype=tf.float32, trainable=True) shape_tri1.vertices = tf.Variable( [[-0.5,1.2,1.2], [0.3,1.7,1.0], [0.5,-1.8,1.3]], dtype=tf.float32, trainable=True) scene_args = pyredner.serialize_scene( scene = scene, num_samples = 256, max_bounces = 1)