Random fields

Just a quick update on the random functionality I implemented for the Vector Fields in the last post:


https://geofflester.wordpress.com/2014/10/27/swirly-vector-fields-of-doom/

The random data I was generating was previously overwriting the values imported for the vector field.
I’ve refactored it so that “Random” is a new “Modifier” component, which means it can be blended in with existing vector field data, e.g flow data baked out of Maya, other Modifier components I’ve implemented.

I’ve also set up a really basic blending between two random data seeds, to have a simple animated random vector field (rather than the previous approach).

Less words, more video!!

Towards the end of the video, I turn on the original Motor component, which starts blending with the randomness.

Probably worth mentioning that all components by default can be controlled by blueprints (because UE4 is awesome), so it would probably only take a few hours of a non-programmers time to:

  • Make a gun that shoots grenades that generate vortices in vector fields
  • A button that randomises particle movement in rooms
  • Fans that blow particles around that turn on and off with player interaction
  • players that generate swirling particles around as they move
  • Etc.

    Oh, also, I bumped the number of particles up to 48 000, for giggles.
    I can actually push it up to about 100 000 before it struggles, which is pretty neat for a 4 year old graphics card (560 ti)! πŸ™‚

    23 thoughts on “Random fields

    1. Hey Geoff,
      Thanks so much for sharing your work in UE4 with vector fields. This is exactly the sort of thing I was looking to implement myself for an art project, and it would be great to get a leg up on the process by checking out the source of your plugin. Are you open to sharing that code?
      John

    2. Heya! I’ll send you an email about it.
      I generally don’t share source code for a few reasons.

    3. Hi there,

      Is there any plugin or example code available to start generating these dynamic vector fields?
      I’m surprised its still so static in unreal, would love to create my own fields.

      Greetings,
      Beer van Geer

      1. Although I’m not posting any of the code up, or planning on releasing a plugin myself, I hope Epic go further with this tech.

        There’s actually some code in the VectorField.cpp to do animated vector fields driven by textures somehow. Haven’t looked into it much, I don’t think it’s exposed in the UI at all.
        On top of that, there’s no support inside of UE4 to generate them, which is what started me down this path, I’d really hope to have the ability to randomize them in the editor, groom them somehow using brushes (like hair plugins in dcc tools), etc, etc.

        I recently discovered that I can’t get my plugin to work without engine changes, because in the editor I was calling PostEditChangeProperty which is not usable in a standalone build. And also I should be able to just call “Update”, none of the stuff I need to call is in the header file, and I’ve had zero luck working out how to get around this because forward declaring the classes doesn’t help me…

        Annnnnnnnnyway, I got so annoyed with it, I’ve temporarily abandoned the idea of doing this as a plugin, but maybe one day I’ll make the engine changes to expose the classes I need, put it up on gitHub, and see if I can convince someone to put it in the engine.

    4. Hey Geoff,
      this looks amazing.
      I know you are not sharing the code, however I was wondering if you could point me in the right direction as I’m pretty new to Unreal.

      Thanks,

      best regards

      1. Thank you πŸ™‚

        If you are / have access to a programmer, definitely check out some of the code in VectorField.cpp. Basically, if you search through all the engine code for UVectorField, there’s only a handful of source files involved in loading them, updating them, etc.

        If you have any specific questions, feel free to email them through, and I’ll try to answer them when I have time πŸ™‚

    5. Now i Can modify the VectorField’s SourceData. But i have to tweak the intensity a little bit with ui to tell the editor update resource. How do you inform the editor to update resource?

    6. Hey ,
      Now i Can modify the VectorField’s SourceData. But i have to tweak the intensity a little bit with ui to tell the editor update resource. How do you inform the editor to update resource?

    7. Ok, so this is one of the areas I was having issues, as per the other comment πŸ™‚

      But I could get it to update in the editor, by firing PostEditChangeProperty.

      #if WITH_EDITOR
      UProperty* VFStaticProperty = FindField(UVectorFieldComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UVectorFieldComponent, VectorField));
      FPropertyChangedEvent PropertyChangedEvent(VFStaticProperty);
      VectorFieldStatic->PostEditChangeProperty(PropertyChangedEvent);
      #else
      VectorFieldStatic->Resource->UpdateResource(VectorFieldStatic);
      #endif // WITH_EDITOR

      Can’t remember why that second part wasn’t working for me in game, but I kind of ran out of steam on this when I decided I’d probably need to make engine changes to get a bunch of stuff working πŸ™‚

    8. I really want this solution.
      I read comment all and engine source code but I can’t how to do it.

      Excuse me, but can you give me the source code?

      1. Sent you an email, hopefully I can help with any questions.

        If anything interesting comes up, I’ll post it back here or do a new post.
        I haven’t touched particle stuff much in the last few years, but there’s some cool tools I plan to try out at *some* point, like some of the tools these guys are making:

        https://jangafx.com/

    9. Hi, Do you load data to CPU, modify it, and send it again ?
      From what I see in the Endine’s source, I would like to create a UTextureRenderTargetVolume to compute my vector field data at runtime on GPU, and link it to a vector field.
      To do so, I would somehow get the FTextureRenderTargetVolumeResource from it (using UTextureRenderTargetVolume::CreateResource ?), and call GetTextureRHI() to get the GPU FTexture3DRHIRef linked to my render target volume.
      Then, I would need to create a UVectorFieldStatic and write this FTexture3DRHIRef to its Resource->VolumeTextureRHI.
      Unfortunately, the FVectorFieldResource struct definition is in a Private header.The public GetVolumeTextureRef() gives me a copy of the raw pointer so I cannot write to it.
      Any advice ?

      1. Hiya!

        So looking over that code again (which is a bit broken now, it’s been a while sorry… :P)…

        I have a VectorFieldComponent as a private member of my new components.
        I make a copy of the data from that component, and then lock and writing directly to that data:

        // somewhere in the header
        UVectorFieldComponent* VectorFieldComponent;

        // Now in the implementation (removed some checking code here to keep it readable)
        UVectorField* VectorField = VectorFieldComponent->VectorField;

        VectorFieldStatic->SourceData.GetCopy((void **)&_originalFieldData, /*bDiscardInternalCopy=*/ false);
        UVectorFieldStatic* VectorFieldStatic = Cast(VectorField);

        FFloat16Color* RESTRICT SourceValue = _originalFieldData;
        FFloat16Color* RESTRICT DestValue = (FFloat16Color*)VectorFieldStatic->SourceData.Lock(LOCK_READ_WRITE);

        And then in a loop writing into the DestValue elements I wanted to change.
        And then after that I’m calling:

        VectorFieldStatic->SourceData.Unlock();

        Now I’m not sure if this helps you very much at all.
        The approach to this code didn’t come from any great position from understanding by me, because I mostly copied it from somewhere else in the code base, and I poked it until it worked πŸ™‚

        It’s very possible that there have been changes to the engine that affect how accessible some of these things are, seems likely considering it looks like when I updated the engine in 2017 the plugin stopped compiling and I never took the time to fix it…

        1. Thanks for your detailed reply !

          Ok, so you are using exclusevely the `SourceData` field that I have neglected, thinking I couldn’t write to a “source”. It is actually a read/write CPU copy of the data.
          So, you are indeed copying from GPU to CPU, modifying the CPU copy, then copying fom CPU to GPU again. I guess that you call `UpdateResource` to update the `Resource` (GPU) I was talking about.

          At least, `FByteBulkData` is in a Public header so it works.

          In my case, I want to update the field in real time in VR, adding fields from movable sources. So it would be a shame to make all those CPU/GPU copies and to make the interpolation and the sum on CPU, because the GPU has built-in functions to do exactly that (although it is usually done with 2d textures rather than 3d). It seems that UE does not provide a way to do it without hacking the engine…

          Let’s hope there is something better under the hood in UE5 (coming soon) !

      2. No probs at all, it was fun jumping back to it and trying to understand what I was doing πŸ™‚

        And yeah even for my messing around, I remember thinking that there was a lot of stuff I was doing on tick that would be expensive too.
        Something else I haven’t looked into, I wonder if Niagara has some interfaces for vector fields that would keep all the updating on GPU? Would be sort of nice to be able to use that and not have to mess with too much engine code, etc. At least for my purposes, it would open up a lot of fun potential.

        1. The Niagara particle emitter has a vector field sampler to read values from a vector field. These values can then be used to set the speed and/or acceleration of the particles, which is really nice. As far as I know, it cannot write to vector fields but I might be wrong.
          I also plan to use Niagara to visualize the resulting field. The output looks exactly the way I want, like when you see dust in the sun following the air flow.

      3. Ok so that side of things I have played around with a little πŸ™‚

        Thinking about it out loud a bit… You *could* set up a group of particles in an emitter that do nothing but read the vector fields and store that data. Then you could treat those as a dynamic vector field, and use a particle attribute reader to read that data and use it from other emitters… Could be interesting πŸ™‚

        1. Hum, I am really a beginner with Niagara, so I don’t really know how much you can do with it.

          What you describe looks like another hack, but it would be interesting still if it worked πŸ™‚

        2. So I played a tiny bit with this, and I think it will work! I need to put a bit more time into it over the next week, but I might even do it as a follow up to this blog… But I’ll let you know the details before that in case it takes me a while to write it up!

    10. Awsome ! I am looking forward to it πŸ™‚
      If it works for my use case, I will send you some screenshots or video.

      1. My lack of experience in Niagara is making this very painful, but I am still working on it, so fingers crossed I will have *something* in the next week or so… Maybe πŸ™‚

        1. The good thing is you are learning something useful !
          In the mean time, UE5 was released yesterday. I am having a look at it right now. I wonder if there will be some useful changes related to vector fields…

        2. Well I posted a comment about it on Twitter so I guess I have to make it work… πŸ™‚

          I have got as far as creating the grid of particles in an emitter, reading a vector field in that I want to modify (not modifying it yet), dumping that to a render target that is read from a different emitter.
          Still lots of work to do, but it’s looking promising!

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out /  Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )

    Connecting to %s