Noise-Based RNG

  Переглядів 61,382

GDC

GDC

3 роки тому

In this 2017 GDC Math for Game Programmers talk, SMU Guildhall's Squirrel Eiserloh discuss RNGs vs. noise functions, and shows how the latter can replace the former in your math library and provide many other benefits (unordered access, better reseeding, record/playback, network loss tolerance, lock-free parallelization, etc.) while being smaller, faster, and easier to use.
Join the GDC mailing list: www.gdconf.com/subscribe
Follow GDC on Twitter: / official_gdc
GDC talks cover a range of developmental topics including game design, programming, audio, visual arts, business management, production, online games, and much more. We post a fresh GDC video every day. Subscribe to the channel to stay on top of regular updates, and check out GDC Vault for thousands of more in-depth talks from our archives.

КОМЕНТАРІ: 81
@kjpg7413
@kjpg7413 2 роки тому
Some super useful information here. Two pain points though: Perlin isn't good default to keep promoting for noise due to squareness, and Simplex/Perlin != Fractal noise. Squareness, or more generally visual anisotropy, runs principally counter to the nature-emulating goals of noise. Noise should look, to a reasonable degree, probabilistically the same in all directions. Simplex(-type) noise is better about that and, while mentioned in the talk, it was given an unfair backseat position. Fractal noise ("fractal Brownian motion" / fBm) is the process of adding together multiple layers of some base noise to produce the so-termed "crunchy" result. It's incredibly useful, but also worthwhile to understand as separate from any individual noise function. That way we can better convey the versatility of noise, and avoid invoking the name of a specific algorithm when we may not need to. Hash (integer "Noise") -> Smooth Noise (e.g. Simplex) -> Fractal Noise (+ many other formula options!), each a building block of the next. Once you move past this, this talk does a great job at covering important fundamentals.
@dotaportalvideo
@dotaportalvideo 3 роки тому
These are the videos I'm here for.
@ciberman
@ciberman 2 роки тому
Squirrel3 is at 44:34. And Squirrel3 with seed is at 51:52
@KKomalShashank
@KKomalShashank 2 роки тому
Squirrel Eiserloh was my game programming professor at SMU Guildhall. He was the best teacher I ever had. The most amazing person, who explained complex concepts in such a cool, interesting and easy-to-understand manner. Everyone has their No. 1 teacher that they remember fondly for the rest of their lives. For me, that teacher is Squirrel Eiserloh.
@yivo3689
@yivo3689 3 роки тому
Perfect timing~ That was a very impressive and detailed talk. I find it quite fascinating how RNG can be influenced, kinda predicted and willingly manipulated.
@VladyVeselinov
@VladyVeselinov 3 роки тому
I'm shaking, this is crazy good, thanks Squirrel!
@GameDevNerd
@GameDevNerd Рік тому
This was a huge help to me as a game/engine programmer and answered a lot of questions I had about this subject without spending many long months going down the rabbit hole of researching and implementing these things and then exhaustively unit testing them
@Sparrow420
@Sparrow420 3 роки тому
I love your talks man, great stuff!
@Kindred192
@Kindred192 3 роки тому
This makes the Factorio world generator make A LOT more sense (among other things). Thanks so much for this.
@skyblazeeterno
@skyblazeeterno Рік тому
good presentation - well thought out arguments for using noise
@FelixTang32
@FelixTang32 2 роки тому
Thank you for the talk!!
@brianviktor8212
@brianviktor8212 2 роки тому
I wanted to transition from generating all data and saving and loading it from a database to using procedural generation. I had to work on the ideal RNG and I created a tool to create many iterations of RNGs with different parameters. They were a mix of bitshift, XOR, XAND and algebra operations (it also had +/-/*) from which I created random and varying amounts, but also varying amounts of bitshift-masks generated from its own RNG, and evaluated them at the end. So I created samples, each contained 100 RNG with varying seeds (0 to 999, or randomly picked, or in steps of ~1000, etc). But I had a special criteria, besides the usual - the FIRST result of each seed had to be measured too. I created a normal version of it, a light version, and I created a BitScrambler - which had the purpose of taking in coordinates (x,y,z) and creating differing numbers. It is like a RNG, but always starting from its zero-state (it only takes the input into account). Imagine that the input 0,0,0; 0,0,1; 0,1,0; 1,0,0 all had to create different numbers (for seeds), and it might go up to thousands or millions. At the end I did a tiny twist and it improved the output by at least a factor of million. Some generated seeds were still increments to each other. Each identical starting seed would mean that a certain coordinate was generating the SAME content as another one. In my early tests with my procedural galaxy generation I had very weird patterns, sometimes even grid-like structures. Now, as I am finished with all this, my galaxy looks exactly the way I want. Btw, storing 10.000.000 solar systems with all planet and moon data required 5gb. Now I can not only have galaxies of basically any size, but also any amount of galaxies. My system for positions is precise up to meters or even better and can map the entire observable universe.
@juanchis.investigadorsonoro
@juanchis.investigadorsonoro Рік тому
Thanks for the presentation. 😀 00:00:00 Intro 00:02:00 Who is Squirrel Eiserloh? 00:02:30 What will we be talking about? 00:06:00 Talk Overview 00:06:30 What do we want in an RNG? 00:11:56 What RNGs should we consider? 00:19:20 Limitations of traditional RNGs 00:26:45 Noise functions 00:36:00 RNG-based Noise 00:46:30 Seeding Noise functions 00:47:35 Multidimensional Noise functions 00:50:18 Noise and RNG Takeaways
@legofan2284
@legofan2284 2 роки тому
This is great, not just for games
@Komagb
@Komagb 3 роки тому
That was intensely good!
@daveyhu
@daveyhu 2 роки тому
46:33 is the algorithm, also at 51:59
@barthpaleologue
@barthpaleologue Рік тому
This is awesome !
@Tesserakt8
@Tesserakt8 2 роки тому
Second time watching this video in 48 hours, it's that good.
@gilleswalther5964
@gilleswalther5964 3 роки тому
Super interesting
@juyas6381
@juyas6381 2 роки тому
52:00 not sure what the mistake is, but a prime should cleary end with a 1 in binary - BIT_NOISE1 does not - so its not actually a prime number - but like I heard from the talk, it is supposed to be at least.
@BradenBest
@BradenBest Рік тому
Put more simply: all primes (except 2) are odd, but not all odds are prime.
@StianF
@StianF Рік тому
None of them are prime numbers. I think he misspoke, I believe the objective of these numbers is to have "interesting bits" for a proper mangling process.
@bonehelm
@bonehelm Рік тому
I noticed the exact same thing and was very confused.
@danielrhouck
@danielrhouck 2 роки тому
This is very interesting, but I do want to point something out: the `std::hash` function is implementation-defined, and identity is completely compatible with the spec. I donʼt know if any implementations actually use it.
@vkessel
@vkessel 2 роки тому
If you parameterize the noise function by a seed, does that statistics suite account for different seeds? For example a noise function may work great at seed 0 but be highly correlated and fail tests at seed 255.
@ddotbuk
@ddotbuk 3 роки тому
Interestingly the new Unity Mathematics library uses a similar method.
@robbydomino
@robbydomino 3 роки тому
Does anyone know how much of his speed measurements translate well when the RNG function is implemented on the GPU? For example I suppose the PerlinHash at 41:48 is way faster on a GPU and does not get stuck on some L2 Cache misses. I have many GPU based noise function implemented in fragment shaders. But i have no good way of measuring there performance. So any advice is welcome. Also any recommendation on how you would assert the performance of a fragment shader is welcome. I know counting the raw instructions is a thing but that would take a lot of time and manual work.
@krisztianszendrodi7057
@krisztianszendrodi7057 3 роки тому
Why not just render a quad? First render it with a basic shader, just outputing white, measuring the render time. Run it for a 1000 frames, get the average time. With that you can run measure the time it takes for say a 1000 frames of random data , substract the first result from it and then you get the time for the noise without other factors like draw calls or any driver or dx/gl level code. Of course you have to divide with the resolution. Also the performance would differ greatly if the framebuffer is too small and much time taken outside of your fragment shader
@cargorunner9960
@cargorunner9960 2 роки тому
Fantastic tutorial. Most of it makes great sense. Would have been nice to have a clear definition of what the speaker means by "noise functions" at the start. By the end I think he is calling the MD5 function a noise function. Where as generally discussions about noise functions discuss gradient noise functions (smoothed random numbers). It is really critical in your code to know if your sequence of random numbers are totally random or smoothed.
@jonohiggs
@jonohiggs 2 роки тому
AFAIK in a discrete sampling they are random, the smoothness is just applied to make a continuous sampling without it looking like a step function
@Spillerrec
@Spillerrec 2 роки тому
The problem is that the speaker does not have a theoretical background in the subject (he mentions this himself), and just defines for himself that "noise functions" are RNG's that satisfies his requirement of being random access. I think he came up with that naming because he has been using perlin/simplex noise which tends to be implemented that way, as they have structure/correlation over time/position. Hash functions have entirely different design goals as well, so pretending a hash function is more like a "noise function" than a seeded RNG doesn't make sense, he appears to be biased here. The solution he presents here is probably quite good for procedural generation (and I will consider using it myself), but I would do a proper evaluation before just applying it for other random stuff.
@jonohiggs
@jonohiggs 2 роки тому
@@Spillerrec given the noise functions can be adapted to look like a noise function, then if the resulting sequence of numbers fulfils all the same statistical tests of randomness then I don’t see any reason not to think and use it like the other sources of random numbers. The ability to index into the sequence is actually super useful for Monte Carlo sims because if you have some degenerate case that breaks the model and need to debug then you don’t need to run the sim from the start but can just jump to that case directly (so long as the noise position is recorded and returned with the error reporting)
@Spillerrec
@Spillerrec 2 роки тому
@@jonohiggs I meant his Squirrel3() function specifically (and I guess the std::hash version as well), not the concept. He did some automated tests, but I wouldn't trust that he hasn't overlooked something or might have an insufficient test of randomness. (Or as he mentioned, that std::hash might not be consistent across implementations.) I'm just saying, don't just let this be the Mersenne Twister replacement that is used without any considerations. I fully agree that sequential algorithms like most RNGs aren't that desirable anymore, as we push for more and more parallelism.
@AltayHunter
@AltayHunter 2 роки тому
47:22 I'm disappointed to discover that he's wrong about std::hash being able to hash anything. In fact the code shown doesn't compile. std::hash is only defined with a single template argument, so the complier complains about the type std::hash.
@alexxkrehmen772
@alexxkrehmen772 2 роки тому
Great stuff here :) What would be the most efficient piece of code to convert this int function to return a random float between 0 and 1 inclusive ? (and keeping the balance of the results)
@vitorbalbino8024
@vitorbalbino8024 Рік тому
Once you get a value, knowing the min and max you can get, just make ( (result - min) / max ) + min.
@DaveLeCompte
@DaveLeCompte Рік тому
Do you really need the _most_ efficient? I would imagine that masking off 24 bits of a 32-bit random integer and jamming them into a float32's mantissa bits would be one of the faster ways to get a random float, no divides necessary. Depends on how expensive divides are on your machine.
@alexxkrehmen772
@alexxkrehmen772 Рік тому
@@DaveLeCompte In cases where you need to generates millions of random values quickly, the most efficient way seems appropriate 😅 Would you have an example of what your are describing please ?
@DaveLeCompte
@DaveLeCompte Рік тому
@@alexxkrehmen772 If you look up IEEE floating point representation, you can see that a single-precision 32-bit float has a big block of bits for the mantissa, which you could copy from the output of a 32-bit integer noise function to get what you want. Shifting bits is probably faster to execute (as opposed to a subtraction, a divide, and an add), but would take you longer to understand the underlying formats, which might not be an efficient use of your programming time. en.wikipedia.org/wiki/IEEE_754 en.wikipedia.org/wiki/Single-precision_floating-point_format If you're using a fixed-point representation, you probably already know how your bits are laid out, and might be even simpler than loading the significand in a floating point representation. Depends on the specifics of your system(s).
@alexxkrehmen772
@alexxkrehmen772 Рік тому
@@DaveLeCompte Ok thanks ! I'll try to dig into this 😁
@naphipps28219
@naphipps28219 3 роки тому
pcg-random is also a really nice family of random generators. Edit: I would recommend looking up the randutils gist from the same author to get pcg32 and pcg64 with fixed entropy. It’s super easy after that. Edit2: I made a gist that I think sums it all up nicely: gist.github.com/naphipps/9784df722d45c8e1bbe7108d182c466a Let me know if you have any questions. (I hope that link works!)
@fortesoft530
@fortesoft530 3 роки тому
I couldn't find the gist . Could you publish the link ?
@naphipps28219
@naphipps28219 3 роки тому
@@fortesoft530 UKposts's fighting me replying to comments, but I updated my original. Let me know if you have any questions!
@Alche_mist
@Alche_mist 2 роки тому
Godot Engine uses PCG32 as of now.
@Kakerate2
@Kakerate2 3 роки тому
16:00 17:30 27:40
@a1ivh
@a1ivh 3 роки тому
Maybe someone can help me out with this. How exactly the noise function providing the random access? Through position or seed? For example in the example has been mentioned, if you have multiple NPC with a set of characteristics then NPC id would be the position and characteristic id would be the seed, right? Or vise versa or I got it totally wrong?
@TechnoFreud
@TechnoFreud 2 роки тому
The random access comes from the "position." As long as each NPC has an ID that remains constant, you can use one noise generator (e.g. Squirrel3), use one seed to get tooth length, a different seed to get how far they slouch forward, etc. These seeds could be hard-coded if you want them to be the same each time, or randomly generated using e.g. Mersenne twister when the world is first created. You have to scale the minimum and maximum values in a way that makes sense, or you could transform how they are distributed if you want 10% of your orcs to have super long teeth. It's probably more intuitive to think of literal x,y,z positions generating the likelihood of a bush growing there, etc.
@quantumoverlord4413
@quantumoverlord4413 3 роки тому
I can pass my finals now :)
@MikePatterson8831
@MikePatterson8831 2 роки тому
Well, the std::hash code snippet doesn't work at all - it just returns the identical position it's fed. How is that at all useful for a random number generator? I don't want to have to feed a new string or object for every new random number. I don't really see how std::hash could be used in a similar way as the Squirrel3 method.
@tupoiu
@tupoiu Рік тому
I bet the guy at 55:48 was throwing off the smaller part of the multiple of the large prime, rather than the bigger part. If you do this, the process is equivalent to multiplying by a smaller non prime.
@LeDabe
@LeDabe 2 роки тому
I find quite strange that his Squirrel3 _and some other hashes_ are faster than the identity (aka increment an integer)
@LeDabe
@LeDabe 2 роки тому
See at 45:11 for instance. But this is not always the case for all is "benchmarks", depends on the slides..
@LeDabe
@LeDabe 2 роки тому
std::hash is generally implemented as "just return the given input integer". I don't know how he compiled his code, but I'd say that libc++ and libstdc++ and msvc have been implementing std::hash as just a return for a while now(forever ?), in this case it's a noop and the noise value returned should be bad (like his identity rng test). He may have cast the ints as bytes and ran std::hash on theses but that's not what he showed nor recommended.. Also, I'm not aware of std::hash taking 2 template arguments (47:22).
@LeDabe
@LeDabe 2 роки тому
A reason why most prng have state is that it prevents (or helps to prevent) backtracking resistance: csrc.nist.gov/glossary/term/Backtracking_Resistance . For gameplay related stuf its not necessary BUT it is as soon as you want a cryptographically sound system (dont encrypt your packets with FNV1a(incremented integer) key stream).
@tupoiu
@tupoiu Рік тому
​@@LeDabe They aren't. The only one that's faster is StackOverflow - which is admittedly very weird.
@StianF
@StianF Рік тому
44:32 He states "These are prime numbers", but none of them are. So what is the reason for this particular selection? As they're part of a larger set of operations of multiplication and bit shifting, is the purpose just to have "interesting bits"? If so, he just misspoke/misremembered, but then - what is considered "interesting bits"? And if not, then there's a pretty big issue with this code, for none of these numbers are prime numbers..
@jerrygreenest
@jerrygreenest 2 роки тому
Let's pray to RNG god for a second, for letting us make the PCG
@bonehelm
@bonehelm Рік тому
I don't think this should be called noise, since that term is usually attributed to "organized noise" algorithms such as simplex, voronoi, etc. His algorithm is more like a stateless RNG to me. As you can use his stateless RNG to generate simplex noise, etc. His argument, to me, boils down to stateless RNG is better than stateful RNG.
@punpckldqd4322
@punpckldqd4322 3 роки тому
Very good talk! Sadly, slides and code aren't available on mathforgameprogrammers.com/ (maybe author no longer maintains it, i dont know)
@Ziplock9000
@Ziplock9000 3 роки тому
@Luc Bloom Nobody said it was hard, it's just convenient to copy and paste or use a repo
@daveyhu
@daveyhu 2 роки тому
@Luc Bloom he's just tweeted this month that there's at least one flaw in his algorithm btw
@Svamenzi
@Svamenzi 2 роки тому
Didn't know that Ben Affleck got into gaming. :D Jk, great talk :)
@TheGreatAtario
@TheGreatAtario Рік тому
…The man's name is _Squirrel?_
@MrNotSpecified01
@MrNotSpecified01 3 роки тому
Who would have thought just getting some numbers could be so difficult. Is there anything truly random in the universe?
@AddGaming.
@AddGaming. 3 роки тому
yes. Quants. If you want some, there are simple python tutorials for accessing a companies quantum computer via API. just google it. "Qiskit" from IBM should be one of those
@icorbrey
@icorbrey 3 роки тому
@@AddGaming. Lmao we really be going RNGaaS
@MyCarllee
@MyCarllee 3 роки тому
It's real randomness in the quantum realm, at least as far as current science knows. Anything entangled with quantum phenomenon is truely random, like our consciousness.
@rafaelbordoni516
@rafaelbordoni516 2 роки тому
If there were no true randomness in the universe, that would mean our own thoughts and ideas aren't random, they're predetermined. On another level, if they are predetermined by a seed but we don't have access to it, then we can't predict things and thus, by definition, it makes them random. Weird stuff, huh? I guess if we could at least determine if things are random or seeded, then we could at least work towards getting the seed. I know it doesn't answer the question, but it has interesting and scary philosophical implications.
@petersmythe6462
@petersmythe6462 2 роки тому
Re: trillions+ becomes masturbatory? I kinda disagree. Let's say you have 10000 areas and you examine each area for 100000 cycles of the RNG? There's a near certain chance one of those 10000 areas will contain duplicate "terrain" to another for an RNG in the low trillions sort of repeat time.
@RiversJ
@RiversJ 2 роки тому
Errr... Compute shader the noise function?
@patrickj
@patrickj 3 роки тому
Not quite what I expected from the title, but the mention of a "noise function" kept me interested... and at the end slightly disappointed.
@unvergebeneid
@unvergebeneid 3 роки тому
In Soviet Russia, random numbers don't generate noise, noise generate random numbers.
@TomNCatz
@TomNCatz 3 роки тому
this is a better summary of the talk
@Ziplock9000
@Ziplock9000 3 роки тому
It's ironic that he talks about data not repeating itself when he repeats the same concepts over and over! Good talk though.
@pfeilspitze
@pfeilspitze 3 роки тому
TLDR ~~for the first 30 minutes~~: Use a hash function instead of a pRNG. You're welcome.
@thorham1346
@thorham1346 2 роки тому
I like how he thinks noise functions are near infinite 🤣
@beepboop9176
@beepboop9176 3 роки тому
Combing techniques of creating values out of nothing can create a lot of immersive experience. Minecraft was made based off noise generating math.
@Ziplock9000
@Ziplock9000 3 роки тому
Games have been using it 20-30 years before Minecraft.
@phlegios
@phlegios 3 роки тому
For 50 something minutes, one programmer boasts about how he managed to come up with a better hash function!
@gower1973
@gower1973 3 роки тому
Well that was a waste of an hour of my time the take away is use std::hash
@cm5754
@cm5754 3 роки тому
The C++ standard allows std::hash to return the input as the hash for the input.
30 Things I Hate About Your Game Pitch
37:37
GDC
Переглядів 1,5 млн
A House Built on Sand: Engineering Stable and Reliable AI
29:33
Лизка заплакала смотря видео котиков🙀😭
00:33
I PUT MY ARMOR ON (Creeper) (PG Version)
00:19
Sam Green
Переглядів 5 млн
Giving Personality to Procedural Animations using Math
15:30
t3ssel8r
Переглядів 2,3 млн
Something Strange Happens When You Follow Einstein's Math
37:03
Veritasium
Переглядів 6 млн
We should use this amazing mechanism that's inside a grasshopper leg
19:19
These Are The Avalanches To Worry About
25:04
Veritasium
Переглядів 308 тис.
Tech Toolbox for Game Programmers
48:14
GDC
Переглядів 248 тис.
No Time, No Budget, No Problem: Finishing The First Tree
31:42
Building Worlds in No Man's Sky Using Math(s)
53:52
GDC
Переглядів 97 тис.
Math for Game Programmers: Juicing Your Cameras With Math
31:34
Лизка заплакала смотря видео котиков🙀😭
00:33