[Music] welcome to beyond emitters shader and surface driven gpu particle effects techniques this is a talk about particle effects this talk is not just aimed at graphics programmers but also technical artists and vfx artists it's very much a hybrid talk so a quick intro about myself i've been working in the game industry since 1994. mainly as a optimization and rendering programmer for a lot of aaa games with some technical artists work on several of them these days i do many roles because i'm independent and i focus a lot more now on art vfx even animation and rigging because for me i feel like there's some kind of special stuff that sort of lies between disciplines and so i really like doing a little bit of
everything these days so the agenda for this talk is first of all i'm going to just go over quickly what the target platform and the design goals were basically what motivated me to focus just on particle related emission and effects and i'll talk about some uh inspiration also some experimentations that i initially started with that worked out pretty well but they have limitations and then i'll eventually get to my sort of what i call my favorite technique that's i feel is very robust and creates some pretty cool stuff uh if you follow me on twitter you may have seen some of that i'll also touch a bit on workflow and optimization and at the end there'll be a question and answer so the development platform in target
this was decided by me a few years ago directx 11 shader model and it works with forward and deferred rendering i've been using unity for several years now and i so i started with way back like unity 4 and pretty much up to the current version right now so a lot of this material i'm covering requires you to have some amount of access or a connection to compute instance and procedural drawing methods to draw a lot of this stuff efficiently but it's adaptable to any engine and a lot of platforms so design goals there's many commonly supported particle emission primitives and many engines already points lines spheres cones um so on and so forth and even meshes these days or skin meshes but my frustration with
particle emission from meshes but it's still in many engines limited to just vertices edges and random points just on top of triangles so we don't really get much sort of interesting finer sort of coloring or extra control and if you want particles to just emit from say part of a mesh uh you usually have to sort of chip that off into its own sub-object and it's not sort of the greatest workflow in my opinion so a lot of my own shader work and personal style involves mixing animated and procedural effects things are intended to be more surreal or abstract looking instead of looking realistic but all of this stuff i'm covering today could work for realistic as well but personally i really wanted these dynamic and usually animating shaders because i like things moving around to give birth to particles in interesting ways so even if they were simply mapped on a
wall or a simple mesh i wanted particles to sort of come off of those surfaces that made it actually look like it was fragments of that surface chipping away and dissolving so to elaborate further my ambitious goal is to have particles emit from literally everything in the world that was kind of one of the core pillars i was working towards for my own game so for the last couple years i've chased this goal to make environments characters pretty much anything you can think of or render on the screen emit particles so how do we do that i also wanted much finer detail in that expression specifically i wanted particles to come off of objects inherit the surface properties of those objects that spawn them i wanted to paint and meshes and work in a very visual way and workflow make things very artist-friendly instead of lots of numbers and sliders and a property panel
so in our industry there's a general avoidance to discuss failure or even talk about the small steps that we take as we move towards our super big huge dream goals not everything is an explosive breakthrough uh we usually present a lot of material at talks in conferences sort of like hey this is all done this works like go and use it it's awesome but i think there's a lot of material that sort of you know works 90 of the time or it's if you're aware of the special cases this stuff is actually very valuable to other developers and i i really wish we would sort of share more of that stuff so in this presentation i'm going to cover uh some of the some of those things that are don't really work for my game but depending on your game and your camera view and performance and other things like that you may find some inspiration or ideas to chase yourself
so looking back i would say this is the original seed of the idea of wanting to spawn particles from everything this is a really old demo uh from unity when they started supporting directx directx11 but it basically just renders an image and looks at the bright parts and draws little sprite flares and i thought well that'd be cool if it spawned particles instead and they you know sort of flew off instead of it just being like draw stars on the shiny parts of objects so a number of view dependent experiments i'll cover now so these experiments only work within the view of the camera but they create some interesting effects that may be of use for certain games or have specific use cases that work within those constraints
so the first one i made after looking at the original sample that was the sort of the seed of the idea was the particle collector it was to just take your zpre pass and render the mesh interception objects against that depth and just mark them into a render target and i like this because there's actually a sort of an upper bound on how many particles you can potentially emit because for any given x y coordinate you know you're a render target you're only emitting one place there so if you had say a wall and a bunch of decals or or something covering it you're not going to like just draw like tons and tons of them so to discuss more in this one so there's basically a full screen pass at the end and we just look at the parts that we marked of interest and right out in the fragment shader at this at this point two and a pen buffer uh
those particle positions because we reconstruct the world space position uh from the copy of the depth and the marked pixels in the render target and then this feeds into the particle gpr gpu particle engine so here's the demo of one of my first experiments so this is a depth intersection there's uh the top left the sort of the debug view of the render target so where the intersection of those mesh objects and the depth happens i decided to part spawn particles there so this is pretty fun and i had tons and tons of ideas with this you can have a water plane intersect geometry or all kinds of things and i played around with this quite a lot and had a lot of fun but this creates some pretty interesting effects but we're dealing with a view dependent approach here so as faces become thin and edge on to
the view we have fewer and fewer samples and eventually it becomes fully edge on our back face and we get nothing so here in the highlighted red areas there's a difference in actual volume of the particles so we have some problems with things sort of flattening out or entirely disappearing so one way to think of this is that every single pixel is a particle emitter it doesn't have to emit just one it connects it could emit as many as we want it's just we have to write that in fragment shader less visible pixels equals less spawn particles so with the limited depth information for the surface is perpendicular to the camera view it's causing the effect to break down so large gaps um appear if we swing the camera around to the side in a scene view or something detached from the normal rendered view so on the left we see these sort of scraped out or
sort of gaps it kind of reminds me of uh shadow mapping acne or something because we're we're out of samples here so we don't have much to work with so how do we fix this so i'm quite a fan of workarounds or gentle hacks so we can patch this with some extra things such as extra particle emission actually if it starts to go edge on and then also add some world space jitter on top of the samples that we actually have that are valid so this is kind of a way to sort of fill fill in the gaps and the way we can detect this is obviously for a given sample we know what the surface normal is relative to the eye view direction now if we're doing faster or burst particle effects or layering this with other effects that aren't view dependent a lot of these shortcomings we can kind
of ignore it's just then like this is just a little extra vfx frosting on the cake so although the single collector pass can create some small particles based on depth intersection between a mesh and scene depth or explicitly marking pixels with shaders i still need a gpu particle emission for mesh data that wouldn't require a z pre-pass and i didn't want to require some strict draw ordering rules so on the left image here there's several mesh objects rendered into the scene each object has extra code in its fragment shader programmed to write out particle emission positions in world space into the append buffer that feeds the gpu particle system the image on the right side is an editor view again of the same scene where i've swung the camera around to see what's going on on the faces we can't see so we have in this case back face and edge on
still not emitting which is problematic now we can do some tricks here with turning off back facing back face calling and then manually discarding in the fragment shader those back faces and get at least front and back face emission but we're not handling the case of things being edge on still and although i was really happy with this effect it was really frustrated because it wasn't quite robust enough for my needs so i wasn't quite done exploring this view dependent stuff in spite of its limitations and so my next experiment was to combine screen space deferred decals with a fragment shader driving particle emission so here in the video i have a blue decal star like just mapped on a ground with a split across it where it obviously should not emit because it's not intersecting the deferred decal so where the positions of the star are visible are also positions that are valid for spawning those particles this effect i like it a lot because it's
again something you could layer with uh on like specific hits like uh bullet hits ricochets sort of anything you can think of now again with this particular implementation i made two variations one basically wrote everything into a single target so i wouldn't get double emission in case the decals overlapped and then another one where i just continually wrote out to the pin buffer as i drew each decal which would allow overlapping so to summarize some important points about these techniques so far at this point i had particles can emit from from anything i drawn into the screen as long as it's in the render target which is great the pro and the con of this is that the density is dependent on pixel screen coverage
so we're using the existing meshes to drive all this so as we draw an object to normally see it in our game view we can attach this extra work and the fragment shader of writing into an append buffer structure to spawn particles so we don't have to have a separate draw we can draw the back faces and do some tricks to make the back faces emit and we still have the problems with partial and off-screen meshes not quite behaving as they should when if we ever rotate or move the camera around so this is this has some very limited uses unfortunately but depending on the context of your game the type of your game how you use your camera in your game these could be of use to you so to keen uh continue on uh
to elaborate more with the fragment shader stuff uh writing to pen buffer we can do like dissolves in material specific stuff already that transfers those material attributes to those shaders so if we shade a blue triangle or a blue pattern or whatever those particles that come from that can get those colors it really depends on the what you put into your pen buffer structure when you are going to pass that data to the gpu normally at the bare minimum you want world position and color but you can add as many parameters as you would like to that so there's a lot of possibilities here for visual effects if the limitations of the technique are acceptable and can be worked around depending on the game and how it uses its camera
in the interest of pushing this technique even further and working around its limitations there's more ideas to consider such as adjusting the camera fov using an explicit separate render pass using a higher resolution render target if you do so to get even better coverage and sampling if you did vr or something and you just allowed rotational pivoting you could render into a cube map and handle those cases fairly easily if it's in a separate pass we can add some kind of temporal jittering to that camera to improve and and catch samples in case you have very thin geometry that you want to have emitting stuff and then finally we can get fancy and look at our camera and see where it's going and somewhat fix the sort of edge on problem by looking ahead so if you're heading towards to look around the corner your extra pass will have the camera
sort of already ahead and looking there so you can get some particles sort of spawned ahead of time before you see the effect sort of break down a little bit [Music] so in this section i will cover object space particle emission this is a more general purpose approach and it's much better suited for all game types although i really like the view dependent stuff and for particle mission building an entire game around the concept of everything that can make particles necessitates an object space approach that's robust enough to handle a third or first person game moving around and then looking everywhere and moving quickly so after a lot of experiments this is sort of what i came to uh to solve my problem and so i call it unfolded mesh shader particle emission and a very extreme simplification of that is
i basically unfold the the every single triangle off of the mesh and then i shade it with a gpu to see what it looks like and then i drive the particle emission from that and this uses the gpu rasterizer but there's a lot of important details to this technique and doing it right and getting it to run fast so this is where i sort of start my deep dive and get really technical regarding the algorithm and also the flow of the data as it passes through the gpu pipeline so a couple important points to just reinforce before i do that this is view independent it supports variable topology sampling density shader effects for every single triangle every single draw call every single instance i assume uh no input topology and v i assume that the input topology and the
shading is fully dynamic because i don't want to bake anything i want i want everything to be dynamic uh it's it's non-negotiable for me so there's no caching or uh precomputation no baking i hate it i don't want that so we need a few essential ingredients to get this working so we need the render target we need a render target for arresterization the one that we have bound normally to render the game will suffice we need an append buffer that's going to store the particle data when we decide we need to spawn particles on these triangle surfaces somewhere and then all the bindings and uniforms and constant buffers and so on and so forth for drawing the mesh normally we can just use that information that we actually we actually want that because we want visual parity with
what we render on the screen what we show the player versus what we calculate when we want to emit particles so with that in mind there's three important minimal sort of components to get this technique to work so we need a vertex shader a geometry shader and a fragment also known as pixel shader so unfolding the mesh the first stop is the vertex shader so we need to compute the world space position of these vertices and we need to store them to the output structure that is going to flow through the geometry shader and down to the fragment shader this is important to do this to basically solve for the world space position of the geometry because this becomes our sort of baseline uh scale for once we need to determine what the sampling density is for determining particle emission so we want a unified sort of scale to be in place
for that so and then the sp position data obviously is going to be that's those are the points we wanted to manipulate to make sure that the gpu shades the topology correctly so we can do the particle emission determination correctly in the fragment shader when we get to that part so an important problem to be solved is that if the bare minimum implementation of particle emission from a mesh is just three trying uh three vertex positions uh in case you want to dynamically tripline or texture an object or for some other reason how do we determine the sampling chart and density for those triangles how do we do that in gpu how do we make it fast so this is a really complex problem space there's lots of research done and i originally thought i would need to create a unique parameterization and
that got really scary and uh and so yeah thankfully i don't need to do any of that so that was not the path i wanted to go down anyway it seemed way more complex so i needed something that would be fast it would still give me the sampling density i needed for the triangles in object space based on their world space size after the visual effects and skinning modified the vertex positions so if you had any squash and stretch or grass wind wave wiggle shaders or anything happening i wanted to account for that also so it then dawned on me that i could completely avoid a majority of the problems with traditional uv atlas and sample generation and complex charting for my use case all we need to do is just solve this problem for each triangle in isolation we don't need to care about its whatever is going on with its neighbors we don't need about stretching or distortioning you know we're not trying to sort of peel an orange here and then like nicely
chart it without squishing triangles or anything so to properly unfold and generate a sampling grid i decided to use the geometry shader these things some people find this objectionable but it's actually really fast so it's important that to reiterate that i didn't want to rely on any precomputed data whatsoever it would have been easy to sort of pre-compute a unique parameterization of uv data precompute some kind of sampling density ahead of time but again i wanted everything dynamic i didn't want to rely on extra data so to solve this one problem one triangle at a time for each triangle i auto uv map it basically just flattening it based on its world space size into the currently bound render target device space to make sure each triangle lies completely within the rasterizable space of the mound render target so we
don't clip it with the guard band or excuse me or any kind of clipping we need to apply a tr an offset translation to it to make sure the gpu sort of sees the whole thing the easiest way to do this is i just calculated the centroid of each triangle and figured out the offset relative to the center of the render target and just slid it to the center so when i do this i get every single triangle the mesh sort of thrown into the center in a little crazy little star starburst kind of shape so after calculating the unfolded triangle and charting it so it's centered into this render target we can output this triangle to visually debug its correctness and make sure we accounted for some things that we may overlook so like such as render target aspect ratio and other things such as face winding order and so on but face winding is usually correct as it comes in so you don't need to worry about that but again it's super easy to visually debug this by just getting this
part working and seeing the triangles in in the render target somewhere as long as they're within the rectangle somewhere you're fine it's also important in my implementation at least you set the depth of the primitive to the near clip plane in case we have a depth render target active or some kind of high z or something going on with the gpu that could potentially basically snipe those triangles from ever going down to the fragment shader stage where we are trying to actually call and write into an append buffer and and spawn these particles so it's okay if these triangles overlap um unlike normal uv mapping so i'll why that works i'll get into it later so now that we have these unfolded triangles in the valid render target area where the gpu sees them they'll cause the fragment shader to run but we need to talk about the sampling density
depending on the textures and the shader effect applied made by the artist we may want an extremely high or very low density so it really depends on what your textures look like or what the effect is and whether you want to emit a lot of particles or small amounts so that's one thing to consider at this point so for every pixel the triangle covers the pixel center center satisfying the rasterization rules of the gpu saying hey we need to shade this pixel the fragment shader executes the gpu will shade that portion of the triangle in a similar manner to how it draws the model normally for the game so at this point we get exactly the same shading that we would normally get on an object when we draw it in the game so these shading results are then combined with additional shader code to determine if that position should emit a particle or not
now to improve the coverage of a sampling especially in cases where you want to use a small triangle for performance reasons or yeah so for each frame and each triangle i add a random subpixel offset to all the vertices of that triangle so we're starting to jitter and that moves the grid around and moves the samples we get the rendering the random jittering is important for improving the sampling especially for static objects such as world your world or level geometry the reason being is when we take those uh static objects and we chart them into this space they'll always end up in the exact same space and then you get the same sampling points which is what you don't want and if your triangles are small this is even more obvious so adding the jitter constantly jittering every single triangle every single frame
fixes that problem and let's use a smaller triangle so in addition to adding the random subpixel offset to the triangle vertices we can also effectively rotate the grid that we're sampling from by just rotating the triangle this jittering is done for every triangle again 60 to 120 times a second to ensure varied sampling from different locations that are also valid within the bounds of that triangle so now that we have this another step we can add is that we can adjust the size of this triangle area by uniformly scaling it so this increases or decreases the scaling footprint this is something you could also tune uh for vfx uh reasons in the case of very few particles needing to be emit from every frame you can actually make these triangles very small so a lot of the stuff i do with their like eight by eight pixels uh or even smaller for cases when you require a burst
emission of a ton of particles uh extremely high number or you need fine detailed sampling then you would scale the the the triangles up so if you wrote your name on a wall and you wanted a burst of several thousand particles to come out perfectly shaped into your name then you would want these triangles to be larger because then you would get more samples you get more accuracy where you need it with our triangle jittered scaled we can proceed to the final fragment shading stage of the triangles so the shader code in general will look exactly like the the shader that you use to draw your object but you've got to add some just a few extra things into it specifically determining how many samples or if that sample based on a random dice roller or some artist tuning value whether it should emit or not
now the interpolant values pass through the vertex shader and the geometry shader down into the fragment shader simplify the amount of calculations needed per pixel sample for driving the particle emission because remember we we passed the world space position uh data along with each vertex so we basically get that for free in terms in terms of determining where where should the particle actually be spawning so in this video here i have an animated horse with a texture that spawns textured with a spawning particles and inherit the color of the polygon surface underneath so after the shading stage is finished this is pushing that data into the pen buffer and then it can be copied with a say a compute shader copy from the append buffer into the more managed gpu particle system buffers that you may have or it needs to be sorted and
whatnot and then you would drop the draw and direct or draw procedural type methods so now that i have particles emitting from triangles with pretty much any fragment shader imaginable there were still a number of important things to think about solving one of these is handling handling very fast moving topology over a single time step refer to some particle systems as distance based emission so if you have a rocket or something flying really fast you need to make sure you get all your smoke puffs sort of connected and covering that to make it look correct so when we have we need to solve for that we need to fill in those gaps so how do we do that so it's similar to an animator needed to do breakdowns or tweens so i just used the geometry shader to sort of do that so this is a preferable approach to in my opinion than pushing all the work down into the fragment shader
i basically create the sort of in-betweens and the geometry shader stage in the case of the triangles being skinned squash stretched the surface area of these triangles is highly variable you usually want also some kind of velocity data in your vertex structure to know where the triangle has sort of been and where it's going and that can be helpful in terms of helping you calculate what the accurately tweened topology should be in between those uh two sort of extremes of like your current frame and your next so the nice thing about this is that the code in the geometry shader stage that is calculating the sampling density we can reuse that for these tweens so each in-between triangle that we add to sort of fill in these gaps we'll also get the correct sampling based on its surface area
in addition to the vertex positions on the triangle area varying for these tweens all of the shader parameters and uniforms can also be varying as well so we need to also adjust those appropriate calculations that determine those things especially things like time delta time your uvs could be scrolling and so on so this uh authoring your affection your tutor effects might be a tiny little bit extra complicated to account for this so while this technique works really well there's a limitation to it geometry shaders actually have limits the more complex your vertex shader structure is or vertex structure is the fewer tweened triangles you can have because if you have normals binomials tangents and so on and so forth your max vertex count is basically dropping because your structure is getting more complex and has requires more storage
so it's necessary to adjust your sort of maximum in betweens that you support to account for this so when i've been talking about this this is mainly been in the context of solving this problem in isolation but what we can do is we can actually do this work in addition to just normally drawing the object by interleaving the work of those two shaders together so as i draw my objects i also use the geometry shader to push out those triangles so in order to get this to work your fragment shader doesn't know whether it's drawing drawing pixels that are intended to be for the normal game view or whether they're for shading and figuring out whether we emit particles or not so how do we figure this out the easiest way to do this is to just add an interpolant that basically flags the all three vertices
and then you can look at that in the fragment chain and say oh okay i'm emitting particles from this fragment i'm supposed to shade right now versus just drawing it normally so uh some more thoughts on refining the emission uh and to reiterate is that not all your samples are going to emit uh even if you just even if you run a really high frame rate and you shrink the triangles down it's you're going to call discard on a lot of a lot of those fragments and adding the jitter is helping you get your improved coverage while not needing to make these triangles extraordinarily extraordinarily large uh we could if you can sort of see the visual grid of this uh if you're emitting a lot of them i personally just add the the smallest amount of world space jitter along the
on the surface of the triangle to sort of visually break the grid it's very easy and then again if you're just trickling out particles from something the triangles can be very small and making them bigger actually won't improve anything so to recap the feature set we finally had something that allowed textured and animated fragment shaders it was view independent i had conditional rights to an pen buffer so i could decide which samples did and did not need to write bound particles i had jittered sampling so i wasn't tied to the resolution of the textures or any kind of precomputed baking to make any of this happen and we can work on pretty much any mesh topology imaginable so for surface material transfer uh to to your spawn particles is pretty straightforward because in the case of a
deferred render and say using mesh particles the output of the append buffer structure would just need to contain the necessarily necessary parameters that you would normally be writing out to the g buffer such as albedo emission and other things of that nature in the case of forward rendered objects emitting particles you might want to do a little bit more work or maybe you want to bake stuff and just have then the particle emission code pass some of that through again there's no hard rules here it's just whatever works for you so one important thing uh for refining this is you need to be or you probably want to be selective about where where these particles are are coming from and where they don't so a few engines out there mostly only support particle emission on a per object or sub mesh level so when we have the ability to paint stuff and run the fragment shader and
determine where this is going to happen uh i use the texture painting workflow for for pretty much all of this stuff so in this example areas that should not be emitting particles i just made them painted black and the painted texture i then save as an uncompressed texture asset so it's just another texture that i add to my shader and then fetch and sort of look at so and and in the fragment shader program there's just one line that says hey is this pixel black if not if it is black then hey we're not going to run the particle emission code it's very easy to drive this stuff based on your textures mesh here of course has a unique uv set applied to it that's independent of the particle emission density so i'm not relying on it whatsoever just to reiterate that so here's another video of me painting on a mesh to dissolve away specific areas this is has a lot of use for visual destruction effects
where you want to emit or not emit particles now since we're emitting this object this topology in object space we're not tied to the resolution of the source texture asset mapped on this geometry so the texture for this is like 256 or something and this is rendered at a much higher resolution we can combine masking dissolving mixed resolutions assigned distance fields or any sort of smoothing stuff and get accurate emission because remember we're jittering the triangles moving them around and getting the sampling at a higher density that's above whatever the texturing is so now that i have the ability to control where the particles emit at a much finer detail level the next desirable parameter to control is the particle flow direction as it leaves the surface of a particular point there's a lot of pre-existing material here flow maps and so on and so forth and it basically just works out of the box if you just
uh implement it when i author this data i don't use normalized flow i just started painting and just mapping the stuff to basically red and blue channels and i got interesting stuff so there's no rules here i mean just experiment all the texture data that you have in shader already could create interesting effects with this so you don't need to run off and like create a bunch of extra textures to make some of this stuff happen so some important things to keep in mind non-destructive workflow of course is really good i like to also use photoshop and adjustment layers use a little bit of quick sole and and some other stuff too sometimes illustrator for paths and gradients for dissolves and and whatnot also i add some tuning values and also a curve modifier in my actual shader so i can get a little more out of those assets as well
so to stretch the topology limit even further and just really drive home what this allows us to do with this this approach is that we can stack and combine multiple effects here in our vertex and geometry shader stages to modify the input topology and it doesn't really increase the performance cost of the later fragment shading stage the reason for that is the surface area would not probably be varying that much so the triangles when you unfold and chart them don't change in size significantly now for certain geometry amplification and procedural stuff such as tessellation or anything that's going to make the surface area of those triangles get bigger then you're obviously going to start to pay more cost in the geometry shader and fragment shader stages so one more thing so this video here i this is like a 60 000 object thing i
just sort of blew up this is actually all on the gpu it's done in the geometry shader so i just fractured each triangle turned each triangle into a tetrahedra and then sort of spun it with a sort of stateless animation and just randomly tumbled them and then fed them to the particle emission stuff so this is like having 60 000 particle emitters of things blowing up and it's all one draw call so i was pretty happy with this tessellation and other approaches that can increase the number of triangles can also be used with this emission technique so again we need to remember though that the more triangles we make are the more surface area we increase then we increase the cost of doing this work depending on your use cases you may want to adjust your tessellation factor in your particle emission geometry separate from what you render and show to the to the player and the normal rendering view
so one extremely common question i got when i showed this to some colleagues was what happens with extremely thin geometry like grass and this is something i i thought about when i also did this implementation because i wanted to make grass burn and like have particles come off every grass blade and stuff like that and the thing is is you can just dilate the triangle uh and after you unfold it into the the space where the gpu is going to shade it basically using like a conservative rasterization approach and we're jittering so we're going to hit those we're going to hit those triangles and we're going to be able to emit from them another thing to keep in mind though when you do this is you just don't do this by default because there's a lot of visual effects you may have where you intentionally crush triangles to be zero area because you have them either some kind of destruction or you know limbs or whatever sort of
collapsing and you you don't want particles to come off of those things so you would test it with an epsilon to make sure that those particles happen and the cool thing about doing this is that if you destroy or just hide things by shrinking them down you don't have to worry about them emitting particles so you sort of get that for free so talk a little bit about level of detail a lot of this is kind of obvious but one way to do it is based on distance whether something's in and out of the frustum you decide hey we're going to emit 50 less particles whether something's in or out of the frustum where you decide to do that sort of calling or determination would be in the vertex shader or the geometry shader or maybe you have a computer that runs even further in advance and writes out to a specific stream of data and sort of helps you and
it helps inform whether you should be emitting from certain pieces of geometry or not so i personally write a lot of my shaders by hand but graphene node-based workflows are everywhere i mean tens and tens of thousands or maybe hundreds of thousands of people are used to this workflow it's really easy you pick it up and you just start connecting things and you see results so uh i've thought a lot about like what what do we what do we do with this technique how do we put it in the hands of of more people because many of the existing tools for shader graph based workflows we're only letting you play with the vertex shader and fragment shader so what does that interface look like when we say hey you run a fragment shader but then you can emit particles from it so these are important questions for not just myself but everybody that wants to
do this stuff to think about and eventually answer so we can leverage the immense amount of shaders and visual effects that a lot of us have already made without any tedious hand porting to make this stuff happen so for uh i have a lot of ideas on how to continue to refine this and optimize it but i'm kind of really just having fun uh porting a lot of shaders and figuring stuff out more but again graph based work workflow um you know if we add something uh you know do we just make it one particle one sample does it does it become uh you know one sample can spawn up to n particles and i think we need to collectively consider what kind of interface do we add to compute or open up the geometry shader stage and
and other things to existing tools so my final thoughts although i'm quite in love with the techniques presented today for emitting particles and i'm really excited to share them with you and i hope you find some inspiration from them these don't replace all the use cases you know a lot of the just very simple point line sphere emitters and stuff are still great tools you know so this is just another the the stuff i've covered today is just more tools in your toolbox so i'd like to thank the following people who reviewed this material and uh encouraged me to chase it so and that's it and thank you for your time
Auto-generated captions from YouTube — names and numbers may be misheard.
Distilling the key insights…
Game Developers Conference · 2026
Deconstructor of Fun · 2026
Comments