Jump to content

Feedback on Function Node in Material Editor.


photo

Recommended Posts

Windows 10, Unigine 2.17.0.1 Community.

First I need some clarification. Seems like right now there are 2 separate Material systems: ULON and Material Graph.
Are ULON and Basemat the same thing?
Is ULON/Basemat deprecated in favor of Material Graph?

Following are my problems regarding Function Node in Material Editor.
Correct me if I misunderstood some things.

No dynamic array support.
Example:

bool between(float p, float a, float b){
    if (p >= a && p <= b || p <= a && p >= b){
        return true;
    }
    return false;
}

int relationPP(float2 P, float2 polygon[4]) {
    bool inside = false;
    int i = 4-1;
    for (int j = 0; j < 4; j++) {
        float2 A = polygon[i];
        float2 B = polygon[j];
        i = j;

        if (P.x == A.x && P.y == A.y || P.x == B.x && P.y == B.y){
            return 0;
        }
        if (A.y == B.y && P.y == A.y && between(P.x, A.x, B.x)){
            return 0;
        }

        if (between(P.y, A.y, B.y)){
            if (P.y == A.y && B.y >= A.y || P.y == B.y && A.y >= B.y){
                continue;
            }
            float c = (A.x - P.x) * (B.y - P.y) - (B.x - P.x) * (A.y - P.y);
            if (c == 0){
                return 0;
            }
            if ((A.y < B.y) == (c > 0)){
                inside = !inside;
            }
        }
    }
    
    if (inside){
        return 1;
    }
    return -1;
}

void function(float2 gl_FragCoord, float2 resolution, out float4 gl_FragColor)
{
    float2 position = resolution.xy * gl_FragCoord.xy;

    float2 rectPos = float2(100.0, 100.0);

    float2 p0 = float2(rectPos.x, rectPos.y);
    float2 p1 = float2(rectPos.x + 600.0, rectPos.y);
    float2 p2 = float2(rectPos.x + 650.0, rectPos.y + 120.0);
    float2 p3 = float2(rectPos.x, rectPos.y + 100.0);
    
    float2 array[4];
    array[0] = p0;
    array[1] = p1;
    array[2] = p2;
    array[3] = p3;
    
    int value = relationPP(position, array);

        gl_FragColor = float4(0.0, 1.0, 0.0, 0.0);
         if (value == 1){
             gl_FragColor = float4(1.0, 1.0, 0.0, 1.0);
         }
}

I have to explicitly state the count in array in relationPP() function definition.
What if I want to make it a variable count? This ties to following issue.

No uniform array parameter.
Example: I want to make text in 3d space that's placed on bend (deformed) plane (like half-cylinder).
ObjectText doesn't allow it. GUI mesh doesn't work correctly with viewport masking, so that's out.
One way is to make alphabet atlas texture, then send array of coordinates to shader telling which positions to sample texture from.
But I can't send them because there's no such parameter.
I'm thinking of using ObjectMeshDynamic for this problem, but that's unrelated to Material Editor.

No texture sampling function. There's a SampleTexture Node with UV parameter, but no such function in code, like texture() in GLSL.
Example: Same as above, I can't sample anything in code. Custom FXAA and other techniques use it as well.

No else{}, else if{} blocks. Easy to workaround, but strange not to see something so basic.

No comment support. Useful for variety of things: explanations, credits, prototyping code...

Implicit vector declaration. In GLSL I can write vec3 color = vec3(1.0); This will extend to vec3(1.0, 1.0, 1.0)
Here I have to write explicitly float3 color = float3(1.0, 1.0, 1.0); or it won't compile.
This is not important issue at all, just nice to have.

No autocomplete. Aside from faster code typing it's easier to learn some API when writing.
Example: GLSL fract() is frac() here, mod() is fmod(), easy to understand from autocomplete.

No intellisense.
Example: I was banging my head once because of mistyping and couldn't understand why shader wasn't compiling.
I now know Console in Editor shows the error, but it's way more user-friendly to see wrong code to be marked in editing.
Instead of going back-and-forth between Material Editor and Console.

No Undo/Redo. This is a total deal-breaker. Because of this I write code in text document and only copy-paste it inside Function Node.
Example: I once wrote a lot of code, somehow selected it and typed a character. It was all gone.

No option to auto-indent/auto-format code. Another not important, but nice to have feature. Code gets messy at times.

Comfortable editing. Editing in Function Node is not a very pleasant experience for sizable code.
There's no maximize option, have to resize every time I edit.
When I click on slider handle and hold it, if I move mouse cursor outside editing window - handle jumps to top.
Selected text can have more pronounced highlighting, hard to see.

Last 5 points might be eliminated if these tasks offloaded to VSCode.
Make some file like ".mfunc", make extension for VSCode and change Function Node to accept such file.
You already offload logic code writing to third-party editors, so why not this one?

Edited by Armikron
Link to comment

Hi Armikron,

 

8 hours ago, Armikron said:

Seems like right now there are 2 separate Material systems: ULON and Material Graph.
Are ULON and Basemat the same thing?
Is ULON/Basemat deprecated in favor of Material Graph?

No, there are not separate. Material Graphs generate ULON materials with shaders written in UUSL.
Basemat is an extension, currently it can be used with either ULON or with deprecated XML based materials.
ULON won't be deprecated.

8 hours ago, Armikron said:

No dynamic array support.

8 hours ago, Armikron said:

I have to explicitly state the count in array in relationPP() function definition.
What if I want to make it a variable count?

This is how HLSL/GLSL work. All arrays must have size since this memory will be allocated on the GPU.
 

8 hours ago, Armikron said:

No uniform array parameter.

