劍英陪你玩轉圖形學 (二)彩虹

瘋光無線發表於2014-09-05

今天的主題是顏色

開篇廢話

今天看到蠻牛把乾貨區放上了主頁,居然還能看到我的帖子,讓我很不好意思。

各位同學對不起,我來晚了。

今天的李總是因為姓李,又總是遲到,所以叫做李總。

今天還是講圖形學,為人不識武藤....,駭駭,最近好像掃黃,不能說這個,大家都知道,關鍵是不搞軟渲染,你就枉然了。軟渲染我們上次已經玩過了,知道所以然,瞭解渲染是怎麼一件事,目標就已經達到了。

渲染這條路上還有很多東西,今天我們到unity3d裡面去玩。圖形相關要聊的事情太多了,從頭講到做一個引擎出來,估計這個系列以後你可以和孩子一起看,我們用unity3d這個引擎,在他的基礎上再繼續去講圖形,還趕得上製造下一代。

首先開篇之前,先來檢查一下作業。

請跟我一起問自己幾個問題:

  1. 怎麼從模型到畫素,我大概理解了嗎?
  2. 關於頂點和矩陣,我真的知其所以然了嗎?
  3. 空間與變換我理解了嗎?

如果這幾個問題還存在疑問,我建議你還是回到第一彈去再玩一遍,我不會告訴你所有的答案,但是我提供給你所有的關鍵字,你得自己補補課了。

記住,我們是一個高階業務(zhuangbi)技巧系列,我們理清楚關鍵思路,基礎還得自己補。

快速提高班

現在教大家一些快速提高自己業務(zhuangbi)水平的方法。

要提高自己的業務水平,第二個要訣是:持。

持這個概念,沒有忍那麼好理解,你可以把他理解為選擇,你要選擇那些你有把握的地方去回答。

一旦出口,就是準確的。

這次不用模擬問答,因為你已經不會破功( zhuangbi shibai)了。

今天使用Unity3D,我先告訴你一些Unity的小技巧,以後體現業務(zhuangbi)水平用得著。

首先, Unity可以簡單的用兩句話講清楚

1.這個Hierarchy皮膚,他體現的是場景管理中的場景圖概念。如果有必要,記住他的英文SceneGraph。

場景圖是什麼呢?說起來也很簡單,就是把場景中的元素,以樹的形式組織起來。看上面第二張圖,什麼都不用說了

2.場景圖中的節點,在Unity中稱為GameObject,GameObject上面可以掛接各種各樣的Component

Unity主要的開發思想便是通過自定義指令碼元件來進行開發

好了,Unity3D是怎麼回事呢,Unity這玩意就是操作場景圖,場景圖節點上是一個元件模型,元件可以自定義指令碼來編寫。

記住這個,你也可以兩句話把Unity3D講透。

 

但是,我們在這裡主要是講圖形,光透是不行的,我們還得分析Unity3D的渲染設計。

Unity3D的渲染設計呢,在頂點這個層面上是非常傳統的三矩陣設計。

DirectX OpenGL 在固定管線時代就一直沿用這個設計,也是圖形學裡面搞了幾十年的經典設計。

三矩陣是

世界矩陣、視矩陣、投影矩陣。

世界矩陣,就是表達模型在世界空間中的具體位置。對應到unity結構就是Transform. localToWorldMatrix.

由於場景圖是有父子關係的,子物體的localToWorldMatrix,是子物體的localMatrix*父物體的worldMatrix得到。

Unity並沒有直接提供localMatrix的結構,而是由一組localPositon localScale localRotate localRuleAngle 來描述。

總之他是表示位置的

視矩陣,決定攝像機的位置和方向,最後能看到什麼東西。

投影矩陣,決定攝像機的視角,遠近裁剪面這些東西,視矩陣和投影矩陣都有攝像機的位置和引數來決定。

這三個矩陣最終被合成為一個,共同決定頂點出現在螢幕上的位置。

 

好了,提高到這裡就可以了,今天我們不深入這個話題。

計算機的顏色

今天專門來講計算機的顏色,這個問題又淺又深,聽我慢慢道來

RGB模型

R=Red,G=Green,B=Blue

