GLSL için rastgele / gürültü fonksiyonları


179

GPU sürücü satıcıları genellikle noiseXGLSL'de uygulama zahmetine girmediği için , tercihen GPU gölgelendiricileri içinde kullanılmak üzere optimize edilmiş bir "grafik rasgeleleştirme swiss army bıçağı" yardımcı işlev seti arıyorum . GLSL'yi tercih ederim, ancak herhangi bir dilin benim için yapacağını kodlayın, kendi başıma GLSL'ye çevirmek için sorun yok.

Özellikle, beklediğiniz:

a) Yalancı rasgele fonksiyonlar - M-boyutlu tohumdan hesaplanan (ideal olarak herhangi bir değer olmakla birlikte, [1,1] veya [0,1] üzerinde N-boyutlu, muntazam dağılım, ancak tohumun kısıtlanması ile sorun değil mesela, muntazam sonuç dağılımı için 0..1). Gibi bir şey:

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) Perlin Gürültüsü gibi sürekli gürültü - yine, N-boyutlu, + - tekdüze dağılım, kısıtlı değerler seti ve iyi görünümlü (Perlin seviyeleri gibi görünümü yapılandırmak için bazı seçenekler de yararlı olabilir). Şunlar gibi imzalar beklerdim:

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

Rastgele sayı üretme teorisine çok fazla girmiyorum, bu yüzden önceden hazırlanmış bir çözüm için hevesle giderdim , ancak "burada çok iyi, verimli bir 1D rand () gibi cevapları takdir ediyorum ve açıklamama izin verin üstüne iyi bir N-boyutlu rand () nasıl yapılır ... " .

Yanıtlar:


264

Çok basit yalancı görünümlü şeyler için, internette bir yerde bulduğum bu oneliner'ı kullanıyorum:

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

İstediğiniz PRNG'yi kullanarak bir gürültü dokusu oluşturabilir, ardından bunu normal şekilde yükleyebilir ve gölgelendiricinizdeki değerleri örnekleyebilirsiniz; İsterseniz daha sonra bir kod örneği kazabilirim.

Ayrıca, Stefan Gustavson'un Perlin ve Simplex gürültüsünün GLSL uygulamaları için bu dosyaya göz atın.


14
Nasıl kullanılır vec2 co? aralık mı? tohum?
Ross