Currently Material Graph doesn't support Array parameters, but you can specify them in ULON/UUSL, see docs.
 

8 hours ago, Armikron said:

Example: I want to make text in 3d space that's placed on bend (deformed) plane (like half-cylinder).
ObjectText doesn't allow it. GUI mesh doesn't work correctly with viewport masking, so that's out.
One way is to make alphabet atlas texture, then send array of coordinates to shader telling which positions to sample texture from.
But I can't send them because there's no such parameter.
I'm thinking of using ObjectMeshDynamic for this problem, but that's unrelated to Material Editor.

Yes, this does sound like ObjectMeshDynamic should work here better.
But as a possibility you can send an array with either StructuredBuffer or via Uniforms, but you'd have to specify max possible amount of vertices beforehand in both cases.
With Uniforms it should look like so:

CBUFFER(my_buffer)
    UNIFORM float4 s_vertex_positions[50];
    UNIFORM float2 s_vertex_texcoords[50];
END

But I would suggest sticking to the ObjectMeshDynamic way.

 

8 hours ago, Armikron said:

No texture sampling function. There's a SampleTexture Node with UV parameter, but no such function in code, like texture() in GLSL.
Example: Same as above, I can't sample anything in code. Custom FXAA and other techniques use it as well.

image.png

Is this what you are asking for? This function samples a texture that was specified as an argument "a" with texcoords from argument "b" and writes value to the "c".
You can also use return here without additional argument "c", but that way you can specify multiple outputs and add meaningful names to them.

 

8 hours ago, Armikron said:

No else{}, else if{} blocks. Easy to workaround, but strange not to see something so basic.

You might want to look into Branch node.

image.png

8 hours ago, Armikron said:

No comment support. Useful for variety of things: explanations, credits, prototyping code...

We have plans to add support for comment nodes, but it's not on the current priority list.

 

8 hours ago, Armikron said:

Implicit vector declaration. In GLSL I can write vec3 color = vec3(1.0); This will extend to vec3(1.0, 1.0, 1.0)
Here I have to write explicitly float3 color = float3(1.0, 1.0, 1.0); or it won't compile.
This is not important issue at all, just nice to have.

That's because under the hood it compiles your code into HLSL, if you are running Windows. HLSL requires explicit declaration. You can also use float3_one and others.

 

8 hours ago, Armikron said:

No autocomplete. Aside from faster code typing it's easier to learn some API when writing.
Example: GLSL fract() is frac() here, mod() is fmod(), easy to understand from autocomplete.

 

8 hours ago, Armikron said:

No autocomplete. Aside from faster code typing it's easier to learn some API when writing.
Example: GLSL fract() is frac() here, mod() is fmod(), easy to understand from autocomplete.

No intellisense.
Example: I was banging my head once because of mistyping and couldn't understand why shader wasn't compiling.
I now know Console in Editor shows the error, but it's way more user-friendly to see wrong code to be marked in editing.
Instead of going back-and-forth between Material Editor and Console.

It would be sure nice to have but currently there are no plans to improve uppon this.

8 hours ago, Armikron said:

No Undo/Redo. This is a total deal-breaker. Because of this I write code in text document and only copy-paste it inside Function Node.
Example: I once wrote a lot of code, somehow selected it and typed a character. It was all gone.

No option to auto-indent/auto-format code. Another not important, but nice to have feature. Code gets messy at times.

Comfortable editing. Editing in Function Node is not a very pleasant experience for sizable code.
There's no maximize option, have to resize every time I edit.
When I click on slider handle and hold it, if I move mouse cursor outside editing window - handle jumps to top.
Selected text can have more pronounced highlighting, hard to see.

Function node is not meant for coding whole material logic in it, it meant to extend Material Graph if certain operations are not supported or a not really comfortable to make with nodes.
For coding materials I'd suggest looking into ULON Based Materials and Abstract Materials.

 

8 hours ago, Armikron said:

Last 5 points might be eliminated if these tasks offloaded to VSCode.
Make some file like ".mfunc", make extension for VSCode and change Function Node to accept such file.
You already offload logic code writing to third-party editors, so why not this one?

There are certain difficulties that arise here. I am not sure if VS Code will help with correct auto-indent, highlighting and autocomplete.
Since function node's code can't be separated from the material it is written in and UUSL includes.

 

So in retrospect, I'd suggest you to stick with ObjectMeshDynamic and write material using Abstract Mesh as a base. You can create a new one by clicking RMB on Asset Browser and selecting Create Code -> Base Material -> Mesh -> Opaque.
image.png


Hope this helps!

 

  • Thanks 1
Link to comment

Thanks for clarifications. I was under impression that Material Graphs will supersede previous methods for some reason.

Didn't know about TEXTURE() and TEXTURE_IN(), exactly what I was looking for. They are not color-hinted and all uppercase compared to other functions.

Regarding Branch Node, I was talking about code in Function Node, there's branch(), but it's just kinda messy compared to conventional way.

Thanks for answers, looks like I'm going with ULON/UUSL in the future.

  • Like 1
Link to comment
On 7/18/2023 at 10:22 PM, Armikron said:

Didn't know about TEXTURE() and TEXTURE_IN(), exactly what I was looking for. They are not color-hinted and all uppercase compared to other functions.

UUSL Textures - Documentation - Unigine Developer

UUSL Textures - Documentation - Unigine Developer

On 7/18/2023 at 10:22 PM, Armikron said:

Regarding Branch Node, I was talking about code in Function Node, there's branch(), but it's just kinda messy compared to conventional way.

I am not sure why if / else doesn't work for you. There is no restrictions on it.

 

Link to comment
×
×
  • Create New...