<commit_before>## 颜色

![<NAME> - Color Chart (1931)](klee.jpg)

我们目前为止还未涉及到GLSL的向量类型。在我们深入向量之前，学习更多关于变量和色彩主题是一个了解向量类型的好方法。

若你熟悉面向对象的编程范式（或者说编程思维模式），你一定注意到我们以一种类C的 ```struct```的方式访问向量数据的内部分量。


```glsl
vec3 red = vec3(1.0,0.0,0.0);
red.x = 1.0;
red.y = 0.0;
red.z = 0.0; 
```

以x,y,z定义颜色是不是有些奇怪？正因如此，我们有其他方法访问这些变量——以不同的名字。```.x```, ```.y```, ```.z```也可以被写作```.r```, ```.g```, ```.b``` 和 ```.s```, ```.t```, ```.p```。（```.s```, ```.t```, ```.p```通常被用做后面章节提到的贴图空间坐标）你也可以通过使用索引位置```[0]```, ```[1]``` 和 ```[2]```来访问向量.

下面的代码展示了所有访问相同数据的方式：

```glsl
vec4 vector;
vector[0] = vector.r = vector.x = vector.s;
vector[1] = vector.g = vector.y = vector.t;
vector[2] = vector.b = vector.z = vector.p;
vector[3] = vector.a = vector.w = vector.q;
```

这些指向向量内部变量的不同方式仅仅是设计用来帮助你写出干净代码的术语。着色语言所包含的灵活性为你互换地思考颜色和坐标位置。

GLSL中向量类型的另一大特点是可以用你需要的任意顺序简单地投射和混合（变量）值。这种能力被（形象地）称为：*鸡尾酒*。


```glsl
vec3 yellow, magenta, green;

// Making Yellow 
yellow.rg = vec2(1.0);  // Assigning 1. to red and green channels
yellow[2] = 0.0;        // Assigning 0. to blue channel

// Making Magenta
magenta = yellow.rbg;   // Assign the channels with green and blue swapped

// Making Green
green.rgb = yellow.bgb; // Assign the blue channel of Yellow (0) to red and blue channels 
```

#### 个人工具箱

