2 คะแนน โดย GN⁺ 2024-02-29 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เป็นการทดลองนำ Euclidean PGA มาใช้จนสุดทางในฟอร์เวิร์ดเรนเดอร์เรอร์ที่เข้ากันได้กับ glTF แทนเมทริกซ์ 4x4 ที่เคยใช้กันแทบเป็นสัญชาตญาณในกราฟิก 3D
  • การหมุนและการเลื่อนตำแหน่งถูกแทนด้วย PGA motor ขนาด 8 float และการประกอบ motor ทั่วไปใช้ 48 การคูณ·40 การบวก ซึ่งน้อยกว่าเมทริกซ์ 4x4 ที่ใช้ 64 การคูณ·48 การบวก
  • การแปลงจุดหากกระจายสมการตรง ๆ จะแพงกว่าเมทริกซ์ แต่เมื่อใช้ sandwich product ที่อาศัยเงื่อนไขการทำให้เป็นปกติ จะลดลงเหลือ 21 การคูณ·18 การบวก และการแปลงทิศทาง·ทิศทางฐานยิ่งถูกกว่า
  • ใน tangent space normal mapping แทนที่ normal และ tangent ด้วย tangentRotor ทำให้ข้อมูลจุดยอดลดจาก 12 float เหลือ 9 float ขณะเดียวกันปรับต้นทุนการแปลงเป็น world-space ให้อยู่ราว 47 การคูณ·38 การบวก ใกล้เคียงวิธีแบบเมทริกซ์
  • เพื่อให้ทำงานกับคอนเทนต์ glTF จริงได้ ต้องแปลงเมทริกซ์เป็น motor ตอนโหลด และติดตาม uniform scale แยกเป็น float ต่างหาก ส่วน non-uniform scale ต้องจัดการแบบจำกัดหรือมีเส้นทาง fallback ไปใช้เมทริกซ์ 4x4

ฟอร์เวิร์ดเรนเดอร์เรอร์ไร้เมทริกซ์ที่สร้างด้วย PGA

  • โปรเจกต์คือ Look, Ma, No Matrices มีเป้าหมายเพื่อทำ ฟอร์เวิร์ดเรนเดอร์เรอร์ที่ไม่มีเมทริกซ์
  • หลัง SIGGRAPH 2019 เป็นต้นมา Geometric Algebra โดยเฉพาะ Euclidean PGA ได้รับความสนใจในชุมชนกราฟิกและแมชชีนเลิร์นนิง แต่ในกราฟิก 3D แบบดั้งเดิม หลายกรณียังหยุดอยู่แค่การเรียก dual quaternion ใหม่ว่า PGA motor
  • การทำงานนี้ผสาน PGA algebra เข้ากับเอนจิน 3D ที่เข้ากันได้กับ glTF โดยไม่ใช่แค่เปลี่ยนชื่อเชิงพีชคณิต แต่จัดโครงสร้างหลายส่วนของกราฟิกไปป์ไลน์ใหม่ในแนวทาง PGA
  • โค้ดอ้างอิงคือ Khronos glTF viewer และเป็นการทดลองแทนที่เมทริกซ์แบบไม่ประนีประนอม มากกว่าจะเป็นการทำเพื่อประสิทธิภาพสูงสุด
    • ท้ายที่สุด hybrid solution อาจเป็นตัวเลือกที่ดีกว่า

เหตุผลที่ตั้งคำถามกับเมทริกซ์ 4x4

  • เมทริกซ์ 4x4 มีบทบาทหลักมายาวนานใน graphics API และ fixed-function pipeline ของ GPU และยังคงเป็นเครื่องมือพื้นฐานของฟอร์เวิร์ดเรนเดอร์ทั่วไป
  • GPU สมัยใหม่ใกล้เคียงกับ โปรเซสเซอร์สเกลาร์ที่โปรแกรมได้ มากกว่า fixed-function pipeline จึงไม่จำเป็นต้องยึดการแทนค่าแบบเมทริกซ์เป็นศูนย์กลางเสมอไป
  • ในเอนจิน 3D จริง เมทริกซ์จำนวนมากเป็น orthogonal matrix ที่มีเฉพาะการหมุนและการเลื่อนตำแหน่ง
  • PGA motor manifold สามารถแทน Euclidean motion ทั้งหมดได้ด้วยต้นทุนการคำนวณและหน่วยความจำที่ต่ำกว่า และยังรวม quaternion กับ dual quaternion ได้โดยไม่ต้องแปลง

