fix and optimisations to perspective projection