作者:Herman Tulleken
改變顏色是一個豐富遊戲內容的好辦法,並且比較容易執行。但困難的是如何選擇漂亮的色彩組合。本文將介紹一些選擇顏色組合的知識。
顏色的基本知識 顏色是非常複雜的。顏色是在光、材質、眼睛和大腦以及少量心理因素的共同作用下產生的。
盡管你不需要知道所有與顏色有關的物理學、生物學和心理學知識,但你必須了解一些背景知識。
以下是選擇色彩範圍的要點。

colours
數字化色彩理論與顏料的色彩(化學顏料、晶體顏色)理論大不相同。事實上,無論如何混合顏色,也不可能產生自然界中的所有顏色。你可以在顏料店買一種非常亮的綠色,但電腦屏幕能產生的最接近的顏色也達不到相同的飽和度。當你研究顏色的算法時,請確保你使用的色彩模式是是數字RGB。
RGB和許多其他色彩模式的矢量距離與我們的感覺到的差異是不一樣的。

grey
這些灰色是等距排列的。但請注意,亮度較高的灰色之間更容易區分。

heu
在每一排,飽和度差距為5%。注意,某些顏色是不能區別的。另外,色相也受到亮度的影響。較淡的藍色比較深的藍色更容易區分,而較暗的品紅色比較淡的品紅色更容易區分。
當你選擇看起來距離“相同”的顏色時,你就必須注意到這些差異。通常來說,你必須使用基於感覺的色彩空間(如LAB色彩)或在其他色彩空間中做適當的調整。
感覺上,LAB色彩空間更統一,是理想的色彩選擇算法的基礎(遊戲邦注:PS專家們應該知道隻操作LAB通道而不操作RGB通道,色相調整的人為痕跡更少)。
色彩感知不是絕對的。顏色的產生受到周邊色彩的影響。給當前顏色選擇匹配顏色或組合多個顏色時,這是一個重要的考慮因素。

color_relavance
色彩和諧理論。盡管很難解釋為什麼某色彩組合比另一種看起來更好,但我們可以通過色彩和諧理論來理解它。
程序性調色板的使用 
tiny wings
程序性調色板可用於:
1、在連續產生的場景中得到更多變體,如《翼飛衝天》。
2、從單一材料中得到更多變體,如上圖所示。
3、給界麵部件自動生成顏色,如早期版本的Microsoft Excel和Open Office Calc中的圖像。
注意
當選擇算法時,你必須考慮以下幾點:
1、你需要多少種顏色?很少還是很多?固定的數量還是任意數量?
2、顏色之間的關係是什麼?例如,是否形成和諧的三色組合?
3、你的顏色組合的對比度是高還是低?
4、在程序性色彩選擇中使用什麼顏色?
5、顏色是否傳達含義?是否需要匹配現實世界的元素?是否采用象征手法,以區分不同類型的元素?
6、你需要什麼類型的變體?連續生成的變體?還是同一個場景中的變體?
算法 1、從預設中選擇隨機顏色
這是非常簡單的一種算法,且容易執行。它隻適用於小色板,當然所用色板都受限於初始設置。但是,它可以與其他算法相結合,以產生更大的色彩組合。
2、統一的隨機RGB
這是程序性色彩選擇的最簡單的算法,也就是給三個RGB通道分別設置隨機值。
color = new Color(Random(), Random(), Random())

Uniform_5_2
這種算法產生的顏色組合通常並不好看。沒有愉悅視覺的結構性、關係性和圖案。以下所有算法都試圖限製色彩產生,以便在色彩之間形成關係性或連貫性。
3、隨機偏移量
這種算法通過計算給定顏色的小量隨機偏移來推斷色彩範圍。

random offset
這種算法容易執行,隻要計算各個RGB組件的隨機偏移量就可以了。另一種辦法是,根據隨機偏移量改變顏色值。
float value = (color.r + color.g + color.b)/3;
float newValue = value + 2*Random() * offset – offset;
float valueRatio = newValue / value;
Color newColor;
newColor.r = color.r * valueRatio;
newColor.g = color.g * valueRatio;
newColor.b = color.b * valueRatio;
在某些情況下,隨機改變值可以模擬陰影,使場景更有深度。
通常來說,這種算法:
1、不適合要求高對比度的小色板。
2、適合基本色確定且重複多次的裝飾性場景。
3、適合有縫的著色貼圖(使用無縫貼圖得到變體更費功夫)。