การแทนข้อมูลและการดำเนินการพื้นฐานของ PGA

  • PGA algebra สร้างจากเวกเตอร์ฐานสี่ตัว e0~e3
    • e1, e2, e3 สอดคล้องกับระนาบ x=0, y=0, z=0 ตามลำดับ
    • degenerate vector พิเศษ e0 แทนระนาบที่อนันต์
  • ในเชดเดอร์ใช้ชนิดข้อมูล built-in ของ GLSL เพื่อใช้การบวก การลบ และการคูณด้วยสเกลาร์ โดยไม่ต้องมี operator overloading
    • motor mat2x4
    • line mat2x3
    • point vec3
    • direction vec3
  • การประกอบ PGA motor ทั่วไปทำด้วย geometric product
    • การคูณเมทริกซ์ 4x4: 64 การคูณ, 48 การบวก
    • การประกอบ motor ทั่วไป gp_mm: 48 การคูณ, 40 การบวก
  • ในชุดการแปลงแบบพิเศษ สามารถใช้การดำเนินการที่ถูกกว่าได้
    • gp_rr: 16 การคูณ, 12 การบวก
    • gp_tt: 0 การคูณ, 3 การบวก
    • gp_rt / gp_tr: 12 การคูณ, 8 การบวก
    • gp_rm / gp_mr: 32 การคูณ, 24 การบวก
    • gp_tm / gp_mt: 12 การคูณ, 12 การบวก

การปรับแต่งการแปลงจุด·ทิศทาง

  • ใน PGA เมื่อแปลงจุด p ด้วย motor M จะใช้ sandwich product M p M̃
  • หากกระจายสมการตรง ๆ จะใช้ 33 การคูณ, 29 การบวก ซึ่งมากกว่าการคูณเมทริกซ์-เวกเตอร์ที่ใช้ 16 การคูณ, 12 การบวก
  • หากใช้ข้อเท็จจริงว่า motor ที่ normalize แล้วเป็นไปตาม M M̃ = 1 เพื่อจัดรูปสมการใหม่ จะลดการแปลงจุดลงเหลือ 21 การคูณ, 18 การบวก
  • ทิศทาง หรือจุดที่อนันต์ มีสัมประสิทธิ์ e123 โดยนัยเป็น 0 จึงถูกกว่า
    • การแปลงทิศทางทั่วไป: 18 การคูณ, 12 การบวก
    • การแปลง basis direction เช่น การแปลงแกน x สามารถลดได้ถึง 6 การคูณ, 4 การบวก
  • การปรับแต่ง basis direction นี้กลายเป็นหลักฐานที่สั่นคลอนความเชื่อเดิมว่าเมทริกซ์เร็วที่สุดเสมอในการจัดการ tangent frame ภายหลัง

การทำให้เป็นปกติ, รากที่สอง, แมปเอ็กซ์โปเนนเชียล·ลอการิทึม

  • squared pseudonorm ของ PGA motor อยู่ในรูป M M̃ = a + b e0123 ซึ่งเป็น Study Number
  • การ normalize ไม่ใช่แค่การ normalize เวกเตอร์ธรรมดา แต่เป็นขั้นตอนที่รับประกันว่า motor ผลลัพธ์จะเป็น orthonormal transformation
    • ต้นทุนการทำ normalize สำหรับ motor ทั่วไป: 21 การคูณ, 5 การบวก
    • สำหรับ pure translation หรือ rotation สามารถใช้เวอร์ชันที่มีประสิทธิภาพกว่าได้
  • rigid transformation ระหว่างจุดสองจุด·เส้นสองเส้น·ระนาบสองระนาบ a, b แทนได้ด้วย M = sqrt(b / a)
    • geometric product ba ขององค์ประกอบสองตัวชนิดเดียวกันจะสร้าง motor ที่สอดคล้องกับการแปลงจาก a ไป b เป็นสองเท่า
    • สามารถคำนวณได้ในรูป sqrt M = normalize(1 + M)
  • logarithm ของ PGA motor คือ scaled line และ scaled line สามารถสร้าง rotation motor ได้ด้วย exponentiation
  • exponential map ของเมทริกซ์ 4x4 ทั่วไปมีต้นทุนเชิงตัวเลขสูง แต่บน PGA motor manifold สามารถมี closed form ที่มีประสิทธิภาพ ได้

อินเวิร์สและ motor factorization

  • Geometric Algebra สามารถคำนวณอินเวิร์สของวัตถุที่ normalize แล้วได้อย่างมีประสิทธิภาพ
    • plane inverse: ตัวมันเอง
    • line inverse: กลับเครื่องหมาย
    • point inverse: กลับเครื่องหมาย
    • motor inverse: reversion
  • เมื่อ bivector ทั่วไปไม่เป็นไปตาม Plücker condition จึงไม่แทนเส้นเดี่ยว จะคำนวณอินเวิร์สด้วย Study Number inverse
  • ในการทำเรนเดอร์มีการใช้ factorization สองแบบ
    • Euclidean factorization: แยก motor เป็น rotation รอบ origin แล้วตามด้วย translation
    • Invariant factorization: แยก motor เป็น translation และ rotation ที่ commute กัน ซึ่งใน 3D รู้จักกันในรูปของ Mozzi-Chasles theorem
  • เมื่อต้องประกอบ tangent frame กับ object-to-world motor การใช้ Euclidean factorization มีประโยชน์เพราะคุณสมบัติของ frame ที่ invariant ต่อ translation

