I’ve implemented lighting channels much like in UE3 by putting an FLightingChannelContainer in ULightComponentBase, UPrimitiveComponent, all their SceneInfos etc. and doing the AND operation in ULightComponent::AffectsPrimitive() and ULightSceneInfoCompact::AffectsPrimitve().
And it works, but only for static lights ― and only after rebuilding the level lighting. Real-time lights seem to ignore the channels, even though I made sure FLightPrimitiveInteractions are not instantiated for components with non-overlapping channels.
G-buffer B’s alpha channel normally contains only the shading model ID, of which there are 6. So they only occupy 3 bits, leaving 5 bits free. I’m populating them with 5 lighting channels by properly adjusting the G-buffer encoding and decoding functions. Light channel bitmasks are injected via new uniform buffer fields in FPrimitiveUniformShaderParameters and FDeferredLightUniformStruct. The masks are ANDed in GetDynamicLighting() in DeferredLightingCommon.usf.
Not really, I no longer work at The Astronauts for whom I made these changes. However, the description above is verbose enough for any programmer to follow and implement them, modulo the new selective output stuff Epic added sometime after 4.7.