Fonctions aléatoires / bruit pour GLSL

179

Comme les vendeurs de pilotes GPU ne prennent généralement pas la peine de les implémenter noiseXdans GLSL, je suis à la recherche d'un ensemble de fonctions utilitaires "graphiques aléatoires couteau suisse" , de préférence optimisé pour être utilisé dans les shaders GPU. Je préfère GLSL, mais le code de n'importe quelle langue fera pour moi, je suis d'accord pour le traduire moi-même en GLSL.

Plus précisément, je m'attendrais à:

a) Fonctions pseudo-aléatoires - Distribution uniforme à N dimensions sur [-1,1] ou plus de [0,1], calculée à partir d'une graine à M dimensions (idéalement n'importe quelle valeur, mais je suis d'accord avec la restriction de la graine à, disons, 0..1 pour une distribution uniforme des résultats). Quelque chose comme:

float random  (T seed);
vec2  random2 (T seed);
vec3  random3 (T seed);
vec4  random4 (T seed);
// T being either float, vec2, vec3, vec4 - ideally.

b) Bruit continu comme Perlin Noise - encore une fois, N-dimensionnel, + - distribution uniforme, avec un ensemble de valeurs contraint et, eh bien, bonne apparence (certaines options pour configurer l'apparence comme les niveaux de Perlin pourraient également être utiles). Je m'attendrais à des signatures comme:

float noise  (T coord, TT seed);
vec2  noise2 (T coord, TT seed);
// ...

Je ne suis pas très intéressé par la théorie de la génération de nombres aléatoires, donc j'opterais avec impatience pour une solution pré-faite , mais j'apprécierais également des réponses comme "voici un très bon rand 1D efficace (), et laissez-moi vous expliquer comment faire un bon rand à N dimensions () dessus ... " .

Kos
la source

Réponses:

263

Pour des trucs pseudo-aléatoires très simples, j'utilise ce oneliner que j'ai trouvé sur Internet quelque part:

float rand(vec2 co){
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

Vous pouvez également générer une texture de bruit en utilisant le PRNG de votre choix, puis téléchargez-le de manière normale et échantillonnez les valeurs de votre shader; Je peux trouver un exemple de code plus tard si vous le souhaitez.

Consultez également ce fichier pour les implémentations GLSL de Perlin et Simplex noise, par Stefan Gustavson.

appas
la source
14
Comment l'utilisez vous vec2 co? est-ce la gamme? la graine?
Ross
12
Méfiez-vous des shaders de fragments à virgule flottante de faible précision avec cet algorithme (par exemple, ARM Mali de S3): stackoverflow.com/questions/11293628/… . Le projet github.com/ashima/webgl-noise ne semble pas avoir de problèmes de lowp.
PT
4
FWIW, la fonction décrite ici est discutée plus en détail ici .
Loomchild
3
FYI: La distribution de cette fonction est horrible.
Tara
3
Je suis nouveau dans GLSL, quelqu'un peut-il expliquer pourquoi co.xyest utilisé, au lieu de co?
kelin
83

Il me vient à l'esprit que vous pouvez utiliser une simple fonction de hachage d'entier et insérer le résultat dans la mantisse d'un flottant. IIRC, la spécification GLSL garantit des entiers non signés 32 bits et une représentation flottante binaire 32 IEEE, donc elle devrait être parfaitement portable.

J'ai fait un essai tout à l'heure. Les résultats sont très bons: il ressemble exactement à statique avec chaque entrée que j'ai essayée, aucun motif visible du tout. En revanche, l'extrait de code sin / fract populaire a des lignes diagonales assez prononcées sur mon GPU étant donné les mêmes entrées.

Un inconvénient est qu'il nécessite GLSL v3.30. Et bien que cela semble assez rapide, je n'ai pas quantifié empiriquement ses performances. L'analyseur de shader d'AMD revendique 13,33 pixels par horloge pour la version vec2 sur un HD5870. Contraste avec 16 pixels par horloge pour l'extrait de code sin / fract. C'est donc certainement un peu plus lent.

Voici ma mise en œuvre. Je l'ai laissé dans diverses permutations de l'idée pour faciliter la dérivation de vos propres fonctions.

/*
    static.frag
    by Spatial
    05 July 2013
*/

#version 330 core

uniform float time;
out vec4 fragment;



// A single iteration of Bob Jenkins' One-At-A-Time hashing algorithm.
uint hash( uint x ) {
    x += ( x << 10u );
    x ^= ( x >>  6u );
    x += ( x <<  3u );
    x ^= ( x >> 11u );
    x += ( x << 15u );
    return x;
}



// Compound versions of the hashing algorithm I whipped together.
uint hash( uvec2 v ) { return hash( v.x ^ hash(v.y)                         ); }
uint hash( uvec3 v ) { return hash( v.x ^ hash(v.y) ^ hash(v.z)             ); }
uint hash( uvec4 v ) { return hash( v.x ^ hash(v.y) ^ hash(v.z) ^ hash(v.w) ); }



// Construct a float with half-open range [0:1] using low 23 bits.
// All zeroes yields 0.0, all ones yields the next smallest representable value below 1.0.
float floatConstruct( uint m ) {
    const uint ieeeMantissa = 0x007FFFFFu; // binary32 mantissa bitmask
    const uint ieeeOne      = 0x3F800000u; // 1.0 in IEEE binary32

    m &= ieeeMantissa;                     // Keep only mantissa bits (fractional part)
    m |= ieeeOne;                          // Add fractional part to 1.0

    float  f = uintBitsToFloat( m );       // Range [1:2]
    return f - 1.0;                        // Range [0:1]
}



// Pseudo-random value in half-open range [0:1].
float random( float x ) { return floatConstruct(hash(floatBitsToUint(x))); }
float random( vec2  v ) { return floatConstruct(hash(floatBitsToUint(v))); }
float random( vec3  v ) { return floatConstruct(hash(floatBitsToUint(v))); }
float random( vec4  v ) { return floatConstruct(hash(floatBitsToUint(v))); }





void main()
{
    vec3  inputs = vec3( gl_FragCoord.xy, time ); // Spatial and temporal inputs
    float rand   = random( inputs );              // Random per-pixel value
    vec3  luma   = vec3( rand );                  // Expand to RGB

    fragment = vec4( luma, 1.0 );
}

Capture d'écran:

Sortie de random (vec3) dans static.frag

J'ai inspecté la capture d'écran dans un programme d'édition d'image. Il y a 256 couleurs et la valeur moyenne est de 127, ce qui signifie que la distribution est uniforme et couvre la plage attendue.

Spatial
la source
17
+1 pour une bonne idée et une mise en œuvre. Je remettrais en question l'affirmation selon laquelle, comme il y a 256 couleurs et que la valeur moyenne est de 127, la distribution doit être uniforme (au sens strict). C'est peut-être uniforme, mais je ne pense pas que nous le sachions encore. Par exemple, une distribution de courbe en cloche pourrait avoir la même moyenne et le même nombre de couleurs, mais ne serait pas uniforme.
LarsH
J'ai voté pour la raison donnée par @LarsH.
Autumnsault
Eh bien, c'est assez bon pour la plupart des applications qui n'ont pas besoin d' uniformité. :-)
itmuckel
5
Il me semble très uniforme, d'après ma perception de l'histogramme ... Je dirais que c'est assez bon pour la plupart des applications qui ont également besoin d'uniformité. (Les seules valeurs qui semblent être moins générées que les autres sont 0 et 255)
leviathanbadger
Merci. Ma probabilité est rouillée. Après avoir examiné le jeu d'instructions GCN, cela devrait être très rapide sur le matériel plus récent car ils prennent directement en charge les opérations de champ de bits dans leurs jeux d'instructions. Les tests que j'ai effectués se sont déroulés sur du matériel plus ancien.
Spatial
73

L'implémentation de Gustavson utilise une texture 1D

Non, pas depuis 2005. C'est juste que les gens insistent pour télécharger l'ancienne version. La version qui se trouve sur le lien que vous avez fourni utilise uniquement des textures 2D 8 bits.

La nouvelle version par Ian McEwan d'Ashima et moi-même n'utilise pas de texture, mais tourne à environ la moitié de la vitesse sur les plates-formes de bureau typiques avec beaucoup de bande passante de texture. Sur les plates-formes mobiles, la version sans texture peut être plus rapide car la texturation est souvent un goulot d'étranglement important.

Notre référentiel source activement maintenu est:

https://github.com/ashima/webgl-noise

Une collection des versions sans texture et utilisant la texture du bruit est ici (en utilisant uniquement des textures 2D):

http://www.itn.liu.se/~stegu/simplexnoise/GLSL-noise-vs-noise.zip

Si vous avez des questions spécifiques, n'hésitez pas à m'envoyer un e-mail directement (mon adresse e-mail se trouve dans les classicnoise*.glslsources.)

Stefan Gustavson
la source
4
Oui, l'implémentation à laquelle je fais référence, votre code sur davidcornette.com auquel @dep a lié, utilise une texture 1D: glBindTexture(GL_TEXTURE_1D, *texID);etc. Ce que vous entendez par "le lien que vous avez fourni" n'est pas clair, puisque vous citez ma réponse mais cette réponse n'était pas liée à votre implémentation. Je mettrai à jour ma réponse pour clarifier ce à quoi je fais référence et refléter les nouvelles informations que vous avez fournies. Qualifier les gens d '"insister" pour télécharger l'ancienne version est une distorsion qui ne vous fait pas honneur.
LarsH
1
PS Vous pouvez écrire à David Cornette (il a ses coordonnées sur davidcornette.com ) et lui demander de changer son lien sur davidcornette.com/glsl/links.html pour lien vers votre source. Je lui enverrai aussi un e-mail.
LarsH
1
PPS Pouvez-vous préciser quelle version utilise uniquement des textures 2D 8 bits? On dirait que cela pourrait être une bonne option pour certaines plates-formes ...
LarsH
31

Bruit d'or

// Gold Noise ©2015 [email protected]
// - based on the Golden Ratio
// - uniform normalized distribution
// - fastest static noise generator function (also runs at low precision)

float PHI = 1.61803398874989484820459;  // Φ = Golden Ratio   

float gold_noise(in vec2 xy, in float seed){
       return fract(tan(distance(xy*PHI, xy)*seed)*xy.x);
}

Voir Gold Noise dans votre navigateur dès maintenant!

entrez la description de l'image ici

Cette fonction a amélioré la distribution aléatoire sur la fonction actuelle dans la réponse de @appas au 9 septembre 2017:

entrez la description de l'image ici

La fonction @appas est également incomplète, étant donné qu'aucune graine n'est fournie (uv n'est pas une graine - même pour chaque image), et ne fonctionne pas avec des chipsets de faible précision. Gold Noise fonctionne à faible précision par défaut (beaucoup plus rapide).

Dominic Cerisano
la source
Merci d'avoir publié ceci. Envisageriez-vous de publier une version exécutable, par exemple sur shadertoy.com, afin que les gens puissent l'essayer dans le navigateur?
LarsH
@snb Shadertoy.com est en maintenance ce mois-ci, soyez patient. J'ai également clairement documenté l'exigence de valeurs de départ irrationnelles dans le code. Puisque le bruit d'or renvoie un scalaire, la construction de vecteurs avec lui est triviale et également documentée dans le code.
Dominic Cerisano
7
Je ne pense pas que ce soit différent des autres fonctions de bruit. quelle est votre preuve que cela a des propriétés spéciales. ce n'est pas parce que vous utilisez un tas de nombres irrationnels que cela est spécial.
M.kazem Akhgary
2
@Dominic: "Il a une distribution supérieure aux fonctions similaires": cela doit être prouvé. tan () est vraiment mal conditionné. tan () près de pi / 2 et sqrt () près de zéro sont très susceptibles de produire des résultats différents sur différents matériels puisque tous les fract (non linéaires * gros) sont basés sur des bits moins significatifs. Des valeurs d'entrée petites ou élevées auront également un impact. En outre, la dynamique des bits varie probablement beaucoup aussi en fonction des emplacements.
Fabrice NEYRET
2
NB: De nos jours, les GLSL ont des entiers, il n'y a donc plus aucune raison de ne pas utiliser des générateurs de hachage "sérieux" basés sur des int quand une distribution de qualité (et dynamique) est requise, avec des performances similaires. (sauf pour les appareils très bas de gamme).
Fabrice NEYRET
12

Il y a aussi une belle implémentation décrite ici par McEwan et @StefanGustavson qui ressemble au bruit de Perlin, mais "ne nécessite aucune configuration, c'est-à-dire pas de textures ni de tableaux uniformes. Il suffit de l'ajouter à votre code source de shader et de l'appeler où vous voulez".

C'est très pratique, d'autant plus que l'implémentation antérieure de Gustavson, à laquelle @dep était lié, utilise une texture 1D, qui n'est pas prise en charge dans GLSL ES (le langage shader de WebGL).

LarsH
la source
1
C'est la meilleure réponse à la demande de type de bruit b) OP! Voici un lien direct github.com/ashima/webgl-noise . Il existe des versions 2D, 3D et 4D prêtes en tant que code GLSL 120.
user362515
3

Utilisez ceci:

highp float rand(vec2 co)
{
    highp float a = 12.9898;
    highp float b = 78.233;
    highp float c = 43758.5453;
    highp float dt= dot(co.xy ,vec2(a,b));
    highp float sn= mod(dt,3.14);
    return fract(sin(sn) * c);
}

N'utilisez pas ceci:

float rand(vec2 co){
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

Vous pouvez trouver l'explication dans Améliorations du rand () canonique à une ligne GLSL pour OpenGL ES 2.0

hoangdado
la source
J'ai parcouru l'article mais je ne suis toujours pas sûr, est-ce que 3.14 est modune approximation de pi?
Kaan E.
2

Je viens de trouver cette version de bruit 3D pour GPU, sans aucun doute la plus rapide disponible:

#ifndef __noise_hlsl_
#define __noise_hlsl_

// hash based 3d value noise
// function taken from https://www.shadertoy.com/view/XslGRr
// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

// ported from GLSL to HLSL

float hash( float n )
{
    return frac(sin(n)*43758.5453);
}

float noise( float3 x )
{
    // The noise function returns a value in the range -1.0f -> 1.0f

    float3 p = floor(x);
    float3 f = frac(x);

    f       = f*f*(3.0-2.0*f);
    float n = p.x + p.y*57.0 + 113.0*p.z;

    return lerp(lerp(lerp( hash(n+0.0), hash(n+1.0),f.x),
                   lerp( hash(n+57.0), hash(n+58.0),f.x),f.y),
               lerp(lerp( hash(n+113.0), hash(n+114.0),f.x),
                   lerp( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);
}

#endif
compréhensible
la source
1
Gold Noise (ci-dessus) est alors évidemment le plus rapide, car il a beaucoup moins d'opérations et n'effectue qu'un seul hachage - celui-ci appelle sa fonction de hachage 8 fois, tout en effectuant des interpolations linéaires imbriquées (lerps). De plus, celui-ci a une distribution inférieure en particulier à faible précision.
Dominic Cerisano
1
Oh bon point, c'est un graphique de type bruit perlin de shadertoh par Inigo Quilez. Nice code Dominic ill check it l8r
com.prehensible
@Fabrice Vous ne semblez pas comprendre la question de l'OP, ma réponse, mon code ou mon commentaire .. Gold Noise est continu par la définition des OP - il accepte les uv et une graine et le prouve en fournissant un shader. Tout dans votre commentaire est faux. Vous continuez à confondre les fonctions de hachage avec les fonctions de bruit pseudo aléatoire. Ils ne sont pas les mêmes. Les fonctions Noise n'ont pas besoin de générer des identifiants uniques comme les fonctions de hachage (le point réel du hachage).
Dominic Cerisano le
S'il vous plaît s'il vous plaît, Dominic, lisez plus et apprenez-en plus avant de réclamer des choses sur des termes que vous pensez comprendre alors que ce n'est pas le cas. Non seulement ces termes sont totalement précis et bien définis dans la littérature, en plus je travaille sur le terrain, mais aussi l'OP prouve qu'il a compris les termes par les exemples qu'il a donnés après. Indice: "continu" + "bruit" + "comme Perlin". en.wikipedia.org/wiki/Perlin_noise
Fabrice NEYRET
Continu n'est qu'un cas d'ajout d'une clause de boucle, de nombreuses fonctions de bruit bouclent et se dégradent après une certaine manière en raison de l'arrondi de bits, en particulier pour les graphiques. Les gars, c'est juste une communication rompue avec vous, utilisez votre temps pour des recherches importantes.
com.prehensible
1

Une version droite et dentelée de 1d Perlin, essentiellement un zigzag lfo aléatoire.

half  rn(float xx){         
    half x0=floor(xx);
    half x1=x0+1;
    half v0 = frac(sin (x0*.014686)*31718.927+x0);
    half v1 = frac(sin (x1*.014686)*31718.927+x1);          

    return (v0*(1-frac(xx))+v1*(frac(xx)))*2-1*sin(xx);
}

J'ai également trouvé du bruit 1-2-3-4d perlin sur le site Web du tutoriel inigo quilez perlin du propriétaire de shadertoy, et voronoi et ainsi de suite, il a des implémentations et des codes rapides complets pour eux.

compréhensible
la source
1

hash: De nos jours, webGL2.0 est là, donc les entiers sont disponibles dans (w) GLSL. -> pour un hachage portable de qualité (à un coût similaire à celui des hachages flottants laids), nous pouvons maintenant utiliser des techniques de hachage "sérieuses". IQ en a implémenté certains dans https://www.shadertoy.com/view/XlXcW4 (et plus)

Par exemple:

  const uint k = 1103515245U;  // GLIB C
//const uint k = 134775813U;   // Delphi and Turbo Pascal
//const uint k = 20170906U;    // Today's date (use three days ago's dateif you want a prime)
//const uint k = 1664525U;     // Numerical Recipes

vec3 hash( uvec3 x )
{
    x = ((x>>8U)^x.yzx)*k;
    x = ((x>>8U)^x.yzx)*k;
    x = ((x>>8U)^x.yzx)*k;

    return vec3(x)*(1.0/float(0xffffffffU));
}
Fabrice NEYRET
la source
0

Veuillez voir ci-dessous un exemple comment ajouter du bruit blanc à la texture rendue. La solution est d'utiliser deux textures: le bruit blanc original et le bruit blanc pur, comme celui-ci: bruit blanc wiki

private static final String VERTEX_SHADER =
    "uniform mat4 uMVPMatrix;\n" +
    "uniform mat4 uMVMatrix;\n" +
    "uniform mat4 uSTMatrix;\n" +
    "attribute vec4 aPosition;\n" +
    "attribute vec4 aTextureCoord;\n" +
    "varying vec2 vTextureCoord;\n" +
    "varying vec4 vInCamPosition;\n" +
    "void main() {\n" +
    "    vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
    "    gl_Position = uMVPMatrix * aPosition;\n" +
    "}\n";

private static final String FRAGMENT_SHADER =
        "precision mediump float;\n" +
        "uniform sampler2D sTextureUnit;\n" +
        "uniform sampler2D sNoiseTextureUnit;\n" +
        "uniform float uNoseFactor;\n" +
        "varying vec2 vTextureCoord;\n" +
        "varying vec4 vInCamPosition;\n" +
        "void main() {\n" +
                "    gl_FragColor = texture2D(sTextureUnit, vTextureCoord);\n" +
                "    vec4 vRandChosenColor = texture2D(sNoiseTextureUnit, fract(vTextureCoord + uNoseFactor));\n" +
                "    gl_FragColor.r += (0.05 * vRandChosenColor.r);\n" +
                "    gl_FragColor.g += (0.05 * vRandChosenColor.g);\n" +
                "    gl_FragColor.b += (0.05 * vRandChosenColor.b);\n" +
        "}\n";

Le fragment partagé contient le paramètre uNoiseFactor qui est mis à jour à chaque rendu par l'application principale:

float noiseValue = (float)(mRand.nextInt() % 1000)/1000;
int noiseFactorUniformHandle = GLES20.glGetUniformLocation( mProgram, "sNoiseTextureUnit");
GLES20.glUniform1f(noiseFactorUniformHandle, noiseFactor);
Klimletov
la source
0

J'ai traduit une des implémentations Java de Ken Perlin en GLSL et l'ai utilisée dans quelques projets sur ShaderToy.

Voici l'interprétation GLSL que j'ai faite:

int b(int N, int B) { return N>>B & 1; }
int T[] = int[](0x15,0x38,0x32,0x2c,0x0d,0x13,0x07,0x2a);
int A[] = int[](0,0,0);

int b(int i, int j, int k, int B) { return T[b(i,B)<<2 | b(j,B)<<1 | b(k,B)]; }

int shuffle(int i, int j, int k) {
    return b(i,j,k,0) + b(j,k,i,1) + b(k,i,j,2) + b(i,j,k,3) +
        b(j,k,i,4) + b(k,i,j,5) + b(i,j,k,6) + b(j,k,i,7) ;
}

float K(int a, vec3 uvw, vec3 ijk)
{
    float s = float(A[0]+A[1]+A[2])/6.0;
    float x = uvw.x - float(A[0]) + s,
        y = uvw.y - float(A[1]) + s,
        z = uvw.z - float(A[2]) + s,
        t = 0.6 - x * x - y * y - z * z;
    int h = shuffle(int(ijk.x) + A[0], int(ijk.y) + A[1], int(ijk.z) + A[2]);
    A[a]++;
    if (t < 0.0)
        return 0.0;
    int b5 = h>>5 & 1, b4 = h>>4 & 1, b3 = h>>3 & 1, b2= h>>2 & 1, b = h & 3;
    float p = b==1?x:b==2?y:z, q = b==1?y:b==2?z:x, r = b==1?z:b==2?x:y;
    p = (b5==b3 ? -p : p); q = (b5==b4 ? -q : q); r = (b5!=(b4^b3) ? -r : r);
    t *= t;
    return 8.0 * t * t * (p + (b==0 ? q+r : b2==0 ? q : r));
}

float noise(float x, float y, float z)
{
    float s = (x + y + z) / 3.0;  
    vec3 ijk = vec3(int(floor(x+s)), int(floor(y+s)), int(floor(z+s)));
    s = float(ijk.x + ijk.y + ijk.z) / 6.0;
    vec3 uvw = vec3(x - float(ijk.x) + s, y - float(ijk.y) + s, z - float(ijk.z) + s);
    A[0] = A[1] = A[2] = 0;
    int hi = uvw.x >= uvw.z ? uvw.x >= uvw.y ? 0 : 1 : uvw.y >= uvw.z ? 1 : 2;
    int lo = uvw.x <  uvw.z ? uvw.x <  uvw.y ? 0 : 1 : uvw.y <  uvw.z ? 1 : 2;
    return K(hi, uvw, ijk) + K(3 - hi - lo, uvw, ijk) + K(lo, uvw, ijk) + K(0, uvw, ijk);
}

Je l'ai traduit de l'annexe B du chapitre 2 de Noise Hardware de Ken Perlin à cette source:

https://www.csee.umbc.edu/~olano/s2002c36/ch02.pdf

Voici une nuance publique que j'ai faite sur Shader Toy qui utilise la fonction de bruit affiché:

https://www.shadertoy.com/view/3slXzM

Parmi les autres bonnes sources que j'ai trouvées au sujet du bruit au cours de mes recherches, citons:

https://thebookofshaders.com/11/

https://mzucker.github.io/html/perlin-noise-math-faq.html

https://rmarcus.info/blog/2018/03/04/perlin-noise.html

http://flafla2.github.io/2014/08/09/perlinnoise.html

https://mrl.nyu.edu/~perlin/noise/

https://rmarcus.info/blog/assets/perlin/perlin_paper.pdf

https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch05.html

Je recommande vivement le livre des shaders car il fournit non seulement une excellente explication interactive du bruit, mais également d'autres concepts de shaders.

ÉDITER:

Pourrait être en mesure d'optimiser le code traduit en utilisant certaines des fonctions accélérées par le matériel disponibles dans GLSL. Mettra à jour ce post si je finis par faire cela.

Andrew Meservy
la source
aussi, je suis à peu près sûr que Perlin / Simplex Noise est toujours pseudo aléatoire. D'après ce que je me souviens, ce qui est intéressant, c'est que vous pouvez superposer et "zoomer" le bruit à différents niveaux pour le rendre très transparent. Ne me citez pas là-dessus, mais quelque chose à penser.
Andrew Meservy
@Zibri Malheureusement, je ne suis pas très familier avec les commandes C ou .sh. Mais il semble que la fonction soit simplement un générateur de nombres pseudo-aléatoires et non une fonction de bruit. Gardez également à l'esprit que les shaders de pixels glsl s'exécutent directement sur le GPU. Vous n'aurez accès à aucune de ces bibliothèques supplémentaires ou capacités de processeur qui pourraient être disponibles dans C.
Andrew Meservy
Le livre des shaders explique en quoi Simplex Noise est une version plus efficace de Perlin Noise en raison de l'inclinaison de la grille et des calculs moins nécessaires par point. Vaut vraiment le détour.
Andrew Meservy
voir aussi les chapitres sur le mouvement brownien fractal et la voronoise
Andrew Meservy
Andrew Meservy: aucune librairie nécessaire ... ma fonction noise est très simple: 2 entiers 64 bits sont l'état x (n) et x (n-1). La formule simple et rapide est x (n + 1) = ROTR ( x (n) + x (n-1), 8). si vous clonez mon git et l'exécutez, vous le verrez en action.
Zibri