12
Bu algoritma ile düşük hassasiyetli kayan noktalı parça gölgelendiricilere dikkat edin (örn. S3'ün ARM Mali): stackoverflow.com/questions/11293628/… . Github.com/ashima/webgl-noise proje konularını lowp sahip görünmemektedir.
PT

4
FWIW, fonksiyon burada tarif edilen daha ayrıntılı olarak ele alınmıştır burada .
Loomchild

3
FYI: Bu işlevin dağılımı korkunç.
Tara

3
GLSL'de yeniyim, kimse neden co.xyyerine kullanıldığını açıklayabilir comi?
kelin

83

Bana basit bir tamsayı karma fonksiyonu kullanmak ve sonucu bir şamandıra mantis içine ekleyebilirsiniz. IIRC GLSL özellikleri 32-bit işaretsiz tam sayıları ve IEEE binary32 float gösterimini garanti eder, bu yüzden mükemmel taşınabilir olmalıdır.

Bunu şimdi denedim. Sonuçlar çok iyi: Denediğim her girişte tam olarak statik gibi görünüyor, görünür bir desen yok. Aksine, popüler sin / fract snippet'i, aynı girdiler verildiğinde GPU'mdaki çapraz çizgileri oldukça telaffuz etti.

Bir dezavantajı GLSL v3.30 gerektirmesidir. Ve yeterince hızlı görünse de, performansını ampirik olarak ölçmedim. AMD'nin Shader Analyzer'ı, bir HD5870'teki vec2 sürümü için saatte 13,33 piksel olduğunu iddia ediyor. Sin / fract snippet'i için saatte 16 piksel kontrast. Bu yüzden kesinlikle biraz daha yavaş.

İşte benim uygulama. Kendi işlevlerinizi türetmeyi kolaylaştırmak için fikrin çeşitli permütasyonlarında bıraktım.

/*
    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 );
}

Ekran görüntüsü:

Static.frag dosyasında rasgele (vec3) çıktı

Bir görüntü düzenleme programındaki ekran görüntüsünü inceledim. 256 renk vardır ve ortalama değer 127'dir, yani dağılım eşittir ve beklenen aralığı kapsar.


17
İyi bir fikir ve uygulama için +1. 256 renk olduğu ve ortalama değerin 127 olduğu için, dağılımın tekdüze olması gerektiği (katı anlamda) olduğu iddiasını sorgulayacağım. Tek tip olabilir, ama henüz bildiğimizi sanmıyorum. Örneğin, bir çan eğrisi dağılımı aynı ortalama ve renk sayısına sahip olabilir, ancak tekdüze olmaz.
LarsH

@LarsH tarafından verilen nedenden dolayı bu oyu kullandı.
Autumnsault

Tekdüzeliğe ihtiyaç duymayan çoğu uygulama için yeterince iyi . :-)
itmuckel

5
Histogram algımla çok düzgün görünüyor ... Tekdüzeliğe ihtiyaç duyan çoğu uygulama için de yeterli olduğunu söyleyebilirim. (Diğerlerinden daha az üretilmiş gibi görünen tek değerler 0 ve 255'tir)
leviathanbadger

Teşekkürler. Benim ihtimalim paslı. GCN komut setine baktığımızda, bu yeni donanımlarda çok hızlı olmalıdır çünkü talimat setlerinde bitfield işlemlerini doğrudan desteklerler. Yaptığım testler daha eski bir donanıma dayanıyordu.
Mekânsal

73

Gustavson uygulaması 1D doku kullanıyor

Hayır öyle değil, 2005'ten beri değil. Sadece eski sürümü indirmekte ısrar ediyorlar. Sağladığınız bağlantıdaki sürüm yalnızca 8 bit 2B dokular kullanır.

Ashima ve ben Ian McEwan'ın yeni sürümü bir doku kullanmıyor, ancak çok fazla doku bant genişliğine sahip tipik masaüstü platformlarında yaklaşık yarı hızda çalışıyor. Mobil platformlarda, tekstüre olmayan sürüm daha hızlı olabilir, çünkü tekstüre etme genellikle önemli bir darboğazdır.

Aktif olarak muhafaza edilen kaynak havuzumuz:

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

Gürültünün hem dokusuz hem de doku kullanan sürümlerinin bir koleksiyonu burada (sadece 2B dokular kullanılarak):

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

Herhangi bir sorunuz varsa, doğrudan bana e-posta göndermekten çekinmeyin (e-posta adresim classicnoise*.glslkaynaklarda bulunabilir.)


4
Evet, bahsettiğim uygulama, @dep'nin bağlı olduğu davidcornette.com'daki kodunuz 1D doku kullanıyor: glBindTexture(GL_TEXTURE_1D, *texID);vb . Cevabımdan alıntı yaptığınızdan, "sağladığınız bağlantı" ile ne demek istediğinizi açık değil ancak bu yanıt uygulamanızla bağlantılı değildi. Ne bahsettiğimi netleştirmek ve verdiğiniz yeni bilgileri yansıtmak için cevabımı güncelleyeceğim. İnsanları eski sürümü indirmede "ısrar" olarak nitelendirmek, size kredi vermeyen bir bozulmadır.
LarsH

1
Not: David Cornette'e yazmak isteyebilir ( davidcornette.com'da iletişim bilgileri vardır ) ve kaynak deponuza bağlanmak için davidcornette.com/glsl/links.html adresindeki bağlantısını değiştirmesini isteyebilirsiniz . Ben de ona e-posta göndereceğim.
LarsH

1
PPS Hangi sürümde yalnızca 8 bitlik 2D dokular kullanıldığı netleştirilebilir mi? Bazı platformlar için iyi bir seçenek olabilir gibi görünüyor ...
LarsH

31

Altın Gürültü

// Gold Noise ©2015 dcerisano@standard3d.com
// - 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);
}

Tarayıcınızda şu anda Altın Gürültüyü görün!

resim açıklamasını buraya girin

Bu işlev, 9 Eylül 2017 itibarıyla @appas'ın cevabındaki mevcut işlev üzerinde rastgele dağılımı geliştirdi:

resim açıklamasını buraya girin

@Appas işlevi de eksiktir, çünkü sağlanan tohum yoktur (uv bir tohum değildir - her çerçeve için aynıdır) ve düşük hassasiyetli yonga setleriyle çalışmaz. Altın Gürültü varsayılan olarak düşük hassasiyetle çalışır (çok daha hızlı).


Bunu gönderdiğiniz için teşekkürler. Çalıştırılabilir bir sürüm yayınlamayı düşünür müsünüz, örneğin shadertoy.com'da, insanlar tarayıcıda deneyebilir mi?
LarsH

@snb Shadertoy.com bu ay bakım görüyor, biraz sabırlı olun. Ayrıca buradaki kodda irrasyonel tohum değerleri gereksinimini açıkça belgeledim. Altın gürültüsü bir skaler döndürdüğü için, onunla vektörlerin oluşturulması önemsizdir ve ayrıca kodda belgelenmiştir.
Dominic Cerisano

7
Bunun diğer gürültü işlevlerinden farklı olduğunu düşünmüyorum. bunun özel özelliklere sahip olduğunu kanıtlayan nedir? bir sürü irrasyonel sayıyı kullanmanız onu özel kılmaz.
M.kazem Akhgary

2
@Dominic: "Benzer fonksiyonlara üstün dağılımı vardır": bunun kanıtlanması gerekir. tan () gerçekten kötü durumda. her tan (doğrusal olmayan * büyük) daha az anlamlı bitlere dayandığından, pi / 2 yakınında tan () ve sıfıra yakın sqrt () farklı donanımlarda farklı sonuçlar üretme olasılığı yüksektir. Küçük veya yüksek giriş değerleri de onu etkileyecektir. Ayrıca, bit dinamikleri konumlara bağlı olarak muhtemelen çok değişir.
Fabrice NEYRET

2
Not: Günümüzde GLSL'nin tamsayıları vardır, bu nedenle benzer performanslarla kalite dağılımı (ve dinamikleri) gerektiğinde "ciddi" int tabanlı karma jeneratörleri kullanmamaya gerek yoktur. (çok düşük uçlu cihazlar hariç).
Fabrice NEYRET

12

Burada McEwan ve @StefanGustavson tarafından Perlin gürültüsüne benzeyen güzel bir uygulama var , ancak "herhangi bir kurulum gerektirmiyor, yani dokular veya tek tip diziler gerektirmiyor. Sadece gölgelendirici kaynak kodunuza ekleyin ve istediğiniz yere çağırın".

Gustavson'ın @dep ile bağlantılı olan önceki uygulamasının GLSL ES'de ( WebGL'nin gölgelendirici dili) desteklenmeyen bir 1D dokusu kullandığı göz önüne alındığında bu çok kullanışlıdır .


1
Bu OP'nin b) gürültü tipi talebine en iyi cevaptır! İşte doğrudan bağlantı github.com/ashima/webgl-noise . GLSL 120 kodu olarak hazır 2d, 3d ve 4d versiyonları vardır.
user362515

3

Bunu kullanın:

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);
}

Bunu kullanma:

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

Açıklamayı OpenGL ES 2.0 için standart tek katmanlı GLSL rand () geliştirmeleri bölümünde bulabilirsiniz.


Makaleyi gözden kaçırdım ama hala emin değilim, 3.14 modpi yaklaşık mı?
Kaan E.

2

Sadece GPU için 3d gürültünün bu sürümünü buldum, alledgedly mevcut olan en hızlı olanı:

#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

1
Altın Gürültü (yukarıda), daha az operasyona sahip olduğu ve sadece bir karma gerçekleştirdiği için açık bir şekilde en hızlıdır - bu, iç içe doğrusal enterpolasyonlar (lerps) yaparken, karma işlevini 8 kez çağırır. Ayrıca bu özellikle düşük hassasiyette düşük bir dağılıma sahiptir.
Dominic Cerisano

1
Oh iyi bir nokta, Inigo Quilez tarafından shadertoh bir perlin gürültü türü grafik. Güzel kod Dominic ill l8r kontrol
com. Anlaşılabilir

@Fabrice OP'nin sorusunu, cevabımı, kodumu veya yorumumu anlamıyorsunuz .. Altın Gürültü OP tanımıyla süreklidir - uv ve bir tohumu kabul eder ve bir gölgelendirici sağlayarak kanıtlar. Yorumunuzla ilgili her şey yanlış. Karma işlevlerini sahte rasgele gürültü işlevleriyle karıştırmaya devam edersiniz. Aynı değiller. Gürültü işlevlerinin, karma işlevleri (gerçek karma işleminin tam noktası) gibi benzersiz tanımlayıcılar oluşturma gereği yoktur.
Dominic Cerisano

Lütfen lütfen, Dominic, durum böyle değilken anladığınızı düşündüğünüz terimler hakkında bir şeyler talep etmeden önce daha fazla bilgi edinin ve daha fazla bilgi edinin. Literatürde sadece bu terimler tam olarak kesin değildir ve iyi tanımlanmıştır, aynı zamanda sahada çalışıyorum, aynı zamanda OP, terimleri daha sonra verdiği örneklerle anladığını kanıtlıyor. İpucu: "sürekli" + "gürültü" + "Perlin gibi". en.wikipedia.org/wiki/Perlin_noise
Fabrice NEYRET

Sürekli, bir döngü yan tümcesi ekleme durumudur, birçok gürültü işlevi, özellikle grafikler için bit yuvarlama nedeniyle belirli bir yoldan sonra döngü ve bozulma gösterir. Beyler, sadece sizden bir iletişim kopuşu, zamanınızı önemli araştırmalar için kullanın.
com. Anlaşılır

1

1d Perlin'in düz, pürüzlü bir versiyonu, aslında rastgele bir lfo zikzak.

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);
}

Ben de shadertoy sahibi inigo quilez perlin eğitim web sitesinde 1-2-3-4d perlin gürültü bulduk ve voronoi ve böylece, onlar için tam hızlı uygulamaları ve kodları var.


1

hash: Günümüzde webGL2.0 var, bu yüzden (w) GLSL'de tamsayılar mevcut. -> kalite taşınabilir karma için (çirkin float karma benzer maliyetle) artık "ciddi" karma teknikleri kullanabilirsiniz. IQ, https://www.shadertoy.com/view/XlXcW4 (ve daha fazlası)

Örneğin:

  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));
}

0

Aşağıda, oluşturulan dokuya beyaz parazitin nasıl ekleneceğine ilişkin bir örneğe bakın. Çözüm iki doku kullanmaktır: orijinal ve saf beyaz gürültü, bunun gibi: wiki beyaz gürültü

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";

Paylaşılan parça, her uygulamada ana uygulama tarafından güncellenen uNoiseFactor parametresini içerir:

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

0

Ken Perlin'in Java uygulamalarından birini GLSL'ye çevirdim ve ShaderToy'daki birkaç projede kullandım.

Yaptığım GLSL yorumu aşağıdadır:

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);
}

Bu kaynaktaki Ken Perlin'in Gürültü Donanımının 2. Bölümünden Ek B'den tercüme ettim:

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

İşte yayınlanan gürültü işlevini kullanan Shader Toy üzerinde yaptığım genel bir gölge:

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

Araştırmam sırasında gürültü konusunda bulduğum diğer bazı iyi kaynaklar:

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

Gölgelendiricilerin kitabını tavsiye ederim, çünkü sadece gürültünün harika bir interaktif açıklaması değil, diğer gölgelendirici kavramları da sunar.

DÜZENLE:

Çevrilmiş kodu, GLSL'de bulunan bazı donanım hızlandırmalı işlevleri kullanarak optimize edebilir. Sonunda bunu yaparsam bu yayını güncelleyeceğim.


Ayrıca, Perlin / Simplex Noise hala sahte rastgele olduğundan eminim. Hatırladığım kadarıyla, ilginç olan şey, çok kesintisiz görünmesini sağlamak için gürültüyü farklı seviyelerde katmanlaştırabilir ve "yakınlaştırabilirsiniz". Bana bu konuda alıntı yapma, ama düşünecek bir şey.
Andrew Meservy

@Zibri Maalesef, düz C veya .sh komutlarına aşina değilim. Ancak, fonksiyonun bir parazit rastgele sayı üreteci olduğu ve bir gürültü fonksiyonu olmadığı anlaşılıyor. Ayrıca, glsl piksel gölgelendiricilerinin doğrudan gpu üzerinde çalıştığını unutmayın. C'de bulunabilecek bu ek kitaplıklara veya CPU özelliklerine
erişemezsiniz

Shader Kitabı, şebekeyi eğmek ve nokta başına daha az gerekli hesaplamalar nedeniyle Simpleks Gürültünün Perlin Gürültüsünün nasıl daha verimli bir versiyonu olduğu konusunda harika bir açıklamaya sahiptir. Kesinlikle okumaya değer.
Andrew Meservy

ayrıca fraktal brownian hareketi ve voronoise bölümlerini görün
Andrew Meservy

Andrew Meservy: kütüphaneye gerek yok ... gürültü fonksiyonum çok basit: 2 64 bit ints x (n) ve x (n-1) durumudur. Basit ve hızlı formül x (n + 1) = ROTR ( x (n) + x (n-1), 8). Gitimi klonlar ve çalıştırırsanız, onu iş başında görürsünüz.
Zibri
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.