dynamic colouring
最大偏移量的效果取決於基本色:
基本色的飽和度越低,結果色彩越豐富。
不同的色相有不同的感覺變化度。例如,如果基本色是黃色,那麼結果比基本色是綠色時更豐富。
4、從漸變中選擇
在以下代碼案例中,Gradient.GetColor的參數介於0到1,在漸變中產生相應的顏色。
統一隨機(Uniform Random)在0到1之間隨機選擇值,並映射到漸變中以選擇顏色。這可以產生結構性效果,但原來就是漸變的色彩組合除外。

gradient
網格(Grid)在選擇已知數量的顏色時非常實用,因為可以保證兩種顏色之間的接近(沿著漸變)程度不會超過1/n。

Grid_Rainbow_5_2
這對於傳達信息的顏色非常有用,如果顏色數量很小的話。
抖動網格(Jittered Grid)在用少量(你已經知道顏色數量)顏色產生更多變體時很實用。這種算法的一個缺點是,序列中的顏色不能保證彼此之間的差距相同。你可以通過限製誤差量為顏色之間的最小距離來解決這個問題。
for(int i = 0; i < n; i++)
color[i] = gradient.GetColor((i + Random.NextFloat()) * intervalSize)
抖動網格非常適用於選擇少量的顏色,這樣多次選擇就會產生不同的結果。
maxJitter = …//some value between 0 1nd 1
for(int i = 0; i < n; i++)
color[i] = gradient.GetColor(
(i + 0.5 + (2 * Random.NextFloat() – 1) * maxJitter) * intervalSize);

rainbow
黃金比例(Golden Ratio)是選擇顏色序列的一種方案,不一定是預設,所以連續選擇的顏色總是彼此相距很遠,且不重複(盡管顏色會越來越接近之前選擇過的顏色)。
offset = Random.NextFloat();
for (int i = 0; i < n; i++)
color[i] = gradient.GetColor(offset + (0.618033988749895f * i) % 1);

GoldenRatioGradient_5_0
這種算法適用於選擇界麵上的連續性高對比度顏色。

player stats
5、在其他色彩空間中選擇隨機通道
例如,使用HSL色域可以產生良好的結果。

random hue

Saturation_5_2

Luminance_5_2

Saturation_Luminance_5_2
6、標準色彩和諧
選擇標準色彩和諧的隨機顏色的方法基本上是一樣的:限製色相數量,控製飽和度和明度。我們可以使用通用的三色係和合適的參數來產生各種色彩和諧。
這種算法需要若幹參數;最重要的是兩個偏角和兩個角度範圍。
這種算法的最簡單形式如下:
1、選擇隨機參考角度。
2、在完全範圍內選擇隨機角度(三個範圍角度加在一起)。
3、如果這個角度小於第一個範圍,那就保留。
4、否則,如果這個角度大於第一個範圍,但小於前兩個範圍之和,那就由第一個偏移度補償它。
5、將這個角度添加到參考角度。
6、以這個角度作為色相的顏色就能產生三色和諧。
以下是這處算法的C#執行算法,產生了給定數量、具有可控飽和度和明度的顏色。
public static List GenerateColors_Harmony(
int colorCount,
float offsetAngle1,
float offsetAngle2,
float rangeAngle0,
float rangeAngle1,
float rangeAngle2,
float saturation, float luminance)
{
List colors = new List();
float referenceAngle = random.NextFloat() * 360;
for (int i = 0; i < colorCount; i++)
{
float randomAngle =
random.NextFloat() * (rangeAngle0 + rangeAngle1 + rangeAngle2);
if (randomAngle > rangeAngle0)
{
if (randomAngle < rangeAngle0 + rangeAngle1)
{
randomAngle += offsetAngle1;
}
else
{
randomAngle += offsetAngle2;
}
}
HSL hslColor = new HSL(
((referenceAngle + randomAngle) / 360.0f) % 1.0f,
saturation,
luminance);
colors.Add(hslColor.Color);
}
return colors;
}
這個算法更直觀地說,就是將參考和偏移角度置於相應範圍的中央。
1、選擇隨機參考角度。
2、在完全範圍內選擇隨機角度(三個範圍角度加在一起)。
3、如果這個角度小於第一個範圍,那就減少它相當於第一範圍的一半角度。
4、否則,如果這個角度大於第一個範圍,但小於前兩個範圍之和,那就由第一個偏移範圍減去第二個範圍的結果來補償它。
5、否則,用第二個徧移角度減去第三個範圍來補償它。
6、將這個角度添加到參考角度。
7、以這個角度作為色相的顏色就能產生三色和諧。
更多變量 1、有了這個算法的置中版本,很容易提供(而不是生成)參考角度,和與其他顏色選擇算法相結合。
2、通過選擇隨機飽和度和隨機明度(可能在給定參數的範圍內)可以添加更多變量。這可能改變和諧方案,因為飽和度/明度突出了邊緣顏色。但在很多時候,這並不成問題。
3、色相可以統一選擇,而不是在整個範圍內隨機選擇。這保證顏色的色相差距最小。
4、如果參數合適,我們可以生成普遍的色彩方案:
A、類似的:選擇第二和第三範圍為0。
B、互補的:選擇第三範圍為0,第一偏移角度為180。
C、補色分割:選擇徧移角度為180+/-一個小角度。第二個和第三範圍必須小於這兩個偏移角度的差值。
D、三色係:選擇徧移角度為120和240。

