ตอนที่ 9: ระนาบ (Planes): พื้นดินที่เราเหยียบ และกำแพงเวทมนตร์ในโลก 3 มิติ

1. 🎯 ตอนที่ 9: ระนาบ (Planes): พื้นดินที่เราเหยียบ
2. 📖 เปิดฉาก (The Hook)
สวัสดีครับนักสร้างโลกจินตนาการทุกคน! ยินดีต้อนรับกลับสู่ซีรีส์ ปูพื้นฐานคณิตศาสตร์สู่โลกคอมพิวเตอร์กราฟิก ครับ
ในตอนที่แล้ว เราได้สร้างกระสุนปืนเวทมนตร์อย่าง “Ray” พุ่งทะลุอวกาศกันไปแล้ว แต่ถ้าโลก 3 มิติของเรามีแต่กระสุนปืนวิ่งไปมาโดยไม่มีพื้นดินให้เดิน ไม่มีกำแพงให้หลบ โลกของเกมก็คงจะว่างเปล่าและไร้จุดหมายใช่ไหมครับ?
เคยสงสัยไหมครับว่า ระบบฟิสิกส์ในเกม (Physics Engine) รู้ได้อย่างไรว่าตัวละครของเรากำลังยืนอยู่บนพื้น ไม่ร่วงหล่นทะลุแผนที่ลงไปในนรก? หรือรู้ได้อย่างไรว่ากระสุน Raycasting ที่เรายิงออกไป มันไปกระแทกเข้ากับกำแพงตึกตรงจุดไหนพอดี? คำตอบของเวทมนตร์เหล่านี้คือสิ่งที่นักคณิตศาสตร์เรียกว่า ระนาบ (Planes) ครับ มันไม่ใช่เครื่องบินนะครับ แต่คือ “แผ่นพื้นผิวแบนราบที่แผ่ขยายออกไปอย่างไม่มีที่สิ้นสุด” และวันนี้เราจะมาแกะสูตรลับที่ใช้สร้างแผ่นดินที่เราเหยียบกันครับ!
3. 🧮 จากตัวเลขสู่กราฟิก (Math to Graphics Foundation)
ในโลกของพีชคณิตเชิงเส้นและเรขาคณิต 3 มิติ การจะสร้าง Plane ขึ้นมาสักแผ่น เราไม่จำเป็นต้องใช้จุดนับล้านจุดครับ เราต้องการ “หัวใจหลัก” แค่ 2 อย่างเท่านั้น:
- Point ($P$): จุดอ้างอิงสักจุดหนึ่งที่รับประกันว่า “อยู่บนระนาบนี้แน่นอน”
- Normal Vector ($\mathbf{n}$): เวกเตอร์เส้นตรงที่ “ตั้งฉาก” กับแผ่นระนาบนั้น (จำ Cross Product ในตอนที่ 6 ได้ไหมครับ? นี่แหละพระเอกของเรา!)
นักคณิตศาสตร์นิยามระนาบด้วย สมการปริยาย (Implicit Equation) ที่สวยงามมากครับ ลองนึกภาพตามนะ ถ้าเรามีจุด $P$ บนระนาบ และมีจุด $\mathbf{x}$ ใดๆ ก็ตามที่อยู่บนระนาบเดียวกัน เวกเตอร์ที่ลากจาก $P$ ไป $\mathbf{x}$ (คือ $\mathbf{x} - P$) จะต้องนอนราบแนบสนิทไปกับระนาบเสมอ และกฎเหล็กมีอยู่ว่า “เวกเตอร์ที่นอนอยู่บนระนาบ จะต้องตั้งฉากกับ Normal Vector เสมอ” ซึ่งการตั้งฉากกันแปลว่า Dot Product ต้องเท่ากับ 0 ครับ! จึงเกิดเป็นสมการระนาบสุดคลาสสิก: $$ \mathbf{n} \cdot (\mathbf{x} - P) = 0 $$
ถ้าเรากระจายสมการนี้ออกมา โดยให้ $\mathbf{n} = [a, b, c]$ และ $\mathbf{x} = [x, y, z]$ เราจะได้สมการระนาบในรูปแบบที่เราคุ้นเคยกันสมัยเรียน: $$ ax + by + cz = d $$ (โดยที่ $d = \mathbf{n} \cdot P$)
ความลับของสเกลาร์ $d$: ถ้าเวกเตอร์ $\mathbf{n}$ ของเราเป็น Unit Vector (ความยาวเป็น 1) ค่า $d$ ตัวนี้จะบอกถึง “ระยะห่างที่สั้นที่สุดจากจุดกำเนิด (Origin) ไปยังระนาบ” ทันทีครับ! ถ้า $d$ มีค่าเป็นบวก แปลว่าจุดกำเนิดอยู่คนละฝั่งกับทิศที่ Normal ชี้ไป และถ้า $d$ เป็นลบ แปลว่าจุดกำเนิดอยู่ฝั่งเดียวกับทิศที่ Normal ชี้ครับ
4. 📐 เจาะลึกเรขาคณิตและการประมวลผลภาพ (Geometry & Image Processing)
ในโลกของการทำโมเดล 3D เราแทบจะไม่เคยป้อนสมการ $ax + by + cz = d$ เข้าไปตรงๆ หรอกครับ แต่งานศิลปะอย่างโมเดล 3D มักจะประกอบขึ้นจาก “รูปสามเหลี่ยม (Triangles)” หรือโพลิกอนจำนวนมหาศาล
แล้วคอมพิวเตอร์จะรู้สมการระนาบของพื้นผิวสามเหลี่ยมแต่ละแผ่นได้อย่างไร? คำตอบคือมันต้องคำนวณสร้างขึ้นมาเองจาก จุดยอด 3 จุด (3 Vertices) ครับ สมมติว่าเรามีจุด $p_1, p_2, p_3$ เรียงกันตามเข็มนาฬิกา (Clockwise) บนพื้นผิว:
- สร้างเวกเตอร์ขอบ (Edge Vectors): $\mathbf{e}_1 = p_2 - p_1$ และ $\mathbf{e}_2 = p_3 - p_1$
- หา Normal Vector: ใช้ Cross Product เพื่อเสกแกนตั้งฉาก $\mathbf{n} = \mathbf{e}_1 \times \mathbf{e}_2$ จากนั้นจับมัน Normalize ให้เป็น Unit Vector $\hat{\mathbf{n}}$
- หาค่า $d$: จับจุดยอดสักจุด (เช่น $p_1$) มาทำ Dot Product กับ $\hat{\mathbf{n}}$ จะได้ $d = \hat{\mathbf{n}} \cdot p_1$
เท่านี้ Game Engine ก็สามารถแอบเก็บสมการระนาบ (Plane Equation) ซ่อนไว้เบื้องหลังโพลิกอนทุกชิ้น เพื่อเตรียมพร้อมสำหรับการคำนวณขั้นต่อไปได้แล้วครับ!
5. 🎮 เวทมนตร์นี้ในโลกความจริง (Real-World Game Applications)
สมการระนาบเอาไปใช้ทำอะไรในเกมได้บ้าง? โอ้โห… ถือเป็น “เส้นแบ่งความเป็นความตาย” เลยครับ! เพราะระนาบหนึ่งแผ่น จะแบ่งโลก 3 มิติออกเป็นสองฝั่งเสมอ คือ “ด้านหน้า (Front-space)” (ฝั่งที่ Normal ชี้ไป) และ “ด้านหลัง (Back-space)”
Game Programmer จะใช้สมการนี้เพื่อตรวจจับการชน (Collision Detection) และระยะห่างจากตัวละครถึงกำแพงครับ สมมติว่าเรามีจุด $\mathbf{q}$ (เช่น ตำแหน่งของตัวละคร) เราอยากรู้ว่าจุดนี้ลอยอยู่ห่างจากระนาบพื้นดินแค่ไหน เราแค่เอา $\mathbf{q}$ ไปแทนค่าในสมการ: $$ \text{distance} = \mathbf{q} \cdot \hat{\mathbf{n}} - d $$ ผลลัพธ์ที่ได้คือ “ระยะห่างที่มีเครื่องหมาย (Signed Distance)” ครับ!
- ถ้าผลลัพธ์ > 0: ตัวละครลอยอยู่ “ด้านหน้า” (หรือด้านบน) ของพื้นดิน
- ถ้าผลลัพธ์ < 0: ตัวละครร่วงหล่นทะลุพื้นไป “ด้านหลัง” (ใต้ดิน) แล้ว! (ระบบฟิสิกส์จะสั่งให้ดันตัวละครเด้งกลับขึ้นมาทันที)
- ถ้าผลลัพธ์ = 0: ตัวละครเหยียบอยู่บนพื้นผิวพอดีเป๊ะ!
6. 🏭 เปิดโรงงานผลิตภาพ (The Graphics Pipeline)
นอกจากเรื่องฟิสิกส์แล้ว สมการระนาบยังเป็นฮีโร่ใน Graphics Pipeline ในขั้นตอนที่เรียกว่า Clipping (การขลิบหรือตัดภาพ) ครับ
ลองนึกภาพมุมกล้อง (Camera) ของเราดูครับ มุมมองของกล้องจะมีขอบเขตจำกัดเป็นรูปทรงปิรามิดหัวตัด เรียกว่า View Frustum ซึ่งประกอบขึ้นจาก “ระนาบ 6 แผ่น” (บน ล่าง ซ้าย ขวา หน้า หลัง)
ก่อนที่ GPU จะลงมือวาดสามเหลี่ยม (Rasterization) มันจะเช็คก่อนว่าสามเหลี่ยมนั้นอยู่นอกขอบเขตกล้องหรือไม่ โดยการเอาจุดยอด (Vertices) ของสามเหลี่ยมมาทดสอบหาระยะห่างกับระนาบทั้ง 6 แผ่นนี้ ถ้าระยะห่างเป็นลบ (อยู่นอกกล้อง) คอมพิวเตอร์จะใช้สมการพาราเมตริกของเส้นตรง (จากตอนที่ 8) วิ่งเข้ามาตัดกับสมการระนาบ เพื่อหา “จุดตัด (Intersection)” แล้วเอามีดกรรไกรทางคณิตศาสตร์ “ตัด” สามเหลี่ยมส่วนที่เกินออกไปทิ้งอย่างแม่นยำ! นี่แหละครับคือเหตุผลที่เกมสมัยใหม่เรนเดอร์ภาพได้รวดเร็ว เพราะมันไม่เคยวาดสิ่งที่อยู่นอกหน้าจอเลย!
7. 🏁 บทสรุป (Level Cleared!)
เห็นความยิ่งใหญ่ของ “ระนาบ (Plane)” แล้วใช่ไหมครับ! จากสมการง่ายๆ อย่าง $\mathbf{n} \cdot (\mathbf{x} - P) = 0$ มันกลายมาเป็นทั้งพื้นดินให้เรายืน เป็นกำแพงให้เราหลบ และเป็นกรอบสายตาที่ใช้ตัดขอบเขตการมองเห็นในโลกกราฟิก ทุกอย่างถูกควบคุมด้วยเวกเตอร์ทิศทางจิ๋วๆ ที่เรียกว่า Normal Vector
ในตอนต่อไป เราจะนำความรู้เรื่อง Ray (กระสุน) จากตอนที่ 8 มายิงใส่ Plane (กำแพง) จากตอนนี้ เพื่อดูว่าเราจะคำนวณหา “จุดปะทะ (Intersection)” แบบเป๊ะๆ สำหรับสร้างรอยกระสุน หรือเงาสะท้อนในเกมได้อย่างไร สนุกแน่นอนครับ รอติดตามกันได้เลย Level Cleared!
สนใจพูดคุยแลกเปลี่ยนเทคนิคการพัฒนาเกม คอมพิวเตอร์กราฟิก หรือออกแบบระบบซอฟต์แวร์? ทีมงาน WP Solution พร้อมให้บริการออกแบบและพัฒนาซอฟต์แวร์แบบครบวงจร ดูรายละเอียดบริการของเราได้ที่: www.wpsolution2017.com หรือพูดคุยปรึกษาเบื้องต้นได้ที่ Line: wisit.p