Running some quick-and-dirty Python code, I find that there are 197,281 positions at 4 ply (which agrees with this).
Of those positions, I find 61,191 can be reached via moves that don't move the evaluation to worse than -0.5 for white or -0.78 for black (roughly symmetric around the initial position). This is ~31% of the positions. The engine runs on each position for 0.1s, so I wouldn't expect this to be especially robust.
Edit:
On reflection, the asymmetry in position at the start of the game is irrelevant; white just has slightly more "playable" moves than black for any given threshold of "playable."
Using @Danya02's suggestion from the comment, I am using the Lichess evaluations where they are available and then looking at a threshold of:
- 0.30 - 21,581 valid positions ~10.9%
- 0.50 - 54,186 valid positions ~27.4%
- 0.60 - 75,796 valid positions ~38.4% (*roughly KID level "playable")
- 0.75 - 106,947 valid positions ~54.2%
- 1.00 - 151,261 valid positions ~76.7%


There's probably something more to "playable" than just compute eval. For example the Kings Indian Defence is roughly ~0.6, but I don't think there's much doubt that it's playable. The playability of a position also depends on the level of the players. I guess one measure might be "positions where both sides score at least 0.3 for a given Elo", but that might be even harder to measure.