تشويش بيرلين

تصغير|شريحة ثنائية الأبعاد من خلال تشويش بيرلين ثلاثية الأبعاد عند z = 0
**تشوش بيرلين او ضوضاء بيرلين** هي نوع من ضوضاء التدرج التي طورها كين بيرلين في عام 1983. له العديد من الاستخدامات ، بما في ذلك على سبيل المثال ولا تقتصر على: إنشاء التضاريس من الناحية الإجرائية ، وتطبيق التغييرات شبه العشوائية على متغير ، والمساعدة في إنشاء نسيج الصورة . يتم تنفيذه بشكل شائع في بعدين أو ثلاثة أو أربعة أبعاد ، ولكن يمكن تحديده لأي عدد من الأبعاد.

طور كين بيرلين ضوضاء او تشويش بيرلين في عام 1983 نتيجة لإحباطه من المظهر "الشبيه بالآلة" للصور التي تم إنشاؤها بواسطة الكمبيوتر (CGI) في ذلك الوقت. وصف النتائج التي توصل إليها رسميًا في ورقة SIGGRAPH في عام 1985 بعنوان *An Image Synthesizer* . قام بتطويره بعد العمل على فيلم الرسوم المتحركة للخيال العلمي Tron *(* 1982) لشركة الرسوم المتحركة Mathematical Applications Group (MAGI). في عام 1997 ، تم منح بيرلين جائزة الأوسكار للإنجاز الفني لإنشاء الخوارزمية ، ونص الاقتباس على النحو التالي:

لم يتقدم بيرلين بطلب للحصول على أي براءات اختراع بشأن الخوارزمية ، ولكن في عام 2001 حصل على براءة اختراع لاستخدام تطبيقات 3D + للضوضاء البسيط لتركيب النسيج . الضوضاء البسيطة لها نفس الغرض ، لكنها تستخدم شبكة أبسط لملء الفراغ. يخفف الضجيج البسيط من بعض مشاكل "الضوضاء الكلاسيكية" لبيرلين ، من بينها التعقيد الحسابي والتشكيلات الاتجاهية ذات الأهمية المرئية.

## الاستخدامات
تصغير|مشهد افتراضي تم إنشاؤه باستخدام ضوضاء بيرلين
ضجيج بيرلين هو نسيج إجرائي بدائي ، وهو نوع من ضجيج التدرج الذي يستخدمه فنانو المؤثرات المرئية لزيادة مظهر الواقعية في رسومات الكمبيوتر . تتمتع الوظيفة بمظهر شبه عشوائي ، إلا أن جميع تفاصيلها المرئية لها نفس الحجم. تتيح هذه الخاصية إمكانية التحكم فيها بسهولة ؛ يمكن إدراج نسخ متعددة من ضجيج بيرلين في التعبيرات الرياضية لإنشاء مجموعة كبيرة ومتنوعة من القوام الإجرائي. غالبًا ما تُستخدم الأنسجة الاصطناعية التي تستخدم ضوضاء بيرلين في CGI لإنشاء عناصر مرئية بواسطة الكمبيوترمثل أسطح الأشياء أو النار أو الدخان أو السحبتبدو أكثر طبيعية ، من خلال تقليد المظهر العشوائي الخاضع للرقابة للقوام في الطبيعة.
تصغير|سطح عضوي تم إنشاؤه باستخدام ضوضاء بيرلين
يتم استخدامه أيضًا بشكل متكرر لإنشاء مواد عندما تكون الذاكرة محدودة للغاية ، كما هو الحال في المشاهد التوضيحية . أصبح خلفاؤها ، مثل الضجيج الكسري والضوضاء البسيط (اكس) ، في كل مكان تقريبًا في وحدات معالجة الرسومات لكل من الرسومات في الوقت الفعلي والأنسجة الإجرائية غير الواقعية في جميع أنواع رسومات الكمبيوتر.

