I'm used to drive WS2812 with PIC32. I simply use SPI with DMA channel and a single level shifter to have 5V signal. In order to code 0 and 1 for WS2812, I simply use a spi clock 5x faster (4MHz), each WS2812 bit is then coded with 5 spi bits (10000 or 11100 for example), and the table is computed before DMA start. Each led (24bits) need 120 spi bits, but it's not a real problem for a PIC32 with a lot of RAM. The SCK io is not really used and SDI input is driven at the right level to have the wanted SDO level when no data is shifted out (SPI shift out SDI input). Tested with 40 WS2812.
On a PIC32MM, for which I had forgotten there was no DMA, I used normal SPI interrupt and it works well in that case because I have only 3 leds and a low refresh rate, 3 interrupts for 1 led would be too much in other cases, and you must prevent delay between 2 spi words (32bits) to prevent timing errors and then color errors.