Penzil: 3d sketching for the web

Hey everyone, I’ve been thinking about writing a showcase post about this project for a while and I think it’s time.

For the past 1.5 years, I’ve been working on a small web tool to sketch in 3d. The result is Penzil. Here’s a video of how it works in practice.

The idea is to bring Blender’s amazing Grease pencil functionality to the web (and, more specifically, to the iPad and the Apple pencil) to open up 3d sketching for a lot of people that are maybe interested in 3d but intimidated by Blender’s learning curve.

The task was… not small. First of all, I knew very little about three.js at the beginning and it took rebuilding the app from scratch twice to get it to a decent place. Even more difficult was figuring out how to actually let people sketch something good without all the incredible features that are baked in Blender from the beginning. Here too, I stumbled quite a bit until I found a model that I find clear and (somewhat) satisfying.

I’m super happy to share learnings from this project so: feel free to ask any question you have. Considering how much I relied on both this forum and on packages made by other three.js devs, it seems only fair to give back!


That’s amazing. Are you using SVGs in there for the strokes?

No SVGs anywere. It’s THREE.MeshLine, which has a custom shader that “expands” a mesh strip.

I did try the SVGRenderer multiple times while developing the project, but while it produces beautiful looking renders, I always found it a bit lacking in key aspects (namely easily rendering variable width lines)

1 Like

Please describe your development stack for Penzil. It looks great. I am interested because you have some fundamental actions - drag / move in 3D, erase/cut, copy, paste - that are essential in my project. Would love to see more details and will try to find what you have explained.
Thanks for this sort of passionate building.

Hey! My stack is actually pretty shallow and the app is fully frontend. Essentially I’m only using Vue.js for the UI and three.js for the 3D stuff. But together with three.js I’m using some amazing components: MeshLines for drawing the lines and CameraControls for controlling the camera.

The rest is mostly native three.js functionalities. Few things worth calling out:

  • the “3d canvas” movement is using a custom combined TransformControls gizmo to allow for movement and rotation at the same time. TransformControls were a bit intimidating to work with but the gizmo code is separate enough from the logic to allow for customization.
  • the eraser is a fun one. You could theoretically use a regular raycaster for this but each one of my lines is an independent geometry, which means that if a drawing is really complex the raycaster would struggle. So I implemented a GPUpicker as explained here. It essentially creates a new scene on the fly, assigns unique colors to each geometry, renders a single pixel, returns the color in that pixel, matches with the unique colors and… TA-DA! you have the fastest picker in the world.
  • cut/copy/paste are actually not there, unless I’m misunderstanding what you mean. I had them in a previous version but decided that they were to difficult to maintain for the first release so I took them out.

If you have any more questions, I’m happy to answer them!