يتم استخدامه بشكل متكرر في ألعاب الفيديو لإنشاء تضاريس تم إنشاؤها إجرائيًا التي تبدو طبيعية.

## تفاصيل الخوارزمية
تصغير|128x128بك| ضوضاء بيرلين معاد قياسها وإضافتها إلى نفسها لخلق ضوضاء كسورية.
يتم تنفيذ ضوضاء بيرلين بشكل شائع كوظيفة ثنائية أو ثلاثية أو رباعية الأبعاد ، ولكن يمكن تعريفها لأي عدد من الأبعاد. يتضمن التنفيذ عادةً ثلاث خطوات: تحديد شبكة من نواقل التدرج العشوائي ، وحساب حاصل الضرب النقطي بين متجهات التدرج وتعويضاتها ، والاستيفاء بين هذه القيم.

### تعريف الشبكة
بديل=|بدون|تصغير|256x256بك| شبكة ثنائية الأبعاد من متجهات التدرج
حدد شبكة ذات أبعاد *n* حيث يرتبط بها كل تقاطع شبكة متجه متجه متدرج بطول الوحدة العشوائي ذي البعد *n* ، باستثناء الحالة ذات البعد الواحد حيث تكون التدرجات مقاييس عشوائية بين -1 و 1.

### المنتج نقطة
بديل=|بدون|تصغير|256x256بك| حاصل الضرب القياسي لكل نقطة بأقرب قيمة تدرج لوني لعقد الشبكة. لا يتم عرض المنتج النقطي مع العقد الثلاثة الأخرى في الخلية.
لحساب قيمة أي نقطة مرشحة ، ابحث أولاً عن خلية الشبكة الفريدة التي تكمن فيها النقطة. ثم حدد ملف 2^n زوايا تلك الخلية ونواقل التدرج المرتبطة بها. بعد ذلك ، لكل زاوية ، احسب متجه الإزاحة. متجه الإزاحة هو متجه الإزاحة من تلك الزاوية إلى النقطة المرشحة.

لكل زاوية ، نأخذ حاصل الضرب النقطي بين متجه التدرج ومتجه الإزاحة إلى نقطة المرشح. سيكون حاصل الضرب النقطي هذا صفراً إذا كانت النقطة المرشحة في زاوية الشبكة بالضبط.

لاحظ أن تأثير متجه التدرج ينمو مع زيادة المسافة ، والذي يمكن تجنبه عن طريق تسوية متجه الإزاحة بطول 1 أولاً. سيؤدي هذا إلى إدخال تغييرات حادة ملحوظة ، باستثناء المسافة التي يتم أخذها في الاعتبار في خطوة الاستيفاء التالية. ومع ذلك ، فإن تطبيع متجه الإزاحة ليس ممارسة شائعة.

بالنسبة إلى نقطة في شبكة ثنائية الأبعاد ، سيتطلب ذلك حساب 4 متجهات إزاحة ومنتجات نقطية ، بينما في الأبعاد الثلاثة سيتطلب 8 متجهات إزاحة و 8 منتجات نقطية. بشكل عام ، الخوارزمية لديها O(2^n) التعقيد ، أين n هو عدد الأبعاد.

### الاستيفاء
بديل=|بدون|تصغير|256x256بك| النتيجة النهائية
الخطوة الأخيرة هي الاستيفاء بين 2^n منتجات النقطية. يتم إجراء الاستيفاء باستخدام دالة لها مشتق أول صفر (وربما أيضًا المشتق الثاني) عند 2^n عقد الشبكة. لذلك ، عند النقاط القريبة من عقد الشبكة ، سيقارب الإخراج المنتج النقطي لمتجه التدرج للعقدة ومتجه الإزاحة للعقدة. هذا يعني أن وظيفة الضوضاء سوف تمر من خلال الصفر في كل عقدة ، مما يعطي ضوضاء بيرلين مظهرها المميز.

لو n=1 ، مثال على دالة تقحم بين القيمة a_0 عند عقدة الشبكة 0 والقيمة a_1 عند العقدة الشبكية 1 هي

