v9.1.1
Menu

Differentiable Renderer Forward

hardFREENeural RenderingCVCV: Image-Based Rendering

Implement the forward pass of a simple differentiable renderer that turns a 3D mesh into a 2D soft silhouette. This process involves projective transformations and a soft splat of the projected geometry, so the image changes smoothly (is differentiable) as the mesh vertices move.

The concept of differentiable rendering is crucial in neural rendering as it allows for the optimization of 3D models using backpropagation. The rendering process can be broken down into steps:

  1. Projecting 3D vertices to 2D using a projection matrix
  2. Splatting each projected vertex with a soft falloff to create a continuous and differentiable output
  3. Ensuring the output is differentiable with respect to the vertices, enabling the computation of gradients
∂I∂V=∂∂Vσ(f(V))\frac{\partial I}{\partial V} = \frac{\partial}{\partial V} \sigma(f(V))

This technique is widely used in computer vision and graphics applications.

Task

Implement diff_render(verts, faces, K, pose, img_size=(256,256)):

  • verts: N×3N \times 3 vertex positions in world coordinates.
  • faces: F×3F \times 3 vertex indices (part of the mesh interface; the silhouette is built from the projected vertices only).
  • K: 3×33 \times 3 camera intrinsic matrix.
  • pose: 4×44 \times 4 world-to-camera transform whose top-left 3×33 \times 3 block is RR and top-right column is tt.
  • img_size: (H, W) of the output image.

Rendering rules:

  1. Camera coordinates: Xc=RX+tX_c = R X + t. Discard vertices with zc≤0z_c \le 0 (behind the camera); if none remain, return an all-zero H×WH \times W image.
  2. Projection: p=KXcp = K X_c, pixel position u=px/pzu = p_x / p_z (column), v=py/pzv = p_y / p_z (row).
  3. Soft splat: take the integer part of (u,v)(u, v) as the centre pixel. Every pixel at offset (dx,dy)(d_x, d_y) with dx,dy∈{−3,…,3}d_x, d_y \in \{-3, \dots, 3\} that lies inside the image receives intensity 11+dx2+dy2\frac{1}{1 + \sqrt{d_x^2 + d_y^2}}. Where splats overlap, a pixel keeps the largest intensity.

Return an H×WH \times W float array with values in [0,1][0, 1] (0 = background).

Example

Input
Mesh vertices, faces, camera
Output
Soft silhouette
Reasoning
  • Inputs: vertices (0,0,5)(0,0,5), (1,0,5)(1,0,5), (0,1,5)(0,1,5) form one triangle 5 units in front of the camera. K has focal length 500 and principal point (128,128)(128, 128); pose is the 4×44 \times 4 identity, so camera and world coordinates coincide; every z=5>0z = 5 > 0 survives.
  • Projection: u=500⋅xz+128u = 500 \cdot \frac{x}{z} + 128, v=500⋅yz+128v = 500 \cdot \frac{y}{z} + 128. The vertices land at pixels (128,128)(128, 128), (228,128)(228, 128) and (128,228)(128, 228): a 1-unit edge at depth 5 spans 100 pixels.
  • Soft falloff: around each landing pixel, offset (dx,dy)(d_x, d_y) gets 11+dx2+dy2\frac{1}{1+\sqrt{d_x^2+d_y^2}}: 11 at the centre, 0.50.5 one step away, 11+2≈0.4142\frac{1}{1+\sqrt{2}} \approx 0.4142 diagonally, down to ≈0.1907\approx 0.1907 at the (3,3)(3, 3) corner.
  • Output: the soft silhouette, a 256×256256 \times 256 image, shape (256, 256), zero except three 7×77 \times 7 blobs: 147 nonzero pixels, peak value 1.
  • Notice the triangle's interior stays 0: only vertices are splatted, so the silhouette is three soft dots. They sit 100 pixels apart, so no two splats overlap and the "keep the largest" rule never kicks in.

Constraints

  • Input parameters: mesh vertices (3D numpy array), faces (2D numpy array of integers), camera (1D numpy array of parameters)
  • Valid ranges: mesh vertices in [-1, 1], faces as indices to mesh vertices, camera parameters in [0, 1]
  • Output format: 2D numpy array (grayscale silhouette) with float32 precision, pixel values in [0, 1]
  • Special conditions: the output silhouette should be differentiable with respect to the mesh vertices, using a projection matrix and rasterization with soft boundaries
  • Assumptions: the input mesh is a valid 3D mesh with non-degenerate triangles, the camera parameters are valid for the given mesh and projection matrix

Learn this in

More from CV: Image-Based Rendering

solution.py

Test results

Sign in to run your code against the test cases.