I noticed there is a block of code commented out via #else inside
FHLSLMaterialTranslator::SwitchWhen I tried enabling this branch, it initially triggered a [check] failure. However, I managed to get it working by modifying the return logic as follows:
It seems to work correctly after this change, but I would like to know if there are any known issues or “gotchas” with enabling this logic.
My main concerns are:
Analytical Derivatives: The code comments suggest that UE material nodes generally follow the principle of returning float values. Does returning a void-type statement (the switch block) interrupt or break the calculation of analytical derivatives?
Compiler Optimization: Since this implementation relies on the switch-case statement modifying a declared LocalVariable rather than returning a value directly, is there a risk that the logic might be incorrectly stripped out or optimized away by the HLSL compiler or UE’s internal graph optimization?
Is it safe for me to use this modified implementation in production?
Thanks for reaching out. First a couple of disclaimers: the material translator is undergoing a complete overhaul and we currently offer limited support for the legacy (current) translator as it is on its way for deprecation. The second implementation of Switch inside the disabled code not being enabled is currently unsupported. It has been put there by the original author of the Switch API for future reference.
That said, I believe your fix is correct. The “AddCodeChunkInner” simply pastes the generated switch HLSL, but the correct value to return is that of the “phi value” in ReturnValue.
Regarding your other questions:
The block should not return a void value, but the phi value as you’re doing in your change. The analytical derivative in the old translator is done by the shader and I think they should still work with the Switch instruction.
The material translator won’t do any particular optimization about it. The HLSL shader optimizer should be reliable in the sense that if it can prove that some case branch is impossible, it will indeed optimize it out. There is no way to “return a value directly” when it comes to a ‘switch’ statement in HLSL/C, using a local variable (a phi value) is the only way so I wouldn’t worry there.
All that said, the new translator will support switch instructions fully and robustly, so your concerns will disappear when the new translator is turned on (a few months away).
Thanks for your reply. I found if I simply fix like that,
int32 ReturnValue = AddCodeChunk(ResultType, TEXT("0"));will always return the same index, that means all switch-case nodes share the same local variable as the returned value.
I just made a simple material including 2 switch nodes, one for float2 and one for float3. It will lead to the error
[SM6] (Node Switch) Cannot cast from smaller type float2 to larger type float3.The sample material will be attached with this reply as well. Is there any further way to refine the code, so that every single switch node can return to different local variables?
That is due to code deduplication happening in the translator. A trick you could employ is to generate a unique initialization string, which would force the phi values to be unique