創作內容

6 GP

【程式&繪圖】RGB≠螢幕上的亮度:sRGB與linear RGB

作者:Shark│2017-11-03 22:04:14│巴幣:60│人氣:2433
這個話題跟畫圖和程式都有關,因為GIMP 2.9新增一個選項而想弄清楚這是什麼,結果發現了當今螢幕的秘密。

GIMP 2.9新增了sRGB和linear RGB的選項,出現在圖片數值精度和圖層屬性兩個地方。


試一下它的作用,如果背景是黑色(RGB=0,0,0),疊上綠色(0,255,0)且alpha=0.5,按照alpha blend的公式G值應該是127或128,但把圖層設成linear RGB的話結果是188,設成sRGB結果才是128。

為了解開這個謎,去找資料看這個設定做什麼用的?怎麼調?

參考資料:
 關於遊戲繪圖引擎
一篇Naughty Dog的投影片
CRYENGINE的說明文件
 關於繪圖軟體
在繪圖軟體裡測試模糊化和混色

可惜筆者手上沒有測量螢幕亮度的儀器,不然可以做更精確的驗證。



RGB是電腦儲存影像資料的標準,記憶體裡儲存RGB數值,顯示影像時要把數值傳送給顯示設備,讓裡面的發光元件發光。
不過這裡藏了一個秘密:RGB值≠發光元件的亮度,即兩者不是線性關係,如果將R值設成0.5,螢幕上只有0.21的亮度,把R設成0.74才能得到0.5的亮度。
(本篇把RGB的範圍定為0.0~1.0,因為這樣公式比較容易推導,且shader裡也是用0.0~1.0計算)

先定義0是發光元件能發出的最小亮度,1是最大亮度,用這個算式換算成實際亮度。
把RGB分量都套用算式。
Cs<=0.04045 → Cl = Cs/12.92
Cs>0.04045 → Cl = pow((Cs+0.055)/1.055, 2.4)

pow(a,b)是a的b次方,巴哈姆特不能打上標故用這個代替。
轉換前的色彩空間稱為sRGB(standard RGB),轉換後稱為linear RGB,分別用Cs、Cl代表。
如果把同一個顏色用兩種色彩空間表示,linear RGB的數字會比sRGB小。
例:
RGB值 0 0.2 0.4 0.6 0.8 1
亮度 0 0.0331 0.1329 0.3185 0.6038 1

反向轉換如下
Cl<=0.0031308 → Cs = 12.92 * Cl
Cl>0.0031308 → Cs = 1.055 * pow(Cl,0.41666) - 0.055

查資料看到這樣做的原因有二,一是跟以前的CRT顯示器有關,CRT電壓-發光強度的關係是接近Cs轉Cl的式子。後來的液晶顯示器就沒有這個物理特性了,不過為了相容以前的資料,仍然製造成發光強度遵循這個算式。
二是人眼對暗色的分辨力比較高,分量是8 bit精度時如果把亮度分成255等分,暗色部分精度有點不能滿足需求,所以讓0~255的數值不是等分,暗的部分比較密集。(上面CRYENGINE的文件裡有張灰階圖可參考)
16 bit以上的精度超過人眼的分辨力,就不一定要用非等分了。

至於繪圖軟體和遊戲裡顯示影像要怎麼做?繪圖軟體和相機都是設計成產生sRGB的圖,可以假設所有圖檔都是sRGB色彩空間,顯示器也設計成要給它sRGB的資料,如果只是原封不動顯示圖那只要把RGB值丟給顯示器,不用轉換。

不過如果有用shader或blend做影像處理,像是用multiply或screen改變亮度、半透明的部分用alpha blend重疊、或3D計算打光,就要做轉換了,因為這些公式都是以linear RGB為前提。
也就是過程要如下,理論上才會正確。

原始sRGB資料 → 轉換成linear → 影像處理 → 轉換回sRGB → 顯示在螢幕

第三個參考資料有示範,在sRGB做模糊化會出現一條暗的區域,是因為沒有做sRGB→linear→sRGB的轉換,交界處有RGB值=0.5的點,但實際亮度是RGB各0.21。



實驗1
在GIMP 2.9做兩個圖層

上層:純綠(0,255,0),圖層alpha設為50%
下層:純黑

然後調整上層的composite space,用拾色器取得重疊後的顏色,第一個是linear,第二個是perceptual。


驗算一下linear的情況
第一步:sRGB轉成linear RGB
  黑色和純綠色各分量都是0和1,轉換後也是0或1
第二步:上層用alpha=0.5跟下層重疊,G值變成0.5
第三步:linear RGB轉成sRGB
  套Cl轉Cs的公式,G=0.7353...
  因為軟體是用0~255表示,乘以255得到187.516...,四捨五入就是188

實驗2
測試D3D的sRGB格式,用自製遊戲引擎同樣做純黑和半透明綠兩個物件,半透明綠用貼圖而不用單色矩形物件,然後截圖並用繪圖軟體看RGB值。
將貼圖和framebuffer設成sRGB格式


似乎無效,想了一下發現原因是premultiply alpha,不是載入圖檔後立刻做,應該先轉換成linear RGB再做premultiply alpha




了解了原理,也要考慮自己的畫圖工法,以及遊戲引擎演算法要不要修改了。

做遊戲的話,貼圖和framebuffer D3D、OpenGL可以自動做sRGB、linear RGB轉換,只要建立時把格式設定成sRGB就行了。但我有些地方是把顏色放在uniform buffer裡傳給shader,要自己寫算式轉換,另外premultiply alpha也要修改。

畫圖的話,GIMP的說明書有寫圖片數值精度是8 bit的話必須用sRGB,否則圖裡暗的部分會異常,16 bit以上的精度才能用linear。圖層重疊的屬性則要設成linear計算才會正確。
如果只是自己一個人畫,那哪種色彩空間影響不大,因為就是一直看著螢幕不斷調整,調到看起來滿意,但跟其他人合作時可能有問題。

有些事想參考一下別人是怎麼做的。

1.畫圖或做遊戲調整畫面的時候,是如何處理sRGB和linear的差異?

2.還有很多繪圖軟體沒考慮到sRGB≠真實亮度,模糊化、混色時沒轉換成linear就計算(我有在用的Inkscape就沒考慮到),這樣不同繪圖軟體交換資料會有問題,看別人的教學或寫教學給別人看也不能重現步驟。
繪師或許也不知道這回事,跟繪師溝通可能也會有問題。
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=3777257
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:繪圖軟體|影像處理|演算法|繪圖心得

留言共 0 篇留言

我要留言提醒:您尚未登入,請先登入再留言

6喜歡★shark0r 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:無接縫tilemap練習... 後一篇:21週年站聚遊記...

追蹤私訊切換新版閱覽

作品資料夾

colanncolann
【繪圖創作】【科嵐工作室】11週年! 2024/4/1 https://home.gamer.com.tw/creationDetail.php?sn=5909405看更多我要大聲說12小時前


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】