Videos The power of signed distance functions (SDF)

Description

Signed distance function (SDF) เป็นคอนเซปต์นึงที่เรียบง่ายแต่ทรงพลังมากสำหรับการทำ procedural graphic รูปที่ใช้เปิดตัวงานตอนแรกก็สร้างด้วย SDF Source code and references: https://d4h.cc/sdf Speaker’s channel https://www.youtube.com/@dtinth Recommended videos https://youtu.be/svLzmFuSBhk https://youtu.be/BNZtUB7yhX4 https://youtu.be/0ifChJ0nJfM https://youtu.be/8--5LwHRhjk https://youtu.be/BFld4EBO2RE https://youtu.be/PGtv-dBi2wE

Chapters

  • Intro 0:00
  • What is GLSL fragment shader? 1:06
  • What is Signed Distance Function? 1:51
  • How to write an SDF? 3:03
  • Using the SDF 4:26
  • Composing SDFs 4:57
  • Let’s draw! 6:37
  • Transforming the space 7:19
  • Code compression 8:12
  • Beyond 2D: 3d ray-marching 8:28
  • Learning resources 8:47

Transcript

คำบรรยายต่อไปนี้อาจไม่ถูกต้องทั้งหมด หากคุณพบข้อผิดพลาดใดๆ คุณสามารถช่วยแก้ไขข้อผิดพลาดได้บน GitHub

Intro0:00

โอเคครับ

อันนี้จะเป็นหัวข้อสั้นๆ นะครับ ที่อยากจะแชร์กับทุกๆ คนนะครับ สวัสดีครับทุกคน ผมชื่อไทนะครับ เพิ่งได้แนะนำตัว หัวข้อ Lightning Talk ของผมวันนี้นะครับชื่อว่า The Magic of Signed Distance Function นะครับ อันนี้คือหน้าเว็บของงาน Creative Coding Meetup บน Eventpop นะครับ แล้วอันนี้ก็คือภาพแบ็กกราวนด์ที่ใช้เนาะ ซึ่งแน่นอนครับสร้างด้วยโค้ดนะครับ แต่ถามว่าใช้โค้ดกี่บรรทัด คือรูปเนี้ยผมมองว่ามันก็มีเอฟเฟกต์เยอะเนาะ มีทั้ง gradient มีทั้ง pattern ที่มันซ้ำกันเรื่อยๆ แล้วก็มีเอฟเฟกต์ ที่เป็นแบบ Inner Glow อ่ะ ถ้าผมเป็น web developer นะ ถ้าคิดว่าถ้าใช้ HTML CSS Canvas หรือ SVG เนี่ย น่าจะหลายสิบบรรทัด แต่ว่า ลอจิกหลักๆ จริงๆ เนี่ยมีแค่ 7 บรรทัดเท่านั้นครับ คราวนี้เนี่ย สมัยก่อนนะก่อนที่ผมจะรู้จักเรื่อง SDF เนี่ย เวลาผมเห็นคนสร้างรูปแบบนี้ได้เนี่ย ผมแบบว้าวมากเลย เพราะไม่คิดว่าโค้ดแค่ 7 บรรทัด มันจะสร้างรูปอะไรแบบนี้ได้ ก็มันก็เป็นอะไรที่ magic มากๆ จนกระทั่ง ผมไปศึกษามันแล้วก็อยากจะมาแชร์ ในวันนี้นะครับว่าแต่โค้ดนี้มันคืออะไร เดี๋ยวเราไปดูกันนะครับ

What is GLSL fragment shader?1:06

โค้ดนี้เรียกว่า Fragment Shader นะครับ เขียนด้วยภาษา GLSL ย่อมาจาก OpenGL Shading Language นะครับ เราสามารถเขียน Fragment Shader ใน VS Code ได้โดยใช้ Extension ที่ชื่อว่า glslCanvas นะครับ โดยหน้าที่หลักของ Fragment Shader เนี่ย คือเอาไว้คำนวณว่า ณ ตำแหน่งใดๆ บนหน้าจอเนี่ย จะให้ GPU วาดสีอะไรลงบน pixel นั้นนะครับ

