بادئ ذي بدء ، اسمحوا لي أن أشكو من أن كلمة "greeble" هي كلمة فظيعة يجب نفيها من القاموس.
حسنًا ، نخرج الحجر من الروح ، ننتقل إلى التفسيرات. Greeble هي تفاصيل صغيرة مكررة تضاف إلى نموذج لمنحه إحساسًا بالحجم وجماليات معينة. أصبحت الفطر شائعة بفضل أفلام الخيال العلمي الكلاسيكية ، والتي كان النحت المادي فيها غالبًا "النموذج":
إذا كنت تعرف بالفعل من خلال برنامج
تعليمي الخاص بالبثق كيفية إخراج الشبكات الإجرائية ، فأنت تفهم كيفية إضافة الفطر. يمكن تحقيق إضافة
عيش الغراب البسيط إلى الشبكة من خلال
سحب كل المضلعات الشبكية
بطول عشوائي .
ومع ذلك ، ربما لاحظت أن البرنامج التعليمي أعلاه ينظر فقط إلى مثلثات البثق ، في حين أن الصورة في بداية المقال عبارة عن فطر مربع. اضطررت إلى ضبط الشبكة بحيث تم تقسيمها إلى رباعي الزوايا ، وغالبًا ما تتكون شبكات كثيرة من مضلعات تحتوي على أكثر من ثلاثة مؤشرات. لذلك ، في هذا البرنامج التعليمي ، سنتعلم كيفية
إخراج مضلع باستخدام مؤشرات n وتطبيق هذه الخوارزمية على الشبكة بالكامل لإنشاء الفطر. نتعلم أيضًا طريقتين لعمل اختلافات في خوارزمية الفطر للحصول على نتائج أقل اتساقًا.
السطح العادي
أولاً ، دعنا نتعرف على كيفية حساب المعدل الطبيعي للمضلع باستخدام مؤشرات n التعسفية. إذا استطعنا أن نفترض أن هذا المضلع
مستوٍ ، أي أن كل رؤوسه موجودة على نفس المستوى ، فإن العملية لا تختلف عن حساب المعدل الطبيعي للمضلع بثلاثة مؤشرات.
السطح الطبيعي هو عمودي على وجه المضلع ، والذي يمكن حسابه عن طريق أخذ
المنتج الموجه من متجهين يشيران على طول حافة المضلع .
بعد ذلك نقوم
بتطبيع هذا المتجه بحيث يكون طوله 1 ، لأن من الطبيعي إلى السطح نحتاج فقط إلى الاتجاه وليس إلى الطول.
وظيفة getFaceNormal (شبكة ، بولي)
Vec3 v1 = mesh: getVertex (poly [1])
Vec3 v2 = mesh: getVertex (poly [2])
Vec3 v3 = mesh: getVertex (poly [3])
Vec3 e1 = v2 - v1
Vec3 e2 = v3 - v2
Vec3 normal = e1: تقاطع (e2)
عودة طبيعية: تطبيع ()
نهاية
إذا لم نتمكن من الافتراض بثقة أن المضلع هو مستو ، فإن الخوارزمية المعروضة أعلاه تفضل المستوى الذي يوجد عليه المؤشران الأوليان. للحصول على تمثيل أكثر دقة للاتجاه الذي تشير إليه المضلعات ، يمكننا بدلاً من ذلك أخذ
متوسط جميع منتجات المتجهات للحواف :
وظيفة getFaceNormal (شبكة ، بولي)
Vec3 n = Vec3 (0 ، 0 ، 0)
لأنني = 1 ، #poly -2 افعل
Vec3 v1 = mesh: getVertex (poly [1])
Vec3 v2 = mesh: getVertex (poly [1+ i])
Vec3 v3 = mesh: getVertex (poly [2+ i])
n: add ((v2 - v1): cross (v3 - v1))
نهاية
عودة ن: تطبيع ()
نهاية
مثال يوضح قذف رباعي مستو.البثق
الآن وقد أصبح لدينا معلومات عن السطح الطبيعي ، فنحن مستعدون لبثق المضلع في الاتجاه الطبيعي. ببساطة ، لبثق المضلع ، نقوم بإنشاء رؤوس جديدة عن طريق تحريك الرؤوس القديمة في اتجاه السطح الطبيعي.
مزيد من التفاصيل:
- إنشاء قمم جديدة "أعلاه" القديمة في الاتجاه الطبيعي.
يمكن حساب رؤوس جديدة كما يلي:
(موقف الذروة القديمة) + (الاتجاه الطبيعي)
هذا "يحول" الموقف القديم في اتجاه السطح الطبيعي.
على سبيل المثال ، انظر إلى الصورة أعلاه ، حيث تتحرك v1 في الاتجاه الطبيعي إلى v5. - قم بإنشاء رباعيات لربط الرؤوس الجديدة والقديمة.
تجدر الإشارة إلى أنه لكل مؤشر في المضلع الجديد ، يتم إنشاء رباعي جديد.
على سبيل المثال ، ألقِ نظرة على رباعية تم إنشاؤها من الإصدار 8 ، الإصدار 7 ، الإصدار 3 ، الإصدار 4 . - استبدل المضلع القديم بمضلع جديد تم إنشاؤه بواسطة رؤوس جديدة. على سبيل المثال ، ألقِ نظرة على رباعية تم إنشاؤها من v5 و v6 و v7 و v8.
وظيفة extrudePoly (شبكة ، polyIndex ، طول)
int [] poly = mesh.polys [polyIndex]
int [] newPoly = []
Vec3 n = getFaceNormal (شبكة ، بولي)
- (1) إنشاء verts مقذوف
ل j = 1 ، #poly القيام به
ع المحلية = شبكة: getVertex (بولي [ي])
newPoly [#newPoly + 1] = # mesh.verts
- طول يحدد طول البثق
شبكة: addVertex (ع + (طول ن *))
نهاية
- (2) الجانبين قذف غرزة مع الكواد
ل j0 = 1 ، #poly القيام به
j1 المحلي = j0٪ #poly + 1
شبكة: addQuad (
بولي [j0] ،
بولي [j1] ،
newPoly [j1] ،
newPoly [j0]
)
نهاية
- (3) نقل الوجه الموجود إلى الحقائق المقذوفة
ل j = 1 ، #poly القيام به
mesh.polys [pi] [j] = newPoly [j]
نهاية
نهاية
الفطر موحد.كل شبكة الفطر
الآن بعد أن أصبح لدينا وظيفة getSurfaceNormal () ووظيفة extrude () ، أصبح الفطر سهل للغاية! نحن ببساطة
نطبق الدالة extrude () على كل مضلع شبكي . نحن نستخدم البثق
بطول عشوائي بحيث يكون لكل مضلع مقذوف حجم مختلف قليلاً ، مما يخلق شعوراً بالملمس. يتم تطبيق الخوارزمية الموضحة أدناه على المكعب الموضح أعلاه ، والذي يتكون بالكامل من رباعي الزوايا.
وظيفة greeble (شبكة)
لأني = 1 ، # شبكة
- هذه القيم العشوائية تعسفية: ص
طول العائمة = عشوائي: getUniformRange (0.1 ، 1.0)
extrudePoly (شبكة ، أنا ، الطول)
نهاية
شبكة العودة
نهاية
مبروك ، لدينا الفطر المكتسبة. ولكن يمكننا أن نفعل أكثر! الآن الفطر موحد جدا. فيما يلي مثالان على التعديلات لجعلها أكثر إثارة للاهتمام.
التعديل 1: وجود الفطريات يعتمد على الصدفة
إنه أمر بسيط جدًا: ما عليك سوى لف القالب لتحديد ما إذا كان يجب تطبيق الفطر على كل مضلع. بفضل هذا ، يصبح الفطر أقل اتساقًا. يتم تطبيق الخوارزمية الموضحة أدناه على المكعب أعلاه.
لأني = 1 ، # شبكة
<strong> إذا كان عشوائيًا: فرصة (0.33) ثم </strong>
طول العائمة = عشوائي (0.1 ، 1.0)
extrudePoly (شبكة ، أنا ، الطول)
نهاية
نهاية
شبكة العودة
نهاية
التعديل 2: إضافة مقياس النتوء
وهذا يتطلب تغيير خوارزمية البثق. عندما ننشئ رؤوس مضلع مبثوق ، يمكننا
تقليلها باتجاه مركز المضلع بمقدار عشوائي لجعل الكائن يبدو أكثر تشويقًا.
بادئ ذي بدء ، يجب أن تتلقى دالة extrude () معلمة إضافية تحدد مقدار تضييق المضلع الجديد. سوف نحدده باسم Vec3 يسمى
scale
. لتحريك قمة الرأس نحو الوسط ، نقوم
بتحريف موضع القمة بين
موضعها الأصلي ومركز المضلع بقيمة
scale
.
(إذا كنت بحاجة إلى معرفة الخوارزمية للعثور على مركز المضلع ، فإنني أوصي سريعًا بالانتقال إلى
البرنامج التعليمي حول التثليث وقراءة التثليث النقطي الوسطى).
- العثور على مركز بولي
Vec3 ج = شبكة: getFaceCentroid (بولي)
ل j = 1 ، #poly القيام به
ع المحلية = شبكة: getVertex (بولي [ي])
newPoly [#newPoly + 1] = # mesh.verts
النفس: addVertex (
math.lerp (cx، px، scale.x) + nx * length ،
math.lerp (cy، py، scale.y) + ny * length،
math.lerp (cz، pz، scale.z) + nz * length
)
شبكة: addVertex (ع + (طول ن *))
نهاية
يمكنك الآن استخدامه في خوارزمية الفطر عن طريق التحجيم بقيمة عشوائية لكل مضلع. حتى نحصل على الصورة الموضحة أعلاه.
وظيفة greeble (شبكة)
لأني = 1 ، # شبكة
طول العائمة = عشوائي: getUniformRange (0.1 ، 1.0)
مقياس Vec3 = (عشوائي: getUniformRange (0.1 ، 1.0) ،
عشوائي: getUniformRange (0.1 ، 1.0) ،
عشوائي: getUniformRange (0.1 ، 1.0))
extrudePoly (شبكة ، أنا ، الطول ، مقياس)
نهاية
شبكة العودة
نهاية
النهاية
عظيم ، وصلنا إلى النهاية! آمل أن يكون هذا البرنامج التعليمي مفيدًا لك.