三原色,這個東西大家都很熟悉,rgb模型是用亮度來表示的

0表示完全黑,1表示完全亮。

0,0,0 是黑色

1,1,1 是白色

0.5,0.5,0.5是灰色

0 1, 0表示沒有,1 表示全部,這個表示法在計算機圖形這塊到處都是,你會慢慢體會到。

索引色,高彩色,真彩色

在早期的計算機處理能力還很低的時候,同螢幕顯示很多顏色很困難,比如小霸王,只能顯示16色。後來機能好一些了,可以顯示256種顏色了。

16色效果

256色效果

在這個階段都有調色盤的設計,因為一個畫素點就用了一個位元組來表示,這個位元組表示用的是第幾種顏色。另外有一張色表,記錄第幾種顏色具體是什麼顏色。時至今日,調色盤依然健在,因為調色盤具有一個很有趣的特性,一些2d遊戲依然在使用。就是不改變圖片,僅改變色表,就能產生不同的效果。

比如街霸2裡面的可以選出不同顏色的角色,都是改調色盤的結果。

為何如此吝嗇,一個畫素只用一個位元組存?

試想蓋子大神的名言,個人電腦只要640k記憶體就夠了。可是一張1024 768的圖片,256調色盤,一個畫素一位元組,640k都放不下。時代在進步,蓋子大神遙想當年,怕也得儼然一笑。

那個時代機能各方面都很捉襟見肘。小霸王的解析度是256 240,只能同時使用16種顏色。後來進化到256色的機器本質還是調色盤,原理一樣。

 

後來機能提高到了一個新的高度。允許用更多的記憶體,更高的髮色數。就產生了15bit顏色 16bit高彩色,24bit真彩色,30bit顏色等等。其中15bit是rgb各用5bit表示0-1怎麼用5bit表示呢?5bit的最小值0表示0,5bit的最大值31表示1

顏色的表示法都是一樣的,用這種表示法可以用任意位長表示rgb顏色。

15bit顏色就是 31,31,31 為白色

24bit顏色就是 255,255,255 為白色,24bit表示最為常用,所以很多小夥伴可能都比較熟悉這個255

30bit顏色就是 1023,1023,1023為白色。

而實際上15bit 每個原色分量只有 32個顏色,尤其以人眼為綠色最敏感,在綠色的表現上非常糟糕。

後來就以16bit更常用,16bit是不對稱的,白色值為 31,63,31,對綠色專門進行了加強。

如下圖就是24bit圖片和16bit的對比,在細節觀察時,還是能發現右邊16bit的圖片過渡較生硬,因為他只能表達出64中純綠色

16bit顏色通常被稱為高彩色。還是在那個記憶體寸土寸金的時代,16bit顏色在色彩表現上已經足夠好。

所以還是流行了很長的一段時間。

 

再後來,記憶體已經不是問題,很多硬體甚至直接拋棄了16bit模式。

24bit被稱為true color(真彩色),除了特別挑剔的眼睛,在照片顯示上,已經很難看出顏色的跳躍過渡。

除非你專門搞一個綠色過渡圖,盯著看,很難看出24bit的瑕疵。

但就是還有那麼一些挑剔的人,覺得24bit畢竟過渡不算完美,就有了30bit,不過30bit至今任然是曲高和寡,僅在專業領域有所展露。

 

而我們常說的32bit顏色,並不是指髮色數,而是24bit+8bit透明通道,32bit就是24bit。

顏色的數學意義

Rgb有基本的數學意義

Rgb三值差距越大,顏色的色彩越強烈,rgb三值差距越小,顏色的色彩越黯淡,這個叫做彩度。又叫飽和度。

Rgb三值數值越高,顏色越明亮,數值越小,顏色越昏暗,這個叫做亮度。

Rgb三值視為一個三角形,值越接近誰,顏色就越接近誰。這個叫色調。

由於RGB並不夠直觀,所以按照上面的數學意義,又建立了HSV色彩模型

無論你用何種繪圖軟體,你總能找到如上圖中的調色器,他們都是基於同一個東西來設計的

就是HSV色彩模型的色調。

色調就是首先畫一個三角形,RGB各作為一個點。然後越接近哪個點,就越接近哪個顏色。