การจัดการเมทริกซ์ glTF และ scale

  • เพื่อให้ทำงานร่วมกับคอนเทนต์ glTF เดิมได้ ต้องแปลงเมทริกซ์เป็น PGA motor ตอนโหลด
  • 4x4 orthogonal matrix แปลงเป็น motor โดยใช้ isomorphism กับ quaternion
    • matrix และ transformation ทั้งหมดที่ import เข้ามาจะถูกแปลงตอน load time
  • PGA motor จัดการ rigid body transformation จึงไม่รวม scaling
  • uniform scaling invariant ต่อ rotation และ translation จึงติดตามได้ด้วย float หนึ่งตัวต่อแต่ละโหนด
    • total scale ของแต่ละองค์ประกอบคำนวณจากผลคูณของ scale ตัวเองกับ parent scale
    • ใช้ total scale กับ vertex ตอน load time หรือในขั้นแรกของ vertex shader
    • ใช้ parent scale กับ translation ตอน load time และตอน animation update
  • จากตัวอย่างไฟล์ glTF แบบสุ่มประมาณ 400 ไฟล์ พบกรณีที่มี scale animation น้อยกว่า 0.5% และ fixed uniform scale พบได้ค่อนข้างมาก
  • non-uniform scaling ไม่ invariant ต่อ rotation จึงยุ่งยากกว่า
    • การจัดการ non-uniform scale ทั่วไปเลี่ยงเส้นทาง fallback ด้วยเมทริกซ์ 4x4 ได้ยาก
    • ในตัวอย่าง glTF พบกรณีที่ non-uniform scale ถูกใช้เฉพาะกับ leaf node และในกรณีนี้จะใช้ scale แยกต่างหากก่อนการแปลงที่เหลือ โดยไม่กระทบ animation key

การแทนที่ Model-View-Projection

  • ฟอร์เวิร์ดเรนเดอร์เรอร์แปลง mesh geometry ใน object space ไปเป็น screen space และกำหนดว่าแต่ละ triangle ครอบคลุม pixel ใด
  • ในบรรดา model, view, projection matrix ของไปป์ไลน์ทั่วไป จะแทนที่ model และ view ด้วย PGA motor
    • ตำแหน่ง vertex ใช้ sw_mp
    • ทิศทาง normal และ tangent ใช้ sw_md
  • โดยทั่วไป projection matrix มี non-zero entry เพียง 5 ตัว จึงไม่ฝืนแปลงเป็น PGA แต่ใช้ expression สำหรับ projection โดยตรง
  • การอัปเดต scene graph hierarchy ฝั่ง CPU ใช้ motor composition แทน matrix composition ทำให้ปริมาณการคำนวณลดลง
  • การแปลง vertex ฝั่ง GPU หากเทียบแบบตรง ๆ motor อาจดูเสียเปรียบ แต่เมื่อเปลี่ยนการแทนค่า tangent frame ผลลัพธ์จะต่างออกไป

การปรับแต่ง tangent space normal mapping

  • vertex shader ของ mesh ที่ทำ tangent space normal mapping โดยทั่วไปต้องแปลง position, normal, tangent
  • normal, tangent, bitangent ประกอบกันเป็น orthonormal frame ดังนั้นใน PGA สามารถแทนด้วย tangentRotor ที่พา canonical basis frame ไปยัง tangent frame ที่ต้องการ
  • วิธีนี้ลดขนาด vertex descriptor
    • แบบเดิม: position 3 + normal 3 + tangent 4 + uv 2 = 12 floats
    • แบบ PGA: position 3 + tangentRotor 4 + uv 2 = 9 floats
    • จำนวน float ต่อจุดยอดลดลง 25%
  • tangentRotor มี double cover และใช้ sign ของ scalar coefficient ให้ตรงกับ classical handedness flag เพื่อแยก even/odd k-reflection
    • อาศัย signed zero และใน vertex shader ดึง handedness ด้วย sign(1/tangentRotor.x)
  • หากแปลง position, normal, tangent ด้วยเมทริกซ์ 4x4 จะต้องใช้ทั้งหมด 48 การคูณ, 36 การบวก
  • วิธี PGA แปลง tangent frame ทั้งชุดในครั้งเดียว แล้วดึง normal และ tangent ออกมา
    • การประกอบ tangent frame: 16 การคูณ, 12 การบวก
    • การดึง normal/tangent: 9 การคูณ, 8 การบวก
    • การแปลง position: 21 การคูณ, 18 การบวก
    • การคูณ 1 ครั้งสำหรับดึง handedness
    • รวม 47 การคูณ, 38 การบวก
  • ต้นทุนการแปลงจุดยอดแทบเท่ากับวิธีเมทริกซ์ และการเก็บ transform ลดจาก 32 floats เหลือ 8 floats

