So, I figured this would be a good thing to actually break down since it’s literally happening to me in real-time. Here goes. I have some passing familiarity with the system in question, but I didn’t not write it nor have I had to do any maintenance to it as of yet.
1:14pm, I get a report that when scrubbing through Time of Day using the scroll wheel in the Developer Commentary game mode the screen gets all red n’ blue. It appears that the height fog is bluish, and static geo is reddish.
Other meetings, yadda yadda yadda
5:15pm - I can get back on to the problem. What I know right now is that it has something to do with the time of day system. I know our TOD system works by lerping between a BUNCH of values set at keyframes (keyframes are set in minutes between 0 and 1440). I know that we’ve got a modulo in place to prevent time values less than 0 and greater than 24 from happening. I add some text components to the time of day actor to see if I can see around when this weird shift occurs.
5:35pm - I can see that the issue occurs right around 1170 (again, just minutes, so this is equates to about 7:30pm) Interestingly, this is the highest value keyframe we have! Next step: to what key is this trying to blend.
(I go check on my wife, who is cooking dinner, and grab a fizzywater)
6:15pm - I add some watch values, and keep the blueprint window open while I run developer commentary mode again and scroll until the issue occurs. Next key is in the morning, at 480. Fantastic! It’s not trying to get some key that doesn’t exist and the system is sufficiently robust as to wrap around.
6:34pm - By now I have managed to reproduce the issue in the editor by change the time value from 19.0 to 20.0. I can toggle back and forth really quickly, so now my iteration loops are shorter. I know that the system affects the Directional Light, Sky Atmosphere, Exponential Height Fog, Post Process, and Skylight. I start turning each of those off and on until I get the issue to NOT occur. Nothing! I watch various values on those actors change as I flip back and forth, I reset the values to default. Nothing!
I look back at the Blueprint and notice an “Overlay PostProcess”. Weird, where is that actor? Not an actor! An unbound component on the Time of Day itself! New thing to watch, flip back and forth, disable the component. No more red and blue! Sweet, getting closer.
I expand a bunch of values in the postprocess settings, flip back and forth, toggle stuff until the issue stops. I notice that the blend weight for a postprocess material flips from 0.0 to 1.0 as I flip from 19.0 to 20.0. I open it up, and plug postprocessinput0 into emissive to nullify the material. No more red and blue! It wasn’t fog!
6:40pm - I start writing this post (dinner is starting to smell really good).
6:50pm - At this point I know that it’s SOMETHING in the postprocess material that adds a tint from near to far (which is why I thought it was the fog, stuff at a distance appeared blue). The background and foreground values don’t appear to change, or to be terribly extreme, but the background is vageuly blue, and the foreground is vaguely red.
Do the values on the postprocess material instance change? No. Distance, falloff, and the colors do not change.
Crack open the parent material, observe that the background and foreground are also extremely blue and red. This doesn’t change with Time of Day. (oh, the default values are more saturated, doi)
What happens if I change the color values on the mat instance?
Nothing, I switched both foreground and background to green and it’s still Red -> Blue.
Back up, double-check to see if there’s anything about creating a dynamic instance, or if there are settings for this material stored in the keyframes. Nope.
Changing the distance does work. Falloff doesn’t. Revert the mat instance.
(Wife brought dinner, it is delicious)
Back to the material. It uses a Blend_Overlay to drop the color onto scene color. I know from years of photoshop that Overlay does weird stuff when the base layer is dark. Swap it for a multiply. Colors are still super saturated, but it changed something, so at least I (I think) I know I’m changing the right thing.
Swap the multiply for a Lerp(SceneColor, OverlaidSceneColor, MyWeightValue).
Colors look a lot better at Weight = 0, so at Weight = 1 they should be fully saturated, right?
Back up a second… SceneTexture:PostProcessInput0 outputs a float4, and the lerped depth for scene color is a float3. You can’t lerp or multiply floats3 and 4, so I had to use a component mask to get the arithmetic to work right. Plug the .rgb input into the blend overlay and skip my manual weight lerp altogether. Super saturated values in the material viewport (expected). Super saturated values in the game viewport as well. Dangit.
Re-enable the weight lerp, but with a default value of 1. Same thing, super saturated. I don’t like this one bit.
Weight = 0 by default, override in the instant to 1, desired results.
Back up, verify that the depth lerp is working as expected, output that straight to emissive. Super saturated in the game viewport, appropriately desaturated in the instance viewport. Oh no…
Change the default color values. That works. Change them in the instance? No effect in the game viewport.
Reset the material to default, have a think. At a time value of 20, the scene postprocess volume currently shows the blend weight of the PP_Depth_Inst to be 0, the TOD’s PostProcess component shows a weight of 1. I can’t change this. The overall blend weight of the TOD postprocess component is 0.04.
(It is at this point, I begin to consider that there may be a Bug afoot)
Is it possible that the postprocess material array isn’t referencing the instance at all, but is in fact referencing the base material? Clear the reference and reapply it. I cannot! I suspect I’m blocked by the TOD update script. Go check the settings, since postprocess blend weights and materials are stored in the keyframes.
I can nuke the material from those keyframes and reapply, I see this update on the component. This does not improve the situation. I change the post process material’s blend weight to 0.5, nothing. 0.01? Nothing. 0.0, good effect. Start advancing through the time of day cycle.
H*ck, now it’s blue at noon. Start checking the PPM arrays at all the other times of day, notice that in some keyframes the ORDER is different fix that, set the weights back where they should be. (Can’t hurt, right?) Cycle through the day. Back to square 1.
Okay, so at 1110 and 1170 the blend weights are 0 but are 1 at each of the other keyframes. Maybe something’s wrong there, set those to 1.
That fixed it! And it didn’t seem to have a negative effect on the times between 1110 and 1170.
WHY DID THAT FIX IT?!
Okay, go back, change the values in the base material to the instance’s values and revert the blend weights to 0.0 for 1110 and 1170. Also solved.
At this point, I am thinking that I have encountered A Bug. Is the bug in the Time of Day script or in the postprocess… stuff? At this point, I believe I’ve found a Content solution (set the default material values to the desaturated ones that are more desirable) and I can comfortably move ahead with it and I’ll try and isolate the specific issue at a later. My hypothesis is like “Postprocess material blend weight = 0.0, the system uses the parent instead”.
Test the time of day scrubbing in developer commentary mode, looks good to go.
Run through the level one more time just to make sure I didn’t goof anything.
I ALMOST FORGOT TO DISABLE MY DEBUG ACTOR.
Phew, what a ride.