Non-Photorealistic Rendering¶
The non-photorealistic rendering (NPR) module provides functionality to render 3D models into 2D sketch-like images using various NPR techniques such as suggestive contours, ridges and valleys, and apparent ridges.
Source: tests/unit/test_npr_renderer.py
[!note] Dependancies Requires
libglfw3-dev,libglew-devon Linux. Also requires X11 forwarding if you run on a remote machine.
Usage¶
NPRRenderOptions¶
NPRRenderOptions stores configurable rendering parameters for NPRRenderer. These options can be used to control properties such as:
canvas size
rendering method
threshold value for different rendering techniques
NPRRenderer¶
The method implements non-photorealistic rendering techniques based on Suggestive Contours for Conveying Shape from SIGGRAPH 2003. It renders 3D models into 2D sketch-like images using various contour-based techniques.
Output: Returns a list of PIL Image objects representing the rendered views from different camera angles.
Available Rendering Methods¶
Suggestive Contour¶
Suggestive contours are curves that appear when the surface bends away from the viewer, helping to convey the 3D shape of the model. This method uses a threshold parameter to control the sensitivity of contour detection.
Ridges and Valleys¶
Ridges and valleys are curves that represent the highest and lowest points on the surface, respectively. This method highlights these features to emphasize the model’s shape and structure.
Apparent Ridges¶
Apparent ridges are view-dependent features that capture the perceived edges of the model, providing a more natural and intuitive representation of the 3D shape.
Code¶
The main interfaces are the NPRRenderer and NPRRenderOptions classes.
from sketchkit.renderer import NPRRenderer, NPRRenderOptions
from sketchkit.core.camera import Camera
import math
from sketchkit.utils.file import save_seq_gif
# Initialize render options
sug_opt = NPRRenderOptions(method="SuggestiveContour", threshold=0.005)
rv_opt = NPRRenderOptions(method="RidgesAndValleys", threshold=0.1)
ar_opt = NPRRenderOptions(method="AppearantRidges", threshold=0.1)
# Initialize renderer with 3D model
renderer = NPRRenderer(obj_path="media/rapid.obj")
# Create cameras at different angles
cameras = []
for angle in range(0, 360, 30):
rad = math.radians(angle)
camera = Camera()
camera.set_look_at([0, 0, 0])
camera.set_xyz([2.5 * math.cos(rad), 2.5 * math.sin(rad), 0])
cameras.append(camera)
# Render with different methods
images = renderer._render(cameras, sug_opt)
save_seq_gif(images, "npr_rendering_suggestive_contour.gif")
images = renderer._render(cameras, rv_opt)
save_seq_gif(images, "npr_rendering_ridges_and_valleys.gif")
images = renderer._render(cameras, ar_opt)
save_seq_gif(images, "npr_rendering_appearant_ridges.gif")
Usage Notes¶
Constructor
NPRRenderer(obj_path, render_options=None)obj_path: path to the 3D model file (OBJ format)render_options: optionalNPRRenderOptionsobject with rendering parameters
NPRRenderOptions
canvas_size: tuple of (width, height) for the output images (default: (512, 512))method: rendering method to use. Supported values are"SuggestiveContour","RidgesAndValleys","AppearantRidges"threshold: threshold value for the selected rendering method (default: 0.005)
Render Method
_render(cameras, render_options=None)cameras: list ofCameraobjects defining different viewpointsrender_options: optional rendering options (overrides the renderer’s default options)Returns: list of PIL Image objects
Normalization
The renderer automatically normalizes the 3D model to fit within a unit cube, which helps ensure consistent rendering results across different models.