I have a quite complex problem. I’m trying to convert a glsl fragment shader to Unreal material nodes. The original shader isn’t amazingly complex but at its core it uses interpolation search and various iterations per pixel. I know that I could write the shader natively as explained here but honestly the documentation is quite lacking and it’s also more difficult to support multiple platforms. So I’ve decided to try the Material editor approach. During the convertion I have encountered the following problems:
To convert the complexity of the original shader in a readable “visual” form I’ve created several Material functions that are then called by the main material. Anyway the original 180 lines of code translated to several big material functions, but I think that this is an intrinsic peculiarity of the “visual nodes” approach.
Iteration isn’t supported in the material editor. Am I right? I’ve searched extensively but I haven’t found anyone asking the same question, something that appears strange to me since iterative code can be quite normal in shaders. To override the problem I’ve created functions that are called consecutively for the required number of steps and that have symmetrical input/output. So, for example, for a simple loop like this:
a = 0;
for (int i = 0; i < 5;i++)
a += function(a);
I’ve created a function that takes ‘a’ as input and outputs ‘a’. On the material there are 5 nodes of the function connected one after another. It works but it’s not very elegant, also it works only for very small cycles.
Now for the real problem. After finishing all the material functions I’ve put them together in the proper material. Unfortunately as soon as I connect the result to the output node the editor stops responding forcing me to kill the process. I’ve tried many times with the same result. I’ve then simplified the material a bit and finally I’ve got an error message:
Error [SM5] warning: Line number “32768” got beyond range
MaterialFloat2 Local31752 = frac(Local31738);
from …/…/…/Engine/Shaders/BasePassPixelShader.usf: 10: #include “Material.usf”
Uh oh, I think I know what’s happening here. I’ve opened the HLSL code window just to discover a huge shader made up of thousands of lines of code. The “not simplified” version of the material was probably so huge that the editor crashed before being able to report the error.
So basically 180 lines of glsl code are translated to >32768 lines of pseudo HLSL code, like these
MaterialFloat3 Local3 = (1.00000000 - Material.VectorExpressions.rgb); MaterialFloat2 Local4 = (Parameters.TexCoords.xy * 1.00000000); MaterialFloat2 Local5 = (Local4 * 2.00000000); MaterialFloat2 Local6 = (Local5 - 1.00000000); MaterialFloat Local7 = dot(MaterialFloat3(Local6,-2.00000000), MaterialFloat3(Local6,-2.00000000)); MaterialFloat Local8 = dot(MaterialFloat3(Local6,-2.00000000), MaterialFloat3(Local6,-2.00000000)); MaterialFloat Local9 = sqrt(Local8); MaterialFloat3 Local10 = (MaterialFloat3(Local6,-2.00000000) / Local9); MaterialFloat3 Local11 = ((abs(Local7 - 0.00000100) > 0.00001000) ? (Local7 >= 0.00000100 ? Local10 : MaterialFloat3(0.00000000,0.00000000,0.00000000)) : -1.00000000); MaterialFloat3 Local12 = (Local11 * 0.00000000); MaterialFloat3 Local13 = (Local12 + MaterialFloat3(10.00000000,3.50000000,5.00000000)); MaterialFloat Local14 = (Local13.r * 0.75000000); MaterialFloat2 Local15 = (MaterialFloat2(Local13.b,Local14) + View.GameTime); ...
The final question is: what am I doing wrong? Maybe I completely miss something and I’m trying to do something in the worst possible way. Does anyone have tried to do something similar? Am I the only one who have tried something so dumb?
Any help would be greately appreciated. Thank you.