1 อธิบาย
P pass เก็บตำแหน่ง 3D ของแต่ละ pixel ไว้ใน R G B (X Y Z) เป็นหน่วยของฉาก (ใน render Blender ของเราเป็นเมตร) matte ที่สร้างจากระยะห่างถึงจุดหนึ่งใน 3D จึงเลือกตามระยะจริง ไม่ใช่ตามตำแหน่งบนจอ ของที่อยู่ติดกันบนจอแต่อยู่คนละความลึกจึงแยกออกจากกันได้ และ matte ยังอยู่ที่เดิมในโลกแม้กล้องขยับ
ประกายไฟลอยสูง 1.0 m เหนือทราย เส้นฟ้าคือขอบของทุกอย่างที่ห่างจากประกายไฟไม่เกิน 2 m: ทรายใต้มันและด้านใกล้ของหุ่น ลอง “วงกลม 2D (จอ)” ก่อนแล้วดูตัวเลขรั่ว จากนั้นสลับเป็น “ทรงกลม 3D (P pass)” คลิกทรายใต้ประกายไฟ (กากบาทส้ม) ยกจุดกลางขึ้น แล้วปรับรัศมี view “P (XYZ→RGB)” แสดงตำแหน่งเป็นสี
matte = 1 − smoothstep(r·(1 − f), r, |P − centre|)2 ลงมือลอง
โจทย์: ทำ matte ของระยะที่แสงประกายไฟส่องถึง คือทุกอย่างที่ห่างไม่เกิน 2 m ครอบเป้าอย่างน้อย 85% และให้ matte รั่วไปไกลกว่า 2.4 m ไม่เกิน 10%
คำใบ้: ขยายวงกลม 2D แล้วดูตัวเลขรั่ว วงกลมที่ครอบเป้าได้ 85% ยังรั่วอย่างน้อย 63% เพราะทรายใกล้กับพื้นที่อยู่ไกลออกไปใช้ pixel ใกล้กันบนจอ ใน 3D ให้คลิกที่กากบาท ยกจุดกลางขึ้นเท่าความสูงของประกายไฟ แล้วค่อยปรับรัศมี
3 เจาะลึก
ตำแหน่งบนจอ กับตำแหน่งใน 3D
roto หรือวงกลม 2D รู้แค่ว่า pixel อยู่ตรงไหนบนจอ ทรายใกล้ประกายไฟอยู่ติดกับพื้นที่ไกลออกไปมากบนจอ วงกลมที่ใหญ่พอจะครอบระยะที่แสงประกายไฟส่องถึงจึงกินพื้นไกลไปด้วย ในฉากนี้วงกลม 2D ที่ครอบเป้าได้ 85% ยังรั่วอย่างน้อย 63%
ใน P pass แต่ละ pixel รู้ระยะจริงถึงประกายไฟ ทรงกลมที่ตั้งจุดกลางที่ประกายไฟจึงเลือกเฉพาะสิ่งที่อยู่ในระยะจริง คือทรายใต้มันและด้านใกล้ของหุ่น และไม่แตะพื้นที่อยู่ไกลแม้จะติดกันบนจอ
ถ้าสองชิ้นทับกันบนจอแต่อยู่คนละความลึก ให้คิดถึง P ก่อนจะวาด roto
สร้าง sphere matte
อ่านค่า P ที่ทรายใต้ประกายไฟ แล้วบวกความสูงของประกายไฟเข้าไปในแกนขึ้น ได้จุดศูนย์กลาง (X, Y, Z) เป็นเมตร จากนั้นทุก pixel คำนวณระยะจาก P ของตัวเองถึงจุดนั้น ระยะน้อยกว่า radius ได้ค่า matte สูง แล้วค่อย ๆ ลดเป็น 0 ตาม falloff
ขอบของ P ที่ผ่าน filter เป็นค่าผสมระหว่างตำแหน่งหน้ากับหลัง การ unpremult ไม่ได้แยกค่าที่ผสมกันออก จึงควร erode หรือ edge-extend matte ก่อนใช้
- 1Shuffle P เข้า rgb
- 2อ่าน P ใต้ประกายไฟ + ยกขึ้น
- 3ระยะถึงศูนย์กลาง
- 4radius + falloff
- 5Erode ขอบ
- 6Grade ผ่าน matte
P, Pref หรือ roto
P matte ยึดอยู่กับตำแหน่งใน world เมื่อกล้องขยับ matte ยังอยู่ที่เดิม จึงใช้แทน roto ที่ต้อง track สำหรับงาน grade ได้ แต่ถ้าวัตถุเคลื่อนที่ วัตถุจะวิ่งผ่าน matte ไป
Pref คือตำแหน่งตอนท่าพัก (rest pose) matte หรือ noise ที่สร้างจาก Pref จึงติดไปกับผิวของวัตถุที่ขยับหรือเปลี่ยนรูป
| แหล่ง matte | เก็บอะไร | matte ทำตัวอย่างไร |
|---|---|---|
| roto 2D | ตำแหน่งบนจอ | ต้อง track ตามกล้อง แยกของที่ทับกันบนจอไม่ได้ |
| P | ตำแหน่งใน world | อยู่กับที่ในฉาก วัตถุที่ขยับวิ่งผ่านไป |
| Pref | ตำแหน่งตอน rest pose | ติดไปกับผิวของวัตถุที่ขยับหรือเปลี่ยนรูป |
P คือ data ไม่ใช่สี
อ่าน P แบบ raw ไม่ผ่านการแปลงสี ค่า P ติดลบได้ ถ้าใช้ Grade เพื่อ scale แกนต้องปิด black clamp ไม่อย่างนั้นตำแหน่งที่ติดลบจะหายไป และ matte ครึ่งหนึ่งจะว่าง
P ของ Blender เป็น Z-up ส่วนเครื่องมือของ Nuke คาดหวัง Y-up จึงต้อง remap แกนก่อนใช้กับเครื่องมือเหล่านั้น
ก่อนเชื่อ P pass ให้อ่านค่าที่พื้นส่วนที่เรียบ แกนที่ชี้ขึ้นต้องได้ค่าเท่ากันทั้งบริเวณ
4 ในงานจริง
ทำใน Nuke
- Read: อ่าน EXR แบบ raw data ไม่แปลงสี แล้ว Shuffle2 ดึง P (หรือ Pref) เข้า rgb
- PositionToPoints2: ตั้ง P_channel (และ N_channel) ดู P เป็น point cloud เพื่อตรวจแกนและหาตำแหน่งประกายไฟใน 3D
- Expression: alpha จากระยะระหว่าง rgb (P) กับจุดศูนย์กลาง หารด้วย radius แล้วกลับค่า
- Erode: กินขอบ matte เข้ามาเล็กน้อย เพราะ pixel ขอบของ P เป็นค่าผสม
- Clamp: เก็บ alpha ไว้ในช่วง 0–1
- Grade: ใช้ matte เป็น mask ของ grade บน comp (ถ้ามี Grade บน P เอง ต้องปิด black clamp)
พลาดบ่อย → แก้ยังไง
- ✗ วาด roto 2D แยกส่วนที่ทับกันบนจอแต่อยู่คนละความลึก✓ ใช้ matte จาก P ซึ่งเลือกตามระยะใน 3D
- ✗ เปิด black clamp ไว้ใน Grade ที่ใช้กับ P✓ ปิด black clamp เพราะ P มีค่าติดลบ
- ✗ ใช้ P กับตัวละครที่เปลี่ยนรูป แล้ว matte ไหลหลุดจากผิว✓ ใช้ Pref ให้ matte ติดไปกับผิว
- ✗ ป้อน P ของ Blender เข้าเครื่องมือ Y-up ตรง ๆ✓ remap แกนก่อน แล้วตรวจว่าพื้นส่วนที่เรียบมีค่าแกนขึ้นคงที่
- ✗ คาดว่าขอบ matte จาก P จะสะอาด หรือหวังให้ unpremult แก้✓ erode หรือ edge-extend matte เพราะ pixel ขอบเป็นค่าผสม
เช็กก่อนส่งช็อต
- P อ่านแบบ raw เป็น data ไม่ผ่านการแปลงสี
- ไม่มี Grade บน P ที่เปิด black clamp ไว้
- แกนของ P ตรวจแล้ว: พื้นส่วนที่เรียบมีค่าแกนขึ้นคงที่
- matte อยู่ที่เดิมในโลกตลอดช็อต ถ้าวัตถุขยับหรือเปลี่ยนรูปใช้ Pref
- ดู view matte แล้วไม่มีส่วนรั่วไปบนพื้นที่อยู่ไกลหรือขอบเรือง
5 เช็กตัวเอง
ทำไมวงกลม 2D ที่ใหญ่พอจะครอบระยะของประกายไฟ ถึงรั่วไปที่อื่น แต่ทรงกลม 3D จาก P pass ไม่รั่ว
🔒 ตอบคำถามด้านบนก่อน แล้วการ์ดนี้จะเปิด
1. หุ่นยนต์เดินและแกว่งแขน อยากได้ matte ที่ติดอยู่กับผิวมือตลอด ควรใช้อะไร
2. ใส่ Grade บน P เพื่อยืด matte ตามแกน แล้วครึ่งหนึ่งของ matte หายไป สาเหตุน่าจะเป็นอะไร
ตัวเลขมาจากไหน: ภาพทั้งหมด render ด้วย Blender 5.2 Cycles จากฉากทะเลทรายและหุ่นยนต์ของเราเอง (tools/assets/passes_cg.py) แล้วคำนวณในเบราว์เซอร์ P pass ของ Blender เป็นเมตรใน world แกน Z ชี้ขึ้น (P ของ plate และ P ของหุ่น) เป้า (ระยะ 2 m จากประกายไฟ) คิดจาก P ของ render เดียวกัน ส่วนที่ห่าง 2–2.4 m ไม่นับทั้งครอบและรั่ว grade สีอุ่นเป็นเอฟเฟกต์แบบสอนหลักการ และ falloff ของทรงกลมเป็น smoothstep แบบสอนหลักการ เครื่องมือใน Nuke อาจใช้ falloff ต่างไป