- บทความนี้เสนอให้สร้าง พาเลต 256 สี โดยอัตโนมัติจาก ธีม base16 ของผู้ใช้ เพื่อปรับปรุงความสม่ำเสมอของสีและความสามารถในการอ่านของเทอร์มินัล
- ธีม base16 แบบเดิมนั้นเรียบง่าย แต่มีจำนวนสีจำกัด ขณะที่ truecolor มีความซับซ้อนในการตั้งค่าและมีปัญหาด้านความเข้ากันได้
- พาเลต 256 สีเริ่มต้นมีคุณภาพด้านภาพต่ำ เนื่องจาก ความสว่างไม่สมดุล, ธีมไม่สอดคล้องกัน, และ การอินเทอร์โพเลตที่ไม่ถูกต้อง
- หากสร้างพาเลตแบบขยายจากสี base16 ด้วย การอินเทอร์โพเลตใน LAB color space ก็จะสามารถรักษาความสม่ำเสมอของความสว่างและคอนทราสต์ พร้อมทั้งให้การแสดงสีที่หลากหลายได้
- เทอร์มินัลหลักหลายตัว (เช่น Ghostty, iTerm2, SwiftTerm) ได้เริ่มนำไปใช้แล้ว และมีความเป็นไปได้ที่ ฟีเจอร์การสร้างพาเลตอัตโนมัติแบบมาตรฐาน จะช่วยยกระดับคุณภาพของระบบนิเวศเทอร์มินัลโดยรวม
ภาพรวมของพาเลต 256 สี
- พาเลต 256 สีประกอบด้วย สีพื้นฐาน 16 สี, คิวบ์ 216 สี, และ grayscale 24 ระดับ
- สีพื้นฐาน 16 สีประกอบด้วยสีดำ สีขาว สีหลัก และเฉดสว่างของแต่ละสี
- คิวบ์ 216 สีคำนวณโดยใช้ 6 ระดับ (0~5) สำหรับแต่ละช่อง RGB:
16 + (36 * R) + (6 * G) + B
- grayscale ประกอบด้วย 24 ระดับระหว่างขาวดำ:
232 + S (S คือ 0~23)
- โครงสร้างนี้เป็น เวอร์ชันแบบย่อของ RGB 24 บิต ที่ลดจำนวนสีลงแต่ยังคงความสามารถในการแสดงผลไว้
ปัญหาของพาเลต 256 สีแบบเดิม
- เกิดความขัดแย้งของสีจาก ความไม่สอดคล้องกับธีม Base16
- พาเลตเริ่มต้นส่วนใหญ่ไม่เข้ากันกับธีม base16 ส่วนมาก
- การอินเทอร์โพเลตสีที่ไม่ถูกต้อง ทำให้ความสามารถในการอ่านบนพื้นหลังมืดลดลง
- เฉดแรกของพาเลตเริ่มต้นถูกคำนวณให้สว่างกว่าความเป็นจริง ทำให้คอนทราสต์อ่อนลง
- มีปัญหาเรื่อง คอนทราสต์ไม่สม่ำเสมอ
- เนื่องจากใช้สีอิ่มตัวเต็มที่จึงทำให้สมดุลความสว่างไม่พอดี และแม้จะอยู่ในระดับเดียวกัน สีน้ำเงินก็ดูมืดกว่าสีเขียว
วิธีการสร้างพาเลต
- แนวทางแก้คือ สร้างพาเลต 256 สีโดยอัตโนมัติจากสี base16 ของผู้ใช้
- แมปสีพื้นฐาน 8 สีของ base16 ไปยังมุมทั้ง 8 ของคิวบ์ 216 สี
- สร้างคิวบ์ด้วย การอินเทอร์โพเลตแบบ trilinear โดยใช้สีพื้นหลังและสีตัวอักษร
- ใช้ LAB color space เพื่อรักษา ความสม่ำเสมอของความสว่างตามการมองเห็น ระหว่างสีต่าง ๆ
- grayscale สร้างขึ้นด้วยการอินเทอร์โพเลตแบบง่ายจากพื้นหลังไปยังสีตัวอักษร
- ในตัวอย่างโค้ด Python มีการใช้ฟังก์ชัน
rgb_to_lab, lab_to_rgb, lerp_lab เพื่อทำการแปลง
สถานะการนำไปใช้และการประยุกต์ใช้
- โค้ดที่เสนอนี้เผยแพร่เป็น public domain จึงสามารถแก้ไขและนำไปใช้ได้อย่างอิสระ
- เทอร์มินัลหลักอย่าง Ghostty, iTerm2, SwiftTerm ได้ติดตั้งใช้งานแล้ว
- ใน kitty, Wezterm, Tabby, Windows Terminal ก็มีการร้องขอให้นำไปใช้หรือกำลังอยู่ระหว่างการพัฒนา
- นักพัฒนาบางส่วนเสนอให้ใช้ OKLAB/OKLCH color space และโครงการมีแผนจะทำให้มาตรฐาน color space เป็นแบบเดียวกัน ตามการตัดสินใจของ Ghostty
- สามารถใช้พาเลตได้โดยตรงผ่านสคริปต์ Python หรือสร้างไฟล์ตั้งค่าเทอร์มินัลโดยอัตโนมัติได้
บทสรุปและข้อเสนอ
- พาเลต 256 สีเริ่มต้นถูกนักพัฒนาโปรแกรมหลีกเลี่ยง เนื่องจาก ความสามารถในการอ่านลดลงและธีมไม่สอดคล้องกัน
- หากเทอร์มินัล สร้างพาเลต 256 สีโดยอัตโนมัติโดยอิงจากธีม base16 ก็จะได้ประโยชน์ดังนี้
- ใช้ ช่วงสีที่กว้างขึ้น ได้โดยไม่ต้องมีไฟล์ตั้งค่า
- ไม่ต้องให้นักพัฒนาเข้ามาเกี่ยวข้องเมื่อ สลับโหมดสว่าง/มืด
- รักษา ความเข้ากันได้กับเทอร์มินัลอย่างกว้างขวาง
- ผู้เสนอเน้นว่าฟีเจอร์นี้ควรถูก เปิดใช้งานเป็นค่าเริ่มต้นแบบ opt-out และในระยะยาวควร กลายเป็นฟีเจอร์มาตรฐาน
1 ความคิดเห็น
ความเห็นจาก Hacker News
ข้อดีของพาเลต 256 สีคือสีหมายเลข 16~255 ถูกกำหนดตายตัว
ดังนั้นจึงมั่นใจได้ว่าอย่างเช่นสีหมายเลข 146 จะเป็น “ม่วงอ่อน” เสมอ
สิ่งนี้มีประโยชน์มากสำหรับนักพัฒนาธีมสีที่ต้องการมอบ ประสบการณ์สีที่สม่ำเสมอ บนเทอร์มินัลอีมูเลเตอร์หลากหลายตัว
ถ้าพาเลต 256 สีถูกสร้างจากพาเลต 16 สีที่เปลี่ยนแปลงได้ สีหมายเลข 146 ก็อาจไม่ใช่สีที่คาดไว้
ผมคิดว่าการทำให้ช่วง 16~255 ไม่เสถียรเหมือนช่วง 0~15 นั้นเป็นทิศทางที่ผิด
มันทำให้อ่านยากสำหรับผู้มีความบกพร่องทางการมองเห็น ผู้ที่ตาบอดสี หรือคนที่ชอบพื้นหลังสีขาว
สุดท้ายผู้ใช้ก็ต้องตั้งค่าสีทั้งของเทอร์มินัลพื้นฐานและของแต่ละแอปแยกกัน
คนใช้เทอร์มินัลเพราะ ประสิทธิภาพ ไม่ใช่เพราะ UI สวย ถ้าอยากได้ของสวยก็ไปทำเว็บฟรอนต์เอนด์แทน
เราไม่ได้ต้องการ “ประสบการณ์ที่สม่ำเสมอ” สีควรถูกใช้อย่างพอเหมาะและเคารพการตั้งค่าของผู้ใช้
พื้นหลังอาจเป็นสีม่วงอยู่แล้ว หรืออาจเป็นตัวอักษรสีม่วงบนพื้นหลังสีขาวก็ได้
พูดอีกอย่างคือ ถ้าแอปไม่รู้การตั้งค่าสีของเทอร์มินัลของฉัน ก็ไม่ควรใช้สีนั้น
ผมใช้ธีม base16 เริ่มต้น และไม่ได้คาดหวังให้มันตรงกับธีมจากบุคคลที่สาม
ผมคิดว่าความต่างระหว่างการเข้าถึงสีระดับเทอร์มินัลกับระดับแอปนั้นใกล้เคียงกับประเด็นเชิงปรัชญามากกว่า
ผมสร้างตัวเรนเดอร์ Markdown แบบสตรีมมิงชื่อ Streamdown
โดยอิงกับ HSV แค่กำหนด สีอ้างอิงเพียงสีเดียว ที่เหลือจะถูกปรับอัตโนมัติเป็นทวีคูณของสีนั้น
ตัวอย่างเช่น องค์ประกอบที่มืดจะลดความอิ่มตัวลง และสัญลักษณ์จะดูสดขึ้น
ต่อให้ปรับ HSV ในการตั้งค่าเพียงเล็กน้อย โทนโดยรวมก็จะเปลี่ยนอย่างเป็นธรรมชาติ จึงไม่ต้องมานั่งไล่ปรับทีละสี
มี โค้ดตัวอย่าง ด้วย
แม้แต่พาเลตพื้นฐาน 16 สีก็ยังมีปัญหา
คำว่า ‘black’, ‘white’, ‘bright black’, ‘bright white’ จริง ๆ แล้วควรสื่อถึง ความต่างของความสว่าง แต่กลับถูกตั้งชื่อเป็นสี
ผมมองมันว่าเป็น “สีที่แทบมองไม่เห็นบนพื้นหลัง”, “สีที่มีคอนทราสต์สูง”, “สีที่มองเห็นได้แต่ไม่เด่น”, และ “สีที่คอนทราสต์สูงที่สุด”
อยากให้มันถูกนิยามโดยยึด คอนทราสต์เป็นหลัก มากกว่าชื่อสี
สี foreground/background ของเทอร์มินัลนั้นแยกจากมาตรฐาน 16 สี จึงยิ่งซับซ้อนกว่าเดิม
และเมื่อไม่รู้พื้นหลัง ก็ควรหลีกเลี่ยงสีดำกับสีขาว หากจะใช้ 256 สี ก็ควรมีธีมเอนจินที่ผู้ใช้ตั้งค่าได้
ผมคิดว่าควรเพิ่มฟีเจอร์นี้ในทุกเทอร์มินัล
ถ้าขยายไปเป็น 24-bit color ก็น่าจะยิ่งดี แต่ต้อง ทำเป็นตัวเลือก
เช่น ถ้าใช้ธีม Solarized ทั้งในเทอร์มินัลและเอดิเตอร์ ก็อาจมีการแปลงสีซ้ำซ้อนกันได้
ถ้าเปิดให้ควบคุมผ่าน environment variable โดยที่แอปไม่ต้องไปเขียนทับการตั้งค่าเอง ก็จะยืดหยุ่นกว่า
ตอนนี้ผมเจอและกำลังใช้ tinted-theming/base24 อยู่
สามารถสลับธีมสีได้ง่ายด้วย tinted shell ถือเป็นวิธีแก้ชั่วคราวที่ค่อนข้างดี
ใน cargo/rustc ก็มีปัญหาเรื่องจำนวนสีไม่พอเหมือนกัน
ถ้าใช้แค่สีเชิงความหมายแบบพื้นฐาน สีที่เหลือก็มีแค่มาเจนตา ดำ และขาว ซึ่งเสี่ยงขึ้นอยู่กับธีม
ใช้แค่ โหมด true color 24 บิต ก็ไม่ต้องมีพาเลตแล้ว
ตาม termstandard/colors เทอร์มินัลสมัยใหม่ส่วนใหญ่รองรับสิ่งนี้
ถึงขั้นว่าหากคำนึงถึงข้อจำกัดทางฟิสิกส์ เช่น ความไม่แน่นอนของไฮเซนเบิร์ก หรือ quantum noise ก็อาจต้องใช้ข้อมูลระดับ 6000 บิตต่อพิกเซล
จินตนาการแบบนี้เป็นการทดลองทางความคิดที่น่าสนใจซึ่งชี้ทิศทางของความก้าวหน้าทางเทคโนโลยี คล้ายกับ มาตราคาดาเชฟ หรือแนวคิดเวลาแห่งจักรวาลแบบโบราณ
ไม่ใช่ผู้ใช้ทุกคนจะตั้งค่า สีพื้นฐานเริ่มต้น ไว้อย่างเหมาะสม
บางเทอร์มินัลอาจออกเขียวทั้งจอหรือส้มทั้งจอก็ได้
วิธีเอาความอิ่มตัวของสีพื้นฐานไปใช้กับทั้งพาเลตก็อาจจะยังดีกว่า
ผมเป็น คนตาบอดสี เลยลำบากกับธีมสีมาตลอด
เลยใช้โมเดล AI เพื่อสร้าง ชุดสีที่อ่านง่าย แบบอัตโนมัติ
พอมันเพิ่มคอนทราสต์จากธีมที่เดิมชอบอยู่แล้ว ก็ทำให้ดูสบายตาขึ้นมาก
คิดว่าวิธีแบบนี้น่าจะช่วยคนอื่นได้ด้วย
แต่ละแอปใช้สีไม่เหมือนกัน บางธีมจึงอ่านง่ายใน CLI บางตัว แต่จางเกินไปในอีกตัว
สุดท้ายก็ต้องมานั่งปรับธีมสีแยกเป็นรายแอป ซึ่งไม่สะดวก
ผมมี protanomaly (ภาวะการรับสีแดงบกพร่อง) เลยใช้ ametameric อยู่
ถ้าใช้ร่วมกับฟีเจอร์นี้ก็น่าจะได้ผลที่ดียิ่งขึ้น