วันอาทิตย์ที่ 21 มิถุนายน พ.ศ. 2558

Premultiply & Unpremultiply

เรื่องแรกๆที่จะสับสนเกี่ยวกับการ Composite CGI(Computer Generate Image) ก็คือเรื่อง Premultiply (หรือ Premul) และ Unpremultiply (หรือ Unmul, Divide) มันคืออะไร? ทำไมเราถึงต้องเข้าใจมัน ก่อนที่จะเป็น Compositor ที่ดีได้?


เรื่องแรก ก็คือ CG render นั้น สะดวกสบายสำหรับเราเพราะ CG render นั้น มาพร้อมกันทั้งข้อมูลสี(RGB) และความโปร่ง(transparent) หรือ alpha(A) ของเรา
แต่ถ้าเราเริ่ม Color Correct(CC) ภาพ CG ของเรา เราเริ่มที่อาจจะเจอปัญหาแปลกๆกับขอบภาพ CG ซึ่งนั่นเป็นเพราะว่าภาพ CG ที่ render ออกมานั้น ส่วนใหญ่เป็นภาพแบบ Premultiply - แปลว่า ภาพที่คุณเอามาใช้นั้น ภาพนั้นถูก "คูณ" ด้วย Alpha channel แล้ว(RGBxA) ซึ่งจริงๆแล้ว เราควรจะ CC ก่อนที่ภาพจะถูก"คูณ" ไม่ใช่หลัง เพราะงั้นเราจึงควรจะต้อง UnPremul เสียก่อน

แล้วมันหมายความว่าอย่างไร คูณก่อน หรือ คูณทีหลัง?


อันดับแรก เรามาดูภาพกัน สมมติว่าภาพข้างบนนี้เป็นภาพลูกบอลที่ประกอบไปด้วยสีต่างๆใน Channel RGB(สีในภาพทำไว้ยกตัวอย่างเฉยๆ) ที่ render จากโปรแกรมอย่าง Maya, 3ds max ทางด้านซ้ายคือภาพที่เราเห็น ส่วนทางขวาคือ Alpha channel ซึ่งโดยปกติภาพที่เราได้มาจากโปรแกรม 3d ส่วนใหญ่นั้นจะเป็นภาพแบบ Premultiply ซึ่งก็คือภาพ RGB ที่ถูก Multiply(คูณ) กับ Alpha แล้ว
โดยถ้าเราดูในแต่ละ Channel แล้ว นี่คือสิ่งที่เราจะเห็น
โดยเราจะเห็นว่าขอบของภาพที่อยู่ในแต่ละ Channel นั้น จะ Fade ตามค่าของ Alpha จากขาวไปสู่สีดำ(ซึ่งสีดำเป็นสีของ Background ที่ถูกเซทจาก Render ของโปรแกรม 3D ส่วนใหญ่) เพราะค่า Alpha นั้น จะมีค่า 0-1 (ดำ-ขาว) อะไรก็ตามที่ถูก"คูณ"ด้วย 0-1 ค่านั้นก็จะเปลี่ยนไปเช่น

Value     Alpha    Result
1                1             1
0.5             0.5          0.25
0.25           0             0

ในขณะที่ถ้าเราดูภาพที่ไม่ได้ทำการ Premultiply หรือเรียกว่า Straight(ใน AE) นี่คือภาพที่เราจะเห็น
ซึ่งถ้าเราดูในแต่ละ Channel ของ RGB นั้น เราจะเห็นว่า ในแต่ละ Pixel ตามขอบภาพนั่นน่ะ ค่าสี(Value) ของแต่ละ Pixel นั้นน่ะ จะยังมีค่าที่ ควรจะเป็น ก่อนที่จะถูก "คูณ" ด้วย Alpha

โดยในโปรแกรม Composite ต่างๆ ก็จะมีวิธีหรือชื่อเรียก กระบวนการ นี้ที่แตกต่างกันไป เช่น AE จะใช้ส่วนของการ Interpret Footage ในขณะที่ Nuke, หรือ Fusion จะใช้ Node Premult/Unpremult และ AlphaDivide/AlphaMultiply ตามลำดับ

ซึ่งกระบวนการ Composite นั้น จะใช้วิธีไหนก็แล้วแต่ เพียงแต่เราต้องพึงระลึกไว้เสมอว่า เราทำงานกับภาพแบบ Premult หรือ Straight เพื่อเมื่อเราทำการ Composite ไปนั้น มันอาจะเกิดอาการของขอบภาพดำ หรือขาวขึ้นมาได้ เพราะ เกิดจากการ "คูณ" ซ้ำไปซ้ำมาหรือเปล่า? ยกตัวอย่างตอนต้น

           Premultiply
Value     Alpha    Result
1                1             1
0.5             0.5          0.25
0.25           0             0

ถ้าเราเอาภาพที่ Premult มาแล้ว แล้วทำการ Composite ที่เกี่ยวข้องกับการ "คูณ" นั่นหมายถึงว่า เรากำลังทำการ"คูณ" เข้าไปอีกหนึ่งครั้ง (RGA x Alpha) x Alpha ซึ่งมักเป็นต้นเหตุของขอบภาพที่มืดดำกว่าที่เราคิด ดังเช่นตารางต่อไปนี้

           Premultiply           x          Composite         =      What You Get
Value     Alpha    Result                Alpha                             Result
1                1             1                         1                                      1
0.5             0.5          0.25                     0.5                                    0.125
0.25           0             0                         0                                      0

