Search Unity

Feedback Custom function graph node possible?

Discussion in 'Visual Effect Graph' started by Thaina, Mar 2, 2021.

  1. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    I'm not so sure but I can't find it in node editor. I think it should be possible to write custom function node like shadergraph could. Some math expression would be simpler if we write it as a code

    Is it possible to have?
     
    LooperVFX likes this.
  2. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    LooperVFX and Thaina like this.
  3. VladVNeykov

    VladVNeykov

    Unity Technologies

    Joined:
    Sep 16, 2016
    Posts:
    550
    Hi @Thaina , @andybak is right, there is nothing out of the box for this at the moment.
    The workaround is using subgraphs for combining logic, or the shadergraph integration if you need custom rendering.

    We have custom HLSL blocks on our roadmap, please feel free to upvote the task if it's needed for your work.
    Thanks!
     
    Matjio, LooperVFX and Thaina like this.
  4. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    Such an important feature I;''m surprised it is not implemented since it is already present in shader graph.
    This could solve all the messy graphs I have got and speed up my development drastically.
     
    LooperVFX likes this.
  5. jffonseca

    jffonseca

    Joined:
    Mar 4, 2020
    Posts:
    13
    how is thi not implemented.. Such a basic thing
     
    koirat likes this.
  6. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    Custom blocks are such a force multiplier that I can't understand why they are such low priority.

    If you give us custom blocks we can fill in so many missing features ourselves. Implement this and you can all take 3 months off and leave us to it!

    Anything that unblocks users from implementing things themselves should be bumped up the list. Make the tools flexible and open to extension. That was always Unity's core strength.
     
    LuisEGV, koirat and HouseofSecrets like this.
  7. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
  8. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    Well, they are separate teams.
     
  9. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    If they don't cooperate than this is some serious waste of productivity.
     
  10. Matjio

    Matjio

    Unity Technologies

    Joined:
    Dec 1, 2014
    Posts:
    108
    Indeed custom blocks in ShaderGraph does not mean it is free for us to
    implement custom blocks in VFXGraph. Even if it is high on our priority list, it is currently not implemented because it was always less voted and requested than other features that took all of our development time (Eg: URP support, improved shader graph integration, 2D support, graphics buffer support,…). Note that some features that we have done might seem less valuable in absolute but prioritization is relative to internal resources and opportunities. In any case, threads like this one, voting on the public roadmap and ideally providing concrete examples of what would unlock such feature for you or what makes it critical more than other features is super valuable for us to help prioritize. Please take a look at the roadmap and if you think it should be the most important thing to do next, let us know why. Prioritization is never perfect, so all feedbacks are welcome. Thanks in advance for your help and understanding!
     
    LooperVFX and koirat like this.
  11. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    There will be always some prioritization and someone unhappy, but koriat probably also meant, that there would be probably a lot of benefits if teams cooperated/communicate each other a bit more. I have no perspective from internal side, but from my perspective there is good example - graph package. Both teams (shader and vfx) worked on graph UI, both of them separately, while they are almost "the same" tool. In result (at least in my opinion) vfx team did way better job than shader team - overall better tool, while both of them could be capable of the same.
    For instance swizzling in vfx is incomparable better than shader graph.
     
    koirat likes this.
  12. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    This statement concerns me greatly. Henry Ford probably didn't actually say “If I had asked people what they wanted, they would have said faster horses” but this springs to mind here. User requests should be a data point and nothing more. A strong product vision and an understanding of how features combine should be the driving force.

    I could write a short novel about how asking users what they want is not the right way to design a product (I don't actually have to as Jason Fried has written several) and I can list several flaws with the current roadmap voting system even if I was to accept that votes should guide features.

    Most of your users don't know about the roadmap and most of those don't vote. It's statistically misleading and not granular enough. And it ignores a core fact - that the utility of some features is not immediately obvious to people in advance. I would argue that this applies especially strongly to custom function nodes. It would enable a small group of users to provide features that would help a much larger group.
     
    koirat likes this.
  13. Oxeren

    Oxeren

    Joined:
    Aug 14, 2013
    Posts:
    121
    One of the popular sentiments on this forum is that Unity does not listen to their users, but when they say that they base their decisions on user feedback, people say that they actually should not have listened, because features they wanted were not popular enough to implement :) Sorry, my actual point is that it is impossible to talk about the internal processes looking from the outside because we have no idea how the feedback is actually evaluated and how decisions are made.
     
  14. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    You can't rebut my point by saying that "popular sentiment has said otherwise". If that's the popular sentiment then I'm specifically arguing against it!

    > Sorry, my actual point is that it is impossible to talk about the internal processes looking from the outside because we have no idea how the feedback is actually evaluated and how decisions are made.

    True. I think it's more the case that the voting/roadmap is a convenient excuse on occasion. I doubt it drives the roadmap entirely. I just don't like it when it's wheeled out in place of a more cogent argument against a particular priority.

    My thinking is thus - features such as the one under discussion - which empower users to fill major gaps in functionality will most likely turn out to be useful far in excess of it's development cost.
     
  15. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    In other thread it was already said that roadmap is huge guide, but actually the dev team is picking what they think is important (might be they just made a mistake). Well, we can only speculate, but I guess the reason is the fact it has no such big value as shader graph custom node, plus it might be time consuming to implement.
    I 100% agree custom node allows to fill all missing gaps, so it has great value overall, but to be very honest I can't see many gaps to fill. Great number of functionalities is already implemented and almost anything custom you might need can be build with operator blocks.
     
  16. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    https://github.com/landonth/unity-vfx-custom-addons

    Based on work done by Thomas Iché - Unity employee.

    I've used it. It works well. It's simple to maintain compatibility with updates to VFX Graph and it's proved invaluable.

    But an official solution would result in more uptake and a higher chance of people sharing code with the wider community. An ecosystem of custom nodes would be very nice.

    With regards to utility, at it's simplest it's a huge time saver. If I want something like "sqrt(cos(x)) + 4*smoothstep(0,0.7,sin(x+t))" that's a massive pain with nodes and seconds if I can write custom functions.

    And suddenly wanting to change sqrt(cos(x)) to cos(sqrt(x)) ? yeah - horrible with nodes, trivial with text. I often do things like this many times when experimenting. Nodes are a huge creativity killer in this regard.

    (https://github.com/IxxyXR/Parametric-VFX is where I used custom nodes)
     
    LooperVFX likes this.
  17. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    Assuming this is all what is needed to implement custom function, plus works correctly and does not break anything (I just checked files, not test), then I don't understand why it is not implemented yet.
    Still, let's not exaggerate, changing sqrt(cos(x)) to cos(sqrt(x)) is not so time consuming, unless you do it 30 times a day.
     
  18. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    That's exactly the point. When I'm experimenting - I change equations around dozens of times. I treat the VFX graph like a creative coding environment and I use it in an exploratory way.

    So yes - I do change graphs 30 times or more sometimes and no, I'm not exaggerating.

    A creative tool should be fluid and malleable. And nodes are in many ways less creative than a text-based tools for me.
     
    Qriva and koirat like this.
  19. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    Agreed, using nodes for complex math equations is a total joy killer.
    I would also say that even non complex equations makes graphs complex.
     
    andybak likes this.
  20. VladVNeykov

    VladVNeykov

    Unity Technologies

    Joined:
    Sep 16, 2016
    Posts:
    550
    Hi all,
    To chime in, I think everyone agrees that a custom node will be useful: both for speeding up some tasks which otherwise require a lot of nodes or subgraphs (as many of you mentioned), as well as for adding some new custom functionality (like loop logic).

    We try to prioritize tasks based on the value they deliver, and of course our resources / ability to deliver them. Things which tend to be higher priority: tasks with no workaround, refactors which otherwise add technical debt if left unaddressed, or blocking requirement for some other work.

    For example, the 2021.2 ShaderGraph integration refactor, which enabled access to the vert function and unlocked the various HDRP/URP material types to be used for VFX particles. There was no workaround for this.

    Or the current work on Instancing; without it, the VFX graph really doesn't scale and is a blocking piece for its adaptation for large projects/games.

    Even some future tasks like nearest neighbor search seem to me (this is my personal opinion) to add more value, but of course this is subjective based on what people use the VFX graph for.

    As for the ShaderGraph custom node or the prototype Thomas made; yes, without doubt these are great starting points, but there's additional work on our end. I'm not a programmer, so take these with a grain of salt, but on the top of my head: lots of UI/UX work, custom attributes support, spaceable properties, access to private VFX functions (considering our API is not ready for public use to write custom blocks/outputs, etc.), shadergraph integration (if used directly in an output to interface with exposed SG properties), and making sure it runs with all our other features on all platforms and graphics APIs we support.

    This is a longwinded way of saying hi, we hear you, and thanks for sharing your input. It definitely helps us to look internally (and this thread sparked a discussion today) at what it will take to implement something for which our community has voiced their pain points. Please rest assured that even if we don't act upon a specific feature right away, these decisions are never taken lightly and we aim for our work to always have our community's best interest at heart.
     
    LooperVFX, Korindian, Thaina and 3 others like this.
  21. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    Thanks Vlad,

    Very reasonable.

    And FWIW - I agree that nearest neighbour is probably more valuable than custom function nodes (mainly because I'm salivating about FluvioFX being resuscitated). And access to VertexID between VFX graphs and Shader Graphs is huge.
     
    LooperVFX, daneobyrd and VladVNeykov like this.
  22. peeweekVFX

    peeweekVFX

    Joined:
    Oct 19, 2015
    Posts:
    14
    Totally agree with you vlad, this custom block, even though the UI does most of the common routine tasks is only scratching the surface of the capabilities of a block and is still really error-prone if you don't know what you are doing with it, I have put some simple access to variables (curves and gradients) and currently there is absolutely no promise my proof of concept will be maintained or improved in the future.

    Another custom function that I'd loved to have worked on, is a custom function operator that parses a string and auto exposes inputs/outputs based on an AST, but it's a whole other level of complexity to do as it does not generate HLSL but VFXExpressions instead, but TBH is way beyond my ability.
     
    LooperVFX, andybak and VladVNeykov like this.
  23. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    Which are all arguments in favour of an official solution :)

    Even a very simple hard to use custom block that was officially maintained would be better than an unofficial, simple, hard to use custom block - which is the current status quo.

    "The perfect is the enemy of the good" and all that.
    That sounds fantastic (and complex to implement). I think this discussion has clarified in my head that there's two different things that I think custom blocks help with:

    1. adding new functionality that would be hard or impossible to implement with nodes
    2. Hugely speeding up workflows that involve building expression trees

    I think there's an slightly overlooked user - someone who might not regard themselves as a developer in the widest sense but isn't afraid of writing code snippets or short scripts. Unity seems to be catering for this type of user less and less - the push seems to be for more complexity on the C# API side of things and "we must hide all traces of code lest we scare away technical artists" at the other.
     
    koirat likes this.
  24. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    I just noticed name "Block" mentioned many times in this discussion.
    But I assume OP and me have more like an "Operator" on our mind.
    Is it the same for all of us?

    Also it's not like a custom function Block would be a bad thing.
     
  25. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    I guess it does not matter, becuase both of them would be most likely capable of doing the same thing (at least for testing).
    Operator is better for sure as you can plug result anywhere you want.
     
  26. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
  27. OrsonFavrel

    OrsonFavrel

    Unity Technologies

    Joined:
    Jul 25, 2022
    Posts:
    194
    koirat and Thaina like this.
  28. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    Custom Function is great. Now it allow while loop and greatly simplified math node

    But still, are there anyway we can reference to shader property in blackboard? Direct naming are not found in HLSL
    It would be more convenient, and also it seem like the HLSL function can only taken 4 arguments (it report some error when I include 5th argument). So if HLSL function can reference the property directly without using argument slot it would be more handy

    Another thing I would like to request is, there should be a way to send Count along with StructuredBuffer. So we could send dynamic list for looping instead of sending
    int count
    separated from buffer
     
  29. JulienF_Unity

    JulienF_Unity

    Unity Technologies

    Joined:
    Dec 17, 2015
    Posts:
    326
    Hi!

    VFX blackboard properties are not directly translated to shader properties (i.e. constant buffer values). They don't necessarily exists on GPU but are inputs to expression graph that are then compiled in CPU bytecode or shader code depending on the branch of the graph. So they are not accessible by name in shader but have to be plugged via graph.

    The 4 inputs limit is a limitation of our expression system. Expressions can either translate to shader code or CPU bytecode. Our byte code uses opcode of 4 operands, hence the limitation. However this does not apply to GPU only expression as they will never translate to CPU bytecode. So the limitation can probably be lifted in that case, it was just not done in this first iteration, but I don't see anything that would technically prevent it (but it might be not that trivial)

    Buffer type in VFX graph is unity graphics buffer type. The count (or element capacity) can be retrieved using https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@16.0/manual/Operator-BufferCount.html
     
    OrsonFavrel and Thaina like this.
  30. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    Thank you very much for your explanation

    What I mean is not the native count of the buffer (which actually is capacity?). I mean I also use the buffer as a list, making it 64 slot but sometimes just send data less than that. And use it in a loop. So I need to send both the dynamic count and buffer itself

    What I wish is we could just send the buffer object and access the count in hlsl directly

    Code (CSharp):
    1. //current approach
    2. float Sum(in StructuredBuffer<float3> points,in int count)
    3. {
    4.     float3 value;
    5.     while(count > 0)
    6.     {
    7.          count--;
    8.          value += points[count];
    9.     }
    10.  
    11.     return value;
    12. }
    13.  
    14. // What I wish
    15. float Sum(in StructuredBuffer<float3> points)
    16. {
    17.     int count = points.count;
    18.     float3 value;
    19.     while(count > 0)
    20.     {
    21.          count--;
    22.          value += points[count];
    23.     }
    24.  
    25.     return value;
    26. }
     
  31. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073