Alright, here's 3 blocks drawn in 3 renders. The tilemap is created at runtime with variants of tiles on each side (which can be changed at compile time).
The sides are calculated using a simple bitmask, so b1111 means left, bottom, right, top respectively, of course, if you negate the bits using n^15 (15 borders) you can set N to the occupied blocks (the middle block has a block on the left and the right, so 10^15 sets it to a block with a border on the top and bottom)