Desired outcome:
Draw a silhouette / outline / edge of constant width around meshes of different shapes in SceneKit. I'm only going for the outer silhouette, and not interested in the inside edges. Eventually, I would like to have the outline only so that and have the inside area of the mesh be either discarded or transparent. I figured that using the stencil buffer may achieve the right look.
What I tried:
- I had success making an SCNTechnique where the first pass scales up the mesh and makes every fragment and constant color, then the second renders it at regular size.
- Then tried writing to a stencil at regular size, then reading from the stencil buffer in the second (scaled up) pass, so that ONLY the outline would be visible. I can't seem to get this to work. I may not have the right "stencilStates" dictionary, though it is hard to know what is wrong, as I can't generate any different visual feedback or errors when trying differnent keys + values. I thought that by clearing the stencil buffer (all 0's), then replacing with 1's ones during the first pass, then reading anything is "notEqual" to 1 would give me just the outline. However I can't seem to stencil out any part of the second pass.
Here is a playground where I've replicated what I tried: https://github.com/mackhowell/scenekit-outline-shader-scntechnique/tree/stencil-test. (The linked branch "stencil-test" is where I've documented this issue.)
And here is my SCNTechnique dictionary:
let stencilPass: [String: Any] = [
"program": "outline",
"inputs": [
"a_vertex": "position-symbol",
"modelViewProjection": "mvpt-symbol",
],
"outputs": [
"stencil": "COLOR"
],
"draw": "DRAW_NODE",
"stencilStates": [
"enable": true,
"clear": true,
"behavior": [
"depthFail": "keep",
"fail": "keep",
"pass": "replace",
"function": "always",
"referenceValue": 1
]
]
]
let embiggenPass: [String: Any] = [
"program": "embiggen",
"inputs": [
"a_vertex": "position-symbol",
"modelTransform": "mt-symbol",
"viewTransform": "vt-symbol",
"projectionTransform": "pt-symbol",
],
"outputs": [
"color": "COLOR"
],
"draw": "DRAW_NODE",
"stencilStates": [
"behavior": [
"depthFail": "keep",
"fail": "keep",
"pass": "keep",
"function": "notEqual",
"referenceValue": 1
]
]
]
let technique: [String: Any] = [
"passes": [
"embiggen": embiggenPass,
"stencil": stencilPass
],
"sequence": [
"stencil",
"embiggen"
],
"symbols": [
"position-symbol": ["semantic": "vertex"],
"mvpt-symbol": ["semantic": "modelViewProjectionTransform"],
"mt-symbol": ["semantic": "modelTransform"],
"vt-symbol": ["semantic": "viewTransform"],
"pt-symbol": ["semantic": "projectionTransform"],
]
]
Thanks!