โดย input เนี่ยจะเป็นตัวแปร ชื่อ gl_FragCoord หน้าตาแบบนี้นะครับ เสร็จแล้ว output คือตัวแปร ชื่อ gl_FragColor — ตัว GPU เนี่ย มันจะรันโค้ดของเรา 1 ทีต่อ 1 pixel แต่ด้วยความที่มันเป็น GPU มันรันหลายๆ pixel ได้พร้อมๆ กันนะครับ แล้วตอนที่โค้ดเรารันเสร็จเนี่ย ตัวแปร gl_FragColor มีสีอะไร มันจะเอาสีนั้นไปเพ้นท์บนหน้าจอนะครับ ฉะนั้นรูปเนี้ยผมใช้ concept ที่เรียกว่า Signed Distance Function นะครับ

What is Signed Distance Function?1:51

ซึ่งผมคิดว่าเป็น concept ที่ทรงพลังมากๆ เลย ฉะนั้นเดี๋ยว session เนี้ย ผมจะไปแบบรวบเร็วมากๆ นะครับ ถ้าฟังแล้วไม่เก็ตทั้งหมดไม่เป็นไรนะ ความตั้งใจผมคืออยากให้รายละเอียดต่างๆ มันผ่านหูผ่านตาซัก 1 รอบ พอไปศึกษาแบบละเอียดจริงๆ เนี่ย ก็อาจจะช่วยให้เข้าใจได้ง่ายขึ้นนะครับ ฉะนั้นมันคืออะไร เดี๋ยวไปดูกันนะครับ สมมุติว่าเรามีรูปร่างหรือ shape นึงนะ ตัวอย่างเช่นวงกลมวงเนี้ย เราต้องการ- เราจะเรียกสิ่งที่เราต้องการจะวาด ว่าเป็น scene นะครับ scene ก็คือ แทนสิ่งที่เราต้องการจะวาดเนาะ SDF คืออะไร? SDF คือฟังก์ชันที่ รับจุดเข้ามาจุดนึง แล้ว return ระยะห่าง

ระหว่างจุดนั้นกับตัว scene นะครับ อย่างเช่นจุดนี้ อ่า จะเห็นว่ามันห่างจากขอบของวงกลม 2 หน่วยเนาะ ฉะนั้นฟังก์ชัน SDF ของเราเนี่ย ถ้ารับจุดนี้เข้าไป จะต้องรีเทิร์นเลข 2 มา - ถ้าจุดนี้ล่ะครับ? - 1 - จุดนี้ล่ะครับ? - 0 โอเค 0 ครับ จุดนี้ล่ะครับ? -1 ถูกต้องครับ คือถ้าจุดมันอยู่ข้างในรูป มันจะต้องรีเทิร์นเลขติดลบมา เพราะว่ามันมาจากคำว่า signed signed แปลว่ามีบวกมีลบนะครับ ดังนั้นเนี่ย SDF หน้าที่ของมันคือทำแบบนี้

How to write an SDF?3:03

คราวนี้ ฟังก์ชันนี้เนี่ย SDF เราจะเขียนฟังก์ชั่น ให้วงกลมนี้ยังไงนะครับ วงกลมมีจุดศูนย์กลาง (h, k) มีรัศมี r นะครับ ถ้าเราอยากจะดูว่าตำแหน่ง (x, y) ห่างจาก ขอบวงกลมเท่าไหร่ก็เอาสูตร ม. 3 มานะครับ เอ๊ะ ม. 4: (x - h)² + (y - k)²

ทั้งหมดสแควรูทนะครับ มันคือสูตรอะไรนะ

