1. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice
  2. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  3. We’re giving 2017.1 beta testers a chance to win t-shirts and a Nintendo Switch. Read more on the blog.
    Dismiss Notice
  4. We want to know how you learned Unity! Help us by taking this quick survey and have a chance at a $25 gift card
    Dismiss Notice
  5. Unity 5.6 is now released.
    Dismiss Notice
  6. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice

NumberFlow, visual editor for procedural textures

Discussion in 'Assets and Asset Store' started by Jasper-Flick, Nov 21, 2013.

  1. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    @kaamos The diagram material manager marks textures as no longer readable, to save memory. It's meant for when you want to fill materials with procedural textures, without custom work.

    If you want to access the generated data, it makes more sense to manually fill a color array with a diagram. Then you don't need to go through an actual texture.
     
  2. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    Ok, so I declare a public CatlikeCoding.NumberFlow.Diagram diag;

    How would I then retrieve the colors for the output _MainTex?
     
  3. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    There are various alternatives of the Diagram.Fill method that you could use. You could either fill a color array, multiple color buffers, or a texture. See the code documentation for details.
     
  4. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    Ah brilliant, a code reference! I didn't notice that on your site, sorted out now, thanks.
     
  5. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    One more question: When I generate my normal maps, the preview in the graph editor appears correct, however when I get the color data for it, it appears to be the same greyscale data as generated for my heightmap.

    The code I'm using looks like this:

    Code (CSharp):
    1.  
    2.         normaltxt = new Texture2D(diag.width, diag.height)        
    3.         col = new Color[diag.width * diag.height];    
    4.         diag.Fill(col, 2);
    5.  
    6.         diag.PostProcess(col,CatlikeCoding.NumberFlow.DiagramNormalFormat.RGB);
    7.         normaltxt.SetPixels(col);
    8.  
    9.         normaltxt.Apply();
    10.         obj.GetComponent<MeshRenderer>().material.SetTexture("_BumpMap", normaltxt);
    11.  
    The output for the normal map is definitely the third one created and should corrospond to index 2, if I generate from index 0 or 1 the correct maps appear in those cases at least.
     
  6. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    @kaamos You have three outputs in your diagram, all normal maps, and one of them behaves different? There has to be a setting that's different for that one.
     
  7. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    This is the setup and the result, using the code I quoted.

    numberbug.png numberbug2.png

    Update:

    So the problem was that when I called PostProcess, I was using an overloaded version without an output index, which then defaults to processing the first output.
     
    Last edited: Feb 21, 2016
  8. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    Good to know that you found the problem!

    Also, be aware that Unity's shader expects normal maps to be stored in the DXT5nm format. That is, in the editor and desktop builds. Mobile builds use RGB. You can use the Automatic mode to always generate the expected format.
     
  9. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    Thanks for the tip. I did switch to automatic mode once it started generating normal maps correctly and I noticed all the artifacts. Running really well now, and producing some really nice looking results! Awesome tool, can't wait to invest some more time into building more sophisticated and extensible graphs in the next week or so.
     
  10. Braddas

    Braddas

    Joined:
    Jun 9, 2013
    Posts:
    24
    Hi, just wanted to add my voice to those who'd love a cubemap feature, I currently use Space Graphics Toolkit to render my planets and some of its texture inputs use cubemaps. I'm sure it's possible to output these if you know the maths, but every time I try to figure it out my brain melts.

    Also wanted to share some of the planets I've been generating with Numberflow. Fantastic asset, thanks for creating it!

    [​IMG]
     

    Attached Files:

  11. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    @Braddas Nice planets! I decided to go ahead and release my cubemap work.

    You can download version 1.3.0 from the asset store right now. I'll update the free version later. You can then mark a diagram as a cubemap generator, via the inspector. Once that's done, the diagram material manager and image export will generate cubemaps for all outputs.

    There's a new Cubemap Direction coordinates node, which gives you access to the normalized cubemap direction per pixel.

    The diagram editor preview window shows one cubemap face. You can change which direction is shown via the inspector. You can also choose to view it from the inside (skybox) or from the outside (planet).

    I've added an example scene that generates one cubemap and puts it on a sphere and a box.

    cubemap-diagram.png
    cubemap.png
    cubemap-export.png

    Exporting cubemaps is straightforward. I'm using the row layout, which Unity will automatically recognize when you set the texture import type to cubemap.

    Runtime generation of cubemaps is more of a hassle. You'll have to fill all six faces of a cubemap, one after the other, changing the diagram's cubemap direction by hand, and setting the pixels of each cubemap face. You can do this in a loop with a single color buffer.

    Unfortunately, the normalmap post-process option is not available for cubemaps. Technically, the process is also incorrect for lon-lat textures, but you can get away with it fairly well. However, as it is restricted to each face in isolation, you'd get horrible seams when using it with cubemaps.

    Another nasty limitation is that runtime-generated cubemaps are in linear space. Unlike with 2D textures, this cannot be changed. You don't need to worry about this when you're using Gamma space (player settings). But when using Linear space, you'll get incorrect colors unless you are indeed generating linear data.

    You can work around this issue by converting the color buffer to linear space before assigning it to the cubemap. Loop through the pixels and do pixel = pixel.linear. The downside is that you'll lose precision for darker colors, which is the advantage of gamma space. The diagram material manager will do this automatically if it detects that you're using linear space while you haven't indicated that the texture is linear.
     
    Last edited: Feb 28, 2016
  12. Braddas

    Braddas

    Joined:
    Jun 9, 2013
    Posts:
    24
    Awesome, thanks so much! The version I see on the download page still seems to be 1.2.2 though, maybe it's awaiting approval?
     
  13. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    @Braddas You should get 1.3 when you download the paid version from the Unity asset store. The free version on my website is still at 1.2.2. I'll update that one when I release 1.3.1, as I just found a bug that I have to fix.

    Also, I've hacked a way to generate an object-space normal-cubemap. I want to see if I can make that workable for release too.

    bumped-sphere.png cubemap-diffuse.png cubemap-normalmap.png
     
  14. Braddas

    Braddas

    Joined:
    Jun 9, 2013
    Posts:
    24
    It's actually the paid Asset Store version I'm referring to, but I've just realised that I haven't upgraded to the latest version of Unity (I'm still on 5.3.1p2), that could be the issue... If not I'll have to try deleting my local cache or something.

    Great news if you can get normal maps working. :)
     
  15. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    Ah yes, I've made the release for 5.3.2. That's why you're not seeing it from Unity 5.3.1.

    As older versions can still be downloaded from the asset store, I'm aggressively moving to the latest Unity version with my own releases. I'm especially looking forward to Unity 5.4, which gives us access to texture arrays.

    The object-space normal maps require custom shaders, but it seems doable to support them right now.
     
  16. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    All right, version 1.3.1 is available. You have a new node type to play with!

    cubemap-bumped-diagram.png
    This diagram was used to produce the sphere I posted on Monday. It's included as an example.

    The Vector3s / Normals / Cubemap node takes a cubemap direction and a height value, and produces a normal vector. So you're converting a spherical heightfield into an object-space normal cubemap.

    For it to make any sense, the height calculation must depend on the same cubemap node that's directly connected to the normal node. Internally, it does direction * height, saving you a multiplication node.

    To get a correct normal, this node has to use derivatives. It will trigger the computation of the height value four times, and each time the cubemap direction will be slightly different. The four results are then used to compute a normal. So yes, it is expensive! But it is also the only way to get correct and seamless normals for cubemaps.

    I've included a simple example shader that demonstrates how you can use that.

    You might see some complaints about missing node types when upgrading. That's because I grouped the cubemap nodes in their own namespace. NumberFlow should fix that automatically after Unity finished compiling the new code.
     
    Last edited: Mar 2, 2016
  17. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    Another question: Any height data I produce with numberflow produces really steppy unity terrains. Is this avoidable or just a product of the fact the output from numberflow isn't r16?
     
  18. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    @kaamos I guess you're using gradients to produce your height data? Don't do that. Unity gradients are 8-bit interpolated, which causes the stepping. It's good enough for colors, but not for height data. Either use noise output floats directly, or use a curve. Then feed that back into your final color channel.
     
  19. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    I output to a float rather than to a color node via a gradient. Then from code I input the diagram, grab that float output, feed it into a texture2d and then step through the texture2d, sending the points to terrainData.SetHeight. Might applying the data to a texture2d be where I'm killing things?
     
    Last edited: Mar 4, 2016
  20. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    Textures use 32bit colors internally, converting between Color and Color32 data. So yes that limits you to 256 levels for one channel. The NumberFlow output is floating-point color data, so you should use that directly if you want higher fidelity.

    Still, Unity gradients also use Color32, so if you use a gradient node you've already quantized your output.
     
  21. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    I've avoided the gradient node and only use a value node for my output, set to RGB. How do I access that data without using the Fill method?
     
  22. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    You have to use a Fill method. That's fine, because it gets you four floats per pixel, stored in a Color struct. You can copy from there to a 2D float array and pass that to SetHeights.
     
  23. kaamos

    kaamos

    Joined:
    Aug 6, 2013
    Posts:
    44
    Well now I feel a bit stupid, I was basically doing that already, just working with an intermediary texture2d for some reason. Thanks for the help! It's a huge benefit to be able to talk through a problem with someone who knows what they're doing a little better than me...
     
  24. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    Good to hear that you got it working!
     
  25. Alex_4x

    Alex_4x

    Joined:
    Feb 2, 2014
    Posts:
    17
    Hello! How i can use pattern for separate two or more different channels ?
    Pattern like this:
    [​IMG]
     
  26. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    You mean different color tiles? You can use conditionals or gradients to switch between them. This works well with noise, but you'll have to use math to generate regular patterns like in those screenshots. For such patterns, if you have a design in mind, it's easier to draw it yourself rather than figure out the arcane expressions to reproduce them. You could then use a pattern texture as input and combine that with procedural content, if you like.
     
  27. Alex_4x

    Alex_4x

    Joined:
    Feb 2, 2014
    Posts:
    17
    I need to use a prepared texture for channel separation. In other words I want to use a texture as one of the inputs, and access to the relative pixel (range 0-1) on each channel Red, Green, Blue, Alpha
    Also, to be able to use the color value of the specified texture as the float value in any formula as a parameter.
    [​IMG]
     
  28. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    That's possible. You can use the free noncommercial version to try it out.
     
  29. Alex_4x

    Alex_4x

    Joined:
    Feb 2, 2014
    Posts:
    17
    Can you make small example diagram how it work ?

    Another question. Can I make a chart is not in the user interface, and set the program? Well, like I did a set of random nodes and want to connect them. Is it possible?
     
  30. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    Technically, you could mess around with the data structure. But it's not designed with that in mind. If you want some random effects, you could try writing a custom node with some pseudo-randomness. Or make a few diagrams and pick one at random.
     
  31. Alex_4x

    Alex_4x

    Joined:
    Feb 2, 2014
    Posts:
    17
    [​IMG]
    Do I understand that if we call "Time", then the value will be automatically installed? And how you can see the current value?
    How can I still receive variable value every frame?
    [​IMG]
     
    Last edited: Dec 3, 2016
  32. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    The editor preview can be animated by using a float input value. You can choose which input is used to animate, which is "Time" by default.

    In a project, you'll use the Diagram.GetInputValue method to get the Value object of a named input node. You can then adjust the value of the appropriate type as you like.
     
  33. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,311
    Does this package work with WebGL? I notice on your demo site that it says it's not WebGL as it uses threading, can that be turned off so it can work single threaded?
     
  34. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    The gallery demo uses the included manager in threaded mode, which indeed doesn't work with WebGL. NumberFlow itself doesn't use threading and works fine on all platforms. It's just that you cannot use the dynamic texture manager object in threaded mode on WebGL.
     
    monark likes this.
  35. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,311
    Is it possible to generate several diagrams and then input the results of those directly into other diagrams to combine them or would this have to be done in code?
    To explain further what I mean, if I generate textures A, B, C and then want to generate A over B and B over C in 2 new diagrams without having to regenerate B each time can I build each texture in a different diagram and pass the results between diagrams?
    I suppose I could do it all in one diagram with multiple outputs but is that the only/best way, from an organisational view point it might be preferable to break it down.

    Also in the documentation it says

    You can mitigate the impact on the frame rate by using threads or by distributing texture creating over multiple frames.

    How is distributing over frames handled, manually in code or a setting somewhere?

    Looks like an awesome piece of work btw, sorry for the bombardment of questions, just checking before purchasing
     
    Last edited: Dec 16, 2016
  36. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    You can use textures as input for diagrams, ideally as color arrays. So yes, you can do what you describe. The best approach depends on your specific use case.

    Besides using the manager, generating the textures is up to you to code. There are various Fill methods that allow complete or incremental computation of pixels. You can give the noncommercial version a try to see whether you like it.
     
    monark likes this.
  37. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,311
    So I have now purchased and all seems good, one question though when making large diagrams how do you navigate about? I can't find any controls that will pan or zoom the diagram once started. If I drag a tile off the edge I can no longer get to it.
     
  38. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    Diagrams are shown inside a scroll view. Scrollbars should show up when the nodes don't fit inside the window. You can navigate it like all other Unity scroll views.

    scrollbars.png

    Personally, I use a big separate window to edit diagrams most of the time.
     
  39. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,311
    Hmm not getting any scrollbars on mine...
     
  40. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    They appear as needed. So you won't get them until you drag a node outside of the view. Open one of the larger example diagrams that won't fit your window, and they should be there.
     
  41. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,311
    Ha oh yeah, I totally missed that when I first tried it.
     
  42. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    All right! Let me know if you need anything else.
     
  43. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,311
    I see the issue now, the preview area and the parameter dialog can both sit on top of the diagram but when that happens it doesn't allow you to scroll it. The only way around it is to create some dummy nodes and push them off the edge to make the area seem bigger than it is.
     
  44. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    Yes, those panels hover above the scrollview. As the preview can be of arbitrary size, I decided not to put it in a separate column next to the diagram.
     
  45. Pointcloud

    Pointcloud

    Joined:
    Nov 24, 2014
    Posts:
    15
    Hi, thanks for your tutorials and this plugin which I recently purchased the full version of. I'm having an issue with it, however- none of the diagram examples included in the package seem to be working. I can open sample scenes but i can't see any sample textures rendering, and when I click on a diagram (like fireball in the demo folder for example) and look at the Numberflow node editor window nothing appears, or nodes do appear but their IDs all have ??? in place of what they should be. I also get returned in console a lot of errors similar to this,

    Unknown NumberFlow diagram function "4361746c696b65436f64696e672e4e756d626572466c6f772e46756e6374696f6e732e466c6f6174732e506c75734f6e65" in diagram Cubemap Bumped
    UnityEngine.Debug:LogError(Object, Object)
    CatlikeCoding.NumberFlow.DiagramNode:Init(Diagram) (at Assets/Plugins/Catlike Coding/NumberFlow/DiagramNode.cs:148)
    CatlikeCoding.NumberFlow.Diagram:Init() (at Assets/Plugins/Catlike Coding/NumberFlow/Diagram.cs:255)
    CatlikeCoding.NumberFlow.Editor.DiagramWindow:OnGUI() (at Assets/Plugins/Editor/Catlike Coding/NumberFlow/DiagramWindow.cs:151)
    UnityEditor.DockArea:OnGUI()

    or

    Material doesn't have a texture property '5f42756d704d6170'
    UnityEngine.Material:GetTexture(String)
    CatlikeCoding.NumberFlow.DiagramMaterialLink:get_HasAssignedTextures() (at Assets/Plugins/Catlike Coding/NumberFlow/Manager/DiagramMaterialLink.cs:59)
    CatlikeCoding.NumberFlow.DiagramMaterialManager:EditorApplicationUpdate() (at Assets/Plugins/Catlike Coding/NumberFlow/Manager/DiagramMaterialManager.cs:107)
    UnityEditor.EditorApplication:Internal_CallUpdateFunctions()

    I can make my own textures no problemo, but it would be nice to play around with the examples to get a better sense of how things are structured. Any suggestions? Thanks again!
     
    Last edited: Feb 2, 2017
  46. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    That happens when you have forced asset serialization to text mode. The included diagrams are stored in binary format, but your Unity interprets them as text. The result is garbled, as you experience. To solve this, go to Edit / Project Settings / Editor and change Mode under Asset Serialization to Mixed. Then reimport the assets.
     
  47. Pointcloud

    Pointcloud

    Joined:
    Nov 24, 2014
    Posts:
    15
    Great thanks for this! This worked, but now I'm having a more unique problem.
    I'm trying to publish to hololens and am returned the following:

    Assets\Plugins\Catlike Coding\NumberFlow\Manager\DiagramMaterialManager.cs(177,17): error CS1729: 'Thread' does not contain a constructor that takes 1 arguments

    Assets\Plugins\Catlike Coding\NumberFlow\Manager\DiagramMaterialManager.cs(178,11): error CS1061: 'Thread' does not contain a definition for 'IsBackground' and no extension method 'IsBackground' accepting a first argument of type 'Thread' could be found (are you missing a using directive or an assembly reference?)

    Assets\Plugins\Catlike Coding\NumberFlow\Manager\DiagramMaterialManager.cs(179,11): error CS1061: 'Thread' does not contain a definition for 'Start' and no extension method 'Start' accepting a first argument of type 'Thread' could be found (are you missing a using directive or an assembly reference?)

    Assets\Plugins\Catlike Coding\NumberFlow\Examples\Demo\DemoController.cs(62,28): error CS0246: The type or namespace name 'ThreadStart' could not be found (are you missing a using directive or an assembly reference?)

    Assets\Plugins\Catlike Coding\NumberFlow\Examples\Demo\DemoController.cs(63,11): error CS1061: 'Thread' does not contain a definition for 'IsBackground' and no extension method 'IsBackground' accepting a first argument of type 'Thread' could be found (are you missing a using directive or an assembly reference?)

    Assets\Plugins\Catlike Coding\NumberFlow\Examples\Demo\DemoController.cs(64,11): error CS1061: 'Thread' does not contain a definition for 'Start' and no extension method 'Start' accepting a first argument of type 'Thread' could be found (are you missing a using directive or an assembly reference?)

    any suggestions on what might be in conflict or absent here? Thanks!
     
  48. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    Builds for hololens are UWP apps. Microsoft decided to use an incompatible threading API for UWP, which is the cause of these errors. Unfortunately, I do not have a hololens and cannot build for it, so I cannot make it work for hololens myself. I need your help for that.

    If you're not using the manager, you can simply delete it and the errors will be gone. If you do use the manager, you can disable threading and get rid of all the tread-related code. If you still want to use threading, you could try to rewrite the threading code to match the UWP API.
     
  49. Pointcloud

    Pointcloud

    Joined:
    Nov 24, 2014
    Posts:
    15
    Thanks for this. I can delete the manager, but then I can no longer use the DiagramMaterialManager. If this class is no longer available, how would you recommend making a material? By exporting a png or sequence? I've tried disabling the thread code with little success. What would be the best way to get the DiagramMaterialManager to still operate without the thread related code?
     
  50. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    767
    You can manually fill textures with diagrams in your own code. The DiagramMaterialManager itself is an example of how to do this. I have published an update in which the manger's script now has a #define THREADING_SUPPORTED at the top. If you comment-out that line, all threading code will be skipped and it should compile for HoloLens. This forces the manager to use the non-threaded approach, which currently generates everything at once, blocking your app until it's done. So it's not ideal, but at least it works. If blocking is not acceptable, the next step is to use a coroutine approach.