Esto se puede hacer con enmascaramiento. Hay múltiples formas de hacerlo.
Una forma sería tener una forma de representar una versión sombreada de elementos en primer plano. Dibuja el fondo. Luego dibuje los elementos de primer plano, con un ligero desplazamiento dependiendo de cómo desee que se mueva la iluminación, de tal manera que solo genere colores negros. Luego dibuja el primer plano normalmente.
Otra forma sería convertir el primer plano en un búfer, un poco más de lo que realmente verías. Luego haga un pase "a negro" y quizás un pase borroso. Ahora renderice la salida de este conjunto de pasadas y luego la sección visible del búfer en primer plano.
Para admitir múltiples luces en diferentes ángulos, puede hacer el paso anterior varias veces o acumularlas todas en un solo búfer. Las matemáticas variarán según lo que intentes lograr, pero una primera suposición de lo que está sucediendo en ese primer video es que simplemente toman la posición de la luz contra la posición de la cámara (centro del área visible) y luego use ese vector (escalado) para determinar cómo compensar las sombras. Algo como:
draw background
for each light intersecting viewing bounds:
offset = light.position - camera.position
offset *= SCALE FACTOR (0.25 maybe)
draw shadow foreground at offset
draw foreground
Las luces que están "más cerca" de la escena tendrán un factor de escala menor. Si desea profundidades múltiples, hay algunas matemáticas para resolver, cosas geométricas simples.