你可能不习惯用数字拾取颜色--这样非常反直觉。幸运的是，（app store上）有许多可以轻松完成这项任务的程序。寻找一个合适自己的并练习将颜色转化为 ```vec3``` 或 ```vec4``` 格式。例如，这是我在[Spectrum](http://www.eigenlogik.com/spectrum/mac)中使用的的模板。


```
	vec3({{rn}},{{gn}},{{bn}})
	vec4({{rn}},{{gn}},{{bn}},1.0)
```

### 混合颜色

现在你了解到如何定义颜色，是时候将先前所学的整合一下了！在GLSL中，有个十分有用的函数：[```mix()```](../glossary/?search=mix)，这个函数让你以百分比混合两个值。猜下百分比的取值范围？没错，0到1！完美！在你学习了这些基于栅格运动功夫后，是时候练习一下了！

![](mix-f.jpg)

看下下列代码中的第18行，这里展示了我们如果是用随时间变化的sin绝对值来混合 ```colorA``` 和 ```colorB```。

<div class="codeAndCanvas" data="mix.frag"></div>

试着来show一下你所学到的：

* 给颜色赋予一个有趣的过渡。想想某种特定的感情。哪种颜色更具代表性？他如何产生？又如何褪去？再想想另外的一种感情以及对应的颜色。然后改变上诉代码中的代表这种情感的开始颜色和结束颜色。<NAME> 开发了一些列流行的计算机动画塑形函数，被称之为平滑函数。你可以研究这些例子并得到启发，但最好你还是自己写一个自己的过度函数。


### 玩玩渐变

[```mix()```](../glossary/?search=mix) 函数有更多的用处。我们可以输入两个互相匹配的变量类型而不仅仅是单独的 ```float``` 变量，在我们这个例子中用的是 ```vec3```。这样我们便获得了混合颜色单独通道 ```.r```，```.g``` 和 ```.b```的能力。

![](mix-vec.jpg)

试试下面的例子。正如前面一个例子，我们用一条线来可视化根据单位化x坐标的过渡。现在所有通道都按照同样的线性变换过渡。


现在试试取消25行的注释，看看会发生什么。然后再试试取消26行和27行。记住直线代表了```colorA``` 和 ```colorB```每个通道的混合比例。

<div class="codeAndCanvas" data="gradient.frag"></div>
<commit_msg>proofread chapter06-ch<commit_after>## 颜色

![<NAME> - Color Chart (1931)](klee.jpg)

我们目前为止还未涉及到GLSL的向量类型。在我们深入向量之前，学习更多关于变量和色彩主题是一个了解向量类型的好方法。

若你熟悉面向对象的编程范式（或者说编程思维模式），你一定注意到我们以一种类C的 ```struct```的方式访问向量数据的内部分量。


```glsl
vec3 red = vec3(1.0,0.0,0.0);
red.x = 1.0;
red.y = 0.0;
red.z = 0.0; 
```

以x,y,z定义颜色是不是有些奇怪？正因如此，我们有其他方法访问这些变量——以不同的名字。```.x```, ```.y```, ```.z```也可以被写作```.r```, ```.g```, ```.b``` 和 ```.s```, ```.t```, ```.p```。（```.s```, ```.t```, ```.p```通常被用做后面章节提到的贴图空间坐标）你也可以通过使用索引位置```[0]```, ```[1]``` 和 ```[2]```来访问向量.

下面的代码展示了所有访问相同数据的方式：

```glsl
vec4 vector;
vector[0] = vector.r = vector.x = vector.s;
vector[1] = vector.g = vector.y = vector.t;
vector[2] = vector.b = vector.z = vector.p;
vector[3] = vector.a = vector.w = vector.q;
```

这些指向向量内部变量的不同方式仅仅是设计用来帮助你写出干净代码的术语。着色语言所包含的灵活性为你互换地思考颜色和坐标位置。

GLSL中向量类型的另一大特点是可以用你需要的任意顺序简单地投射和混合（变量）值。这种能力被（形象地）称为：**鸡尾酒**。


```glsl
vec3 yellow, magenta, green;

// Making Yellow 
yellow.rg = vec2(1.0);  // Assigning 1. to red and green channels
yellow[2] = 0.0;        // Assigning 0. to blue channel

// Making Magenta
magenta = yellow.rbg;   // Assign the channels with green and blue swapped

// Making Green
green.rgb = yellow.bgb; // Assign the blue channel of Yellow (0) to red and blue channels 
```

#### 个人工具箱

你可能不习惯用数字拾取颜色--这样非常反直觉。幸运的是，（app store上）有许多可以轻松完成这项任务的程序。寻找一个合适自己的并练习将颜色转化为 ```vec3``` 或 ```vec4``` 格式。例如，这是我在[Spectrum](http://www.eigenlogik.com/spectrum/mac)中使用的的模板。


```
	vec3({{rn}},{{gn}},{{bn}})
	vec4({{rn}},{{gn}},{{bn}},1.0)
```

### 混合颜色

现在你了解到如何定义颜色，是时候将先前所学的整合一下了！在GLSL中，有个十分有用的函数：[```mix()```](../glossary/?search=mix)，这个函数让你以百分比混合两个值。猜下百分比的取值范围？没错，0到1！完美！学了这么久的基本功，是时候来用一用了！

![](mix-f.jpg)

看下下列代码中的第18行，这里展示了我们如果是用随时间变化的sin绝对值来混合 ```colorA``` 和 ```colorB```。

<div class="codeAndCanvas" data="mix.frag"></div>

试着来 show 一下你所学到的：

* 给颜色赋予一个有趣的过渡。想想某种特定的感情。哪种颜色更具代表性？他如何产生？又如何褪去？再想想另外的一种感情以及对应的颜色。然后改变上诉代码中的代表这种情感的开始颜色和结束颜色。<NAME> 开发了一些列流行的计算机动画塑形函数，被称为[缓动函数](http://easings.net/)。你可以研究这些[例子](../edit.html#06/easing.frag)并得到启发，但最好你还是自己写一个自己的缓动函数。


### 玩玩渐变

[```mix()```](../glossary/?search=mix) 函数有更多的用处。我们可以输入两个互相匹配的变量类型而不仅仅是单独的 ```float``` 变量，在我们这个例子中用的是 ```vec3```。这样我们便获得了混合颜色单独通道 ```.r```，```.g``` 和 ```.b```的能力。

![](mix-vec.jpg)

试试下面的例子。正如前面一个例子，我们用一条线来可视化根据单位化x坐标的过渡。现在所有通道都按照同样的线性变换过渡。


现在试试取消25行的注释，看看会发生什么。然后再试试取消26行和27行。记住直线代表了```colorA``` 和 ```colorB```每个通道的混合比例。

<div class="codeAndCanvas" data="gradient.frag"></div>

{'fraction_non_alphanumeric': 0.22879070732213233, 'fraction_numerical': 0.02281684297863514, 'mean_word_length': 6.429892141756548, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3046435', 'n_tokens_mistral': 3257, 'n_tokens_neox': 3482, 'n_words': 293}