วันจันทร์ที่ 1 มิถุนายน พ.ศ. 2558

Color space 101

หน้านี้แปลมาจาก (http://galannicolas.com/mediawiki-1.13.3/index.php?title=Color_Space_101) และทำการดัดแปลงนิดหน่อยในเรื่องโปรแกรมที่พูดถึง เพราะ ไม่มีใครใช้ Shake กันอีกแล้ว ผมเลยเปลี่ยนเป็น Nuke, Fusion แทน

โพสนี้หวังว่าจะทำให้เข้าใจเรื่อง Color Space ได้มากขึ้น ไม่มากก็น้อย โดยจะอธิบายให้เข้าใจง่ายๆ โดยไม่เน้นเป๊ะมากนัก
 

เปรียบเทียบ

เมื่อทำการแสดงผลแบบที่ไม่มีการทำ color management เลย, ขึ้นอยู่กับข้อมูลที่อยู่ในไฟล์ภาพ คุณจะเห็นภาพประมาณนี้

LINEAR

Linear color space = physical color space

ฟิสิกส์อาจจะทำให้ปวดหัวก็จริง แต่มันทำสามารถอธิบายกฏ และความเข้าใจเกี่ยวกับพฤติกรรมของแสงได้เป็นอย่างดี
โดยสูตรที่ใช้ทำการปรับภาพโดยวิศวกรนั้น มาจากฟิสิกส์ ดังนั้นมันเลยถูกออกแบบมาให้ทำงานได้ดีกับ physical color space (หมายถึงการตรวจวัดแสง) โดยใน physical color space นั้น แสงทำตัวเป็นแบบ linear (หมายถึงเป็นเส้นตรง) เพราะงั้น physical color space จึงหมายถึง linear color space
แต่สูตรก็สามารถทำงานได้ไม่เลวนักบน color space อื่นๆ เพราะงั้นหลายๆคนเลยไม่เข้าใจว่าอะไรกันนักหนา ที่จะต้องมาเจ้าใจอะไรให้มากมาย ซึ่งประโยชน์ที่แท้จริง ก็คือ ทำให้ภาพออกมาดีที่สุด

จะรู้ได้ยังไงว่า ภาพที่ได้มาเก็บข้อมูลมาเป็นแบบ linear ?

ภาพที่เก็บข้อมูลมาเป็นแบบ linear จะดู "มืด" เกินไป ถ้าคุณดูภาพแบบ ไม่มี การทำ color management.
ดังนั้นถ้า 95% ของเวลาที่คุณเห็นภาพที่ดูมืดเกินไป(ไม่ได้ทำ color management), ก็ให้เดาได้ว่ามันถูกเก็บข้อมูลมาเป็นแบบ linear.

ไฟล์นามสกุลใด ที่ออกแบบมาให้ใช้ linear color space เป็นค่ามาตราฐาน

------------------------------------
Open EXR (.exr)
------------------------------------
แต่ก็มิได้หมายความว่า ทุกไฟล์ Open EXR จะถูกเก็บข้อมูลแบบ linear

ถ้าคุณทำงานกับภาพ linear

อย่าทำงานแบบ 8 bits depth per channel. มันจะทำให้ได้ผลลัพย์แย่ๆ (จะไม่อธิบายนะ เพราะไม่อยากให้ยาก)

ข้อดี

เมื่อเข้าใจแล้ว คุณจะทำงานได้ดีขึ้น เวลาทำ lighting และ compositing.

ข้อเสีย

คุณต้องมีโปรแกรมที่ทำงานแบบมี color management เพื่อจะเห็นภาพที่ถูกที่ควร.
ต้องทำความเข้าใจใหม่เรื่องแสงจาก "classic lights" แบบเดิมๆ เป็นของใหม่เมื่อใช้ "physical lights".

Physical lights / physical shaders

  • ถ้าสูตรถูกออกแบบมาเพื่อใช้กับ linear space, ทำไม "classic parameters" ของแสงถึงใช้งานไม่ได้?
ก็เพราะว่า "ความเร็ว" และ "ราคาของที่จัดเก็บข้อมูล" ในสมัยเริ่มต้นของการทำ CG
คือเมื่อก่อน Computers ช้า และแพง เพราะงั้นจึงไม่สามารถใช้สูตรจริงๆได้ จึงต้องทำการ "ประมาณหยาบๆ" และอีกอย่างก็คือการหลอกๆบางสมการ (เช่น: specular และ reflections) และยังไม่สามารถใช้ค่าแบบ linear ได้ เพราะข้อมูลนั้นต้องการค่าที่มากกว่า 8 bits per channel จะเก็บได้ เมื่อเทียบกับข้อมูลที่เราต้องการเมื่อเทียบกับสายตาของมนุษย์ โดยการหลอกๆนั้นก็ได้ทำให้ เกิดความไม่ต่อเนื่องกันกับโลก physical (ซึ่งสมัยก่อนก็จำเป็น เพราะมีคล้ายๆก็ยังดีกว่าไม่มีเลย) แต่ไอเดียหลักๆของสูตรพวกนี้ก็ยังมาจากโลก physics. ตอนนี้ computers ก็เร็วขึ้น และถูกลง ทำให้สามารถทำให้เราใกล้เคียงโลกความจริงขึ้นเรื่อยๆ (เช่น: global illumation).
 

LOG

Log color space = film scan color space

จะรู้ได้ยังไงว่า ภาพที่ได้มาเก็บข้อมูลมาเป็นแบบ log ?

ภาพที่เก็บข้อมูลแบบ log จะดูฝ้าๆ ถ้าคุณดูภาพแบบ ไม่มี การทำ color management.
ดังนั้น 95% ของเวลาที่คุณเห็นภาพที่ฝ้าๆแบบเห็นได้ชัด (โดยไม่ได้ทำ color management), เดาได้เลยว่า ภาพถูกเก็บข้อมูลแบบ log.

ไฟล์นามสกุลใด ที่ออกแบบมาให้ใช้ log color space เป็นค่ามาตราฐาน

------------------------------------

Cineon (.cin หรือบางทีก็ เลขเรียง 4 ตัว โดยไม่มีนามสกุล)
Dpx (.dpx)
------------------------------------
ถ้าคุณทำงานกับภาพ log
ถ้าคุณปรับภาพที่เก็บข้อมูลแบบ log โดยไม่ทำการแปลงเป็น linear (หรือเป็น sRGB) ก่อน, เป็นไปได้ว่าคุณกำลังทำผิดพลาดหรือ คุณอาจจะกำลังทำงานบน เครืองที่มีการใช้ software/hardware ที่สามารถทำงานบนภาพแบบ log ได้โดยตรง.
ถ้าคุณเป็นแบบที่สอง คุณคงไม่มาอ่านของพวกนี้ เพราะงั้น เดาได้ว่า คุณกำลังพลาดแล้วล่ะ
 

การทำงานกับภาพ log ที่ถูกต้อง

ภาพ Log นั้นจะมาจาก film scanners. มันถูกออกแบบมาเพื่อนำพาข้อมูลเกี่ยวกับสีไปให้ได้มากที่สุด โดยอย่าไปคิดว่ามันเป็นภาพที่่นำไปใช้ได้เลย แต่ให้คิดว่ามันเป็นการ "บีบอัดข้อมูล" (แบบไฟล์ zip หรือ tar.gz ). ครั้นเมื่อทำการแปลงไปเป็นภาพแบบ linear แล้วนั้น (ประมาณ unzipped), คุณจึงจะสามารถทำงานกับภาพได้. โดยการแปลงแบบนี้มักจะทำโดยตรงโดยโปรแกรม compositing (เช่น: Nuke, AE, Fusion).
ครั้นเมื่อทำงานเสร็จ เราต้องแปลงกลับไปเป็น log เพื่อที่จะสามารถนำไปยิงกลับเป็นฟิลม์ได้
 

SRGB

sRGB color space = คือ color space ปกติ ก่อนที่จะรู้เรื่อง color spaces เสียด้วยซ้ำ

จะรู้ได้ยังไงว่า ภาพที่ได้มาเก็บข้อมูลมาเป็นแบบ srgb ?

ภาพที่เก็บข้อมูลแบบ sRGB ดูเหมือน "ถูกต้อง" ถ้าคุณดูภาพแบบ ไม่มี การทำ color management.
ดังนั้นถ้า 95% ของเวลาที่คุณเห็นภาพที่ดูปกติ (ไม่ได้ทำ color management), ก็ให้เดาได้ว่ามันถูกเก็บข้อมูลมาเป็นแบบ srgb.

ไฟล์นามสกุลใด ที่ออกแบบมาให้ใช้ sRGB color space เป็นค่ามาตราฐาน

------------------------------------
Jpeg (.jpg)

------------------------------------

มีอะไรอยู่ใน sRGB?

sRGB ถูกออกแบบมาเพื่อทำการแสดงผลค่าที่อยู่ใน image buffer ของ video card ไปที่จอบ้านๆ, โดยไม่มีการทำ color management. ก็เพื่อจะได้ไม่ต้องสนเรื่องคนใช้และเครื่องที่แตกต่างกัน (เพื่อจะได้เร็วกว่าบนเครื่องช้าๆ (ไม่ค่อยสำคัญแล้วตอนนี้ แต่สำคัญตอนที่มันถูกสร้างขึ้น)). สิ่งที่สำคัญอีกอย่างก็คือ สามารถแสดงความแตกต่างของสีได้มีประสิทธิภาพกว่า ด้วยความจุที่เท่ากัน (= มันดูดีกว่าที่จะแสดงภาพ sRGB เทียบกับ linear image ที่ทำการ color management เมื่อคุณมีแค่ 8 bits ต่อ channel).
sRGB คือ color space ที่ใช้กันเกลื่อนบนโลก internet. *รู้ไว้ใช่ว่า Rec709, คือ color space ที่ใช้กับ HDTV. โดยคร่าวๆแล้ว มันก็เหมือนกับ sRGB ในหลักการ, แตกต่างกันเพียง gamma.

ข้อดี

ไม่ต้องเข้าใจอะไรมาก ใครๆก็ใช้กัน อย่างพวกกล้องก็แปลงเป็น Jpeg ให้เลย

ข้อเสีย

  • ปรับยาก สีเน่าง่าย สีผสมกับแปลกๆ ปรับมากไม่ได้ระหว่างแสงและเงา
เพราะสูตรที่ใช้ปรับแสงสี ไม่ได้ถูกออกแบบมาเพื่อ sRGB color space.

ทำไมถึงทำงานกับ sRGB ด้วยสูตรที่ออกแบบมาสำหรับ linear color space ไม่ได้?

เพราะถึงมันแตกต่างกัน แต่มันก็มีความสัมพันธ์กันอยู่บ้าง สูตรพวกนี้เลยทำตัวไม่ค่อยดีนัก แต่ก็ทำงานได้ใกล้เคียง ในแบบที่คุณอาจจะคาดหวังได้บ้าง
แต่ เหตุผลหลักก็คือ: เราตัดสินคุณภาพของงานด้วยสายตา (ขึ้นอยู่แต่ละบุคคล).
เพรางั้น เราเลยทำงานด้วยตา โดยไม่สนค่าของตัวแปรต่างๆ สนแต่ภาพสุดท้าย.
ถ้าเราทำแบบเดียวกันกับการคำนวนจำนวนพลังงานแสงเลเซอร์ที่ใช้ผ่าตัดคนไข้ เราก็คงฆ่าเขาตายแน่ๆ !!!
 

การแปลง

linear เป็น sRGB

ใช้ gamma 2.2 ซึงก็ไม่เลวนักในการประมาณค่าการแปลงจากภาพ linear เป็นภาพ sRGB :
Image:NG Kodak lin 2.jpg --> GAMMA( 2.2 ) --> Image:NG Kodak srgb 2.jpg
 

sRGB เป็น linear

ใช้ gamma 1/2.2:
Image:NG Kodak srgb 2.jpg --> GAMMA( 1 / 2.2 ) --> Image:NG Kodak lin 2.jpg
 

log เป็น linear

ใช้ LogLin node โดยปรับเป็น "log to lin".
Image:NG Kodak log 2.jpg --> LOGLIN( conversion = "log to lin" ) --> Image:NG Kodak lin 2.jpg
 

linear เป็น log

ใช้ LogLin node โดยปรับเป็น "lin to log".
Image:NG Kodak lin 2.jpg --> LOGLIN( conversion = "lin to log" ) --> Image:NG Kodak log 2.jpg
 

COLOR MANAGEMENT และ LUT

 

การทำงานแบบ Linear , ต้องมีการ color management

ถ้าคุณแสดงภาพที่เก็บแบบ linear color space ใน image buffer, คุณจะเห็นภาพที่มืดเกินไป. ดังนั้น ถ้าคุณทำงานกับภาพ linear, คุณต้องมีระบบ software ที่จะทำการ แปลงภาพ linear โดยอัตโนมัติ เป็น sRGB เพื่อการแสดงผลเท่านั้น.
ถ้าคุณทำงานกับ Nuke, Fusion คุณสามารถใช้ gamma node ที่ตั้งค่า (1/2.2) เพื่อการนี้. คุณสามารถต่อเอาไว้สุดท้ายกับภาพที่คุณต้องการจะดูบน viewer. แน่นอนมันจะเสียเวลา และอาจจะพลาดหรือน่ารำคาญที่ต้องทำอะไรแบบนี้ตลอด!!!
เพื่อที่จะหลีกหนีเรื่องอะไรแบบนั้น, จินตนาการถึง gamma node ที่ถูกซ่อนเอาไว้ โดย interface, และเชื่อมต่อระหว่าง ภาพที่คุณต้องการจะดูกับ viewer.
ซึ่งมันจะมีระบบอะไรแบบนี้ ในหลายๆ software, รวมทั้ง Nuke, Fusion (ไม่มีใน Maya ณ ขณะที่เขียน).
โดยมากจะเรียกว่า LUT หรือ viewer LUT.
โดยใน Nuke จะเรียกว่า viewerProcess เรียกดูได้จากการกด S ที่หน้าต่าง viewer.
โดยใน Fusion จะเรียกว่า View LUT เรียกดูได้จาก ปุ่ม LUT ที่หน้าต่าง viewer
 

แล้ว LUT  คืออะไร?

LUT หมายถึง : Look Up Table.
คือชุดแถวลำดับข้อมูลที่ได้ถูกทำการคำนวนเอาไว้ก่อน เพื่อจำลองความสัมพันธ์ทางคณิตศาสตร์ ยกตัวอย่าง 8 bits, คุณจะมีค่าตัวเลขอยู่จำนวนเท่ากับ 256 ที่จะนำมาคำนวนในแบบจำลองทางคณิตศาสตร์ที่ต้องการตัวเลขตั้งต้นจำนวน 8 bits เช่นกัน .เมื่อทำการคำนวนแล้ว คุณสามารถเข้าไปดูแถวข้อมูล โดยใช้ค่า 8 bit เป็นดัชนี เพื่อชี้ไปที่ค่าที่ถูกแปลงไปแล้วได้.

แล้วอะไรคือความเกี่ยวข้องกันระหว่าง gamma กับ LUT ของเรา?

ก็เหมือนสมการทั่วๆไป คือเราสามารถคำนวนเอาไว้ก่อนได้ โดยเราก็คำนวนค่า gamma เอาไว้ก่อน โดยเราจะเก็บค่าที่ได้จากการแปลงค่า gamma นั้น เอาไว้ใน LUT ของเรา.
โดยกระบวนการนี้ จะทำให้เราสามารถแปลงสมการหลายๆอัน เอาไว้ล่วงหน้าได้ (เติมเองโดยผู้แปล: ก็คือประมาณว่า เราลดภาระการคำนวนขณะทำงาน โดยคำนวนเอาไว้ก่อนล่วงหน้า เพื่อให้ได้ผลลัพย์ที่ต้องการ โดยไม่ต้องคำนวนทุกครั้งที่จะใช้. บางคนก็แปลงโดยใช้ gamma เฉยๆ บางคนก็ใช้อะไรที่ซับซ้อนกว่านั้น (เช่น: การแปลงด้วย Truelight).
ซึ่งจะมี LUT อยู่สองแบบที่ใช้กันมาก ก็คือ LUT 1D และ LUT 3D.

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

LUT 1D

A LUT 1D means : one dimensionnal array
It is used to precompute a function with ONE INPUT. So by using three LUT 1D, you can precompute simple grading were each ouput channel is depending only on ONE input channel.
R input -> R output
G input -> G output
B input -> B output
  • 8 bits to 8 bits LUT 1D
One LUT 1D takes 256 bytes of memory.
One operation using three LUT 1D needs precomputed arrays of total size: 3 * 256 = 768 bytes = 0.75 K
  • 16 bits to 16 bits LUT 1D
One LUT 1D takes 65536 * 2 bytes = 131072 bytes = 128 K
(There is a factor of 2 because 16 bits is 2 bytes).
One operation using three LUT 1D tneeds precomputed arrays of total size: 3 * 128 K = 384 K = 0.375 M
 

Some examples from shake nodes possibly using LUT 1D:

Brightness
Clamp
Compress
ContrastLum
ConstrastRGB
Expand
Gamma
Invert
LogLin
Lookup
Solarize
Threshold
 

LUT 3D (=cube)

Sometimes grading or conversion are more complicated and each output channels can't be defined by knowing only one input channel.
In this case you can still precompute your grading or conversion but it is more costly.
You need to sample your color cube as if it was a volume (think about sampling densities in a fluid cube).
At each position in your sampled cube you associate a color. The position is the input color, the color associated to the position is the output color.
Finaly, when you process your image, you find which color is associated in to your input color in your sampled volume (which has the form of a cube).

Because you compute the whole color, you need one LUT 3D for the whole image operation you're doing.
(R,G,B) input -> (R, G, B) output
  • 8 bits to 8 bits LUT 3D
One LUT 3D takes 256 * 256 * 256 * 3 Bytes = 50331648 Bytes = 49152 KB = 48 MB (it's multiplied by 3 because in a LUT 3D you compute the resulting RGB channels at once)
One operation in 8 bits using one LUT 3D needs a precomputed array of total size: 48 MB
  • 16 bits to 16 bits LUT 1D
One LUT 3D takes (65536 * 2) * (65536 * 2) * (65536 * 2) * 3 Bytes = 6291456 GB = 6144 Tera Bytes !!!!!!
As you can guess it is really too huge. So if you're doing a LUT 3D for 16 bits images you need to down sample your 16 bits color cube and use interpolation on the fly to get the missing samples.

As you can see, one LUT 3D is more powerfull but more expensive than three LUT 1D.
 

Some examples from shake nodes possibly using LUT 3D:

Truelight
SpillSupress
Keyers (think as your resulting alpha as a RGB gray image, same maths behind)
 

Questions? / Answers?

Feel free to send me a mail at nicosfx@gmail.com

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

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