How To Procedurally Randomize Background Characters (Blender 2.93)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
random character generation is not an easy task to tackle in blender however it's not necessarily hard bottom line is i want an easy way to to randomly generate characters and randomly generate things in general within blender my favorite way to do it is using the random property in the object info node in the material editor i have this cube here i'm in cycles and i have my denoiser turned on and i'm just going to add a material to it so this base color here can be anything at once obviously if i added an object info node we have this random property of the object info so a little bit of background about this random this object info node works off of the index of this which is basically the the unique identifier of this object within the entire scene each each each object is going to carry its own index so it will give you a different random value so if i plug this random directly into the base color it's going to generate me a random color from zero to one which is basically from black to white a random shade of gray if i were to duplicate this again it's a different color i can continue to duplicate this because it's going to generate a new object i've generated five objects that each have five unique identifiers again since we have five objects we've generated five unique identifiers and that's basically five unique ones of these nodes so even though it's the same material we're getting a different output and this is really powerful but there is an issue with it you can't just continue to use this random like oh sweet okay we have random stuff now let's randomize everything well this here is the same number no matter where where this random goes within the object so what i mean by that is this is an a dark gray and this is a bright white say i want to also randomize the roughness well if i plug this random back into the roughness we have an issue because everywhere that is white is also going to be not reflective or very rough and everywhere that's dark though the roughness value of the darkness is going to be pretty low so we want to switch that up so every time we need a new random we have to add in a white noise if you plug the random directly into the white noise down here and then this value can go into the roughness we now have a brand new random because this is basically just changing the seed so if i were to plug the value directly into the output here to see you can see these values these gray values are much different than these gray values and you can take this a step further and change this white noise from 3d to 40 and now you have this slider which basically is like an additional random seed so if i just change this number to one let me plug it in first here every time i just change this number at all i get a different random seed so say i want to have another random then say i want to randomize the metallic value well i would plug the random into a white noise and i would just give this a new seed and plug this into the metallic so we have this random for the metallic we have this random for the roughness and we have this random for the base color and this is basically the idea so what i like to do is i like to just make it simple for myself and i want to create a new node and i call it true random or a random node because there isn't really a random node and it's a really simple node to make we just take a white noise and you can set the make sure it's set for 4d and the w is at zero it doesn't fully matter and then you'll take an object info node and you just have to plug the random directly into the vector and that's the extent of the node we can just highlight those and create a group and we want to output the random value and on the input you want to put the w and we can over here in the inputs we can just change w to seed so you know it's this is the seed if you want a different random output and again this is going to be random based on the object's id and then there's the value out so if i tab out of that i can now change this properties over here the name of this i can change the name of this to random so now i have a random node and if you want to get fancy you can give it a color you don't have to but a random node so now i can delete all this all this ugliness here and i can plug this over here and now i have a random node and if i want a random color i can plug it in there and if i want a random metallic value i can plug it in there but i don't want to be the same random as this so i have to change the seed to something different so now the seed of one is going to give us a different random pattern than the base color and then i want a different random for the the roughness i can change it again to two so now we actually have we're just getting random generations here one way to probably see this a little better is if i add a hue saturation here and then we can make the random the hue and just give it a give it a color here so now every time i duplicate one of these i will get a new with the same material a brand new shader that's either metallic reflective or has a different color and they they're not the same random pattern if that makes sense it actually builds its own random pattern so that's the base level of what we're working with here today and here i've built a just a character head to show you now um the first thing we can do if i duplicate this character over nothing changes because there's no random setup so i can keep duplicating this over and nothing changes so let's switch over here i have the um i have this slot open if i can click on the slot i'll go to the skin shader i am just using the skin bsdf that i created in my other tutorial if you want to click up here to watch um it'll teach you how to make the skin shader and we have a skin tone slider so i can go from really white to darker skin i want that every object here so if i have i see this object as cube if i click again i have cube 10 cube 11 each of these have their own id so what does that mean well it means since we made our true random node if i go into our group here and i add in random here i can plug it in to the skin tone and each of these characters is going to randomly be assigned a skin tone based off of their their unique identifier and we can use this as the first seed so skin tone will be the first seed now you have to make sure you're not overlapping these seeds otherwise it's going to use the same pattern and you don't want to do that but i want to take a look at hairstyles so i i keep you know running into this issue where this is now we're dealing with shapes you know anything that you can change color reflective or you know subsurf scattering any of those are materials that can be changed but how do you actually change the shape of something without using a driver or anything so i figured out that if we use displacement we can change it okay so i have this one hairstyle that i made here and this i took from this is a very stylistic hairstyle this is very stylized hairstyle but if i go to the side view here and like i did in my character creation tutorial i just like to grab this part of the scalp up here and go back and then you can also grab these sideburns if you like i can just duplicate it and then p to separate it by the selection and then i have this little bit of hair that you can actually start styling so alt e to extrude along the faces and then maybe i'll make a bit of a high top [Music] okay so i have these five these five haircuts here and i am just going to go through and they all have no material on them which is perfect so i am just going to go through and give them all a material i will call this one balding so each each hairstyle has its own material now and now that they're like that i can just grab all of them and i can we have to be sure we're we're sort of backing ourselves up so make sure you're saving as you're going but also it's helpful sometimes to just click to move all of your hairstyles into a collection and then right click it and duplicate your collection and then you can just call it hairstyles bu for backup and you can just turn it off just so you know you have them sitting somewhere in case you totally mess this up and want to go back so i'll grab all my hairstyles and i'll just right click on them and i will select the objects so i have everything inside that collection and i don't have to worry that i didn't accidentally grab one because i know everything i want is in the collection and i and from the outliner i right clicked and i selected all the objects now i can ctrl j and join them all together so i have now one object with a bunch of different meshes inside so i'll grab this object and i will move it back to the center 0.25 for the direction all right so here's all my hairstyles and it's as simple as i can just join these two together so we are all in one object it kind of looks like he's wearing a hat right now let's look in in the rendered view okay perfect so so here's what's going to get a little more advanced um we need to we need to basically randomize which which hairstyle shows and the way to do that is first of all go into each hairstyle so since you merged them together all the hairstyles should come together and you'll have them in here so you go through each hairstyle so you'll want to go in under options and change from displacement only to bump you want to change it from bump only to displacement and bump this is going to allow you to physically displace the mesh within the render and you want to do this for each of your hairstyles here okay so now this is going to allow you to take advantage of this displacement here okay so i'm going to teach you how to create this thing but if it's too difficult to create and you can't figure this out don't worry you can skip ahead to the video and i'll provide a link to download it in the description of this video so in the groups here we are going to use this random hairstyle now this is the ultimate node for doing this and the random hairstyle displacement will plug into here but this random hairstyle is made up of multiple nodes as well that i created the random hairstyle is made up of an h master random node that i created an h mesh node and an activator node now they're not that difficult we're going to walk through each one of them okay so i'm in a brand new scene here i'm going to open up i'm going to load in a cube here and we'll make a new material like the first thing we do with the other materials we have to set this displacement to displacement and bump and i will hide this principle bsdf because it's just sort of in the way right now and i'll put it up because we're not going to look at the shading or anything we just want to focus on the displacement so let's think about displacement for a second what does it do so in texture coordinates if i open up a texture if i were to throw the object coordinates into the displacement it's going to double in size now why is that well it's because we are displacing right if there's nothing on there it's not being displaced at all so it's already as it is but if i displace it by the coordinates it takes what it already is which is zero to one and then say okay let's displace it from zero to one it displaces it by exactly what it is so if we want to do any displacement we have to sort of subtract out this initial displacement and again really what that means is we already have uh coordinates happening to make this shape if you add this object coordinates into the displacement it's going to double that it's going to double the vector so we don't want that so basically we want to add in a vector math and we want to just subtract those coordinates again so basically we're taking the object coordinates and then we're subtracting the object coordinates and displacing by that which means we're displacing by nothing so if i take this away nothing changes right because essentially i'm just doing one minus one and i'm saying hey displace this by zero so the reason we do this is because now at the you want to do this at the very end right you want to say okay everything i just did all that displacement i want to do only that displacement and not the original object coordinates so if i make a little line here so any displacement that i do to the top of the subtraction is going to be the only displacement for the whole object so we can do a lot of crazy things here we can do you know scaling and morphing and rotating and all this fun stuff that people like to do in november but for the sake of this we really want to just do something really simple i want to take another vector math and at the top of this here you can i can add this so i can say hey let's add some let's add left to right x or let's add uh on the y you know but really i want to change this add to multiply and look if i multiply it by zero there's nothing there and if i multiply it by one there's something there and that's the power of of this displacement in this whole technique is because we're going to say hey i want to randomize when this is one i want it zero and if i coordinate all those together on however many haircuts i have total uh it will actually randomize through through all those using that beautiful object random that we still created here because we're still in the materials property that's that's the most important takeaway here is the fact that we're controlling the actual mesh inside the material shader editor so if you look at what we just created here if i open up my activator here you can see that every all that's inside the activator is exactly what we just created except for the fact that this active will be will be open so we just created this pretty much where we have the object coordinates that are subtracted from the object coordinates right these two go in here but on the top branch here we have this multiply this is vector multiply and we want to multiply it with either one or zero whether it's active or not so if it's not active we're going to be sending a zero to this multiply and basically we're going to multiply the original coordinates by zero so we get zero and then we take 0 minus the original coordinates so we get negative coordinates and then if you displace the negative coordinates at the very end nothing is going to show up uncheck this displacement and i just plug this guy in here we need to send it object coordinates but if it's not active nothing's there so if i do make it active it's going to appear there and let me show you how this works so as this goes down this is basically a scale from zero to one right zero it's zero times the coordinates and one it's going to be one times the coordinate all inside of our activator now i don't want any of this scaling happening so that is why whatever this value is here that's being sent so there's going to be a value being sent to this active and that's going to be either 0 or 1. i take a math node here and i put it between there and i just do i just do greater than 0.5 so that way it just snaps there's no scaling it's just either zero or it's one and that's all it is so if i were to if so now let me bring out an h mesh so now that you know what the activator does the activator is basically saying oh okay it's either active or it's not that's pretty simple inside the h mesh which is basically just the hair mesh right if i open this up we have exactly that and this is just a glorified version of what we just created again um we have the activator that's being sent this active node right into here and we're just sending it through a greater than so that way we don't get the weird scaling we just get an on or off pretty much a binary switch and we're sending it object coordinates so this is where it's containing the coordinates so our h mesh pretty much can take the place of all this so i can just get rid of all this here now and i just have an h mesh right we don't even need the activator we have the hair mesh now the hair mesh says are you active no or is it active yes and it's either 0 or 1. we want to send this value are you 0 or are you one and to do that we have this node the h master random so let me draw this out now we have this hair mesh right and we want to say okay we have one two three four five different haircuts and i want to randomly pick one of these haircuts to turn to to turn on on this character which means which means we want to randomly send one to one of the haircuts and zero to the rest right because we have this h mesh so we have five so say haircut number two will be turned on we want to send a signal of zero to the first one one to the second zero zero zero this is what you would consider a case or or a switch you want to send um one to one of these numbers and the way we're going to do that is we will set up a math node we'd have one math node a final math node and you want to think of this like a color ramp so take a look at this color ramp here if i were to add in our random node that we created and we'll just give it a random node of three for for the sake of this if i plug this random node in here we're going to say one fifth of the time one out of every five times here it's going to send a one so plug this color right into the h mesh here so as i start duplicating this over we're gonna randomly get one out of every five times this this mesh is going to show up see it's it's quite unlikely but as you change this number the the random ability of this comes the random ability of these appearing shows up so we want a way to control this a little better and unfortunately the color ramp does not have a node input for this position and i know you can set it up with a driver but i really just don't want to do that so we're going to make a manual color ramp so how do you make a red a manual color wrap well basically let's break down what is a color ramp 0.2 so right now i'm saying i'm sending it a value and if this value is greater than 0.2 it's going to be black or if it's less than 0.2 it's going to be white so we can do that so let's get a math note here and we'll say hey let's set i guess get a greater than let's start with a let's start with a less than if it is less than a certain threshold whatever that value is right so we get a value node and we'll say one div or we'll say 0.2 perfect if there's a value that's less than 0.2 it's going to return 1. if it's greater than 0.2 it's going to return 0. so right now this color wrap is exactly what this is doing now the problem with this is you have to actually think about this color ramp being able to move so whenever i do the next hairstyle down the line we really want this to look like point four point two oops four and this one being point two but the problem is now we have all this white space that now should be black you really want it to look like this now see how we've actually shifted this down the row one because each haircut is essentially going to sit into one of these slots one of these five slots however many divide it by so we have to factor that into this because otherwise just this less than we're really right now we really have this and we don't want that we want to have another space so we have to think okay so it's going to be less than 0.2 but greater than zero right or whatever this value is minus itself so this value 0.2 subtracted by itself which in this case is zero so i've combined these all together sweet now i know this is confusing but stay with me here basically we want to make an and gates we want to say when this is less than the num when this when this is less than this threshold but it's also greater than this threshold so just in this little window here when it's less than and when it's greater than which if this returns a one and this returns a one we want to do and which is a multiply so i want to multiply these together this is going to give us a basically an and gate so this multiplied by this is and and this is our our final output here this is going to say yes you are active in that case you are active i'll duplicate this again this is going to be our threshold here so we'll say 0.1 so i'll do ugly all these guys over here and we'll just stick with our original one all right now this is a very nitpicky thing but technically this side of the of the and gate is less than but this that has to be greater than or equal to which is not here so unfortunately we have to also make or equal to so if i were to duplicate this and i will make this one compare compare is equal to so we have to compare this value to this one which is the same as this greater than we're saying hey are these two equal with a with a with a wiggle room of nothing it has to be exactly equal if this is greater than or equal to or think about that as we or so another math operator or we would add them together that way we always get something if this is zero and this is zero neither of them it's going to return zero if one of them is it'll be zero plus one or one plus zero that's going to return a one if they're both it'll send a two but we can clamp this to be only zero or one it won't go above one so this is now effectively an or gate which i can rename or i can name this and so greater than or equal to and i can send this value into the end now so basically now we know that is this value on the bottom end of this exactly or higher than less than this oh baby this is really getting into the into the math isn't it all right so i'll shut this down here so why are we doing this well because we want to be able to shift this around for each one so this point two here why is this point two well this is because we have five haircuts and the likeliness of randomly selecting one of them is one out of five or point two which if you want to be more more jazzy about this we can delete this and we can add another math node we can plug this right in and we can do a divide and the likeliness is 1 divided by five or we name this value the number of hairstyles i'll just call this hairstyles so this is the number of hairstyles and i can plug this right in here and i can say hey we have five hairstyles this number is going to equally divide this color wrap into five portions or 0.25 say you decided to make six hairstyles well i can then do that and now it's going to equally divide this all the way down through but for the sake of ours we have five hairstyles why did i do this weird thing here where i said or it's greater than zero i mean look at it this is zero right it's this number subtracted by this it's one minus one right it's 0.2 minus 0.2 that's 0. why didn't i just plug 0 into there well it's because we needed the top part we needed another portion up here so the top part i like to multiply this top part by one right and this value here that we're multiplying by on the greater than is going to be which hairstyle is it so if it's the first hairstyle well then it's gonna be here right because it's zero but if it's the second hairstyle we actually take that point two and we times it by two and now it's point four right here so let's take a deeper look here okay so if it's hair hairstyle number one let me multiply it by well this thing sits here which really is just a bunch of math to get it back down to zero it's like doing the distance formula from zero comma zero to zero comma zero it's a lot of math just to get you to obviously zero but it's important if we know in the future we're going to be adding more factors into this which we are okay right we have five hairstyles so we have to be able to slide this thing around all all the way so on a base level right we're sending one divided by five which is point two over into this and we're saying hey times point two by one okay sweet we have point two still i get it we still have point two nothing nothing changed and now we have point two over here we're saying subtract point two by point two all right we have zero this is putting out zero right now so we did all this math just to get back to zero excellent why are you telling me this logan well here's why this value is our random this is the random thing we're sending to it okay so it's gonna check this and say hey is this does this random fall between 0 and well 0.2 right it's coming from here let's run this over we have 1 divided by 5 which is 0.2 going into the less than okay so is it less than point one is as one point one less than point two yes and point one is greater than or equal to it's greater than so that means it is true so that means yes we're gonna return a one and we're gonna say yeah it's active um so this is pretty much set up to go right we have the random value we're sending to it but there's still more we have to do here this number at the top this point two multiplied is actually what's going to be less than the reason we do that is because we're going to say oh if we're checking hairstyle 2 we have to now see that point one is is actually slid over right now it's point four let's check this guy it's point two well now it's in this range and point one doesn't sit in there it's gonna be from point two all the way to point four right so this is we're going to change that for haircut two so if now if it's haircut three suddenly point four to point six fits but the math always works the math always will work so we're in the right spot now and uh oh look what we just made we literally just made this h master random that's all this is it's the exact same thing we just made with with some exceptions here so i'll go over that here in a minute i'm going to take it away from this active from this h mesh now this h master random wants to know these values it wants to know hey how many uh how many hairstyles do you have total um we have five i'll plug that in right here it's gonna send that what what hairstyle are you looking at right now to do the random one well that would be one okay and what's the what's the the random seed you're gonna send it hey this is logan from the future just chiming in real quick i just want to clarify what's going on here so this random seed function here is actually going to replace this value up here that you put this is the randomizer so i never really went over this but basically you're going to want to replace this value here with that random node we made earlier and that's what's going to fit in so once you group this all together uh you'll want to plug the w from the random node so the random will be here going over this the w on the other side of the random is going to be going coming out of this random seed so you're going to have hairstyles total and then uh the hairstyle number you're on will come out of this one but i never really explained to that i just wanted to just wanted to throw that in so you understood actually what was happening here if i would update this random master right now i would go in here and we don't need this white this white noise or this because look at this do you know what this is we don't need a white noise or an object info because we already made this group earlier we made a random group right i can delete this guy and i can delete this guy and i can just plug in my random to the random seat the ham look at that so now we can change the random seed from outside of this so now you see that we've just made this exactly um so we have this whole thing right and i can move this all out of the way because realistically now all that is this this h master random that value is just this final and value saying is that mesh turned on and that is going to go right into this h mesh here right we're going to say yep you know what we have we've got five total meshes and we have and we're going to look at uh mesh two or three or four or five one of these five will always produce a one and the other four will always not produce that number let me add in so let's take a look at this an h master random and an h mesh well geez look at that we have this final random hairstyle and that's exactly what this is this is if i go into it it's just these two it's literally just these two um we have to though we have to open this up so because random hairstyle when we we have to only change the style number the rest has to stay the same across so the total styles has to say that stay the same across all the materials and the random seed has to stay the same because it wants to use the same random pattern and it wants to use the same number so this random pattern has to stay the same that's why we keep it inside this this random hairstyle and we're only changing which style we're looking at this is all we have to focus on right so we made we made a random hairstyle node right congrats to you because that was that was a tough one and inside that you made an h master random and you made an h mesh and you made an activator which the activator is just inside the h mesh so you have the activator inside the h mesh and then you have these two inside this one this here is the hierarchy we're looking at for the for the random hairstyle node okay all that math all right so how does it apply right well let's switch back over here so we're back in our main scene all right and we now have we have five different hairstyles right so let's look at this first of all for the balding i'll leave that alone for right now so we don't need these because they're all inside the random hairstyle so if you did that the hard part if you did it correctly and again if you couldn't follow along you can just download this directly from the link i provided in the video it's as easy as this we need to just drop in the random hairstyle so you would append it from whatever the blend file is that you have saved and you would grab this and just like an object going into edit mode tab into it and then we're going to look at these master variables here for the whole for the whole scene and we're going to say how many hairstyles do we have well in this case we have five and what random seed do you want let's just call this because the skin tone already used seed one we'll call this seed two remember it's important to change that random seed so we're not using the same pattern as the skin tone so i will go back out of this and now this this is ready to be used i can plug this directly into the material output one important thing to remember is make sure your gear your scale is equaled out otherwise you'll get weird things going on so the scale has to be at one for this to work so again just you'll just plug this guy directly in there and we're gonna say hey for balding this is hairstyle number one all right so i'll go over to the suave hairstyle and i'll shut this down and then i will grab a random hairstyle and i'll plug in the displacement and i'll say this is style number two and i'll grab buzz cut and i'll hide it up and i'll plug in a random hairstyle and say this is style number three i'll grab the flat top and i will random hairstyle plug it in and i'll say this is style number four and then slight bangs i will plug in a random hairstyle yet again and i'll say this is number five all right now look at that four out of five of these are disappeared right now and why is that well it's probably because the random value that this thing uh gave for this unique identifier was somewhere around three you know point uh 0.4 to 0.6 um and what's important here is if you look from this view you'll still see them all here because this is something you only get out of a rendered view alright so if i duplicate this around new new skin tone same haircut but as i keep duplicating these look i'm going to get a random haircut every time i duplicate it now i can still go and edit this so let's say the slight bangs so let's just put this displacement over here and we can say the um the slight bangs let's just give them a hair color about there maybe darken it up sure something like that um that's cool but maybe you know you also want the hair color to change right it's as simple as okay well let's do what we just did again on honest on easier level go into our groups here and we'll add in a random and we'll change the seed to three because our skin tone is one our hair style is two now the hair color will be three just remember which one you're going to use for each different thing search let's just do a color ramp and i can let's just add some hair colors in here so zero we have black there [Music] and then i like to you know the smaller the less room they have the less likely they'll come up so you can always just go through and um yeah at the very end here you can actually like add in some some unnatural like dyed hair colors like something like what's a hair color you probably wouldn't see often walking down the street but you might you know you just you just might so like a purple purpley hair maybe right just like there's a small chance that someone's going to have this hair color all right perfect if i hit f2 i can rename this hair colors perfect and since this is the seed for this i can just plug this value right in there and i will grab both of these here and i will plug first i'll plug it into the hair the base hair color now that's going to work for just the uh just the slate bangs because we have to affect all of them remember so we'll grab these here and we'll control g that and um i don't know that we need anything but we can't uh we don't no reason we can't change it later if we do back in here i will call this one random hair color perfect and that actually contains the seed already so i can just go through each of these flat top open this guy up and we'll enter groups we'll drop in a random hair color and just plug that right in here because remember we want to use the random color right because it has its own seed bolding open this up random hair color into the base color look at this guy we got a purple this guy's a got a purple haircut over here you know but it's not likely it's not likely is this buzz cut mr buzz cut over here it does not have one yet all right random hair color there we go i think that's all of them and look at that every time you can regenerate a new group of people let me save this remember to save so if i was going to redo this here i might make this this uh buzz cut a little closer to the head just because you know whatever but um you know this this is a random character generator right here and it's using different different randoms every time every new character i duplicate is going to be you know it's gonna be uh it's gonna be new that's that works for me for a crowd the cool thing is you can still animate these characters you can still give them shape keys you can still rig them even if you wanted to and that gets pretty intensive too but on on the on the renderer whenever you have a bunch of characters do a bunch of stuff but like that that doesn't look like there's one character that's exactly the same and i mean maybe in the front row but just to show you here um i can just open up this random hair color and i can just change this cd ever so slightly if you hold shift you know it changes the seat of these so it's like yeah let's see a different distribution of these but i actually liked where three was that was pretty cool um but yeah so you know that that's the tough part there with with so congrats to you for going through the tough part of actually actually making the the mesh the mesh sort of come in and out using the displacement but if you couldn't figure it out just yet it was a little too advanced for you totally cool totally cool feel free just to download it i've provided a link in the description to download the shader i've built so you don't have to think through it you can just use it and use it as an art tool so i really hope this helped you out i appreciate you watching and let me know if you want to go further with us with this random character generator stuff in the future there's so much we could cover with random character generation that i don't even you know this is the first place i began i don't want to say i don't know where to begin because i already began but uh you feel me you know so let's just maybe we'll go do a little more of these so thanks for watching if this helps you out subscribe leave a comment let me know what you thought and uh feel free to follow me on instagram at lgard53 elgard53 i'm posting animations over there and also my client works so uh yeah feel free to reach out dm me and all the good stuff so take care [Music] you
Info
Channel: FruitZeus
Views: 3,145
Rating: undefined out of 5
Keywords: Procedural Tutorial Blender 2.93, Blender 2.93 Procedural Tutorial, Blender 2.93 Procedural Characters, Blender 2.93 Procedural Random, Blender 2.93 Random Character Generator, Blender Procedural Character Randomizer, Procedural Character Randomizer, Random Character, Blender Randomize Characters, how to blender 2.93, how to make procedural characters, how to procedurally randomize characters, Blender Background Characters, Procedural Background Characters, Background Characters
Id: W3nsLYNY7z8
Channel Id: undefined
Length: 46min 21sec (2781 seconds)
Published: Sat Jul 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.