เรขาคณิตวิเคราะห์ ภาคตัดกรวย ที่เรียนกันตอน ม. 4 นะครับ เราก็เอารัศมีมาหักลบ เราก็จะได้ SDF ของวงกลมนี้ครับ แต่ว่าจริงๆ น่ะ เวลาเราเห็นสูตรแบบนี้ มันน่ากลัวนะ เราตั้งชื่อง่ายๆ แล้วกัน จุด C จุด P เรามีเวคเตอร์ CP มีเวกเตอร์ CP เราเขียนแบบนี้สั้นสั้นก็ได้ ซึ่งมันก็จะเข้าใจง่ายด้วยนะ เพราะว่าถ้าจุด- เพราะว่าถ้าจุด P มันอยู่นอกวงกลมเนี่ย เส้นนี้มันจะยาวกว่ารัศมี มันจะได้เลขบวก แต่ว่าถ้าจุดนี้มันย้ายไปข้างในเนี่ย เส้นนี้มันจะสั้นกว่ารัศมี จะได้เลขลบ ดังนั้นเขียนแบบนี้ได้ ด้วยความที่เราเป็นโปรแกรมเมอร์ครับ เราตั้งชื่อ C ตั้งชื่อ P มันไม่ดีนะครับ เราควรจะตั้งชื่อตัวแปรให้มันสื่อเข้าใจง่ายหน่อย พอมาเขียนเป็น GLSL ก็จะได้โค้ดประมาณนี้นะครับ และสุดท้ายถ้าเรารู้ว่าจุดศูนย์กลางอยู่ตรงไหน รัศมีอยู่ตรงไหน เราสามารถ hard code เข้าไปได้ ทำให้โค้ดมันสั้นลง ก็จะเหลือแค่นี้ครับ ฉะนั้นเนี่ยเราสามารถ represent วงกลมด้วย สูตรสั้นๆ แค่นี้ได้แล้วนะครับ ในเว็บของคุณ Inigo Quilez เนี่ย จะมีสูตรของ SDF ต่างๆ ให้ศึกษา เยอะมากนะครับ

ก็ลองไปศึกษากันได้นะครับ คราวนี้เนี่ยเรามี SDF แล้ว เราเอาไปทำอะไรได้นะครับ

Using the SDF4:26

สิ่งที่เราทำได้คือเราสามารถเช็คค่า SDF ณ จุดต่างๆ แล้วก็เอาระยะทางเนี่ยมา map เป็นสี

พอ map เป็นสีแล้วก็ระบายสีลงไป ทำแบบเดียวกันกับทั้งภาพ เราก็จะได้รูปวงกลมแบบนี้นะครับ ก็จะเห็นว่าโค้ดสั้นๆ แค่นี้ สามารถ present วงกลม ส่วนโค้ดตัวนี้เอาไว้คำนวณ แปลงจาก distance กลายเป็นสี ด้วยความที่มันเป็นโค้ดเนี่ย เราก็สามารถปรับ shading ได้ตามใจ ที่เราต้องการนะครับ

Composing SDFs4:57

คราวนี้ความเจ๋งต่อไปของ SDF คือ เราสามารถเอา SDF มา compose กันได้นะครับ สมมุติว่าเรามีวงกลมสองวงนะ แต่ละวงกลมก็จะมี SDF ของมันเองนะ อันนี้คือระยะห่างจาก A ระยะห่างจาก B ถ้าเราเอาระยะห่างจาก A และระยะห่างจาก B มา minimum กัน - คิดว่าเกิดอะไรขึ้นครับ? - รวม?