: f(x) = a_0 + \operatorname{smoothstep}(x)\cdot(a_1-a_0) \ \ \text{for }0\leq x\leq 1

حيث تم استخدام وظيفة الخطوة السلسة .

عادةً ما تنتج وظائف الضوضاء المستخدمة في رسومات الكمبيوتر قيمًا في النطاق [-1.0،1.0] ويمكن قياسها وفقًا لذلك.

## تطبيق
ما يلي هو تنفيذ ثنائي الأبعاد لضوضاء بيرلين الكلاسيكية ، مكتوبًا في لغة C.

كان لتطبيق المرجع الأصلي من قبل بيرلين اختلافات كبيرة  :

* إنها تستخدم نهجًا ثلاثي الأبعاد عن طريق الإقحام بين 8 زوايا للمكعب بدلاً من الزوايا الأربع للمربع أدناه.
* يقوم اتجاه التدرج العشوائي بتبديل أجزاء من إحداثيات عدد صحيح من الزوايا ، وهو أسرع بكثير من الخلط باستخدام التداخل عند التردد العالي لدورات إحداثيات عدد صحيح للزوايا ، يتم دمجه وتدويره مرة أخرى بتردد عالٍ بواسطة منتج: التدويرات ليست موحدة وزعت.
* قسمت طريقة بيرلين مساحة الأعداد الصحيحة إلى مكعبات 256 × 256 × 256 ثم تستخدم تبديلًا عشوائيًا لهذه المكعبات لخلطها ، ثم يتم تعيين زاوية من اثني عشر اتجاهًا للمكعبات المجاورة غير المتغيرة في مساحة الرصف 4 × 4 × 4: هذا يتطلب فقط عدد صحيح لكنه يحافظ على توزيع موحد للاتجاهات.
* وظيفة الاستيفاء هي الخطوة الأكثر سلاسة من 4 درجات (مع المشتقات الثلاثة الأولى تساوي الصفر على حدود التثبيت) وليست الخطوة الخطية الأساسية. هذا يتجنب القطع الأثرية المرئية ، لا سيما على طول الرؤوس أو الأقطار التي تنضم إلى زوايا العينة ، حيث تكون النتيجة متباينة الخواص (تلطيخ الضوضاء البيضاء المرغوبة إلى ضوضاء وردية ؛ إذا تم استخدام الضوضاء لتوليد بلورة صلبة ، فلن تكون سوداء بالكامل و معتم للضوء ، ولكنه شفاف وملون جزئيًا في بعض اتجاهات المراقبة المنفصلة).