看看上圖中,除了把色環拉成一條線的那個,你都能找到一個RGB三角形

然後把三角形變成六角形,RG之間插入rg混出的黃色,以此類推。

可以用從三角形到圓型的任意形狀表達色調。

顏色本來是難以捉摸的,詩人們,詞人們都傾向於這樣認為。從對彩虹的描寫可見一斑。

我的世界從此以後多了一個你,有時天晴有時雨

顏色是難以捉摸的,那是以前,赤橙黃綠藍靛紫,再看看色調,是不是發現,原來色調就是彩虹,彩虹就是色調。

然後再加上彩度,和亮度,HSV色彩模型可以表示成一個圓錐,越接近頂面中點彩度越低,越接近尖錐亮度越低。

 

HSV是一個直觀模型,直觀的東西意味著你不需要花力氣去記什麼東西,亮度、飽和度、色調這些東西都是直觀可見的東西。

李總之前就告訴過各位,圖形學裡面,看得見摸得著的東西很多,都是土得掉渣的,不要被洋氣的名字嚇到了。

 

介紹這些東西是為了對RGB進行改變的時候知道你在幹什麼。

變化RGB的值

RGB的取值範圍0~1,如果操作出了出界的值,就取邊界

變化RGB的值是為了產生各種效果,為了保持直觀,我們會在Unity裡面編寫Shader來說明。

首先我們一起來建立測試環境

新建場景,搞個quad。新建一個mat,新建一個shader,掛上去。

然後找兩張色彩鮮豔,看著舒服的圖片來測試

 

我把Shader簡單修改了一下,不要怕Shader,我們第一彈已經告訴你,Shader,不過如此。

好現在把圖片拖上去,這個Shader不受光照影響,會把圖片原原本本的呈現出來

加法

RGB的加法,表示顏色的疊加,顏色越加越亮。

  1. + (0,1,0)=(1,1,0) 紅加綠等於黃

(0.5,0,0)+(0.7,0,0)=(1.2,0,0)=(1,0,0);兩個暗紅相加就是更亮的紅色,超出1.0的就作為1.0,到頂了再加還是紅色

對圖片來說,加法會不規則的改變原來的顏色,有不協調感,像是加了一層上去。

一般只有光效才會採用加法混合,就是為了不協調。

我們先來做一個顏色疊加

調節AddColor引數的值,顏色就會被直接加到圖片上,超過1的部分取邊界,這個現象叫過曝,過分曝光,有的時候就會追求這個效果。

然後我們把兩張圖加到一起

很不協調,記得我們前面說過,只有光效適合疊加

換上光照圖

乘法

RGB的乘法,表示對亮度的改變,對三個分量乘以相同的值,則三個分量一起變化亮度,色調不變。

對三個分量乘以不同的值,則三個分量分別變化,色調會改變。

對圖片來說,圖片乘以圖片沒有什麼意義,一般採用圖片乘以一個顏色值,可以表示對整個圖片的亮度進行修改。

AlphaBlend

透明混合 是加法和乘法的組合運用。

NewColor =SrcColor*(1-Alpha)+Color*Alpha;

將底圖的顏色根據當前圖的(1-alpha)降低亮度

將當前圖的顏色根據當前圖的alpha 降低亮度,再合併到一起。

若alpha越低,底圖的亮度降低的越少。若alpha越高,當前圖的亮度降低的越少。

,先弄一張有Alpha通道的圖片

去色

    去色就是把飽和度拉下來,讓圖片看起來是黑白的

我們前面講過,rgb三分量差距越小,則飽和度越低,三分量相等,就是黑白的。

由於人眼對綠色最為敏感,所以有個簡單的方法,讓rgb全部都等於綠色的值。

對於色彩鮮豔的圖片你完全可以這樣做,不過這個方法有個缺陷,如果圖片綠色成分太少,就會很糟糕。

紅色明亮的部分也都很昏暗,沙發和背景完全無法區分了

更準確的方式是按照人眼的敏感度求權出亮度

好了,我們已經說明了幾種最常用的變化方式和他的意義,記住。

做圖形,最重要的是空間想象(腦補)能力

 

再會。

 

未完持續

相關文章