โดยคุณจะเห็นว่า ในขณะที่ส่วนที่ Alpha เป็น 0 หรือ 1 นั้น ภาพที่คุณจะได้นั้น ไม่เปลี่ยนแปลงไป แต่ส่วนที่เปลี่ยนแปลงไป ก็คือ ส่วนที่อยู่ระหว่าง 0-1 นั้น จะ "มืด" ลงอย่างรวดเร็ว

ส่วนที่ว่าทำไมจึงต้องทำ CC ก่อนที่จะทำการ Multiply นั่นก็เพราะว่า บางกรณีของ CC นั้นเป็นกระบวนการแบบ บวก หรือ ลบ ซึ่งจะต่างจากการ คูณ โดยจะยกตัวอย่าง

RGB x Alpha x ColorCorrect = RGB x ColorCorrect x Alpha

ซึ่งอันนี้ไม่มีปัญหา จะเรียงแบบไหนก็ได้
แต่เมื่อมีการ บวก หรือ ลบ ในการทำ CC นั่นจะทำให้ทุกอย่างเปลี่ยนไปทันทีเพราะ

(2 + 3) x 4 ไม่เท่ากับ (3 x 4) + 2

ดังเช่นตัวอย่างนี้

Unpremult CC                                              Premult CC
0.6 pixel value                                              0.6 pixel value
 + 0.2 add color correct value                         x 0.5 premultiply by alpha pixel value
0.8 color correct pixel value                           0.3 premultiplied pixel value
 x 0.5 premultiply by alpha pixel value            + 0.2 add color correct value
0.4 correct resulting RGB value                  0.5 wrong resulting RGB value



โดยสรุปที่แนะนำเอาไว้ในหนังสือ Digital Compositing for Film and Video นั่นก็คือ

  1. ถ้าคุณไม่ต้องการจะทำ CC ภาพ CG ก็ให้ปล่อยให้มันเป็น Premultiply ไป และเมื่อทำการ Composite ก็ให้ ปิด การทำ premultiply ที่ composite node นั่นซะ 
  2. ถ้าคุณต้องการทำ CC ภาพ CG ก็ให้คุณ Unpremult ซะก่อน แล้วก็ทำ CC ของคุณซะ และเมื่อถึงการ Composite ก็ให้คุณ เปิด การทำ premultiply ที่ composite node นั่นซะ


7VnBcpswEP0aH9MB2yHJMXaT9NL2kOm0PSpGBk2ERGUR2/n6rNDKiOCkTVHwTN2T0VtppX0Pdlk8msyLzY0iZf5ZppSPxlG6GU0+jsbjOI6n8GOQrUWSCEYGyBRLcVID3LJHasHTCNGKpXTVmqil5JqVbXAhhaAL3cKWkre3KEmG7j3gdkF4F/3OUp1b9HycNPgnyrLcbRMnF9ay0lvnI6VLUnF9UkMYa0GcL4xqE9nhCe64fTYuiWid6FHKogUoutpR5aJl7egFeWjteSdVSlUL4kzc+zROrkBKJSU4MlfFZk65kdMpZZddv2DdnV1RgUd5fcF4Ylc8EF5hLB06laxESs2CeDSZrXOm6W1JFsa6hjsOsFwXHM3ojipN3Q3YPVMTKdy0VBZUqy1MWXuCR8hP7ok9TtAXQcay3domRLjAKF+IOHDAmSJ2/78MGhe4hw2fUTf0KIndLeNTkiDWhxFMDwEZoVSEpyQ+G5CT08Cc3Bk//Sk5KCeYgoNxIhURUAz6szI9JCtngVkpK1XCwv6sJM9ZiQdkxe3lsUBTKPQ4lErnMpOC8KsGnTU8QS32OaEbpn941z/NlA+nZiTgYMZkVtSDxrbSSt7v3iKmu+JkDvI6p3BuWalaoCY/aqIyirPq9NBlXlFONHtoe+9FozvOP0AjplSfxjqjDEEjSrj3mexN0llIljDJ+izVGWYIllCh92EJ9A/HEubYg7C0rwwmHE4xW0o4ss9f8qsyL/K14cR2C5cwYTwtN40RrjLzO7txfuAI1pU1dFSBmmBwTw7L61xyaboLIYXJA0vG+TOIcJaZtmYB5JpGZGYqDIPu6xINBUvTOonsq1ISZi+5XAOSwzx4yev3vv+GV1902ipTIcTcV71DiLnI2H817eOC/fkgcp73ljM+3yfnN1EqWsA3hSMV9bCq4l7BVa2Zn0ulzFer4xT2z1qndxLWNR/Bs+9cFuWRCtrp+iLMiYMIij6CC3oN70aRzb8QnvV454xfv3ha79BjLb8Xbf3dMzaI/N1PH363irT9tqfAPgK7itqy6ylsG9G0FZ2eovkG/eaewv234TUVlr3wXQUMm2/8tc3772Zy9QQ=

ถ้าใครต้องการเข้าใจเรื่องนี้แบบละเอียดกว่านี้ ลองดู video ที่ผมดู น่าจะทำให้เข้าใจได้มากขึ้นอีก

หรือจาก link พวกนี้ครับ

  1. Getting An Edge On Understanding Premultiplication
  2. Understanding Premultiplied Images

ไม่มีความคิดเห็น:

แสดงความคิดเห็น