Issue resolved but I'm really baffled by the cause. Apparently commenting out certain image state variable in the Bullpup fixes the colorshift? I was editing this copy, so it did have some extra image states compared to the original. Fiddling around with it, I suspect it has something to do with too much image state data messing with the colorshift somehow.
stateName[0] = "Activate";
stateTimeoutValue[0] = 0.05;
stateTransitionOnTimeout[0] = "LoadCheckA";
stateSound[0] = weaponSwitchSound;
stateName[1] = "Ready";
stateTransitionOnNoAmmo[1] = "Reload";
stateTransitionOnTriggerDown[1] = "FireCheckA";
stateAllowImageChange[1] = true;
stateName[2] = "Fire";
stateTransitionOnTimeout[2] = "BurstCheck1";
stateTimeoutValue[2] = 0.08;
stateFire[2] = true;
stateAllowImageChange[2] = false;
stateScript[2] = "onFire";
stateEjectShell[2] = true;
stateEmitter[2] = gunFlashEmitter;
stateEmitterTime[2] = 0.05;
stateEmitterNode[2] = "muzzleNode";
stateWaitForTimeout[2] = true;
stateSound[2] = bullpupFire1Sound;
stateName[3] = "Delay";
stateTransitionOnTimeout[3] = "FireLoadCheckA";
stateTimeoutValue[3] = 0.06;
stateEmitter[3] = gunSmokeEmitter;
stateEmitterTime[3] = 0.03;
stateEmitterNode[3] = "muzzleNode";
stateName[4] = "LoadCheckA";
stateScript[4] = "TT_onLoadCheck";
stateTimeoutValue[4] = 0.01;
stateTransitionOnTimeout[4] = "LoadCheckB";
stateName[5] = "LoadCheckB";
stateTransitionOnAmmo[5] = "Ready";
stateTransitionOnNoAmmo[5] = "Empty";
stateName[6] = "Reload";
stateTimeoutValue[6] = 1.6;
stateScript[6] = "onReloadStart";
stateTransitionOnTimeout[6] = "Wait";
stateWaitForTimeout[6] = true;
stateName[7] = "Wait";
stateTimeoutValue[7] = 0.8;
stateScript[7] = "onReloadWait";
stateTransitionOnTimeout[7] = "Reloaded";
stateName[8] = "FireLoadCheckA";
stateScript[8] = "TT_onLoadCheck";
stateTimeoutValue[8] = 0.01;
stateTransitionOnTimeout[8] = "FireLoadCheckB";
stateName[9] = "FireLoadCheckB";
stateTransitionOnAmmo[9] = "Smoke";
stateTransitionOnNoAmmo[9] = "ReloadSmoke";
stateName[10] = "Smoke";
stateEmitter[10] = gunSmokeEmitter;
stateEmitterTime[10] = 0.3;
stateEmitterNode[10] = "muzzleNode";
stateTimeoutValue[10] = 0.2;
stateTransitionOnTimeout[10] = "Ready";
stateTransitionOnTriggerDown[10] = "Fire";
stateName[11] = "ReloadSmoke";
stateEmitter[11] = gunSmokeEmitter;
stateEmitterTime[11] = 0.3;
stateEmitterNode[11] = "muzzleNode";
stateTimeoutValue[11] = 0.2;
stateTransitionOnTimeout[11] = "Empty";
stateName[12] = "Reloaded";
stateTimeoutValue[12] = 0.01;
stateScript[12] = "onReloaded";
stateTransitionOnTimeout[12] = "Ready";
stateName[13] = "Fire1";
stateTransitionOnTimeout[13] = "BurstCheck2";
stateTimeoutValue[13] = 0.08;
stateAllowImageChange[13] = false;
stateScript[13] = "onFire";
stateEjectShell[13] = true;
stateEmitter[13] = gunFlashEmitter;
stateEmitterTime[13] = 0.05;
stateEmitterNode[13] = "muzzleNode";
stateWaitForTimeout[13] = true;
stateSound[13] = bullpupFire1Sound;
stateTransitionOnNoAmmo[13] = "NoFire1";
stateName[14] = "Fire2";
stateTransitionOnTimeout[14] = "Delay";
stateTimeoutValue[14] = 0.08;
stateAllowImageChange[14] = false;
stateScript[14] = "onFire";
stateEjectShell[14] = true;
stateEmitter[14] = gunFlashEmitter;
stateEmitterTime[14] = 0.05;
stateEmitterNode[14] = "muzzleNode";
stateWaitForTimeout[14] = true;
stateSound[14] = bullpupFire1Sound;
stateTransitionOnNoAmmo[14] = "NoFire2";
stateName[15] = "Empty";
stateTransitionOnNotLoaded[15] = "Reload";
stateTransitionOnLoaded[15] = "LoadCheckA";
stateName[16] = "FireCheckA";
stateScript[16] = "TT_onFireCheck";
stateTransitionOnTimeout[16] = "FireCheckB";
stateName[17] = "FireCheckB";
stateTransitionOnNotLoaded[17] = "Fire";
stateTransitionOnLoaded[17] = "Empty";
stateName[18] = "NoFire1";
stateTransitionOnTimeout[18] = "NoFire2";
stateTimeoutValue[18] = 0.08;
stateAllowImageChange[18] = false;
stateWaitForTimeout[18] = true;
stateSound[18] = block_ChangeBrick_Sound;
stateName[19] = "NoFire2";
stateTransitionOnTimeout[19] = "Delay";
stateTimeoutValue[19] = 0.08;
stateAllowImageChange[19] = false;
stateWaitForTimeout[19] = true;
stateSound[19] = block_ChangeBrick_Sound;
stateName[20] = "BurstCheck1";
stateScript[20] = "onBurstCheck";
stateTransitionOnTimeout[20] = "Fire1";
stateTimeoutValue[20] = 0.01;
stateName[21] = "BurstCheck2";
stateScript[21] = "onBurstCheck";
stateTransitionOnTimeout[21] = "Fire2";
stateTimeoutValue[21] = 0.01;
Commenting out both stateTimeoutValue[20] and stateTimeoutValue[21] fixes the issue, commenting out only 1 causes the image to look invisible, leaving both uncommented causes the image to look as if there were no colorshift applied.