Motivation
The goal of illustrative visualization is the emphasis of interesting features in data. Typical methods are the blurring of contextual information or exploded views of multi-layered objects. Another possibility to separate primary from secondary information is the use of cutaways. In a complex geometric scene, important objects are often occluded by others, e.g. a room in a building that is occluded by the walls, or the components of a machine that are occluded by the casing. The idea is to construct a volume that that covers the area of the scene in which occluders are positioned and subtract this volume from the scene.
An approach that works in real-time is outlined in the article "Adaptive cutaways for comprehensible ren-
dering of polygonal scenes" by M. Burns and A. Finkelstein, published in "ACM SIGGRAPH Asia 2008 papers". This project implements the technqiues proposed in the paper and provides simple editing capabilities that allows for testing with different models and environments. Included in the project is a set of two-manifold, closed models that have been assembled into a scene to showcase the functionality.
Features
The application can load models from COLLADA .dae files and render them in NPR style. The user may move and scale the models to build scenes as well as save and load scenes. The workflow is realized as a combination of direct manipulation by transforming gizmos and modifying properties via text commands.
The core function is the demonstration of adaptive cutaways that run in real-time. When the user selects an objects, the application calculates a depth representation of a conical shape with the apex in the object and the base on the near plane. This cone surrounds the area in the scene that could potentially occlude the selected object. By subtracting it from the scene, the user has an unobstructed view on the object.
Several improvements are described in the article by Burns and Finkelstein and have also been implemented:
- Perspective compensation: The area that is subtracted from the scene stays about constant, when the user zooms in and out with the camera. This is achieved by adapting the slope of the cutout volume to the depth of its origin fragment.
- Local angles: The slope of the cutout volume can be adjusted on a per-object basis and multiple objects can be active at the same time. The resulting cutout shape is the union of the individual shapes.
- Edge compression: When a cutout object moves in and out of the screen, there can be a visible discontinuity because the cutout disappear instantly as the last fragment of the object disappears. This is avoided by diminishing the slope of pixels near the edge of the screen.
- Floor constraints: Objects that are positioned on a floor easily cut into the floor at a flat angle and this creates a distracting effect. By imposing a floor constraint, the cutout volume avoids floors as long as the camera is positioned higher than the floor. As the camera moves beneath it, the cutout shape follows smoothly and extends downwards.
- Line types: To retain a sense of the occluded geometry, the outlines of objects that are cut away can be turned on either fully or as ghost lines. Ghost lines are visible in occluding regions but become invisible if they are close to a cutout object.
Manual
Your graphics card must support OpenGL 3.3 for the application to work. The test scene s_test.sce will be loaded upon startup. Use the following controls to manipulate the scene:
- Drag the right mouse button to orbit the camera.
- Move the mouse wheel to move the camera closer or further away from the target.
- Press C to reset the camera target.
- Press F to target the current selection.
- Press the left mouse button to select an object in the scene, hold SHIFT for multi-selection.
- After selecting an object, a transformation gizmo will be displayed. Drag it with the left mouse button to translate or scale the object.
- Press TAB to display or hide a terminal.
The terminal executes commands to load and save scenes and models and to fine-tune the properties of the cutaway effect. The following commands are allowed:
model <filename.dae>
: Loads a COLLADA file from the models/
folder and places it in the scene.
loadscene <filename.sce>
: Loads a scene from the scenes/
folder.
savescene <filename.sce>
: Saves the current scene to the scenes/
folder.
global <value>
: Adjusts the size of the cutout volume globally, between 0 and 90.
local <value>
: Adjusts the size of the cutout volume for the current selection, between 0 and 90.
edit [on|off]
: Enables or disables the transformation gizmo.
edge [on|off]
: Enables or disables edge compression.
dir [on|off]
: Enables or disables the floor constraint.
line [on|ghost|off]
: Sets the line type.
ghost <value>
: Sets the distance of the ghost lines to the cutout object, between 1 and 4.
cancut [on|off]
: Sets whether the current selection can produce a cutout volume.
canbecut [on|off]
: Sets whether the current selection is affected by the cutout volume.
Implementation
The different render passes are implemented in the render()
method of the class Vis2Window
. It is responsible for binding framebuffers and shaders and calls causes the scene to draw its objects whenever necessary. Render passes:
- Jump Flooding: The depth values of the backfaces furthest away from the camera of all the cutout objects are drawn into a frame buffer. For each fragment, the desires slope and its position is written as well. The class
JumpFlooding
is called to calculate an approximate distance transform of the depth image. The result is a depth representation of the cutout volume from the current camera's perspective, called the distance transform buffer. Edge compression, the floor constraint, perspective compensation and local angles can all be realized by adjusting the slopes for each fragment. The Jump Flooding mechanic is adapted from this thesis.
- Front faces: The distance transform buffer generated in the previous pass can be used to perform an additional depth test in the fragment of the cell shading program. Fragments in front of the cutout volume are discarded while unselected objects are drawn. The front faces of the selected objects are drawn without this additional depth test. The cell shader writes to cell buffer, which contains two color attachments. The first is used to store the shaded pixels and the second will contain the ID values of the drawn objects. The ID attachment is used for ID picking and allows the user to select objects.
- Cut surfaces: Cut surfaces are the new surfaces created by the cutaway effect. They show the interior of objects that intersect the cutaway volume partially. The cut surface shader operates on the back faces of unselected objects and projects them on the cutout volume in the direction of the viewing rays. This yields the correct depth values of the fragments. The normals are calculated by transforming the points to world space and using the partial derivative functions of GLSL. In this pass, the depth attachment of the cell buffer is both read from written to decide whether the back face fragments are occluded by a front face fragment. The results are written to the cell buffer.
- Ghost pass: If ghost lines are enabled, the cutout objects are flat-shaded and drawn to a small-resolution gauss buffer. The contents are blurred with a Gauss-Filter by a distance proportional to the ghost line distance. This image will later be used to stop the ghost lines from occluding the cutout objects.
- Silhouette pass: A depth image of the entire geometry is stored in the depth attachment of the edge buffer. An edge detection shader is used once on the depth attachment of the cell buffer, thus rendering the silhouettes of the geometry that is currently visible to the the viewer, including the cut surfaces. If lines are enabled, the shader is also run on the depth attachment of the edge buffer. If the lines type is set to ghost lines, the gauss buffer is used to determine the visibility of the lines.
- Gizmo ID pass: The gizmo is rendered into the ID attachment of the cell buffer to enable picking.
- Combine pass: The contents of the cell buffer and of the edge buffer are combined and drawn to the screen.
- Interface pass: The gizmo and the terminal are rendered on top of the scene.