หน้าแรก · Lab · Case Files: แก้ปัญหา comp จากงานจริง

CF3 เคส 3: element ว่าง ๆ ที่ทำให้ทั้งเฟรมมืดลง

พิกเซล alpha 0 ที่มีสีติดลบ จาก log black

Case Files: แก้ปัญหา comp จากงานจริง · ~8 นาที · ฟรี

1 อธิบาย

อาการ: พอ merge element จากลูกค้าเข้าไป ทั้งเฟรมมืดลงนิดหนึ่ง แม้แต่ตรงที่ element ว่างเปล่า เงาในหินกลายเป็นดำสนิท ลองชี้เมาส์ที่ node "Log decode (the file)" ตรงที่ว่าง ค่า rgb อ่านได้ −0.014 ทั้งที่ alpha = 0

ต้นเหตุ: element ถูก premult บนค่า log แล้วเก็บเป็นไฟล์ log พิกเซลที่ว่างจึงอยู่ต่ำกว่าโค้ดดำของ log และถอดกลับเป็น linear ได้ค่าต่ำกว่า 0 เล็กน้อย Merge over บวก A เข้าไปตรง ๆ (A + B·(1 − a)) ค่าติดลบจึงไปกด plate ทั้งเฟรม node สามตัวด้านบนจำลองไฟล์นั้น ในงานจริงแก้ไฟล์ไม่ได้ ต้องแก้หลัง Read

fix: rgb + k·(1 − a)

2 ลงมือใน mini compositor

โจทย์: อ่านค่าที่ว่างของ element แล้วใส่ค่าที่หักล้างกันใน "Constant k (fix)" (r, g, b)

ปล่อย node ของไฟล์ (Constant log black, Log decode) ไว้ตามเดิม Merge plus ตัวล่างใช้ (1 − a) เป็น mask อยู่แล้ว

SkyVFX mini compositor · CF3640×360 · float · 1001

3 เจาะลึก

ค่าติดลบมาจากไหน

ไฟล์ log เก็บดำไว้ที่โค้ดที่สูงกว่า 0 ถ้า premult ใน linear อย่างถูกต้องแล้วค่อย encode เป็น log พิกเซลที่ว่างจะได้โค้ดดำพอดี และถอดกลับได้ 0 ปัญหาเกิดเมื่อ element ถูก premult บนค่า log (premult ใน log) พิกเซลที่ว่างจะได้โค้ด 0 ซึ่งต่ำกว่าโค้ดดำ พอถอดกลับเป็น linear จึงได้ค่าต่ำกว่า 0 เล็กน้อย ในงานจริงวัดได้ราว −0.009 ถึง −0.014 แล้วแต่ไฟล์และ log curve

ค่านี้เล็กจนมองไม่เห็นใน element เดี่ยว ๆ แต่ Merge over บวกมันเข้าทั้งเฟรม ทำให้เงาใน plate ที่ค่าต่ำกว่า 0.014 กลายเป็นดำสนิท

  1. 1ไฟล์ log แบบ premult
  2. 2Read ถอดเป็น linear
  3. 3ว่าง = −0.014
  4. 4over บวกทั้งเฟรม

ทำไมแก้ด้วย rgb + k·(1 − a)

ทางลัดแบบ "ถ้า a = 0 ให้สีเป็น 0" แก้แค่พิกเซลที่ว่างสนิท ขอบนุ่มที่ alpha อยู่ระหว่าง 0 กับ 1 ยังติดค่าลบเป็นสัดส่วน จึงเห็นขอบมืดบาง ๆ

การบวก k·(1 − a) คืนค่าตามสัดส่วนความว่าง: ที่ a = 0 บวกเต็ม k ที่ a = 1 ไม่บวกเลย สีของตัว element จึงถูกต้องเท่าเดิม และขอบนุ่มก็สะอาด

k ต้องวัดใหม่ทุกไฟล์ อย่าลอกค่าจากช็อตอื่น

ป้องกันไว้ก่อน: preflight ทุก element

ก่อนใช้ element จากคนอื่น ให้ sample พิกเซลที่ว่าง (ต้องเป็น 0 ทั้ง rgb และ a) ดู alpha ที่ gain ×4 หาเงาหรือคราบที่ติดมา และเช็กว่าเป็นภาพเคลื่อนไหวจริงหรือเฟรมเดียวซ้ำ ปัญหาพวกนี้เจอได้บ่อยในไฟล์ที่ export จากโปรแกรมอื่น

4 ในงานจริง

ทำใน Nuke

  1. Read element → Expression: r + kblack*(1-a) (ทำแบบเดียวกันกับ g และ b) → Merge over
  2. ตั้งชื่อ knob เองให้ไม่ชนชื่อช่อง: ชื่อ g ใน Expression จะอ่านช่องเขียวแทน
  3. หา k: sample ที่ว่างของ element ที่ output ของ Read ไม่ใช่หลัง key หรือ grade
  4. ตรวจผล: comp ตรงที่ element ว่างต้องเท่ากับ plate ก่อน merge (ลบกันด้วย Merge difference ได้ 0)

พลาดบ่อย → แก้ยังไง

  • ✗ ใช้ "a == 0 ? 0 : r" แล้วจบ✓ ขอบนุ่มยังติดค่าลบ ใช้ rgb + k·(1 − a)
  • ✗ วัด k หลัง key หรือ keymix✓ วัดที่ Read โดยตรง ค่าหลัง node อื่นอาจถูกผสมจนผิด
  • ✗ คิดว่าทั้งเฟรมมืดเพราะ plate เพี้ยน✓ ดู plate ก่อน merge กับหลัง merge ถ้าต่างกันตรงที่ว่าง ต้นเหตุคือ element
  • ✗ ใช้ค่า k เดียวกันทุกช็อต✓ k ขึ้นกับไฟล์และ log curve วัดใหม่ทุกครั้ง

เช็กก่อนส่งช็อต

  • ที่ว่างของทุก element อ่านได้ 0 ทั้ง rgb และ a
  • ตรงที่ element ว่าง comp = plate
  • ขอบนุ่มของ element ไม่มีเส้นมืด
  • alpha ไม่มีเงาหรือคราบติดมา (ดูที่ gain ×4)

5 เช็กตัวเอง

เช็กตัวเอง 1 ข้อ

element ว่างเกือบทั้งเฟรม แต่ทั้งเฟรมมืดลง สาเหตุคืออะไร

สิ่งที่ได้เรียน

🔒 ตอบคำถามด้านบนก่อน แล้วการ์ดนี้จะเปิด

คำถามเพิ่ม

1. element ว่างอ่านค่า rgb −0.010, alpha 0 ควรบวกเท่าไหร่ที่พิกเซลขอบที่ alpha 0.5

2. ทำไมค่าติดลบในที่ว่างทำให้ทั้งเฟรมมืด

ตัวเลขมาจากไหน: ค่า −0.014 มาจากการวัดจริงบน element log แบบ premult ในงานหนึ่ง (ปัดเป็น 3 ตำแหน่ง) ค่าจริงต่างกันตามไฟล์ ในห้องนี้จำลองไฟล์ด้วย Constant + Invert + Merge from ให้ได้ rgb − k·(1 − a) Merge, Invert และ Constant ตรงกับ Nuke 17.0v2