Harmony
7、三色混合
這個算法需要三種顏色,隨機混合以產生色板。
這種標準的算法會產生大量灰色調顏色。如果效果不理想,可以通過限製三色中的其中一色的量來控製灰度。以下是這個算法的例子(如果灰度控製是1,那就相當於標準算法。)
public static Color RandomMix(Color color1, Color color2, Color color3,
float greyControl)
{
int randomIndex = random.NextByte() % 3;
float mixRatio1 =
(randomIndex == 0) ? random.NextFloat() * greyControl : random.NextFloat();
float mixRatio2 =
(randomIndex == 1) ? random.NextFloat() * greyControl : random.NextFloat();
float mixRatio3 =
(randomIndex == 2) ? random.NextFloat() * greyControl : random.NextFloat();
float sum = mixRatio1 + mixRatio2 + mixRatio3;
mixRatio1 /= sum;
mixRatio2 /= sum;
mixRatio3 /= sum;
return Color.FromArgb(
255,
(byte)(mixRatio1 * color1.R + mixRatio2 * color2.R + mixRatio3 * color3.R),
(byte)(mixRatio1 * color1.G + mixRatio2 * color2.G + mixRatio3 * color3.G),
(byte)(mixRatio1 * color1.B + mixRatio2 * color2.B + mixRatio3 * color3.B));
}
可以使用不同的混合算法,例如減少混合量或色相插值。

high grey value

grey value 2
以下你可以看到設置灰度值的效果。左邊的灰度值為0,右邊的為1。

grey value 3
單色材質 與手繪材質不同,程序改變的材質可能看起來非常單調和無趣。
這個問題可以通過幾種方法來解決。這些方法都要求相當高的藝術修養,但理解技術和其運作方式(如何影響藝術傳達)也是非常重要的。
使用有色材質。這種基本材質必須是完全灰度的。給它們上色會抵消最終的顏色,可以用於本地色彩變量。

coloured textures
通道獨立色彩修正。有時候可以通過分別調整通道值來得到良好的效果。在下圖的例子中,陰影呈紅色(左邊的圖片沒有經過色彩修正)。

colour correction
使用有色光。在稍有不同的角度上使用有色光,單調的材質可以變得更細膩。如下圖的場景中有三種性質相同的光,但右圖的光是紅色、藍色和綠色(3倍強度,以補償各種光中缺少的通道)。

coloured lights
準備美術材料 準備美術材料需要認真計劃。最大的難題是想出如何一致地分離材質。為了便於讀者了解這個過程,以下我解釋了我自己準備本文圖片的方法:
1、蕨類使用單一材料。各種蕨類從當前設置中隨機選擇顏色,這樣我就可以方便地編寫顏色選擇的腳本。
2、每一部分的花都使用不同的材料。隻有花瓣必須改變顏色,所以我必須修改一部分網格(花瓣)的腳本以調整顏色。
3、空間場景再次在網格的各個部分中使用分離材料。此時,我使用設置所有副網格顏色的全局腳本。
你可以看到,這個過程可能很複雜,特別是如果你要用不同的算法來給不同的元素上色,並且對象也很複雜。
以下是準備美術材料的同個小技巧:
1、如果你用程序性顏色疊加你的灰度材質,覆蓋大範圍灰度範圍的材質必須更靈活。你的顏色應用算法或你選擇的顏色可能總是減少最後的對比度,但要恢複就更困難得多。
2、認真計劃你修改最終結果的方法,以免返工(這是一個普遍的藝術原則,但如果你體表和這個技術,這一條就更顯重要了)。例如,至少有四種方法可以加深顏色:改變材質、改變顏色選擇算法的輸入、改變光照、或改變後期效果。你可以簡單地調整循環,以免浪費時間。一個策略是,給所有東西做一個基準麵,然後在按材質、算法、光照、後期效果的順序調整它們。
3、在這些情況下,可能索引顏色比較實用,因為各個索引相當於色板中的一種顏色,而不是給各種顏色使用不同材料。
4、在犧牲磁盤空間而獲得性能的情況下,你可以提前準備材質。