def render(self, vertices, faces, textures): # fill back if self.fill_back: faces = torch.cat( [faces, faces[:, :, faces.new([2, 1, 0]).long()]], dim=1) textures = torch.cat( [textures, textures.permute(0, 1, 4, 3, 2, 5)], dim=1) # lighting faces_lighting = vertices_to_faces_th(vertices, faces) textures = lighting_th(faces_lighting, textures, self.light_intensity_ambient, self.light_intensity_directional, self.light_color_ambient, self.light_color_directional, self.light_direction) # viewpoint transformation if self.camera_mode == 'look_at': vertices = look_at_th(vertices, self.eye) elif self.camera_mode == 'look': raise NotImplementedError vertices = look(vertices, self.eye, self.camera_direction) # perspective transformation if self.perspective: vertices = perspective_th(vertices, angle=self.viewing_angle) # rasterization faces = vertices_to_faces_th(vertices, faces) images = self.rasterize_rgb(faces, textures) return images
def test_forward_rgb_th_3(): """Same silhouette as blender""" # load teapot vertices, faces, textures = utils.load_teapot_batch_th() # Fill back by reversing face points order faces = torch.cat([faces, faces[:, :, faces.new([2, 1, 0]).long()]], dim=1) textures = torch.cat([textures, textures.permute(0, 1, 4, 3, 2, 5)], dim=1) # Add lighting light_intensity_ambient = 1 light_intensity_directional = 0 light_color_ambient = [1, 1, 1] # white light_color_directional = [1, 1, 1] # white light_direction = [0, 1, 0] # up-to-down faces_lighting = vertices_to_faces_th(vertices, faces) textures = lighting_th(faces_lighting, textures, light_intensity_ambient, light_intensity_directional, light_color_ambient, light_color_directional, light_direction) faces_th = preprocess_th(vertices, faces, perspective=True) rasterize_rgb_th = RasterizeRGB(256, 0.1, 100, 1e-3, [0, 0, 0]) images = rasterize_rgb_th(faces_th, textures) image = images[2].cpu().numpy().mean(0) # Extract silhouette from blender image ref = scipy.misc.imread('./tests/data/teapot_blender.png') ref = ref.astype('float32') ref = (ref.min(-1) != 255).astype('float32') scipy.misc.imsave('./tests/data/test_rasterize_rgb_th3.png', image) assert np.mean(np.abs(ref - image)) < 1e-8
def test_backward_silhouette_th_2(): """Backward if non-zero gradient is on a face.""" vertices = np.array([[0.8, 0.8, 1.], [-0.5, -0.8, 1.], [0.8, -0.8, 1.]]) faces = np.array([[0, 1, 2]]) textures = np.ones((faces.shape[0], 4, 4, 4, 3), 'float32') pyi = 40 pxi = 50 grad_ref = np.array([ [0.98646867, 1.04628897, 0.], [-1.03415668, -0.10403691, 0.], [3.00094461, -1.55173182, 0.], ]) # Add lighting light_intensity_ambient = 1 light_intensity_directional = 0 light_color_ambient = [1, 1, 1] # white light_color_directional = [1, 1, 1] # white light_direction = [0, 1, 0] # up-to-down vertices, faces, textures, grad_ref = utils.to_minibatch_th( (vertices, faces, textures, grad_ref)) faces_lighting = vertices_to_faces_th(vertices, faces) textures = lighting_th(faces_lighting, textures, light_intensity_ambient, light_intensity_directional, light_color_ambient, light_color_directional, light_direction) faces.requires_grad = True vertices.requires_grad = True faces_th = preprocess_th(vertices, faces, perspective=False) rasterize_silhouettes_th = RasterizeRGB(64, 0.1, 100, 1e-3, [0, 0, 0]) images = rasterize_silhouettes_th(faces_th, textures) images = images.mean(dim=1) loss = torch.sum(torch.abs(images[:, pyi, pxi])) loss.backward(retain_graph=True) assert (vertices.grad - grad_ref).abs().mean() < 1e-3
def test_forward_rgb_th_2(): """Different viewpoint""" # load teapot vertices, faces, textures = utils.load_teapot_batch_th() # Fill back by reversing face points order faces = torch.cat([faces, faces[:, :, faces.new([2, 1, 0]).long()]], dim=1) textures = torch.cat([textures, textures.permute(0, 1, 4, 3, 2, 5)], dim=1) # Add lighting light_intensity_ambient = 0.5 light_intensity_directional = 0.5 light_color_ambient = [1, 1, 1] # white light_color_directional = [1, 1, 1] # white light_direction = [0, 1, 0] # up-to-down faces_lighting = vertices_to_faces_th(vertices, faces) textures = lighting_th(faces_lighting, textures, light_intensity_ambient, light_intensity_directional, light_color_ambient, light_color_directional, light_direction) faces_th = preprocess_th(vertices, faces, perspective=True, eye=[1, 1, -2.7]) rasterize_rgb_th = RasterizeRGB(256, 0.1, 100, 1e-3, [0, 0, 0]) images = rasterize_rgb_th(faces_th, textures) image = images[2].cpu().numpy().transpose(1, 2, 0) ref = scipy.misc.imread('./tests/data/test_rasterize2.png') / 255 scipy.misc.imsave('./tests/data/test_rasterize_rgb_th2.png', image) assert np.mean(np.abs(ref - image)) < 1e-2
def test_lighting(): """Test whether it is executable.""" faces = np.random.normal(size=(64, 16, 3, 3)).astype('float32') textures = np.random.normal(size=(64, 16, 8, 8, 8, 3)).astype('float32') lighted_textures = lighting(faces, textures) textures_th = torch.Tensor(textures) faces_th = torch.Tensor(faces) lighted_textures_th = lighting_th(faces_th, textures_th) mean_err = np.mean( np.abs(lighted_textures.data - lighted_textures_th.numpy())) assert mean_err < 1e-5