-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Seeds #9
Comments
The "fake" way of doing this is to add a constant offset to one or |
This feature wish came from @pyalot so perhaps he can speak to the appropriateness of translating the sample window for his application. Perhaps a constant macro for permutation group offset would suffice? Macro parameters will soon be first-class module parameter constructs so this would give us A.) no cost and B.) easy parameterization once glol has been polished a bit more. The down-side is a new shader program for each seed+effect combination but this isn't too bad as A.) the seeds will probably be generated in an authoring tool for aesthetic sampling and B.) seed state transitions aren't smooth. How would you feel about the abstraction of the polynomial parameters into constant macros? |
I don't want to have to attach your whole preprocessor just to set a seed value.
|
I was not suggesting you do that. I was merely pointing out that macros can be dynamic with sufficient software. You may use your own pre-preprocessor or manually set the value. Please, answer Stefan's question: Can you elaborate on where a seed would be needed, and why
Why? The seeded permutation is a finite group. Is generating a new shader insufficient? Regardless, pre-preprocessors exist which can fulfill a symbolic dependency by either macro or uniform. The crucial aspect is the penalty-free abstraction for your (undeclared) application.
Directly in a single shader? What's the use case?
Where is this calculation? Why is the seed changing frequently? |
It doesn't matter, you don't have to understand why. The fact is that fix-compiled seeds are utter fucking crap period. |
You seem to have a problem with reading comprehension and professional communication. Seeding/initialization at each compilation stage (including run-time) is possible. Putting penalty-free methods into the distributed source gets us a common interface to noise parameters. Is there a reason that an offset to the input coordinates does not satisfy your use case? |
An offset into periodic noise is periodic. |
Yes, but the period is long and unnoticeable for the use cases I can Please understand that I am not being a pain, I seriously want to know. If you don't feel like explaining this more clearly to a person really wanting vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); by inserting the following line: p = permute(p + vec3(seed)); where 'seed' is an integer value (stored as a float for compatibility). p = permute(mod289(p + vec3(seed))); Quite a lot of extra computations compared to a simple offset, |
@stegu My beef is with dsheets not with you. I've had a lot of this kind of counterproductive conversations with him of the kind where he keeps asking "why" and I try to explain it and it goes nowhere. So him coming on with another of the "why why why" comments makes me see red all over. And secondly, I'm not asking for this. I've told dsheets that it would be handy, he choose to agree. I can live without a seed with your library, I have other noise sources that do what I need them to do. So consider this a service to you, not the other way around. And feel free to do or not do whatever you like. And if you prefer not to, that's fine. I can't make you not publish crap. That's up to you. So I'll explain it, this one time. A lot of noise cannot be used in realtime because of two reasons. The first reason is that sometimes the result has to be the same on every machine because it carries real meaning (such as terrain height in a game for instance). And the second reason is that sometimes you do things to noise (like convolution, sharpening, blurring or any other kind of kernel filter) that make it prohobitively expensive for instance:
That means that quite often you need to bake noise (or the result of the computation) into a texture. This however has one important problem. Unbounded noise goes on forever which is nice. But baked noise has borders (the texture size). If you render unbounded noise into a texture obviously the borders will not match up. This is fine in some cases, but in others where you'd like to use this noise to provide detail it is not. The only solution to reclaim some of the quality of noise (going on forever) is to repeat the texture. Now in order do that you need repeatable noise. And while the quality of repeatable noise may not be as nice as simplex noise, it makes it feasible to bake. So regarding the offset into the noise. The offset in repeatable noise is of course repeated. This has some nice qualities (you can choose a "soft" seed that'll wrap around) but it has some that are not so nice (you can't get a completely different pattern). For instance if you choose a size of 10x10 cells, then there's only 10 substantially different slices into that noise. Worse yet, any noise (any use you make of it) is the same, not just this one use. For artistic control it is quite often necessary to get entirely different patterns. If you only have 10 patterns to deal with and you combine them a lot, you will end up with very crappy results. So, a real seed is one necessary component of any real noise function. I didn't think this had to be explained, but apparently it has to be explained, to the people who want to do real noise functions. |
Thanks for the explanation. I understand your motivation perfectly now, and the change So you see, the use case really does matter a whole lot here, because it is not
I really think you generalize too far here, and promote your view as the only right one.
Hmm. Wouldn't that be just O(N_M_X) ? If not, what am I missing here? Anyway, thanks for the constructive input. |
I might have bungled that a little, but it is an exponential. Say you have a 16-tap kernel, so for discrete samples (N) it'll make 16 taps. So the runtime would be O(N*16). If you access this discrete sample with the next kernel it will make 16 taps for each discrete sample. Each of which will do 16 taps. So it's O(N_16_16). At 2 filters it's O(N_16_16_16) so the analytic runtime case is O(N_M^X). If each filters result is stored say for two filters, then the example would be O(N_M + N_M) for two filters, O(N_M + N_M + N_M) for three and so on. So the cached runtime case is O(N_M*X). If the produced result does not have to be changed in a frame, the runtime becomes O(1).
|
I see. Reading "filtering", I was assuming storage of dense sample sets from each step, basically I must say I am not really seeing when one would need to do such full-blown uncached analytic |
Successive filters are required if you do things like source -> erode -> blur -> flow -> sharpen etc. If the desire is for a gapless product on the borders then only repeatable sources can be used. An aperiodic source precludes usage in storing intermediary results and hence would force an analytic solution. |
I see what you mean, but I don't quite agree. Assuming yoy are rendering a bounded area of texels and that it can be meaningfully filtered with discrete convolution kernels, the function can still be sampled, stored as a texture during filtering and then scrapped. Wasteful, yes, but not exponential in complexity for many successive filters. But then again, I have no information on the exact conditions for the applications you have in mind. Anyway, now I should implement and test that seed argument... |
@pyalot reported "this is your periodic 2D noise layered in 10 octaves with a lacunarity of 2 and a gain of 1" http://codeflow.org/pictures/perlin.png vs. "this is a bicubically interpolated noise from a sin/dot random source with the same parameters" http://codeflow.org/pictures/bicubic-random.png "the noise is billowy (i.e. abs(n))" and "this artifact is not as apparent when using fbm octaves, although in your noise things seem to be more regularly distributed" via freenode #webgl IRC chan and speculated "it's possible this is the artifact of a lacking seed" due to "self-similarity degradation". |
Comparing 2D Perlin (gradient) noise to random value noise is not a This use case is actually the worst possible case for gradient noise. Just compare billowy noise abs(noise) and abs(noise+0.2) from a http://www.itn.liu.se/~stegu/aqsis/absnoisetest/noisetest_nooffset.jpg The difference is subtle at the code level, but the visual change is |
@stegu This conversation happened 3 years ago, so hoping for a response is admittedly a bit of a shot in the dark. I've successfully incorporated the integer seed using the process you suggested into the 3D noise function, giving me 289 unique noisefields. I'm generating a procedural galaxy, so planets must use a unique seed, as the periodicity is too small to use offsets. Eventually I'll replace this with a texture-lookup implementation if that proves faster, but having the ability to modify the seed from within my development environment (Unity) in real-time is invaluable. Anyway, perhaps unsurprisingly, the 289 unique seeds are insufficient, and so I naively attempted to implement the 'vector seed' idea you suggested.
This produces extreme artifacts, where the simplex grid is clearly visible: I expect this result is fully due to my naive implementation, and not your idea. If you're still around, would you mind elucidating how I might go about incorporating the vector seed? Either way, thank you to everyone here! |
@bfishman I used this project for my own procedural terrain modeler. I implemented the vector based seed, but I don't remember getting any artifacts. It's too long ago that I remember exactly what I did, but my changes are here: If you want to see for yourself, there are packages available for my project if you run windows or arch linux. |
@johanhelsing Thank you, but unfortunately I'm working with 3D noise. I implemented the exact same code as you did, in 2D, and it worked fine. But apparently this technique requires modification in 3D. I'm still reading through the pre-publication article and attempting to understand how the additional permutation actually works, mathematically, so hopefully will come to a solution on my own. In that case, I'll report back here for posterity. But any hints from @stegu would be greatly appreciated!! |
Quick update: The following code seems to work.. although I haven't figured out a way to rigorously test all of the combinations. I'm not convinced that it's functioning as intended, although the artifacts are gone:
|
I'm late to the party here, but I see you managed quite well without me.
Thanks for your input! Your implementation seems to work as intended.
I haven't figured out a way to rigorously test all of the combinations.
You're definitely not alone. When you increase the dimensionality of the
parameter domain and/or the support domain, it becomes downright impossible
to actually test every part of it. The pragmatic approach used by most
people in computer graphics is "If it seems to work for a bunch of randomly
picked cases, it's probably OK". Spectral properties of pseudo-random
functions are particularly difficult to test.
|
It's not important that every random seed produces a good result. However, it is important that at least half of them do. You don't want to end up in a situation where a user has to mash the "new seed" button 20x to get a good alternative seed. But mashing it two or three times is ok. |
@pyalot Maybe in your specific use case it's not important. For me, however, that's not the case. I work on procedural content generation for games (no human author involved). Imagine if half of all started games looked like crap. |
I'm in the same boat as @johanhelsing - my use case is that of entirely procedural content generation (at runtime), with no option for human filtering. But what is more important to me than 'good looking' noise, personally, is stability and variety. As long as the algorithm produces a noise field whose output remains bounded within the expected range, which is continuous in the 0th, 1st, and 2nd derivative, and where each seed is different than 99.9% of other seeds: even if the differences between unique seeds are generally small to minute - if it meets these criteria, I'm a happy coder. At that point, I'll count on my hybrid multi fractals and other noise shaping algorithms to chaotically expand upon those minute differences to produce satisfyingly different terrains. But as the idiom goes, garbage in, garbage out. @stegu Thanks for checking in to help validate the technique. And, of course, thanks for your work in the first place :) your presentation of the simplex noise algorithm (and subsequent textureless variant) is so much more approachable the Mr. Perlin's, and is no doubt responsible for its widespread adoption (although I still see people starting modern projects using the first version of Perlin Noise... It boggles..) |
I'll be posting the code in complete form soon, also incorporating gradient calculation. Is @ijm or anyone else from Ashima around? I'd be happy to make a PR, or I could create a new project entirely if that's preferred. Standing by for now. |
Please keep me in the loop! On Friday, January 15, 2016, bfishman notifications@github.com wrote:
|
Maybe I'm missing something, why not use 4d noise? Where the button On Friday, January 15, 2016, John Davis jdavis@pcprogramming.com wrote:
|
4D noise is much more computationally expensive than using 3D noise with a seed. |
In that case, probably best to fork. On Friday, January 15, 2016, bfishman notifications@github.com wrote:
|
Seeing how this thread is still very informative and discusses some optional and potentially useful changes which have not been incorporated into the versions in the repository, I am keeping it open, despite some very insulting and rude comments in the thread. |
I added p = permute(p + vec3(289 * stroke_number)); |
That's... brittle. Different offsets will create different patterns, some
of which might be "bad" because of correlation.
If it works, fine, but I would test the crap out of it before trusting the
code, i.e. display all 289 variations and make sure there are no uglies in
there.
Also, you should use floor() on that mult with 289. The permutation
polynomial fails to work as intended if the input is not an integer, and
allowing for an arbitrary fractional part in the seed makes it impossible
to test all outcomes.
Den lör 29 juli 2023 21:22Clive McCarthy ***@***.***> skrev:
… I added p = permute(p + vec3(289 * *stroke_number*));
where *stroke_number* is a random number between 0.0 and 1.0 that I pass,
via a uniform, to my shader generated by Intel's RDRAND CPU based random
number generator:
https://www.intel.com/content/www/us/en/developer/articles/guide/intel-digital-random-number-generator-drng-software-implementation-guide.html
It seems to do what I want.
—
Reply to this email directly, view it on GitHub
<#9 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFGK2XH4GCWJGCS4LLKJ7DXSVPG3ANCNFSM4ACX4CSA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
And, of course, to maintain maximum compatibility with all versions of
GLSL, "289" should be "289.0". Unimportant on most platforms, but still
required on some.
|
Thank you Stephan, |
Thanks for the information! Always nice to hear how people find creative
uses for noise. With some "soft" thresholding using a smoothstep()
function, I think noise would be good for creating that "wiped-off" look.
The size of the noise blobs would correspond to the size of the rag, or
rather the hand holding the rag. With some stretching of the noise, perhaps
even along slanted and slightly curved lines to make it look like someone
right-handed did the wiping, it could probably create a good illusion.
If you feel like experimenting with assistance from others, I recommend
Shadertoy. You can find me there under the same name as here on Github,
i.e. "stegu", but I might need a heads-up here to see your posts there. I'm
slow and sleepy from post-Covid, so I'm not very active on Shadertoy at the
moment.
|
Provide a means to seed noise generators
The text was updated successfully, but these errors were encountered: