Lindsay Kay
BioDigital Tech Talk
July 14, 2017
Silhouettes
Emphasis
for
in
WebGL


Silhouettes: Stencil Technique
- Draw non-emphasized objects
- Enable stencil testing
- Draw emphasized objects
- Configure to not render on top of pixels already in stencil buffer
- Draw emphasized objects again, with flat color, expanding mesh along vertex normals


Step (3)
Step (5)
Combined result
Silhouettes: Stencil Technique (2)
We expand along the normals because simply scaling an object will create a uneven silhouette:

Silhouettes: a small enhancement



Expand each outline vertex by amount proportional to its depth
Silhouettes: The JavaScript
// Render object using standard shader
gl.clearStencil(0);
gl.clear(GL_STENCIL_BUFFER_BIT);
gl.enable(GL_STENCIL_TEST);
gl.stencilFunc(GL_ALWAYS, 1, -1);
gl.stencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
drawObject();
// Render glowing, expanded version of object
gl.stencilFunc(GL_NOTEQUAL, 1, -1);
gl.stencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
drawObject();
Silhouettes: The GLSL
attribute vec4 position;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
attribute vec3 normal;
uniform float outlineWidth;
void main(void) {
vec4 projPos = projMat * viewMat * modelMat * vec4(position.xyz, 1.0);
vec3 offset = (normal * (outlineWidth * (projPos.z/1.0)));
vec4 worldVertex = modelMat * vec4(modelVertex.xyz + offset, 1.0);
mat4 viewMatrix = viewMat;
gl_Position = projMat * (viewMatrix * worldVertex);
}
uniform vec3 outlineColor;
void main(void) {
gl_FragColor = vec4(outlineColor, 1.0);
}
Vertex shader:
Fragment shader:
Silhouettes: a small hitch for some objects

- Mesh normals must be smooth, otherwise there will be gaps in the silhouette at hard edges
- Not a problem for organic shapes, though

Silhouettes: Drawing halo as wireframe
- Draw halo as thick wireframe
- Solves broken outline on hard edges
- Problem: WebGL on Windows has limited wire thickness


Standard shader (1)
Thick wireframe (5)
Result
Silhouettes: Status in Human

- Implemented in BDS fork of SceneJS
- https://github.com/biodigital-human/scenejs/tree/outlining
- Using vertex displacement method, breaks on hard edges
- Need to find workaround for bug in WebGL before deploying
Outlining for Emphasis in WebGL
By xeolabs
Outlining for Emphasis in WebGL
A simple WebGL technique for highlighting objects without changing their appearance
- 2,034