```c
#include <math.h>

/* Function to linearly interpolate between a0 and a1
 * Weight w should be in the range [0.0, 1.0]
 */
float interpolate(float a0, float a1, float w) {
    /* // You may want clamping by inserting:
     * if (0.0 > w) return a0;
     * if (1.0 < w) return a1;
     */
    return (a1 - a0) * w + a0;
    /* // Use this cubic interpolation [[Smoothstep]] instead, for a smooth appearance:
     * return (a1 - a0) * (3.0 - w * 2.0) * w * w + a0;
     *
     * // Use [[Smootherstep]] for an even smoother result with a second derivative equal to zero on boundaries:
     * return (a1 - a0) * ((w * (w * 6.0 - 15.0) + 10.0) * w * w * w) + a0;
     */
}

typedef struct {
    float x, y;
} vector2;

/* Create pseudorandom direction vector
 */
vector2 randomGradient(int ix, int iy) {
    // No precomputed gradients mean this works for any number of grid coordinates
    const unsigned w = 8 * sizeof(unsigned);
    const unsigned s = w / 2; // rotation width
    unsigned a = ix, b = iy;
    a *= 3284157443; b ^= a << s | a >> w-s;
    b *= 1911520717; a ^= b << s | b >> w-s;
    a *= 2048419325;
    float random = a * (3.14159265 / ~(~0u >> 1)); // in [0, 2*Pi]
    vector2 v;
    v.x = cos(random); v.y = sin(random);
    return v;
}

// Computes the dot product of the distance and gradient vectors.
float dotGridGradient(int ix, int iy, float x, float y) {
    // Get gradient from integer coordinates
    vector2 gradient = randomGradient(ix, iy);

    // Compute the distance vector
    float dx = x - (float)ix;
    float dy = y - (float)iy;

    // Compute the dot-product
    return (dx*gradient.x + dy*gradient.y);
}

// Compute Perlin noise at coordinates x, y
float perlin(float x, float y) {
    // Determine grid cell coordinates
    int x0 = (int)floor(x);
    int x1 = x0 + 1;
    int y0 = (int)floor(y);
    int y1 = y0 + 1;

    // Determine interpolation weights
    // Could also use higher order polynomial/s-curve here
    float sx = x - (float)x0;
    float sy = y - (float)y0;

    // Interpolate between grid point gradients
    float n0, n1, ix0, ix1, value;

    n0 = dotGridGradient(x0, y0, x, y);
    n1 = dotGridGradient(x1, y0, x, y);
    ix0 = interpolate(n0, n1, sx);

    n0 = dotGridGradient(x0, y1, x, y);
    n1 = dotGridGradient(x1, y1, x, y);
    ix1 = interpolate(n0, n1, sx);

    value = interpolate(ix0, ix1, sy);
    return value; // Will return in range -1 to 1. To make it in range 0 to 1, multiply by 0.5 and add 0.5
}
```


## التقليب
تستخدم العديد من تطبيقات ضجيج بيرلين نفس مجموعة التبديل التي استخدمها كين بيرلين في تطبيقه الأصلي. هذا التنفيذ هو على النحو التالي:
```c
int permutation[] = { 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 
                      103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 
                      26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 
                      87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 
                      77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 
                      46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 
                      187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 
                      198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 
                      255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 
                      170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 
                      172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 
                      104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 
                      241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 
                      157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 
                      93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 };
```
هذا التقليب المحدد ليس مطلوبًا تمامًا ، على الرغم من أنه يتطلب مصفوفة عشوائية من القيم [0-255] (ضمناً). في حالة إنشاء جدول تبديل جديد ، يجب توخي الحذر لضمان التوزيع المنتظم للقيم.

## التعقيد
لكل تقييم لوظيفة الضوضاء ، يجب تقييم المنتج النقطي للموضع ومتجهات التدرج عند كل عقدة في خلية الشبكة المحتوية. وبالتالي ، فإن ضوضاء بيرلين تتناسب مع التعقيد O(2^n) ل n أبعاد. تشمل بدائل ضوضاء بيرلين التي تنتج نتائج مماثلة مع مقياس تعقيد محسّن ضوضاء بسيطة وضوضاء OpenSimplex .

## أنظر أيضا

* ضوضاء القيمة
* ضوضاء المحاكاة
* ضوضاء بسيطة

## مراجع

## روابط خارجية

* الأسئلة الشائعة حول الرياضيات في بيرلين لمات زوكر
* يوضح برنامج Rob Farber التعليمي توليد ضوضاء Perlin وتصورها على معالجات الرسوم التي تدعم CUDA
* مكتبة جيسون بيفينز الشاملة C ++ لتوليد قيم ضوضاء معقدة ومتماسكة
* تطبيق PHP (GitHub)
* شرح ضوضاء بيرلين في العمق (مع كود مصدر C ++)
* كتاب شادر بقلم باتريسيو غونزاليس فيفو وجين لوي
* مولد ضوضاء بيرلين على الإنترنت
* حزمة Python لإنشاء ضوضاء Perlin

تصنيف:التوليد الإجرائي
تصنيف:رسوميات الحاسوب
تصنيف:صفحات بترجمات غير مراجعة
تصنيف:كسيريات
تصنيف:مؤثرات خاصة