ใช่ครับ มันจะได้รูปนี้ เหมือนกัน union เหมือนกัน เอารูปมา union กันนะครับ ก็จะได้รูปนี้ แล้วถ้าเอามา max กันล่ะ? - ตัดกัน - มันก็จะได้รูปนี้ เหมือนเป็นการ intersect กันนะครับ ฉะนั้นเนี่ย จะเห็นว่า SDF ง่ายๆ หลายๆ อันเนี่ย เอามารวมกัน ด้วย operation ง่ายๆ มันสร้างรูป ได้เยอะมากเลย เช่น ถ้าเอา SDF มาติดลบ ก็จะเหมือนกลับข้างในเป็นข้างนอก ข้างนอกเป็นข้างใน พอเราเอามาติดลบแล้วเอามา max กัน ก็จะได้รูปนี้ เหมือนเอาเฉพาะ area ที่อยู่ใน A แต่ไม่อยู่ใน B ทำกับอีกด้านนึงแล้วเอามารวมกันก็จะได้รูปนี้ อ่า เอาตัวเลขมาลบออก มันจะทำให้รูปกว้างขึ้น

เอาตัวเลขมาบวกเข้าไปเนี่ย มันจะทำให้รูปเล็กลง แล้วก็ตามเน็ตเนี่ย มันจะมีฟังก์ชัน ภาษา GLSL ให้เราไป โหลดใช้ได้เยอะ มากเลยครับ อย่างเช่นฟังก์ชัน smoothMin เนี่ย เป็นฟังก์ชันง่ายๆ ที่ทำหน้าที่คล้ายๆ ฟังก์ชัน min แต่ว่าเวลาเอามาใช้กับ SDF เนี่ย ตอนที่ขอบมัน จะรวมกันน่ะ มันดูสวยขึ้นน่ะ มันดูมนๆ ขึ้นเนาะ ถ้าเรา เอา SDF มา absolute แล้วก็ลบตัวเลขออก จากรูปทึบมันจะกลายเป็น outline นะครับ เอาเป็นว่าทำได้หลายอย่างมากๆ เลยครับ จากรูป ง่ายๆ เล็กๆ นะครับ แล้วก็อย่างที่บอก พอเรามี distance เนี่ย เราสามารถเอามาทำเป็น ระบายสีได้

Let’s draw!6:37

ฉะนั้นเดี๋ยวเรามา วาดรูปนี้กันนะครับ ผมเริ่มจากวงกลมเล็กๆ อันนี้ก่อน แล้วก็วงกลมใหญ่ๆ ชื่อว่า B เนาะ เสร็จแล้วผมมีแท่ง แท่งแนวตั้งเนี่ย ชื่อว่า C แท่งแนวนอนชื่อว่า D เสร็จแล้วผมเอามา max กัน เกิดอะไรขึ้นครับ

max กันกลายเป็นสี่เหลี่ยม กลายเป็นสี่เหลี่ยม เหลือรูปนี้ เสร็จแล้วผมเอา E มา min กับ B ก็กลายเป็นรูปนี้ เสร็จแล้วผมสร้างวงกลมอีกรูปนึง แต่ว่าเอาเฉพาะพื้นที่ข้างนอก แล้วเอามาตัดกับรูปนี้ ตัว F เนี่ย ก็จะเหลือตัวนี้ สุดท้ายผมเอาตัว H เนี่ยมา min กับตัว A ก็จะได้รูปนี้ครับ

Transforming the space7:19

คราวนี้ความเจ๋งอย่างถัดไปของ SDF นะครับคือ เราสามารถแก้ไขรูปโดยการปรับเปลี่ยนระบบพิกัดครับ จะเห็นโค้ดตรงนี้ที่ผมคอมเมนต์ไว้นะ p = abs(p) การที่เราเอา p มา absolute p = abs(p) เนี่ย การ absolute เกิดอะไรขึ้น คือระบบพิกัดที่- พิกัดที่มันอยู่ตำแหน่งลบเนี่ย มันจะกลายเป็นภาพสะท้อนของตำแหน่งบวก สิ่งที่เกิดขึ้นคือกลายเป็นแบบนี้ครับ อย่างต่อไปคือการ modulo นะครับ

การ modulo คือพิกัดที่มันเลยตัว divisor