fragment shader และข้อจำกัดของ baked texture

  • เพื่อโหลดคอนเทนต์เดิม ขั้น fragment shader ยังต้องใช้ TBN matrix อีกครั้ง
  • baking tool จะ interpolate vertex normal และ tangent บน triangle face ในกระบวนการ bake high-detail mesh ลงบน low-detail mesh แล้วสร้าง orthogonal TBN matrix ที่แต่ละ fragment เพื่อทำ tangent space normal texture
  • การ interpolate basis vector ทำให้เกิดความคลาดเคลื่อนแบบฉบับของวิธีเมทริกซ์ และความคลาดเคลื่อนนั้นถูก baked อยู่ใน texture แล้ว
  • ดังนั้น implementation นี้จึงดึง normal และ tangent vector ออกจาก tangentRotor อย่างชัดเจน
  • หากควบคุม baking tool ได้ ก็สามารถส่ง tangentRotor ไปยัง fragment shader ได้ตรง ๆ แล้ว normalize จากนั้นใช้แปลง sampled normal
    • ไม่จำเป็นต้องสร้าง TBN matrix
    • ไม่จำเป็นต้องดึง normal/tangent ใน vertex shader
    • ลด varying parameter ได้หนึ่งตัว
    • ตัด expensive orthogonalization ใน fragment shader ออกได้ด้วย

motor skinning และ animation blending

  • PGA motor isomorphic กับ dual quaternion จึงนำไปใช้กับ skinning ได้อย่างเป็นธรรมชาติ
  • หลังแปลง inverse bind matrix เป็น motor แล้ว จะ blend bone motor ด้วยรูปแบบเดียวกับ dual quaternion skinning
  • transformation ที่ถูก blend จะปรับเครื่องหมายให้เดินตาม shortest arc และ normalize transformation ผลลัพธ์อีกครั้ง
  • animation blending ก็ทำแบบเดียวกัน โดย blend PGA motor โดยตรงบน CPU แล้ว normalize

ผลลัพธ์ของการทดลองแทนที่เมทริกซ์

  • การทำ implementation ที่แทนที่เมทริกซ์ด้วย PGA ล้วน ๆ ในฟอร์เวิร์ดเรนเดอร์เรอร์ที่เข้ากันได้กับ glTF นั้นเป็นไปได้
  • ความคาดหมายว่าต้นทุนการแปลงจะแพงกว่า ไม่ได้เรียบง่ายเช่นนั้นเมื่อใช้การแทน tangent frame และการปรับแต่ง sandwich product
  • ในกรณีทั่วไปของ tangent space normal mapping วิธี PGA motor ทำให้ต้นทุน vertex shader แทบเท่าวิธีเมทริกซ์ พร้อมกับลด memory footprint ของ vertex ได้มาก
  • การปรับปรุงด้านหน่วยความจำที่เก็บ vertices ได้มากขึ้นราว 33% ในพื้นที่เท่าเดิมนั้นเด่นเป็นพิเศษ
  • เทคนิคนี้สามารถนำไปใช้กับเอนจิน 3D เดิมได้ในฐานะ drop-in replacement โดยแทบไม่เพิ่มต้นทุน vertex shader และไม่ต้องแก้ส่วนอื่นของไปป์ไลน์

