Amazing. Someone who understands why what they're doing works and can explain it coherently. Absolutely enlightening.
@darkarps7 ай бұрын
that was one of the best tutorials I've seen on Niagara, incredibly useful stuff, god tier shit, well done!
@yonjuunininjin Жыл бұрын
Omg, this right click on variables inside custom HLSL and getting function calls is huuuuge. I tried to find the functions in C++, but they were named so weirdly, I had no idea what to call. Beeeeeeeeeeg thank you!
@chriszuko Жыл бұрын
Glad it helped! This is why the video is so long because its just... a bunch of weird nuances like that!
@heikoberres8737 Жыл бұрын
Thank you, was wishing for a tutorial like this for a longer time already
@chriszuko Жыл бұрын
Glad it helps!!
@prrrszalonyАй бұрын
Thanks! That was super well explained :)
@ultracapitalistutopia3550 Жыл бұрын
Thanks for this amazing tutorial. Instead of generating spheres and a vec4 array from the BP, I just spawn particles in the same emitter, then use Particle Attribute Reader to feed the particle location and size data to the simulation stage (Get XXX by Index is totally sufficient, no need for the more costly Persistent ID). Anyway different use case demands different solution.
@chriszuko Жыл бұрын
Thanks and nice find yea, that's a good alternative method for sure :)
@htfkid11 ай бұрын
Can you elaborate on how you did this? thank you!!
@nickgennady8 ай бұрын
Thank you. I can now convert my water gerstner waves from using materials to write to render targets to Niagara grid2D. This will boost performance by 2X minimum and allow for more control over wave data as Niagara supports arrays.
@chriszuko8 ай бұрын
Awesome! That should work well yea!
@nickgennady7 ай бұрын
Wow thanks again. I did get my 2X boost in performance for my gerstner waves (there like 1000 of em now) as expected and think I can get 3X with more work. I did not end up using Grid2D and just “direct set xy” set to image resolution but video still gave me the idea to Niagara. Was originally going to use a compute shader but I do not like working with unreals compute shaders on c++ / cpu side compared to Unity and Godot.
@myrontruesdale7506Ай бұрын
@@nickgennady I'm trying to do something similar--can you elaborate on this some as I have little hlsl experience?
@bringfire Жыл бұрын
This is great! Thank you! Super clear and incredibly informative. Thanks for making this a beginner friendly tutorial.
@chriszuko Жыл бұрын
Whew!! Trying to account for all skill levels is incredibly challenging so I am glad it helps!
@metafuel Жыл бұрын
I look forward to watching this. Great work. Thank you for your time in explaining.
@chriszuko Жыл бұрын
Much appreciated! Good luck!
@justinederuyck201611 ай бұрын
Absolutely Awesome! Also love your tutorial/explanation technique! This might be a dumb question but I'm trying to built a somewhat similar effect, but what if I wanted to take a render target that was already drawn on and spawn the system off of that already established RT? Do you have any tips about how you'd go about it with the knowledge you have about render targets/niagara?
@chriszuko11 ай бұрын
Yep, so the entire section where you create the render target inside of niagara can be replaced with a user input of a render target set from BP instead (Similar to all of the other data that is coming in, you can also pump in an external render target) Hope that helps!
@ItsBaffledd10 ай бұрын
This stuff is awesome and I really appreciate the video! My biggest issue is "how", like how am I suppose to know this stuff exists and how to use it all correctly. I understand you said you watched that other older video but just In general I feel Niagara is severely lacking in any documentation past creating simple sprite, ribbon or mesh emitters. This makes me think Niagara is way more powerful then its being shown as by the official docs from epic, I need to really start looking into stuff. Thanks again!
@chriszuko10 ай бұрын
It's just kind of how it is unfortunately.. and I agree.. you have to rely a lot on googling to find random forum posts, videos, or whatever that lean heavily on someone tinkering with a specific niche part of the engine for days or weeks at a time. That's probably the key there.. is that a lot of these things take time to even document.. This tutorial took me 3-5 days to make the video and fully written up docs. This part of niagara is very powerful, but also very much an added bonus on top of everything else it can do.
@jetmaymendo5136 Жыл бұрын
Great tutorial, although I spotted one mistake - When declaring for loop in HLSL there should be "
@chriszuko Жыл бұрын
Yea niagara in particular is friendly about that so I didn't worry too much. good call though!
@henrylockett10 күн бұрын
This is a really useful tutorial! Thank you. Do you know what kind of performance hit this kind of setup is? If I were using a 128x128 render target and grid, and running a for loop over around 200 particles (using their locations rather than an array of actors), I imagine this would be quite expensive but maybe not if it's handed over to the GPU?
@chriszuko10 күн бұрын
Around 27:51 in the vid I show the results a bit for the setup here. You can expect maybe 1000 items to be closer to 1-2ms .. most of the cost is sending the data to niagara and not the niagara itself so if you find a way to get the data to niagara faster (maybe data channels.. ) Then it can probably support quite a bit more without going over 1ms
@chriszuko10 күн бұрын
For a 128x128 with 200 locations it shouldn't be anything super heavy at all. My guess would be close to 0.2ms or so.
@ZeroDantemL3 ай бұрын
Awesome work mate. Been looking for something like this. Just wanted to ask is there a method to write data from the particle stage to the grid? I have some point data that I want to interpolate through niagara particle stage before sending it off to the material and I just can't seem to find any info about writing particle data to the grid.
@chriszuko3 ай бұрын
You CAN yes. You have to have an emitter in the same system and then in the grid emitter you can read the first emitter's data. If you look through the fluid plugin's examples there is a 2D flame FX based off of particle positions which might be a good example for you to copy from.
@EmreNevayeshirazi2 ай бұрын
Hey, thanks for the tutorial. Probably a stupid question but what is the benefit of sending positions to RT from Niagara instead of BP or C++? Is the benefit come from sending directly from GPU?
@chriszuko2 ай бұрын
Not a stupid question. Keeping the Render Target drawing in a niagara GPU emitter as much as you can is "generally" going to be faster because it is processed on the GPU instead of the CPU. In my case, I switched to this after having already gone down the C++ route with a canvas and drawing directly to a Render Target on the game thread. Further Explanation To be clear there are 2 parts to this. 1. The sphere positions are being sent to the niagara emitter via a blueprint actor in this case. 2. Those positions are processed and drawn on a Render Target directly in niagara in it's simulation stages which is all processed on the GPU. You can speed up part 1 by having a much more efficient way to query positions and send them to niagara. I think data channels exist now which is something I need to look into that should speed up this process. Part 2 however benefits from niagara's ability to process data during it's simulation stages all on the GPU. This is then written directly to the render target via the Grid2D data format which is also incredibly powerful and can be a bit more efficient if you spend the time to tweak the hlsl code a bit. There are also many other benefits of this too like being able to scale the processing of this via the detail modes in emitters. The downside is you do have to write hlsl code which is a bit of a pain. Hope this helps.
@EmreNevayeshirazi2 ай бұрын
@@chriszuko Thank you very much!
@JorisJehs3 ай бұрын
I'm using something derived from this in a project. It works in the editor, but not in a build. The error is "Could not find template object for NiagaraDataInterfaceTexture_0" and "Missing Dependency, missing package import". Have you ever encountered something like this while using grid 2d, or do you know what could cause it? Thanks!
@chriszuko3 ай бұрын
Hmm, I haven't encountered that. You could probably get around that if you use a render target from the content browser instead? But you shouldn't have to. I've been able to use this method in a packaged build just fine O.O soo not sure what the difference would be project/implementationwise
@JorisJehs3 ай бұрын
@@chriszuko I'll figure it out, thanks for the answer!
@Fabio-zc7bs5 ай бұрын
Woukd this method be easier if used to get player position to make foliage or water interaction???
@chriszuko5 ай бұрын
You can offset the center position of the data sent to niagara so that it follows the player sure. I think for foliage interaction I think it's not a bad solution. Always gotta get crafty for stuff like that :)
@MarcusBuer3 күн бұрын
When I run your example on the final level it works perfectly, but when I try to copy the contents, or bring your assets to my level, or even import your level as a sublevel in my level, the User.LocationsAndSizes doesn't get filled (the LocationsAndSizes array is empty on the NS inside the manager blueprint). Any idea what I may have been doing wrong? 🤣🤣
@chriszuko3 күн бұрын
that's very odd. Unfortunately nothing comes to mind O.O Sorry it's giving you issues :/
@MarcusBuer3 күн бұрын
@@chriszuko Don't worry mate! Thanks for sharing, I'll try to understand this, as it will be super helpful on a project :)
@DerObernator Жыл бұрын
this is really awesome 💯 thank you very much. I just have one problem I cannot set a Vector4 Array to niagara its mind boggling that it does not work (bp or c++) only works if I send locations with Niagara Set Position Array and the sizes with the scalar equivalent 😕
@chriszuko Жыл бұрын
Glad to help! You can download the example project for free. Maybe it can help you figure out what is different between what you have and what works in the example project. :)
@LowFiTitan9 ай бұрын
Awesome tutorial! I did have a question on the grid2d/niagara part. Do you know if you are able to write to a grid 2d without hitting the play button? I was looking to do this editor side, but my initial tests havent been successful, so I was just curious if you had experimented with it in that way
@chriszuko9 ай бұрын
Thanks! The only way would be if you are using a blueprint that could send the data to the niagara component in the editor. Could be an editor utility widget or editor utility actor too. Look up making an actor tick in editor for unreal and that should get you there.
@LowFiTitan9 ай бұрын
@@chriszuko thanks for the quick reply! I will check that out!
@PeoplesGaming Жыл бұрын
Some heroes don't wear capes
@kiradark23227 ай бұрын
Wow this is great thank you very much, a question, is it possible to use it to obtain height data from a spline?
@chriszuko7 ай бұрын
Glad it worked for you! What i would try is to query positions along the spline using a set distance. Then set the radius so that it minimizes how bumpy the line is.
@kiradark23227 ай бұрын
@@chriszuko Does this mean that the spline depends on a spherical shape? In the case of a road, would this be possible?
@chriszuko7 ай бұрын
@@kiradark2322 yea it's possible just the distance you do each position check would be closer to eliminate the spherical effect. Kind of like a stroke in photoshop. It's just a bunch of circles.
@kiradark23227 ай бұрын
@@chriszuko Thanks for the information, I have definitely never seen a solution to obtain height data from a spline. It would be really great to see a tutorial or some solution in the future. That would definitely bring you a lot of views.
@myrontruesdale75062 ай бұрын
I'm not super great at hlsl--do you have any ideas at how I might make the circles disappear more slowly? Like leaving trails in their movement?
@chriszuko2 ай бұрын
Should be able to just multiply delta time going into the HLSL function to control how fast the fade is. 27:45
@myrontruesdale75062 ай бұрын
@@chriszukoThank you! I also wanted to ask you if you knew of any hlsl resources for unreal that were particularly helpful for if I wanted to get better at this
@chriszuko2 ай бұрын
@@myrontruesdale7506 For sure! I do not unfortunately. In my case I leaned heavily on other scripting languages I knew and focused in on just this one section of code.
@Vitoralo56011 ай бұрын
If you could help me?, how could i make the render target follow the player, or offset it kind of also so it's independent of size and position of other things? i've put the niagara system in my character, and what i pass to it, is GetActorLocation * GetActorScale3D / 8.0f, which works a little bit, but a way that's independent would be better, i actually plan to do somekind of rt interaction manager, that's gonna detect things and pass it to the niagara
@chriszuko11 ай бұрын
You could use the position of the niagara particle system instead so then all of the offset calculations are done in niagara.
@EnvaggedTadpole7 ай бұрын
Did you figure this one out? I am trying to do the same thing but I'm very much struggling.
@slayerofwhales97206 ай бұрын
When attempting the "writeToTexture" module, the stage doesnt seem to iterate over the entire render target, instead only filling the left hand side of the RT. Any ideas?
@chriszuko6 ай бұрын
Not entirely sure. First guess would be the size of the grid when initializing isn't matched with the rendertarget size.
@chriszuko6 ай бұрын
After attempting on my end, It looks like it requires moving the initializing of the grid to the update emitter and not spawn.
@carmodycaramel8664 Жыл бұрын
Is it possible for the write to grid to use the location of the blueprint actor, instead of EXACT 0,0,0 world position? I'd like it to be able to write to grid without having the niagara system and the receiving object to be in the world center. EDIT: Also, there is a noticeable offset when the location actors are at the edge of the render target plane.
@chriszuko Жыл бұрын
Yup, you have to offset the location you are putting into niagara for it to work by adding the actor's location on top (Or subtracting, can't remember)
@claudiocroci7990 Жыл бұрын
Hello Beautiful Video! I wanted to ask a question. I've attached the ball's blueprint to a player to write the player's trail on the Texture Render. The issue is that now the position of the ball on the plane is being read incorrectly, and there's always an offset. Is there a way to make the trail's position independent of the size/position of the plane?
@chriszuko Жыл бұрын
Yep, you'll have to do some math to offset the position you send to niagara by the size of the plane and the plane's position. Typically it's something like taking the location * the scale of the plane + the plane's location.
@claudiocroci7990 Жыл бұрын
@@chriszuko I need to do this calculation on the BP before send to the niagara right?? or inside the niagara where is also the hlsl code??
@chriszuko Жыл бұрын
@@claudiocroci7990 before niagara in BP is where I was imagining.
@fran.fndz.techart Жыл бұрын
what i want to know is that grid tool for window snap lol
@chriszuko Жыл бұрын
I can't operate without it now. It's called window grid. No fluff. Just works.
@MatrakenKENАй бұрын
Is there any particular reason not to use a ParameterSetFor in the scratch module?
@chriszukoАй бұрын
Which part is this referring to?
@MatrakenKENАй бұрын
@@chriszuko at 18:38 I was trying to do a basic setup for interactable foliage and terrain, using Grid2D instead of drawing to a RT from material (BTW thanks for the video in that regard), and I ended up using a ParameterSetFor for writing every item in the array to the Grid2D, is there a reason for using custom code instead of niagara's own loop?
@chriszukoАй бұрын
@@MatrakenKEN ah ok cool, typically the HLSL code will run faster and be easier to manage in the long run than the node equivalents as things get complicated. That being said, if parameterSetFor works instead of having the HLSL node at all, then that's not a terrible alternative so long as it doesn't get too too complex and you feel like you can manage it.
@MatrakenKENАй бұрын
@@chriszuko all good! I'll keep the native loop at least for iterating until I get the final result.
@RayJ-b6s10 ай бұрын
oh!!! i love it ! thank you
@chriszuko10 ай бұрын
Glad to help!
@zerolinke8768 Жыл бұрын
Very interesting, but I'm a little confused. According to the HISL code, this seems to be a very inefficient way. Suppose there are 256 cells, and each time you have to loop 256 times, even though you only have one pixel to display, you have to calculate the distance 256 times, is that right?
@chriszuko Жыл бұрын
I show the performance notes at the end and voice my thoughts on this 27:51. This is a nice way to send in data and draw whatever it receives in an expandable way and keep the performance impact minimal (Under 1ms when dealing with 100's of locations). Since it runs on the GPU, 256x256 is rather quick even if calculates distance per grid. You could optimize this further by making it so it only calculates the exact distance after a bounds of some sort, but for the sake of this tutorial and my usage, it's not needed. Another optimization that could be done would be doing initial calculations with a smaller grid size and then up-scaling from there to a larger grid. But at least this gives a good starting point. Hope that helps the confusion :)
@zerolinke8768 Жыл бұрын
@@chriszuko Thank you very much for your reply, I think it's because I don't know Nigara very well. Your video gave me a lot of insight... Also some of the current dots disappear, how can I adjust the code to show only one pixel unit, like radar?
@myrontruesdale750617 күн бұрын
How would I draw something other than a circle using this?
@chriszuko17 күн бұрын
I imagine you could do simple shapes either with math or just.. based on the grid values offset from the point location's grid values. There might be a way to sample the particle's actual value as well .. this gets a bit more complex.. imo, the easiest way would be to use multiple locations to create a shape close to what you need
@plankins4702 Жыл бұрын
Great tutorial! I have been working on something similar. Looping over evey item worked with way more particles than I would have thought, but I seem to be hitting the limits. Right now, I am trying to use a compute shader. Do you have experience with compute shaders for this purpose? Or is there another method you would recommend, to draw lots of positions to a RT?
@chriszuko Жыл бұрын
Hmmm Technically setting Niagara to GPU is a compute shader. So I am not entirely sure what you are trying to do.
@talalqazi95456 ай бұрын
the location and sizes array is in world space and the grid 2d is in?
@chriszuko6 ай бұрын
The answer? Grid2D is in arbitrary space.. it doesn't care (Technically pixel-space in this case based on the render target size). The HLSL code does distance checks based on the locations converted from world to pixel space. Making the plane work if you move it around. This setup has a RenderTargetPlane in the BP that is matched up so that the render target shows based on the positions of the spheres in worldspace. So everything is world space UNTIL.. you move the plane or the BP containing the plane, then everything is offset by that location. You can easily do this by just offsetting back the sphere location being sent to niagara by the actor location / plane location. Hope that helps!
@talalqazi95456 ай бұрын
@@chriszuko yes it did help. Thank you for the reply and sorry for the wierd comment. Fluid plugin also has unit to world space module to completely make a system out of it i gues.ty so mch
@chriszuko6 ай бұрын
Glad to hear it! That sounds like a nice node yea!@@talalqazi9545
@wayfarergamedev1138 ай бұрын
Hmm, I enable Niagara Fluids but there is not "Set Grid2D" It only adds "Grid2D Generate distance fields." I am on Unreal. 5.3.2
@chriszuko8 ай бұрын
Did you uncheck the Library Only checkbox when searching?
@wayfarergamedev1138 ай бұрын
@@chriszuko Thanks. That was the issue. Still think its weird they took a basic feature and moved it to another plugin. Subscribed.
@chriszuko8 ай бұрын
@@wayfarergamedev113 Glad it worked! Yea that was part of the motivation for making a tutorial.. too many gotcha's like that which are un-documented. I imagine they will move it in the future.
@myrontruesdale7506Ай бұрын
What is Execution Index to Grid Index?
@chriszukoАй бұрын
This is just a conversion function to easily get the intended grid cell coordinates when it's executing the logic. Every time the logic is ran, it runs with a different execution index, one for each of the cells in the grid. Execution index is 0 1 2 3 4 etc for each of the grid cells. Grid index is the X and Y coordinates for the grid. (0,0) (1,0) (2,0) (3,0) etc Hope that helps :)
@Maxparata4 ай бұрын
2:16 WTF is that grid!?
@chriszuko4 ай бұрын
Something called "WindowGrid" its free and it changed my life.
@Maxparata4 ай бұрын
@@chriszuko Thanks for the info! I'm ready to change my life too! XD