示例#1
0
文件: utils.py 项目: jk7ss/redner
def generate_quad_light(position: tf.Tensor, look_at: tf.Tensor,
                        size: tf.Tensor, intensity: tf.Tensor):
    """
        Generate a pyredner.Object that is a quad light source.

        Args
        ====
        position: tf.Tensor
            1-d tensor of size 3
        look_at: tf.Tensor
            1-d tensor of size 3
        size: tf.Tensor
            1-d tensor of size 2
        intensity: tf.Tensor
            1-d tensor of size 3

        Returns
        =======
        pyredner.Object
            quad light source
    """
    d = look_at - position
    d = d / tf.norm(d)
    # ONB -- generate two axes that are orthogonal to d
    a = 1 / (1 + d[2])
    b = -d[0] * d[1] * a
    x = tf.where(d[2] < (-1 + 1e-6), tf.constant([0.0, -1.0, 0.0]),
                 tf.stack([1 - d[0] * d[0] * a, b, -d[0]]))
    y = tf.where(d[2] < (-1 + 1e-6), tf.constant([-1.0, 0.0, 0.0]),
                 tf.stack([b, 1 - d[1] * d[1] * a, -d[1]]))
    v0 = position - x * size[0] * 0.5 - y * size[1] * 0.5
    v1 = position + x * size[0] * 0.5 - y * size[1] * 0.5
    v2 = position - x * size[0] * 0.5 + y * size[1] * 0.5
    v3 = position + x * size[0] * 0.5 + y * size[1] * 0.5

    with tf.device(pyredner.get_device_name()):
        vertices = tf.stack((v0, v1, v2, v3), axis=0)
        indices = tf.constant([[0, 1, 2], [1, 3, 2]], dtype=tf.int32)
        m = pyredner.Material(diffuse_reflectance=tf.constant([0.0, 0.0, 0.0]))
    return pyredner.Object(vertices=vertices,
                           indices=indices,
                           material=m,
                           light_intensity=intensity)
示例#2
0
with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())):
    position = tf.Variable([0.0, 0.0, -5.0], dtype=tf.float32)
    look_at = tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32)
    up = tf.Variable([0.0, 1.0, 0.0], dtype=tf.float32)
    fov = tf.Variable([45.0], dtype=tf.float32)
    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)

mat_perlin = pyredner.Material(diffuse_reflectance=diffuse,
                               specular_reflectance=specular,
                               roughness=roughness)
with tf.device(pyredner.get_device_name()):
    mat_black = pyredner.Material(
        diffuse_reflectance=tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32))
    materials = [mat_perlin, mat_black]
    vertices = tf.Variable([[-1.5, -1.5, 0.0], [-1.5, 1.5, 0.0],
                            [1.5, -1.5, 0.0], [1.5, 1.5, 0.0]],
                           dtype=tf.float32)
    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)
    shape_plane = pyredner.Shape(vertices, indices, 0, uvs)
    light_vertices = tf.Variable([[-1.0, -1.0, -7.0], [1.0, -1.0, -7.0],
                                  [-1.0, 1.0, -7.0], [1.0, 1.0, -7.0]],
                                 dtype=tf.float32)