ผมจำไม่ได้ว่าเรียกว่าชื่อว่าอะไร แต่ว่ามันจะ wrap กลับไปข้างล่าง มันก็จะทำให้ pattern repeat สุดท้ายผมก็- อีกรูปนึงก็คือ ตัวนี้ผมพลิกระบบพิกัด

ให้มันเป็นแนวทะแยงก็จะได้รูปนี้นะครับ แล้วก็ปรับเฉดสีก็จะเป็นแบบนี้

Code compression8:12

คราวนี้ก็เหลือแค่ inline โค้ดทั้งหมดเข้าไป มันก็จะเป็นแบบนี้

เหลือแค่นี้ โอเค ใกล้หมดเวลาแล้วนะครับ นอกจาก 2 มิติ นะ SDF เนี่ย สามารถใช้วาดรูป 3 มิติด้วย

Beyond 2D: 3d ray-marching8:28

แต่ผมยังทำไม่เป็นเนาะ แต่ว่าบนเว็บของคุณ Inigo Quilez เหมือนเดิมเนี่ย เขามีเว็บ รวมสูตร SDF 3 มิติ ไปให้ศึกษากัน จริงๆ เนี่ยไอ้นี่ผมยกมาให้ดู แค่นิดหน่อยนะ แต่ว่าเว็บของเขาเนี่ย คือแบบยาวมากๆ มีสูตร SDF ต่างๆ เต็มไปหมดเลย

Learning resources8:47

ผมยังทำแบบที่เขาทำไม่เป็นนะ แต่ว่าผมมี channel YouTube อะไรต่างๆ มาแนะนำ ให้ลองไปศึกษาดูนะครับ ถ้าสนใจ channel แรกชื่อ SimonDev นะครับ เขาจะสอนการทำเทคนิค ray marching แล้วก็ใช้ SDF เนี่ย ในการวาดรูปด้วย math จะเห็นว่า SDF เนี่ยสามารถเรนเดอร์ พวกเงา สามารถเรนเดอร์

พวก shading คำนวณแสงและเงาได้นะครับ อีก channel นึงคือ channel Code Parade นะครับ เอา SDF เนี่ยแล้วก็ ray marching เนี่ย มาสร้างเป็น fractal 3 มิติ สุดท้ายนะครับ Inigo Quilez คนเดิมนะครับ คือ โหดมากๆ เขาสร้างภาพคน สร้างภาพวิวทิวทัศน์ สร้างภาพต่างๆ ด้วยเทคนิคพวกนี้ ทุกอย่างทำด้วยสูตรคณิตศาสตร์ ไม่ใช้ไฟล์โมเดล ไม่ใช้ไฟล์ texture เลยนะครับ มีโค้ดให้ศึกษาด้วย เดี๋ยวลองไปดูกันได้นะครับ คุณ Inigo Quilez เขาทำเว็บเนี่ยครับ ชื่อ ShaderToy เนาะ ก็เข้าไปที่เว็บเนี้ย แล้วก็ลองกดดูรูปต่างๆ เราจะเห็น source code นะครับ แล้วลองไปแก้ source code ดูว่ามันมีผลกับรูปยังไงนะครับ ก็เอาไว้ให้ศึกษาทำความเข้าใจ

กับ SDF ได้นะครับ สุดท้ายก็จะมี hashtag ชื่อ つぶやきGLSL นะครับ

ที่คนใน Twitter เนี่ยก็จะมาโชว์พาวกัน ว่าเขาสามารถสร้างรูป อะไรได้บ้าง โดยใช้โค้ด GLSL แค่ 1 ทวีตนะครับ

ก็ผลงานเจ๋งเยอะมากนะครับ ก็ลองเข้าไปดูใน hashtag นี้นะครับ พวกลิงก์ต่างๆ เกี่ยวกับ talk นี้นะครับ ผมจะใส่ไว้ที่ URL นี้นะครับ โอเคครับ ก็เนื้อหาที่จะแชร์ ก็มีประมาณนี้ครับ ขอบคุณมากครับ