The technique I used here is
- Split all shadow-casting shapes into a list of line segments.
- For each line segment, generate a quad mesh.
- In a renderpass, render each quad mesh with a shader that displaces the outer edge away from the light source. These are all rendered to a screenspace RenderTexture. As this is done by the GPU, it's very fast.
- In a renderPass, multiply the current screen by the light texture.
In my current version of this. I do a few more things to to get soft shadows (generating triangles at the ends of line segments for the soft penumbra part of the shadow), so soft shadows are definitely possible with this method.
As all the lights are drawn to a single screenspace texture before rendering, it would be possible to run AA on this, but it might require implementing it from scratch/reverse engineering one of Unity's render passes, which wouldn't be a minor task.