示例#3
0
文件: load_obj.py 项目: n1ckfg/redner
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
                           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()):
    mat_grey = pyredner.Material(diffuse_reflectance=tf.Variable(
        [0.5, 0.5, 0.5], dtype=tf.float32, use_resource=True))
    mat_black = pyredner.Material(diffuse_reflectance=tf.Variable(
        [0.0, 0.0, 0.0], dtype=tf.float32, use_resource=True))
    materials = [mat_grey, mat_black]

    # tf.constant allocates arrays on host memory for int32 arrays (some tensorflow internal mess),
    # but pyredner.Shape constructor automatically converts the memory to device if necessary.
    floor_vertices = tf.Variable([[-2.0, 0.0, -2.0], [-2.0, 0.0, 2.0],
                                  [2.0, 0.0, -2.0], [2.0, 0.0, 2.0]],
                                 dtype=tf.float32,
                                 use_resource=True)
    floor_indices = tf.constant([[0, 1, 2], [1, 3, 2]], dtype=tf.int32)
    shape_floor = pyredner.Shape(floor_vertices, floor_indices, None, None, 0)
    blocker_vertices = tf.Variable([[-0.5, 3.0, -0.5], [-0.5, 3.0, 0.5],
                                    [0.5, 3.0, -0.5], [0.5, 3.0, 0.5]],
                                   dtype=tf.float32,
示例#5
0
pyredner.set_use_gpu(
    tf.test.is_gpu_available(cuda_only=True, min_cuda_compute_capability=None))

with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())):
    cam = pyredner.Camera(
        position=tf.Variable([0.0, 0.0, -5.0], dtype=tf.float32),
        look_at=tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32),
        up=tf.Variable([0.0, 1.0, 0.0], dtype=tf.float32),
        fov=tf.Variable([45.0], dtype=tf.float32),  # in degree
        clip_near=1e-2,  # needs to > 0
        resolution=(256, 256),
        fisheye=False)

with tf.device(pyredner.get_device_name()):
    mat_grey = pyredner.Material(
        diffuse_reflectance=tf.Variable([0.4, 0.4, 0.4], dtype=tf.float32),
        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')
示例#6
0
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)
    position = tf.Variable([0.0, 0.0, -1.0], dtype=tf.float32)
    look_at = tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32)
    up = tf.Variable([0.0, 1.0, 0.0], dtype=tf.float32)
    fov = tf.Variable([45.0], dtype=tf.float32)
    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,
                          fisheye=True)

with tf.device(pyredner.get_device_name()):
    mat_grey = pyredner.Material(diffuse_reflectance = \
        tf.Variable([0.5, 0.5, 0.5], dtype=tf.float32))
    materials = [mat_grey]
    vertices = tf.Variable(
        [[-1.7, 1.0, 0.0], [1.0, 1.0, 0.0], [-0.5, -1.0, 0.0]],
        dtype=tf.float32)
    indices = tf.constant([[0, 1, 2]], dtype=tf.int32)
    shape_triangle = pyredner.Shape(vertices, indices, 0)
    light_vertices = tf.Variable([[-1.0, -1.0, -9.0], [1.0, -1.0, -9.0],
                                  [-1.0, 1.0, -9.0], [1.0, 1.0, -9.0]],
                                 dtype=tf.float32)
    light_indices = tf.constant([[0, 1, 2], [1, 3, 2]], dtype=tf.int32)
    shape_light = pyredner.Shape(light_vertices, light_indices, 0)
shapes = [shape_triangle, shape_light]

with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())):
    light_intensity = tf.Variable([30.0, 30.0, 30.0], dtype=tf.float32)
