-- Texture Rendering vertices: [batch_size, V, 3], vertices in world space, for calculating normals, then shading transformed_vertices: [batch_size, V, 3], rnage:[-1,1], projected vertices, in image space, for rasterization albedos: [batch_size, 3, h, w], uv map
(self, vertices, transformed_vertices, albedos, lights=None, light_type='point', background=None, h=None, w=None)
| 217 | self.register_buffer('constant_factor', constant_factor) |
| 218 | |
| 219 | def forward(self, vertices, transformed_vertices, albedos, lights=None, light_type='point', background=None, h=None, w=None): |
| 220 | ''' |
| 221 | -- Texture Rendering |
| 222 | vertices: [batch_size, V, 3], vertices in world space, for calculating normals, then shading |
| 223 | transformed_vertices: [batch_size, V, 3], rnage:[-1,1], projected vertices, in image space, for rasterization |
| 224 | albedos: [batch_size, 3, h, w], uv map |
| 225 | lights: |
| 226 | spherical homarnic: [N, 9(shcoeff), 3(rgb)] |
| 227 | points/directional lighting: [N, n_lights, 6(xyzrgb)] |
| 228 | light_type: |
| 229 | point or directional |
| 230 | ''' |
| 231 | batch_size = vertices.shape[0] |
| 232 | # normalize z to 10-90 for raterization (in pytorch3d, near far: 0-100) |
| 233 | transformed_vertices = transformed_vertices.clone() |
| 234 | transformed_vertices[:, :, 2] = transformed_vertices[:, |
| 235 | :, 2] - transformed_vertices[:, :, 2].min() |
| 236 | transformed_vertices[:, :, 2] = transformed_vertices[:, |
| 237 | :, 2]/transformed_vertices[:, :, 2].max() |
| 238 | transformed_vertices[:, :, 2] = transformed_vertices[:, :, 2]*80 + 10 |
| 239 | |
| 240 | # attributes |
| 241 | face_vertices = util.face_vertices( |
| 242 | vertices, self.faces.expand(batch_size, -1, -1)) |
| 243 | normals = util.vertex_normals( |
| 244 | vertices, self.faces.expand(batch_size, -1, -1)) |
| 245 | face_normals = util.face_vertices( |
| 246 | normals, self.faces.expand(batch_size, -1, -1)) |
| 247 | transformed_normals = util.vertex_normals( |
| 248 | transformed_vertices, self.faces.expand(batch_size, -1, -1)) |
| 249 | transformed_face_normals = util.face_vertices( |
| 250 | transformed_normals, self.faces.expand(batch_size, -1, -1)) |
| 251 | attributes = torch.cat([self.face_uvcoords.expand(batch_size, -1, -1, -1), |
| 252 | transformed_face_normals.detach(), |
| 253 | face_vertices.detach(), |
| 254 | face_normals], |
| 255 | -1) |
| 256 | |
| 257 | # rasterize |
| 258 | rendering = self.rasterizer(transformed_vertices, self.faces.expand( |
| 259 | batch_size, -1, -1), attributes, h, w) |
| 260 | |
| 261 | #### |
| 262 | # vis mask |
| 263 | alpha_images = rendering[:, -1, :, :][:, None, :, :].detach() |
| 264 | |
| 265 | # albedo |
| 266 | uvcoords_images = rendering[:, :3, :, :] |
| 267 | grid = (uvcoords_images).permute(0, 2, 3, 1)[:, :, :, :2] |
| 268 | albedo_images = F.grid_sample(albedos, grid, align_corners=False) |
| 269 | |
| 270 | # visible mask for pixels with positive normal direction |
| 271 | transformed_normal_map = rendering[:, 3:6, :, :].detach() |
| 272 | pos_mask = (transformed_normal_map[:, 2:, :, :] < -0.05).float() |
| 273 | |
| 274 | # shading |
| 275 | normal_images = rendering[:, 9:12, :, :] |
| 276 | if lights is not None: |
nothing calls this directly
no test coverage detected