--- ip_noise_generator Set the noise generator for number of value patterns and normal perturbations The 'ip_noise_generator' keyword may be used with the scalar value patterns: agate, bozo, bumps, granite, marble, noise_cubed, spiral1, spiral2 and wrinkles. It may also be used with the noise perturbation: dents. Options: -------- The keyword should be followed by values of 1, 2 or 3. Defaults: --------- The default noise generator is (2), which is the range corrected (Skinner) version. Description: ------------ The available internal pattern (ip_) noise generators are: 1) The original, 0-1 clipping (Skinner) noise of POV-Ray prior to v3.5. 2) The range corrected (Skinner) noise which is the default since v3.5. 3) The Perlin (original method) noise generator. In most patterns / perturbations the noise generators are the basis for the pattern and always used. For a few patterns like spiral1 and spiral2 the noise generator is only used when an internal turbulence (it_frequency) is specified. Background noise :-) -------------------- An attempt to globally frame noise use in POV-Ray (yuqk). Disclaimer ---------- What follows is my current understanding of 'noise' as used within POV-Ray. There is code, but comments and documentation are thin. I sometimes don't completely believe the comments I do see given the behavior of the code. I've now been digging around in the code now more than 10 years and I've still not looked at all of what might be thought of as 'noise' related code. I better understand what I've coded up myself in the yuqk fork of POV-Ray, but there too, I'm often using C++ provided features which I understand only to some surface depth. Current noise types ------------------- Random number streams. Random number streams conforming to statistical distributions. One value smoothed noise. Three value smoothed noise. One value, turbulent (Brownian motion), noise. Three value, turbulent (Brownian motion), noise. Random number streams --------------------- This is the parse time seed() and random() mechanism. This functionality is built atop a hashing algorithm which takes as input a value and generates a 'random' output value based upon it. The hashing mechanism turns into 'random value stream' where the last generated value is used as the next input value to the hashing function. The values returned are usually constrained to a range, often [0..1], and reasonably random one value to the next. The yuqk fork adds the inbuilt functions: f_randn() - Hash based stream. Starting seed where you pick the returned value. Random sets of values per seed. f_hash() - Direct access to a hash function taking and returning doubles. Options, but the main aim is to give users direct access to the hash function. Create anything from random number streams, to extended cells like patterns and more. f_clock() - Virtual machine / on the fly 'now' like features and more. Note! Official releases of POV-Ray do NOT support 'now' use in functions at parse time and provides no means to get a Virtual Machine (VM) 'now' like value. The yuqk fork does support 'now' while setting up functions. The value is fixed to what it was when parsed as with any other parse time calculated constant. Random number streams conforming to statistical distributions ------------------------------------------------------------- Here the values are random from one to the next, but they conform to some statistical distribution via some post random stream treatment. The statistical shaping of values has traditionally been done with macros defined in include files like rand.inc. The yuqk fork adds the inbuilt function(s): f_distribution() - A collection of statistical distribution forcing methods. Random values as input - changed to fit some random distribution of values. f_popnrm_rnoise() - A very fast normalized random noise function. Uses x,y,z inputs by default, but one or more of those can be fixed values. Distribution well centered and balanced, but the method outputs random values to a distribution with obvious steps. One value smoothed noise ------------------------ Usually based upon Noise() in the base POV-Ray code(*). The generator used is selectable. Where CPU makers have provided custom code exploiting hardware features, Noise() is one of the functions which can been optimized. The smoothed forms of noise use some hash based stream of random values too, but as part of larger methods which include smoothing / gradient functions to produce the overall, more natural, result. The output values conform to a centered, sort of, normal / Gaussian result, but one which value wise is a bit rough(*). (*) - The yuqk fork fixed a, forever standing, center drift with omega value issue in this function! See: https://news.povray.org/povray.binaries.images/thread/%3C5ec57058%241%40news.povray.org%3E/?mtop=430642 The only direct access users have to Noise() is with: f_noise3d() - Calls Noise(). Values centered roughly at 0.5 in a 0..1 range. f_snoise3d() - Calls Noise(). Values centered at 0.0 in a -1..1 range. There is some indirect use and control by users of the noise generator used with certain patterns and features. The yuqk fork adds the inbuilt function(s): f_bump() - Calls Noise(). Features beyond bumps pattern. f_noise_cubed() - Calls Noise(). Experimental noise shaping features. Three value smoothed noise -------------------------- Internal to the POV-Ray code this usually the DNoise() function. There is no way to switch base noise generation method with it. Where CPU makers have provided custom code exploiting hardware features, DNoise() is one of the functions which has been optimized. Comments in the code indicate DNoise() (and DTurbulence which uses it) are Perlin noise based. Probably so, but I have no easy way to know looking at the code. What is important to remember the result is fixed with respect to noise generator settings. In some patterns this potentially confusing as with 'dents' where Noise() and DNoise() are used, but only the former function changes with the generator setting. The DNoise() functionality is used in many of the normal perturbations, but there is otherwise no direct user access. The yuqk fork plans to implement a f_dnoise() inbuilt function, but the work has yet to bubble to the top. One value, turbulent (Brownian motion), noise --------------------------------------------- Internal to the POV-Ray code this usually the Turbulence() function which uses Noise(). The Turbulence type noise is used in some value patterns with an ability to change the noise generator (ip_noise_generator). Also in fog{} and irid{} with (noise_generator). The yuqk fork adds the inbuilt function(s): f_turbulence() - Direct access to Turbulence(). Three value, turbulent (Brownian motion), noise ----------------------------------------------- Internal to the POV-Ray code this usually the DTurbulence() function which uses DNoise(). In POV-Ray there is direct access to DTurbulence() via the vturbulence() parse time Scene Description Language (SDL) function. It is DTurbulence() we use when when we specify turbulence via a warp{} or the stand alone turbulence keywords (the latter strongly discouraged). In this role DTurbulence is a spatial modifier. The yuqk fork adds the inbuilt function(s): f_dturbulence() - Direct access to DTurbulence(). General notes ------------- A) The yuqk fork differs from official releases of POV-Ray in being able to set the noise generator in all inbuilt functions using Noise() or Turbulence() internal code. Functions like f_noise() in yuqk have an extra parameter used for this purpose. In official releases of POV-Ray, the noise generator used in all functions is the range corrected Skinner version (2). B) When jitter is turned on, the yuqk fork returns POV-Ray (yuqk) to true random jitter for Anti-Aliasing (AA) in all three methods based upon the boost implementation of a Mersenne Twister random noise generator for doubles. See: https://en.wikipedia.org/wiki/Mersenne_Twister. The jitter can be made stable render to render by setting stochastic_seed= / +ss to a fixed seed value (the hint there is a hashing method therein). C) There is other noise use in the POV-Ray code which uses various methods. Much of it coming in the form of jitter specifications in area lights and such. D) There exists too some specialized random number sequences. Some, like that used with the official POV-Ray AA jitter (which is always on) and the crackle cache have been eliminated or replaced with more robust implementations. Some patterns such as cells and facets still use pre-calculated ranges of a random number stream. Indexes by starting seed / or simpler random index value are used for array accesses. There is too crand which use random values in each render. Expect I've forgotten half a dozen random number generator uses in the code as I write this. D) I don't think the absolute quality of the random noise generators matters that much in a ray tracing tool like POV-Ray. It cannot be bad, but decent is almost always good enough. Issues: ------- The yuqk for has yet to implement the f_dnoise() inbuilt function to access and return a DNoise() results by component value as full doubles or as a 3x 21 bit float encoded value. --- Yuqk changed the 'noise generator' keyword used with patterns / perturbations to 'ip_noise_generator'. Plus, it implements a 'noise_generator' keyword for fog{} and irid{} while deleting the global_settings{} noise_generator option. If an old scene didn't use 'noise_generator' and still does not, results are the same. If the previous 'noise_generator' use was in patterns or perturbations - and it still is - the noise generator results will be the same. If an old scene used the global_settings option, and set it to other than 2, all patterns / perturbations where the generator can be set, fog{} and irid{} will need to add 'ip_noise_generator' or 'noise_generator' settings which match the old global_settings value. True, if one wants to match noise dependent results. --- As mentioned elsewhere, the base Noise() function in the POV-Ray source code long had a distribution centering drift as the omega values changed. The yuqk fork fixed this issue. The fix sometimes ripples into rendered results. Where internal code could be adjusted to, more or less, match previous behavior - as with irid{} - that was done. The yuqk fork state: -------------------- 'ip_noise_generator' is new. Where useable: -------------- Only within Scene Description Language (SDL) during parsing. // SPDX-License-Identifier: CC-BY-SA-4.0