You can get some offset by changing the length of LIGHT_VEC, for example:
LIGHT_VEC = LIGHT_VEC - normalize(LIGHT_VEC) * min(length(LIGHT_VEC, offset);
This looks pretty good when the light is further away from the occluder, but close to an occluder it doesn't give the kind of even offset like in Teleglitch. It might be possible to use the vertex shader somehow to get a more even offset.
To have regular lights and the field-of-view light working together the only solution I found was to have a polygon (identical to the occluder polygon) as a mask on top of the wall graphics node for the field-of-view shadows to be drawn on. You can use the _draw()
command in the occluder node to draw the polygon, or you can use a separate Polygon2D node. The color of the mask node should be fully transparent. The mask node and the graphics node should have different light masks that match the lights. I put the graphics node and regular lights on mask 2 and the mask node and field-of-view light on mask 1 (if you want the normal lights to cast shadows you also have to set bit 1 on them). The field-of-view light mode should be either mix or mask. The mask nodes get the light shader:
uniform float offset;
LIGHT_VEC = LIGHT_VEC - normalize(LIGHT_VEC) * min(length(LIGHT_VEC), offset);
SHADOW = vec4(0.0, 0.0, 0.0, 1.0);
LIGHT = vec4(0.0, 0.0, 0.0, 0.0);