1 ความคิดเห็น

 
GN⁺ 2024-02-29
ความคิดเห็นบน Hacker News
  • Freya Holmér หนึ่งในผู้สร้าง YouTube ด้านคณิตศาสตร์/กราฟิกที่ผมชอบ เพิ่งทำวิดีโอแนะนำพีชคณิตเชิงเรขาคณิตออกมาได้ดีมาก: https://www.youtube.com/watch?v=htYh-Tq7ZBI&ab_channel=Freya...
    ถ้าสนใจกราฟิก 3D โดยเฉพาะสไปลน์/เส้นโค้งเบซิเยร์ วิดีโอของเธอทั้งหมดก็ควรค่าแก่การดู
    โดยส่วนตัวแล้วพีชคณิตเชิงเส้นเป็นเรื่องยากสำหรับผมมาตลอด แต่แนวทางแบบ พีชคณิต Clifford นี้รู้สึกเข้าใจได้โดยสัญชาตญาณมากกว่าเยอะ

    • เป็นการนำเสนอที่ดีจริง ๆ และทำให้นึกถึง https://enkimute.github.io/ganja.js/
      ไลบรารีนี้สร้างโดย enkimute ผู้เขียนต้นฉบับ เป็นไลบรารีที่น่าทึ่งทีเดียว เพราะเป็นสคริปต์ไฟล์เดียว ไม่ต้อง build แต่ยังรองรับพีชคณิต N มิติและการเรนเดอร์ด้วย
    • นึกแล้วว่าบทความนี้น่าจะพูดถึงคนนี้ ดูวิดีโอเรื่องสไปลน์กับเบซิเยร์แล้วก็สนุกเหมือนกัน และการนำเสนอก็เข้าประเด็นได้ดีโดยไม่รู้สึกว่าเร่งเลย
    • ในคอมเมนต์ YouTube ก็มีคำอธิบายเสริมและคำถามที่ดีอย่างน่าประหลาดใจ
      เช่น คำอธิบายเรื่องส่วนที่ Freya ผ่านไปค่อนข้างเร็วหรือละไว้ อย่าง ความไม่สลับที่ของการคูณ ก็ทำได้ค่อนข้างดี
  • พีชคณิตเชิงเรขาคณิตเคยเป็นปริศนาโดยสมบูรณ์อยู่พักหนึ่ง แต่สุดท้ายพอเข้าใจแบบนี้ก็คลี่คลาย: มันก็แค่ การคูณพหุนาม เพียงแต่มีปริมาณบางอย่างที่ลำดับการคูณสำคัญ และตารางการคูณแปลก ๆ เท่านั้นเอง เช่น i*i = 1, i*j = -j*i
    สื่อแนะนำส่วนใหญ่ทำให้ผลคูณเชิงเรขาคณิตของเวกเตอร์สองตัว (x1*i + y1*j) * (x2*i + y2*j) ดูลึกซึ้งและลึกลับ แต่จริง ๆ แล้วเหมือนการกระจายแบบ FOIL ที่เรียนในพีชคณิตระดับปีหนึ่ง:
    (x1*i + y1*i)(x2*i+y2*j) = x1*x2*i*i + x1*y2*i*j + y1*x2*j*i + y1*y2*j*j = (x1*x2 + y1*y2) + (x1*y2 - y2*x1)*i*j
    ค่าในวงเล็บแรกคือ dot product ที่คุ้นเคย และค่าในวงเล็บที่สองสอดคล้องกับ cross product ที่คุ้นเคย แต่ถูกแสดงด้วยฐานของมิติใหม่ชื่อ i*j และต่างจาก cross product ตรงที่มัน generalize ไปยังมิติใด ๆ ก็ได้ ในพีชคณิตเชิงเรขาคณิตเรียกสิ่งนี้ว่า wedge product
    พอเข้าใจตรงนี้ การอนุมานสูตรการหมุนก็ง่ายขึ้น เพราะสามารถนำเทคนิคที่คุ้นเคยจากพีชคณิตไปใช้แก้ปัญหาเรขาคณิตได้ตรง ๆ

    • ใน https://youtu.be/htYh-Tq7ZBI?si=lOmsCL2DoqUCQgh1&t=1540 ที่มีคนพูดถึงในคอมเมนต์อื่น Freya อธิบายการลดสัจพจน์ให้เหลือข้อเดียวได้ยอดเยี่ยม
      ถ้ากำหนดให้ค่าของเวกเตอร์คูณกับตัวเองเป็นกำลังสองของความยาวเวกเตอร์นั้น ที่เหลือทั้งหมดก็เป็นผลตามมาจากการคูณพหุนามธรรมดา สวยงามทีเดียว
    • คำอธิบายนี้แสดงความเปรียบต่างที่น่าสนใจ ไม่กี่วันก่อนมีคนถามว่าทำไมชั้นเรียนคณิตศาสตร์ถึงไม่สอนวิธีและเหตุผลของการดำเนินการ แต่ให้แค่สูตรแล้วให้คำนวณ ในขณะที่ตรงนี้โฟกัสอยู่ที่ว่า operation นั้น ทำอะไร มากกว่าทำไมมันถึงเป็นจริง
      “มันทำงานอย่างไร?” กับ “ทำไมมันถึงทำงาน?” เป็นสองคำถามที่ครูคณิตศาสตร์ต้องหาสมดุล และในคอร์สหนึ่ง ๆ ก็ยากที่จะตอบทั้งสองอย่างได้ดีเสมอ
    • พจน์ที่สองไม่ใช่ cross product แต่เป็น ผลคูณพีชคณิตภายนอก หรือไบเวกเตอร์ cross product ใช้ได้เฉพาะใน 3 มิติ แต่ผลคูณพีชคณิตภายนอกใช้ได้ในมิติใด ๆ ที่สูงกว่านั้นด้วย
      cross product ของเวกเตอร์สามมิติสองตัวคือเวกเตอร์อีกตัวที่ตั้งฉากกับระนาบที่เวกเตอร์ทั้งสองสร้างขึ้น ส่วนผลคูณพีชคณิตภายนอกคือ 2-vector หรือไบเวกเตอร์ที่กวาดพื้นที่รูปสี่เหลี่ยมด้านขนานระหว่างเวกเตอร์ทั้งสอง และอยู่บนระนาบที่เวกเตอร์ทั้งสองวางอยู่ ใน 3 มิติ เวกเตอร์จาก cross product จะตั้งฉากกับระนาบไบเวกเตอร์นี้
    • สิ่งหนึ่งที่ใช้เวลานานที่สุดในการเรียนคณิตศาสตร์คือการตระหนักว่า ของส่วนใหญ่ถูกนิยามในวิธีที่เรียบง่ายที่สุดเท่าที่จะเป็นไปได้
      โดยเฉพาะถ้าจะนิยามผลคูณแบบ bilinear m:V x V -> V บนปริภูมิเวกเตอร์ V ก็เท่ากับการกำหนด m เฉพาะกับคู่ของเวกเตอร์ฐานพอดี ถ้าเรียกสิ่งนี้ว่า “สมบัติสากลของ tensor product” ก็คงได้แต่พูดว่า “อ้อ อย่างนี้นี่เอง”
  • สำหรับ interpolation ของการหมุน มีหลายแนวทางที่น่าสนใจ ทั้ง พีชคณิตเชิงเรขาคณิต, quaternion และแม้กระทั่ง interpolation ของเมทริกซ์ทั้งตัว: https://www.gamedev.net/tutorials/programming/math-and-physi...
    แต่พอ optimize โค้ดด้วยมือแล้ว โค้ดสุดท้ายของแนวทางส่วนใหญ่แทบจะคล้ายกัน ความต่างอยู่ที่ว่าเราเข้าใจกฎและความเป็นไปได้อย่างไร
    เท่าที่รู้เล็กน้อย พีชคณิตเชิงเรขาคณิตดูเป็นแนวทางที่สอดคล้องและทรงพลังที่สุด มันไม่คุ้นเคย และรับเข้าไปในตอนแรกค่อนข้างหนัก แต่คนที่ข้ามกำแพงนั้นไปได้ก็มักชอบมัน
    ตรงกันข้าม ทุกคนใช้ quaternion แต่ก็บ่นว่าไม่เข้าใจ และบอกว่าถ้าจะทำให้เห็นภาพต้องใช้หนังสือทั้งเล่ม อย่างหนังสือ 『Visualizing Quaternions』 ของ Andrew J. Hanson และ Steve Cunningham

    • ผมไม่ใช่นักคณิตศาสตร์ และในงานก็ไม่ได้ใช้เรขาคณิตมากนัก แต่กำลังเรียนพีชคณิตเชิงเรขาคณิตเล่น ๆ และเมื่อก่อนก็เคยพยายามเรียน quaternion
      พีชคณิตเชิงเรขาคณิตสนุก ส่วน quaternion ไม่สนุก พีชคณิตเชิงเรขาคณิตรู้สึกเหมือนเข้าใจแล้ว แต่ quaternion แม้จะตามเลกเชอร์และทำโจทย์ไป ก็แน่ใจได้แค่ว่ายังไม่เข้าใจ ตอนนี้พอรู้พีชคณิตเชิงเรขาคณิตบ้างแล้ว ในที่สุดก็เริ่มรู้สึกว่าเข้าใจ quaternion อยู่บ้าง
    • Naive Lie Theory』 เป็นหนังสือที่ยอดเยี่ยม และสอน quaternion ตั้งแต่บทแรก
      https://www.goodreads.com/en/book/show/4419538
  • ถ้าสนใจหัวข้อนี้ มีสไลด์ดี ๆ ที่ไล่ภาพรวมแนวคิด Grassman/Clifford/พีชคณิตเชิงเรขาคณิตอยู่ที่นี่: http://www.terathon.com/gdc12_lengyel.pdf
    และยังมีเว็บดี ๆ อีกแห่ง: https://mattferraro.dev/posts/geometric-algebra

  • ไม่ควรพลาด “A swift introduction to projective geometric algebra” ที่ยอดเยี่ยมของ Sudgy ด้วย: https://www.youtube.com/watch?v=0i3ocLhbxJ4
    และเว็บอ้างอิงหลักคือ https://bivector.net
    ยังเข้าร่วม Discord ของ bivector ที่มีอาจารย์ นักวิจัย และผู้สนใจมากกว่า 1,000 คนได้ด้วย: https://discord.gg/vGY6pPk

    • Eric Lengyel ผู้เขียนงานนำเสนอนั้น ยังเขียนหนังสือ 『Foundations of Game Engine Development, Volume 1: Mathematics』 ด้วย และบทที่ 4 ก็ว่าด้วยหัวข้อเดียวกัน
  • พูดตามตรง ผมไม่ค่อยชอบวิธีที่พีชคณิตเชิงเรขาคณิตทำให้เกิด องค์ประกอบผสม สารพัดแบบ ถ้าไม่ระวังว่ากำลังเอาอะไรไปคูณกับอะไร
    การที่สิ่งที่เคยเป็นปริภูมิ n มิติต้องใช้พจน์ได้มากถึง 2^n ก็รู้สึกจัดการยาก
    มันน่าจะช่วยจัดการเรขาคณิต หรือก็คือผลคูณภายในได้ดีกว่านี้ แต่ผมยังไม่เคยเห็นคำอธิบายที่ทำให้เชื่อได้ว่าทำไมถึงใช้แค่ผลคูณลิ่มกับ ตัวดำเนินการดาว Hodge หรือ musical isomorphism ไม่ได้
    สิ่งที่เหมือน “เวทมนตร์” อย่างการเปลี่ยนไบเวกเตอร์ u^v ให้เป็นการหมุนในระนาบนั้น e^(u^v)t โดยเนื้อแท้แล้วก็คือการใช้ musical isomorphism เปลี่ยน 2-form u^v ให้เป็น automorphism เชิงเส้น แล้วทำให้เข้าใจ e^(u^v)t เป็นเลขชี้กำลังของเมทริกซ์
    อีกตัวอย่างที่ยกกันบ่อยคือทำให้สมการ Maxwell กลายเป็นสมการเดียวได้ แต่ถ้าใช้ differential forms ก็สรุปได้อยู่แล้วเป็นสองสมการที่เป็นจริงด้วยเหตุผลต่างกัน ผมเลยไม่เข้าใจประโยชน์ของการรวมมันเป็นสมการเดียว

    • ประโยคที่ว่า “สิ่งที่เคยเป็นปริภูมิ n มิติต้องใช้พจน์ได้มากถึง 2^n” บางครั้งการประหยัดนั้นเป็นเพียงภาพลวงตา
      ตัวอย่างเช่น เวกเตอร์ปกติแปลงต่างจากเวกเตอร์ตำแหน่ง เราอาจแทนทั้งสองด้วยโครงสร้างข้อมูลเดียวกันได้ แต่ก็ต้องคอยติดตามว่าข้างในเป็นเวกเตอร์ชนิดใด และต้องใส่กรณีพิเศษที่จัดการต่างกันไว้ทั่วโค้ด
      พีชคณิตเชิงเรขาคณิตเผชิญเรื่องนี้ตรง ๆ โดยใช้ฐาน (i,j,k) สำหรับเวกเตอร์ และใช้ฐานแยกต่างหาก (j*k, k*i, i*j) สำหรับชนิดอื่น
      ในแง่ที่ว่าสมการเดียวดีกว่าสองหรือสี่ นี่จึงเป็นตัวอย่างที่ดีว่าปริภูมิมิติสูงกว่ากลับประหยัดด้านการจัดเก็บมากกว่ามิติต่ำกว่าได้
      สนามไฟฟ้าแตกต่างจากสนามแม่เหล็กค่อนข้างคล้ายกับที่เวกเตอร์แตกต่างจากไบเวกเตอร์ จะจัดการสนามไฟฟ้าและสนามแม่เหล็กเป็นสมการแยกแบบเฉพาะกรณีก็ได้ หรือจะจัดการอย่างสม่ำเสมอด้วยวิธีเดียวก็ได้
    • องค์ประกอบผสมนั่นแหละคือส่วนสำคัญ
      ควอเทอร์เนียนที่ w=1, x,y,z=0 คือเอกลักษณ์ ส่วนควอเทอร์เนียนอย่าง w=0, x=1 หรือ w=0, x=y=0.7 สอดคล้องกับการหมุน 180 องศาเท่านั้น
      ถ้าต้องการการหมุนใด ๆ ก็ต้องใช้การผสมของสองอย่างนี้ คือผสม “การหมุน 180 องศารอบเส้นนี้เล็กน้อย” กับ “การหมุน 0 องศา/เอกลักษณ์เล็กน้อย” การมีทั้งสเกลาร์และไบเวกเตอร์อยู่ด้วยกันหมายถึงสิ่งนี้เอง
      ถ้าพยายาม “ระวัง” ด้วยผลคูณลิ่มและผลคูณภายในเพื่อหลีกเลี่ยงการผสม แปลว่าใช้ผิดแล้ว ผลคูณเชิงเรขาคณิต คือพระเอก และมันสร้างการผสมที่ยอดเยี่ยมมาก
    • เห็นด้วยว่าความสับสนมีอยู่แล้ว แนวทางดั้งเดิมแค่กวาดความสับสนนั้นไปซ่อนไว้ใต้พรม
      ตัวอย่างเช่น ถ้าจัดการกับเวกเตอร์ปกติ ก็ต้องติดตามปริภูมิ n มิติอย่างน้อยสองชุดที่แปลงต่างกันพอสมควร
      การแทนจุด ระนาบ เส้น เวกเตอร์ปกติ การเลื่อนขนาน และการหมุนทั้งหมดด้วยชนิด multivector เดียวและกฎที่สอดคล้องกันนั้น เมื่อเข้าใจแล้วค่อนข้างรู้สึกปลดปล่อยมาก แม้ผมเองก็ยังอยู่ระหว่างเรียนรู้ก็ตาม
  • การ interpolation ของแอนิเมชันด้านล่างเจ๋งจริง ๆ แต่ผมรู้สึกว่าโมเดลในส่วนอื่นของหน้าเว็บน่าจะ คึกคักน้อยลง หน่อย
    คณิตศาสตร์ก็ยากพออยู่แล้วโดยไม่ต้องมีลูกช้างเชียร์ลีดเดอร์

    • ผมกลับคิดตรงกันข้าม ถ้าไม่มีแรงเชียร์แบบช้าง ๆ นั่น ผมคงอ่านไปไม่ถึงท้ายหน้า
  • ถ้าผู้เขียนเห็นอยู่ อยากให้ช่วยนิยามตัวย่อ PGA ตอนใช้ครั้งแรกด้วย

    • สำหรับคนที่สงสัย PGA คือ projective geometric algebra หรือ พีชคณิตเชิงเรขาคณิตแบบโปรเจกทีฟ
      มันเพิ่มเวกเตอร์ฐานศูนย์เข้าไปหนึ่งตัวในเวกเตอร์ฐานของปริภูมิที่กำลังทำงานอยู่ วิธีนี้ทำให้แทนวัตถุเรขาคณิตที่ไม่ผ่านจุดกำเนิดด้วยพีชคณิตได้
    • โดยเฉพาะส่วนที่เขียน “Fast PGA” เป็น FPGA นั้นค่อนข้างชวนสับสน
    • แก้แล้ว mea maxima culpa
  • อัลกอริทึมแบบนี้มีประสิทธิภาพไหมเมื่อคำนึงถึง GPU?
    ผมมีภาพจำลาง ๆ ว่า GPU เหมาะกับงานเมทริกซ์ เลยสงสัยว่าถ้าใช้การวางรูปแบบด้วยพีชคณิตเชิงเรขาคณิต จะเสียข้อได้เปรียบนั้นไปจนในทางปฏิบัติไม่ได้ดีกว่าหรือเปล่า
    เป็นการเดาแบบไม่ค่อยรู้ ถ้าผิดก็ช่วยแก้ให้ด้วย

    • เป็นความเข้าใจผิดที่พบบ่อยมากว่าพอมีการคูณเมทริกซ์-เมทริกซ์และเมทริกซ์-เวกเตอร์ในมาตรฐาน GPU แล้ว บริษัท GPU จะต้องเร่งความเร็วสิ่งเหล่านี้แน่ ๆ
      จริง ๆ แล้วทั้ง shader core ก็เป็น SIMD อยู่แล้ว จึงไม่จำเป็นว่าจะทำแบบนั้นได้เสมอไป GPU บางรุ่นทำ บางรุ่นก็ไม่ทำ
    • เวลาเขียนโปรแกรม ต้องหาสองอย่างให้ได้: ปริมาณที่อยากคำนวณคืออะไร และวิธีที่มีประสิทธิภาพที่สุดในการคำนวณมันคืออะไร
      PGA มีภาระในการทำความเข้าใจไม่น้อย แต่เป็นวิธีที่ดีมากสำหรับจัดการข้อแรก ยังไงก็ตาม ปกติแล้วควรลองวิธีที่ง่ายที่สุดและนำไปใช้จริงง่ายที่สุดก่อน
      การนำไปใช้ที่ได้จากการแก้ข้อแรกด้วย PGA นั้นเพียงพอสำหรับทำต้นแบบส่วนที่เหลือของโปรแกรมและเบนช์มาร์กเพื่อหาคอขวดที่แท้จริง โชคดีที่ในกรณีส่วนใหญ่ มันมักเป็นวิธีคำนวณที่เร็วที่สุด หรือเร็วพอจนไม่กลายเป็นคอขวด
      ต่อให้กลายเป็นคอขวด มันก็ทำให้เข้าใจปัญหาที่กำลังแก้อย่างลึกซึ้ง ผมคิดว่าควรมีความเข้าใจแบบนั้นก่อนเริ่มไล่บีบ cycle ด้วยความหวังว่าจะเร็วพอ
    • บทความนี้พูดถึงเรื่องนั้นพอดี สรุปคือโดยรวมอาจอยู่ในระดับใกล้เคียงกัน
  • นี่ดูเหมือนการถกเถียงความต่างเล็ก ๆ น้อย ๆ ที่ปลายสุดของความก้าวหน้า
    การที่แอนิเมชันโครงกระดูก 3D ยังใช้ เมทริกซ์ 4x4 บน GPU หมายความว่าคณิตศาสตร์ที่พัฒนาขึ้นเพื่อจุดประสงค์นี้บน CPU ในยุคประมาณ Half-Life 1 ยังคงอยู่แนวหน้า ตั้งแต่ปี 1998 ถึง 2024 ก็ 26 ปีแล้ว
    อีก 1,000 ปีข้างหน้า แอนิเมชัน 3D ก็คงยังเหมือนเดิม

  • บทความนี้เกินขอบเขตความเข้าใจของผม แต่ชื่อเรื่องทำให้นึกถึงการทดลองที่เคยทำ เรนเดอเรอร์ 3D ง่าย ๆ
    หลังจากพยายามเรียนพีชคณิตเชิงเส้นแล้วล้มเหลวหลายครั้ง ตอนอาบน้ำผมก็นึกขึ้นได้ว่าการหมุน 3D ก็แค่การหมุน 2D สามครั้ง และอันนั้นผมรู้อยู่แล้ว ประมาณหนึ่งชั่วโมงต่อมาก็ได้เรนเดอเรอร์ 3D แบบ wireframe ที่มี perspective ด้วย
    แนะนำให้ทุกคนลองทำดู