示例#8
0
    position = tf.Variable([0.0, 2.0, -4.0], dtype=tf.float32)
    look_at = tf.Variable([0.0, -2.0, 0.0], dtype=tf.float32)
    up = tf.Variable([0.0, 1.0, 0.0], dtype=tf.float32)
    fov = tf.Variable([45.0], dtype=tf.float32)
    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()):
    mat_shiny = pyredner.Material(
        diffuse_reflectance=tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32),
        specular_reflectance=tf.Variable([1.0, 1.0, 1.0], dtype=tf.float32),
        roughness=tf.Variable([0.0005], dtype=tf.float32))
    mat_grey = pyredner.Material(
        diffuse_reflectance=tf.Variable([0.5, 0.5, 0.5], dtype=tf.float32))
    mat_black = pyredner.Material(
        diffuse_reflectance=tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32))
    materials = [mat_shiny, mat_grey, mat_black]

    #############################################
    # Shapes

    # tf.constant allocates arrays on host memory for int32 arrays (some tensorflow internal mess),
    # but pyredner.Shape constructor automatically converts the memory to device if necessary.

    # floor
    floor_vertices = tf.Variable([[-4.0, 0.0, -4.0], [-4.0, 0.0, 4.0],
示例#9
0
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
示例#10
0
# Tensorflow by default allocates all GPU memory, leaving very little for rendering.
# We set the environment variable TF_FORCE_GPU_ALLOW_GROWTH to true to enforce on demand
# memory allocation to reduce page faults.
import os
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
import tensorflow as tf
tf.compat.v1.enable_eager_execution()
import pyredner_tensorflow as pyredner

vertices, indices, uvs, normals = pyredner.generate_sphere(16, 32)
m = pyredner.Material(diffuse_reflectance=tf.constant((0.5, 0.5, 0.5)))
obj = pyredner.Object(vertices=vertices,
                      indices=indices,
                      uvs=uvs,
                      normals=normals,
                      material=m)
filename = 'results/test_save_obj/sphere.obj'
directory = os.path.dirname(filename)
if directory != '' and not os.path.exists(directory):
    os.makedirs(directory)
pyredner.save_obj(obj, 'results/test_save_obj/sphere.obj')
示例#11
0
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
示例#12
0
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)
示例#13
0
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])
img = pyredner.render_albedo(scene=scene)
pyredner.imwrite(img, 'results/test_camera_distortion/target.exr')
示例#14
0
# Use GPU if available
pyredner.set_use_gpu(
    tf.test.is_gpu_available(cuda_only=True, min_cuda_compute_capability=None))

with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())):
    cam = pyredner.Camera(
        position=tf.Variable([0.0, 0.0, -5.0], dtype=tf.float32),
        look_at=tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32),
        up=tf.Variable([0.0, 1.0, 0.0], dtype=tf.float32),
        fov=tf.Variable([45.0], dtype=tf.float32),  # in degree
        clip_near=1e-2,  # needs to > 0
        resolution=(256, 256),
        fisheye=False)

with tf.device(pyredner.get_device_name()):
    mat_vertex_color = pyredner.Material(use_vertex_color=True)
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()):
示例#15
0
with tf.device('/device:cpu:' + str(pyredner.get_cpu_device_id())):
    position = tf.Variable([0.0, 0.0, -5.0], dtype=tf.float32)
    look_at = tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32)
    up = tf.Variable([0.0, 1.0, 0.0], dtype=tf.float32)
    fov = tf.Variable([45.0], dtype=tf.float32)
    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()):
    mat_green = pyredner.Material(
        diffuse_reflectance = tf.Variable([0.35, 0.75, 0.35], dtype=tf.float32))
    mat_red = pyredner.Material(
        diffuse_reflectance = tf.Variable([0.75, 0.35, 0.35], dtype=tf.float32))
    mat_black = pyredner.Material(
        diffuse_reflectance = tf.Variable([0.0, 0.0, 0.0], dtype=tf.float32))
    materials = [mat_green,mat_red,mat_black]
    tri0_vertices = tf.Variable(
        [[-1.7,1.0,0.0], [1.0,1.0,0.0], [-0.5,-1.0,0.0]], dtype=tf.float32)
    tri1_vertices = tf.Variable(
        [[-1.0,1.5,1.0], [0.2,1.5,1.0], [0.2,-1.5,1.0]], dtype=tf.float32)
    tri0_indices = tf.constant([[0, 1, 2]], dtype=tf.int32)
    tri1_indices = tf.constant([[0, 1, 2]], dtype=tf.int32)
    shape_tri0 = pyredner.Shape(tri0_vertices, tri0_indices, 0)
    shape_tri1 = pyredner.Shape(tri1_vertices, tri1_indices, 1)
    light_vertices = tf.Variable([[-1.0,-1.0,-7.0],[1.0,-1.0,-7.0],[-1.0,1.0,-7.0],[1.0,1.0,-7.0]],
        dtype=tf.float32)