minor tweaks to enforce writing conventions

pull/28/head
kynd 9 years ago
parent 3cece61dcd
commit bac200ad28

@ -37,7 +37,7 @@
## GLSLとは
GLSLはopenGL Shading Languageの略で、標準化されたシェーダー言語のつです。これ以降の章ではこの言語を扱います。他にもハードやOSによって異なるシェーダー言語があります。
GLSLはopenGL Shading Languageの略で、標準化されたシェーダー言語の1つです。これ以降の章ではこの言語を扱います。他にもハードやOSによって異なるシェーダー言語があります。
ここからは[クロノスグループ](https://www.khronos.org/opengl/)によって策定されたOpenGLの仕様に基づいて話を進めます。OpenGLの歴史を知っておくと奇妙な訳注プログラミング、言語仕様上の慣習を理解する助けになるかもしれません。[openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html)に軽く目を通しておくと良いでしょう。
## なぜシェーダーは厄介だと思われているのか

@ -14,15 +14,15 @@
2. 最終的なピクセルの色は、予約語として確保されたグローバル変数、```gl_FragColor```に割り当てられます。
3. このCによく似た言語には```gl_FragColor```のような組み込みの「変数」や「関数」、「型」があります。このサンプルでは浮動小数点精度を持つ4次元ベクトル```vec4```型が使われています。またこの後、```vec3```、```vec2```のような型や、おなじみの```float```、```int```、```bool```なども登場します。
3. このCによく似た言語には```gl_FragColor```のような組み込みの「変数」や「関数」、「型」があります。このサンプルでは浮動小数点精度を持つ4次元ベクトル ```vec4``` 型が使われています。またこの後、```vec3```、```vec2``` のような型や、おなじみの ```float```、```int```、```bool``` なども登場します。
4. ```vec4```型をよく見ると、4つの引数はそれぞれ赤RedGreen、青Blue、透過度Alphaの各チャンネルに対応していることが分かるでしょう。またこれらの値が正規化されているnormalized、つまり```0.0```から```1.0```の値をとることも読み取れます。後ほど、値が正規化されていると変数間の写像に便利であることを学びます。
4. ```vec4```型をよく見ると、4つの引数はそれぞれ赤RedGreen、青Blue、透過度Alphaの各チャンネルに対応していることが分かるでしょう。またこれらの値が正規化されているnormalized、つまり ```0.0``` から ```1.0``` の値をとることも読み取れます。後ほど、値が正規化されていると変数間の写像に便利であることを学びます。
5. プリプロセッサマクロが使えるのも、このサンプルから読み取れるもう一つの大事な「C言語的」特徴です。マクロはコンパイルの前に処理されます。マクロを使うとグローバル変数を定義```#define```)したり、```#ifdef```と```#endif```を使って場合分けを行うことができます。全てのマクロの命令はハッシュタグ(```#```)で始まります。コンパイルの直前には全ての```#define```の呼び出しが置き換えられ、```#ifdef```や```#ifndef```といった条件文のチェックが行なわれます。上のサンプルでは、```GL_ES```が定義されているときにだけ2行目のコードを挿入します。```GL_ES```は多くの場合、モバイル機器やブラウザー上でコンパイルされたことを意味します。
5. プリプロセッサマクロが使えるのも、このサンプルから読み取れるもう一つの大事な「C言語的」特徴です。マクロはコンパイルの前に処理されます。マクロを使うとグローバル変数を定義```#define```)したり、```#ifdef``` ```#endif``` を使って場合分けを行うことができます。全てのマクロの命令はハッシュタグ(```#```)で始まります。コンパイルの直前には全ての ```#define``` の呼び出しが置き換えられ、```#ifdef``` ```#ifndef``` といった条件文のチェックが行なわれます。上のサンプルでは、```GL_ES``` が定義されているときにだけ2行目のコードを挿入します。```GL_ES``` は多くの場合、モバイル機器やブラウザー上でコンパイルされたことを意味します。
6. 浮動小数点型はシェーダーに不可欠で、その精度はとても重要な意味を持ちます。精度が低いとレンダリングが速くなる代わりに品質が下がります。もしこだわりたければ、GLSLでは浮動小数点を使うそれぞれの変数ごとに精度を指定できます。一行目の```precision mediump float;```は、全ての浮動小数点型の変数に中レベルの精度を指定しています。より低い精度(```precision lowp float;```)や高い精度(```precision highp float;```)を選ぶこともできます。
6. 浮動小数点型はシェーダーに不可欠で、その精度はとても重要な意味を持ちます。精度が低いとレンダリングが速くなる代わりに品質が下がります。もしこだわりたければ、GLSLでは浮動小数点を使うそれぞれの変数ごとに精度を指定できます。一行目の ```precision mediump float;``` は、全ての浮動小数点型の変数に中レベルの精度を指定しています。より低い精度(```precision lowp float;```)や高い精度(```precision highp float;```)を選ぶこともできます。
7. 最後に、そしておそらく一番大切なことですが、GLSLの仕様では変数の自動的な型変換は保証されていません。どういうことでしょう。メーカーは色々な方法でグラフィックカードを高速化しようとしますが、同時に最低限の仕様を満たす必要があります。自動的な型変換はこの最低限の仕様には含まれていません。上のサンプルでは```vec4```型は浮動小数点精度を持っているので、```float```型の値が割り当てられることになっています。コードの一貫性を保ち、真っ白な画面で何時間もデバッグするのを避けるために、浮動小数点型の値には小数点(```.```)を使うことを習慣にしましょう。下記のようなコードはうまく動くとは限りません。
7. 最後に、そしておそらく一番大切なことですが、GLSLの仕様では変数の自動的な型変換は保証されていません。どういうことでしょう。メーカーは色々な方法でグラフィックカードを高速化しようとしますが、同時に最低限の仕様を満たす必要があります。自動的な型変換はこの最低限の仕様には含まれていません。上のサンプルでは ```vec4``` 型は浮動小数点精度を持っているので、```float``` 型の値が割り当てられることになっています。コードの一貫性を保ち、真っ白な画面で何時間もデバッグするのを避けるために、浮動小数点型の値には小数点(```.```)を使うことを習慣にしましょう。下記のようなコードはうまく動くとは限りません。
訳注gl_FragColorはGLSL1.3から非推奨になりました。以降のバージョンでは開発者が自由に名前をつけることができます。この本のサンプルは1.2以前のバージョンで書かれているため、gl_FragColorを出力用の変数として用います
@ -40,7 +40,7 @@ void main() {
* 6行目をコメントアウトして好きな値を関数に割り当ててみましょう。
* 特定の色を返す別の関数を用意して```main()```関数の中で使ってみましょう。ヒント:下記のコードは赤色を返す関数です。
* 特定の色を返す別の関数を用意して ```main()``` 関数の中で使ってみましょう。ヒント:下記のコードは赤色を返す関数です。
```glsl
vec4 red(){
@ -54,4 +54,4 @@ vec4 red(){
vec4 color = vec4(vec3(1.0,0.0,1.0),1.0);
```
この章のサンプルはさほど面白くはありませんが、キャンバス上のピクセルを全て同じ色に変える最も基礎的な例です。この後に続く章ではピクセルの色を2種類の入力、空間画面上のピクセルの位置と時間ページがロードされてから経過した秒数を使って変化させる方法を学びます。
この章のサンプルはさほど面白くはありませんが、キャンバス上のピクセルを全て同じ色に変える最も基礎的な例です。この後に続く章ではピクセルの色を2種類の入力、空間画面上のピクセルの位置と時間ページがロードされてから経過した秒数を使って変化させる方法を学びます。

@ -2,7 +2,7 @@
ここまで、GPUが沢山のスレッドを並列に処理する様子を見てきました。それぞれのスレッドは画像の各部分への色の割り当てを受け持っています。シェーダーではスレッド間の情報のやりとりを行うことはできませんが、CPUからそれぞれのスレッドに入力を送ることはできます。グラフィックカードは全てのスレッドにまったく同じ入力を、読み取り専用で送るように設計されています。それぞれのスレッドは同じデータを受け取り、それを書き換えることはできません。訳注英語の”uniform”には均一な、一様な、という意味があります
これらの入力は```uniform```変数と呼ばれGLSLでサポートされているほとんどの型が使えます。サポートされている型には ```float```、```vec2```、```vec3```、```vec4```、```mat2```、```mat3```、```mat4```、```sampler2D```、```samplerCube```などがあります。
これらの入力は ```uniform``` 変数と呼ばれGLSLでサポートされているほとんどの型が使えます。サポートされている型には ```float```、```vec2```、```vec3```、```vec4```、```mat2```、```mat3```、```mat4```、```sampler2D```、```samplerCube``` などがあります。
uniform変数はシェーダーの冒頭、浮動小数点精度の設定の後に型指定付きで定義します。
```glsl
@ -15,7 +15,7 @@ uniform vec2 u_mouse; // mouse position in screen pixels
uniform float u_time; // Time in seconds since load
```
uniform変数はCPUとGPUの間の小さな架け橋だと考えることができます。変数の名前は実装次第で変わりますが、この本のサンプルでは一貫して```u_time```(シェーダーが開始してから経過した秒数)、```u_resolution```(シェーダーが描画する領域の大きさ)、```u_mouse```描画領域の中のマウスの位置を渡すことにします。ここでは変数の種類を示すためにuniform変数の名前は```u_```で始めるという慣例に従っていますが、他の場所では異なる名前が使われているのも見かけることでしょう。
uniform変数はCPUとGPUの間の小さな架け橋だと考えることができます。変数の名前は実装次第で変わりますが、この本のサンプルでは一貫して```u_time```(シェーダーが開始してから経過した秒数)、```u_resolution```(シェーダーが描画する領域の大きさ)、```u_mouse```描画領域の中のマウスの位置を渡すことにします。ここでは変数の種類を示すためにuniform変数の名前は ```u_``` で始めるという慣例に従っていますが、他の場所では異なる名前が使われているのも見かけることでしょう。
例えば[ShaderToy.com](https://www.shadertoy.com/)では同じ意味を持つuniform変数に下記の名前が付けられています。
@ -31,7 +31,7 @@ uniform float iGlobalTime; // shader playback time (in seconds)
<div class="codeAndCanvas" data="time.frag"></div>
GPUの驚くべき機能の一つとして、角度や三角関数、指数関数などがハードウェア上で高速に処理されることが挙げられます。サポートされる関数には [```sin()```](../glossary/?search=sin)、 [```cos()```](../glossary/?search=cos)、[```tan()```](../glossary/?search=tan)、 [```asin()```](../glossary/?search=asin)、[```acos()```](../glossary/?search=acos)、 [```atan()```](../glossary/?search=atan)、[```pow()```](../glossary/?search=pow)、 [```exp()```](../glossary/?search=exp)、[```log()```](../glossary/?search=log)、 [```sqrt()```](../glossary/?search=sqrt)、[```abs()```](../glossary/?search=abs)、 [```sign()```](../glossary/?search=sign)、[```floor()```](../glossary/?search=floor)、 [```ceil()```](../glossary/?search=ceil)、[```fract()```](../glossary/?search=fract)、 [```mod()```](../glossary/?search=mod)、[```min()```](../glossary/?search=min)、 [```max()```](../glossary/?search=max)、[```clamp()```](../glossary/?search=clamp)などがあります。
GPUの驚くべき機能の1つには、角度や三角関数、指数関数などがハードウェア上で高速に処理されることが挙げられます。サポートされる関数には [```sin()```](../glossary/?search=sin)、 [```cos()```](../glossary/?search=cos)、[```tan()```](../glossary/?search=tan)、 [```asin()```](../glossary/?search=asin)、[```acos()```](../glossary/?search=acos)、 [```atan()```](../glossary/?search=atan)、[```pow()```](../glossary/?search=pow)、 [```exp()```](../glossary/?search=exp)、[```log()```](../glossary/?search=log)、 [```sqrt()```](../glossary/?search=sqrt)、[```abs()```](../glossary/?search=abs)、 [```sign()```](../glossary/?search=sign)、[```floor()```](../glossary/?search=floor)、 [```ceil()```](../glossary/?search=ceil)、[```fract()```](../glossary/?search=fract)、 [```mod()```](../glossary/?search=mod)、[```min()```](../glossary/?search=min)、 [```max()```](../glossary/?search=max)、[```clamp()```](../glossary/?search=clamp) などがあります。
さて、また上のコードで色々と実験をしてみましょう。
@ -39,15 +39,15 @@ GPUの驚くべき機能の一つとして、角度や三角関数、指数関
* 変化のスピードを上げて、点滅がなくなりひとつの色に見えるまで速くしてみましょう。
* つのチャンネルrgbの変化の頻度を別々に変えて、面白いパターンを作ってみましょう。
* 3つのチャンネルrgbの変化の頻度を別々に変えて、面白いパターンを作ってみましょう。
## gl_FragCoord
デフォルトの出力として```vec4 gl_FragColor```を使うことができるのと同様に、GLSLにはデフォルトの入力として画面上の「フラグメント」、つまりピクセルの位置を表す```vec4 gl_FragCoord```が用意されています。```vec4 gl_FragCoord```を使うとスレッドが描画領域内のどこで作業をしているかを知ることができます。この```gl_FragCoord```はスレッドごとに異なる値を持っているためuniform変数とは呼ばず、代わりにvarying変数と呼びます。
デフォルトの出力として ```vec4 gl_FragColor``` を使うことができるのと同様に、GLSLにはデフォルトの入力として画面上の「フラグメント」、つまりピクセルの位置を表す ```vec4 gl_FragCoord``` が用意されています。```vec4 gl_FragCoord``` を使うとスレッドが描画領域内のどこで作業をしているかを知ることができます。この ```gl_FragCoord```はスレッドごとに異なる値を持っているためuniform変数とは呼ばず、代わりにvarying変数と呼びます。
<div class="codeAndCanvas" data="space.frag"></div>
上のサンプルではフラグメントの座標を描画領域全体のサイズで割ることによって正規化しています。こうすると座標値の範囲が```0.0```から```1.0```の間に収まるため、簡単にx座標とy座標の値をrとgのチャンネルに対応させることができます。
上のサンプルではフラグメントの座標を描画領域全体のサイズで割ることによって正規化しています。こうすると座標値の範囲が ```0.0``` から ```1.0``` の間に収まるため、簡単にx座標とy座標の値をrとgのチャンネルに対応させることができます。
シェーダーの世界ではデバッグに使える手段は限られています。判別しやすい色を変数の値に割り当てて確認するのは数少ない方法の一つです。GLSLのコーディングは時としてガラス瓶の中に船の模型を組み立てるのに似ています。どちらも同じくらい難しいですが、結果は美しく達成感があるものです。
@ -55,13 +55,13 @@ GPUの驚くべき機能の一つとして、角度や三角関数、指数関
それでは、サンプルが理解できているか確かめてみましょう。
* 座標```(0.0,0.0)```が描画領域のどこを指すかわかりますか?
* 座標 ```(0.0,0.0)``` が描画領域のどこを指すかわかりますか?
* ```(1.0,0.0)```、```(0.0,1.0)```、```(0.5,0.5)```、```(1.0,1.0)```はどうでしょう?
* ```(1.0,0.0)```、```(0.0,1.0)```、```(0.5,0.5)```、```(1.0,1.0)``` はどうでしょう?
* ```u_mouse```の使い方はわかりますか? ```u_mouse```の値は正規化されていないことに注意してください。この変数を使って色を変化させることはできますか?
* ```u_mouse``` の使い方はわかりますか? ```u_mouse``` の値は正規化されていないことに注意してください。この変数を使って色を変化させることはできますか?
* ```u_time```と```u_mouse```の座標を使って色のパターンを自由に変化させてみましょう。
* ```u_time``` ```u_mouse``` の座標を使って色のパターンを自由に変化させてみましょう。
さて、課題を終えたところで、このシェーダーの力を他にどこで使うことができるのか興味が湧いているのではないでしょうか。
次の章ではオリジナルのシェーダーをthree.js、Processing、openFrameworkで使う方法について説明します。

@ -8,7 +8,7 @@
### **Three.js**を使う
謙虚で才気あふれる[リカルド・カベロ](https://twitter.com/mrdoob)Ricardo Cabello aka MrDoobと[その他のメンバー](https://github.com/mrdoob/three.js/graphs/contributors)によって開発された[Three.js](http://threejs.org/)は、おそらく最もよく知られたWebGLのフレームワークのひとつです。このJavascriptのライブラリを使って3Dグラフィックを作る方法を学べる、サンプルやチュートリアル、本も沢山あります。
謙虚で才気あふれる[Ricardo CabelloMrDoob](https://twitter.com/mrdoob)と[その他のメンバー](https://github.com/mrdoob/three.js/graphs/contributors)によって開発された[Three.js](http://threejs.org/)は、おそらく最もよく知られたWebGLのフレームワークのひとつです。このJavascriptのライブラリを使って3Dグラフィックを作る方法を学べる、サンプルやチュートリアル、本も沢山あります。
下記はシェーダーをThree.jsで使うために必要なHTMLとJavascriptのサンプルです。```id="fragmentShader"```と書かれたスクリプトに注目してください。ここに、この本に登場するシェーダーをコピーして実行することができます。
@ -92,7 +92,7 @@
### **Processing**を使う
[ベン・フライ](http://benfry.com/) Ben Fryと[ケイシー・リース](http://reas.com/) Casey Reasが2001年に開発を始めた[Processing](https://processing.org/) はコーディングを始めるのに最適な、驚くほどシンプルでパワフルな開発環境です(少なくとも私にとってはそうでした)。[アンドレアス・コルブリ](https://codeanticode.wordpress.com/) Andres ColubriはopenGLとビデオに関する重要なアップデートを行いました。これによってProcessingでのシェーダーの使用が今まで以上に簡単になりました。Processingのスケッチは```data```フォルダーからシェーダーを検索します。このフォルダーにサンプルコードをコピーして```shader.frag```と名前を付けてください。
[Ben Fry](http://benfry.com/)と[Casey Reas](http://reas.com/)が2001年に開発を始めた[Processing](https://processing.org/) はコーディングを始めるのに最適な、驚くほどシンプルでパワフルな開発環境です(少なくとも私にとってはそうでした)。[Andres Colubri](https://codeanticode.wordpress.com/)はopenGLとビデオに関する重要なアップデートを行いました。これによってProcessingでのシェーダーの使用が今まで以上に簡単になりました。Processingのスケッチは ```data``` フォルダーからシェーダーを検索します。このフォルダーにサンプルコードをコピーして ```shader.frag``` と名前を付けてください。
```processing
PShader shader;
@ -113,7 +113,7 @@ void draw() {
}
```
シェーダーを2.1以前のバージョンで使うには、最初に```#define PROCESSING_COLOR_SHADER```を追加する必要があります。つまり以下の様なプログラムになります。
シェーダーを2.1以前のバージョンで使うには、最初に ```#define PROCESSING_COLOR_SHADER``` を追加する必要があります。つまり以下の様なプログラムになります。
```glsl
#ifdef GL_ES
@ -136,8 +136,7 @@ Processingでシェーダーを使う方法についてより詳しく知りた
### **openFrameworks**を使う
誰にでも落ち着ける場所があるものです。私にとっては今でも[openFrameworks](http://openframeworks.cc/)のコミュニティがそうです。このC++のフレームワークは、openGLやその他のC++のライブラリをラップして使いやすくしてくれます。様々な意味でProcessingに似ていますが、C++のコンパイラを扱う分だけ明らかに複雑です。openFrameworksはProcessingと同様に```data```フォルダー以下のシェーダーのファイルを検索します。サンプルを```shader.frag```にコピーして読み込むようにしてください。
誰にでも落ち着ける場所があるものです。私にとっては今でも[openFrameworks](http://openframeworks.cc/)のコミュニティがそうです。このC++のフレームワークは、openGLやその他のC++のライブラリを内包して使いやすくしてくれます。様々な意味でProcessingに似ていますが、C++のコンパイラを扱う分だけ明らかに複雑です。openFrameworksはProcessingと同様に ```data``` フォルダー以下のシェーダーのファイルを検索します。サンプルを ```shader.frag``` にコピーして読み込むようにしてください。
```cpp
void ofApp::draw(){
@ -152,4 +151,4 @@ void ofApp::draw(){
}
```
openFrameworksでシェーダーを使う方法についてより詳しく知りたい場合は[ジョシュア・ノーブル](https://processing.org/tutorials/pshader/)の[素晴らしいチュートリアル](http://openframeworks.cc/tutorials/graphics/shaders.html) を参照してください。
openFrameworksでシェーダーを使う方法についてより詳しく知りたい場合は[Joshua Noble](https://processing.org/tutorials/pshader/)の[素晴らしいチュートリアル](http://openframeworks.cc/tutorials/graphics/shaders.html) を参照してください。

@ -7,33 +7,33 @@
![ベスト・キッド1984](mr_miyagi.jpg)
私たちにとってミヤギさんの壁に当たるものは、下記に示すコードの枠組みです。この枠組みを使って、正規化されたx座標の値を2種類の方法で目に見えるようにしてみます。1つめの方法では色の明るさを使い黒から白への綺麗なグラデーションを見てください、2つめでは緑色の線を描画しますここではx座標の値をそのままy座標に割り当てています。plot関数のことは今はあまり気にしないでください。すぐ後で詳しく説明します。
私たちにとってミヤギさんの壁に当たるものは、下記に示すコードの枠組みです。この枠組みを使って、正規化されたx座標の値を2種類の方法で目に見えるようにしてみます。1つめの方法では色の明るさを使い黒から白への綺麗なグラデーションを見てください、2つめでは緑色の線を描画しますここではx座標の値をそのままy座標に割り当てています```plot``` 関数のことは今はあまり気にしないでください。すぐ後で詳しく説明します。
<div class="codeAndCanvas" data="linear.frag"></div>
上記のサンプルの20行目と26行目を見てください。
```vec3```型のコンストラクタに値を1つだけ渡すと、コンストラクタは3つの色のチャンネルに同じ値を割りてようとしているのだと解釈します。一方で```vec4```は三次元のベクトルともう1つの値ここではalpha、つまり透明度で初期化されています。
```vec3``` 型のコンストラクタに値を1つだけ渡すと、コンストラクタは3つの色のチャンネルに同じ値を割りてようとしているのだと解釈します。一方で ```vec4``` は三次元のベクトルともう1つの値ここではalpha、つまり透明度で初期化されています。
このコードがミヤギさんの壁です。よく観察して理解しておくことが大切です。この0.0から1.0の空間には何度も立ち帰ることになるでしょう。そしてあなたはいずれ、色と形を操る技をマスターするのです。
このコードがミヤギさんの壁です。よく観察して理解しておくことが大切です。この 0.0 から 1.0 の空間には何度も立ち帰ることになるでしょう。そしてあなたはいずれ、色と形を操る技をマスターするのです。
このサンプルのx座標とy座標または明るさの1対1の対応は線形補間と呼ばれています。
ここから私たちは数学的な関数を使って線を形作っていくことになります。例えばxを5乗すれば曲線を作ることができます。
訳注ここではx=0.0からx=1.0の間のグラフが一次方程式で書ける、つまりグラフが直線になることを指して線形補完 * Liniear Interpolation*という言葉が使われています。参考:[Wikipedia: 線形補間](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E8%A3%9C%E9%96%93)。このの章の原文ではInterpolateという単語が複数回登場しますが、厳密な使い方ではない箇所もあるため以下では「補完」という訳語はあてませんでした。興味がある方はコンピュータグラフィックスやアニメーションの世界で補完関数 *Interpolator* がどのように使われているか調べてみましょう。)
(訳注:ここでは x=0.0 から x=1.0 の間のグラフが一次方程式で書ける、つまりグラフが直線になることを指して線形補完 * Liniear Interpolation*という言葉が使われています。参考:[Wikipedia: 線形補間](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E8%A3%9C%E9%96%93)。このの章の原文ではInterpolateという単語が複数回登場しますが、厳密な使い方ではない箇所もあるため以下では「補完」という訳語はあてませんでした。興味がある方はコンピュータグラフィックスやアニメーションの世界で補完関数 *Interpolator* がどのように使われているか調べてみましょう。)
<div class="codeAndCanvas" data="expo.frag"></div>
面白いでしょう? 19行目の指数```5.0```)を他の数に変えてみましょう。例えば値を```20.0```, ```2.0```, ```1.0```, ```0.0```, ```0.2```, ```0.02```に変えてみます。この値と指数の関係を理解しておくととても役立ちます。この例のように数学的な関数を様々な場面で用いると、コードを表現豊かに操ることができます。鍼で気の流れを操るようにデータの流れを操るのです。
面白いでしょう? 19行目の指数```5.0```)を他の数に変えてみましょう。例えば値を ```20.0```, ```2.0```, ```1.0```, ```0.0```, ```0.2```, ```0.02``` に変えてみます。この値と指数の関係を理解しておくととても役立ちます。この例のように数学的な関数を様々な場面で用いると、コードを表現豊かに操ることができます。鍼で気の流れを操るようにデータの流れを操るのです。
GLSLには多くのネイティブ関数が用意されており、[```pow()```](../glossary/?search=pow)はその中の1つです。ほとんどのネイティブ関数はハードウェアのレベルで高速に処理されるので、適切に使えばより速いコードを書くことができます。
GLSLには多くのネイティブ関数が用意されており、[```pow()```](../glossary/?search=pow) はその中の1つです。ほとんどのネイティブ関数はハードウェアのレベルで高速に処理されるので、適切に使えばより速いコードを書くことができます。
19行目の指数関数を[```exp(st.x) - 1.0```](../glossary/?search=exp), [```log(st.x - 1.0)```](../glossary/?search=log), [```sqrt(st.x)```](../glossary/?search=sqrt)など他の関数で置き換えてみましょう。
19行目の指数関数を [```exp(st.x) - 1.0```](../glossary/?search=exp), [```log(st.x - 1.0)```](../glossary/?search=log), [```sqrt(st.x)```](../glossary/?search=sqrt) など他の関数で置き換えてみましょう。
### StepとSmoothstep
GLSLには他にも、値を変化させるのに使うことができるネイティブ関数があります。これらもまたハードウェアで高速に処理されます。
[```step()```](../glossary/?search=step) 関数は2つのパラメーターを受け取ります。1つめは境界または閾値で、2つめはこの関数によってチェックされる値です。境界より小さい値には全て```0.0```を返し、境界以上の値には```1.0```を返します。
[```step()```](../glossary/?search=step) 関数は2つのパラメーターを受け取ります。1つめは境界または閾値で、2つめはこの関数によってチェックされる値です。境界より小さい値には全て ```0.0``` を返し、境界以上の値には ```1.0``` を返します。
下記のコードの20行目の閾値を変えて試してみてください。
@ -43,14 +43,14 @@ GLSLには他にも、値を変化させるのに使うことができるネイ
<div class="codeAndCanvas" data="smoothstep.frag"></div>
上記の例の12行目では、[```smoothstep()```](../glossary/?search=smoothstep)が```plot()```関数の中で緑色の線を描画するために使われていますね。この関数をx軸に沿って見ていくと、それぞれの点で特定のyの値に対して急激に高い値を返しています。どうなっているのでしょう。```plot```関数は2つの [```smoothstep()```](../glossary/?search=smoothstep)を組み合わせてこれを実現しています。下記の関数を見てください。上の20行目をこの関数で置き換えて、結果を```plot```関数のグラフを垂直に切った断面だと考えてみましょう。背景が線のように見えるでしょう?
上記の例の12行目では、[```smoothstep()```](../glossary/?search=smoothstep) ```plot()``` 関数の中で緑色の線を描画するために使われていますね。この関数をx軸に沿って見ていくと、それぞれの点で特定のyの値に対して急激に高い値を返しています。どうなっているのでしょう。```plot``` 関数は2つの [```smoothstep()```](../glossary/?search=smoothstep) を組み合わせてこれを実現しています。下記の関数を見てください。上の20行目をこの関数で置き換えて、結果を ```plot``` 関数のグラフを垂直に切った断面だと考えてみましょう。背景が線のように見えるでしょう?
```glsl
float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);
```
訳注おまけ。plot関数を理解するには引き算の片側を消して```smoothstep(0.2,0.5,st.x)```もしくは```smoothstep(0.5,0.8,st.x)```だけにしてみるのも良いと思います。2つのグラフの位置が少しずれていて、引き算をすると真ん中だけが残されるのが分かりますね。20行目の```smoothstep( pct-0.02, pct, st.y) -
smoothstep( pct, pct+0.02, st.y)```でも同じことを試してみましょう。)
(訳注:おまけ。```plot``` 関数を理解するには引き算の片側を消して ```smoothstep(0.2,0.5,st.x)``` もしくは ```smoothstep(0.5,0.8,st.x)``` だけにしてみるのも良いと思います。2つのグラフの位置が少しずれていて、引き算をすると真ん中だけが残されるのが分かりますね。20行目の ```smoothstep( pct-0.02, pct, st.y) -
smoothstep( pct, pct+0.02, st.y)``` でも同じことを試してみましょう。)
### サインとコサイン
@ -69,21 +69,21 @@ GLSLには他にも、値を変化させるのに使うことができるネイ
下記を試して何が起きるか見てみましょう。
* ```sin```を計算する前に時間の値(```u_time```)をxに足してみましょう。x座標に沿った動きを身につけましょう。
* ```sin``` を計算する前に時間の値(```u_time```をxに足してみましょう。x座標に沿った動きを身につけましょう。
* ```sin```を計算する前に、xに```PI```を掛けてみましょう。波の幅が縮まり、xが2進むごとにyが1サイクル上下するのを確認しましょう。
* ```sin``` を計算する前に、xに ```PI``` を掛けてみましょう。波の幅が縮まり、xが 2 進むごとにyが1サイクル上下するのを確認しましょう。
* ```sin```を計算する前に時間の値(```u_time```)をxに掛けてみましょう。周波数が次第に増えて波の幅が狭くなっていく様子を見てください。u_timeが既に大きくなりすぎていてグラフが読めないほどになってしまっているかもしれないので注意してください。訳注もしグラフが線ではなく黒い靄のようなイズになってしまう場合は、一度ページをリロードしてからもう一度試してください。u_timeはページを読み込んでからの累積時間なので、ここまで読み進める間にかなり大きな値になっている可能性があります
* ```sin```を計算する前に時間の値```u_time```をxに掛けてみましょう。周波数が次第に増えて波の幅が狭くなっていく様子を見てください。u_timeが既に大きくなりすぎていてグラフが読めないほどになってしまっているかもしれないので注意してください。訳注もしグラフが線ではなく黒い靄のようなイズになってしまう場合は、一度ページをリロードしてからもう一度試してください。u_timeはページを読み込んでからの累積時間なので、ここまで読み進める間にかなり大きな値になっている可能性があります
* ```sin(x)```に1.0を足してみましょう。値が0.0から2.0の間に収まるように波の位置が上にずれる様子を見てください。
* ```sin(x)``` 1.0 を足してみましょう。値が 0.0 から 2.0 の間に収まるように波の位置が上にずれる様子を見てください。
* ```sin(x)```に2.0を掛けてみましょう。振幅が倍になります。
* ```sin(x)``` 2.0 を掛けてみましょう。振幅が倍になります。
* ```sin(x)```の絶対値([```abs()```](../glossary/?search=abs))を計算してください。弾むボールの軌跡のように見えるでしょう。
* ```sin(x)``` の絶対値([```abs()```](../glossary/?search=abs))を計算してください。弾むボールの軌跡のように見えるでしょう。
* ```sin(x)```の値から少数部分だけを取り出してみましょう([```fract()```](../glossary/?search=fract))。
* ```sin(x)``` の値から少数部分だけを取り出してみましょう([```fract()```](../glossary/?search=fract))。
* [```sin(x)```](../glossary/?search=sin)の値を超える最小の整数([```ceil()```](../glossary/?search=ceil))と、それより小さい最大の整数([```floor()```](../glossary/?search=floor)を足して、1と-1だけからなるデジタル波を作ってみましょう。
* [```sin(x)```](../glossary/?search=sin) の値を超える最小の整数([```ceil()```](../glossary/?search=ceil))と、それより小さい最大の整数([```floor()```](../glossary/?search=floor)を足して、1 -1 だけからなるデジタル波を作ってみましょう。
### 便利な関数あれこれ
@ -115,7 +115,7 @@ GLSLには他にも、値を変化させるのに使うことができるネイ
スパイスや珍しい食材を集めるシェフのように、デジタルアーティストやクリエィティブコーダーは自らシェイピング関数に取り組むのが大好きです。
[Iñigo Quiles](http://www.iquilezles.org/)は便利な関数の[素晴らしいコレクション](http://www.iquilezles.org/www/articles/functions/functions.htm)を持っています。 [この記事](http://www.iquilezles.org/www/articles/functions/functions.htm)をまず読んでから、下記にあるGLSLへ翻訳を見てみましょう。浮動小数点の数値に「.小数点」を追加したり、Cの関数をGLSL特有の関数名で置き換える、例えば```powf()```の代わりに```pow()```を使うなどの細かな変更点に注意してください。
[Iñigo Quiles](http://www.iquilezles.org/)は便利な関数の[素晴らしいコレクション](http://www.iquilezles.org/www/articles/functions/functions.htm)を持っています。 [この記事](http://www.iquilezles.org/www/articles/functions/functions.htm)をまず読んでから、下記にあるGLSLへ翻訳したバージョンを見てみましょう。浮動小数点の数値に「.小数点」を追加したり、Cの関数をGLSL特有の関数名で置き換える、例えば ```powf()``` の代わりに ```pow()``` を使うなどの細かな変更点に注意してください。
* [Impulse](../edit.html#05/impulse.frag)
* [Cubic Pulse](../edit.html#05/cubicpulse.frag)
@ -131,7 +131,7 @@ GLSLには他にも、値を変化させるのに使うことができるネイ
#### 演習
[Kynd](http://www.kynd.info/log/)が作った[数式の表](www.flickr.com/photos/kynd/9546075099/)を見てください。数値と関数をどのように組み合わせて、0.0から1.0の間で値をコントロールしているかを読み取りましょう。実際に関数を置き換えて練習してください。鍛える程にあなたのカラテは強くなります。
[Kynd](http://www.kynd.info/log/)が作った[数式の表](www.flickr.com/photos/kynd/9546075099/)を見てください。数値と関数をどのように組み合わせて、0.0 から 1.0 の間で値をコントロールしているかを読み取りましょう。実際に関数を置き換えて練習してください。鍛える程にあなたのカラテは強くなります。
![Kynd - www.flickr.com/photos/kynd/9546075099/ (2013)](kynd.png)

@ -13,7 +13,7 @@ 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]``` といったインデックスを使ってアクセスすることもできます。
色をx, y, zで表して定義するのは分かりにくいし誤解を招きそうですね。そのため、ベクトル型の変数では同じ情報に違う名前を使ってアクセスできるようになっています。```.x``` ```.y``` ```.z``` の代わりに ```.r``` ```.g``` ```.b``` もしくは ```.s``` ```.t``` ```.p``` を使うことができるのです(```.s``` ```.t``` ```.p``` は通常、テクスチャ空間の座標を示すのに使われます。これについては後の章で学びます)。ベクトル型のデータにはまた、 ```[0]``` ```[1]``` ```[2]``` といったインデックスを使ってアクセスすることもできます。
下記のコードでは同じデータにアクセスするための全て方法を示しています。
@ -72,7 +72,7 @@ Robert Pennerは[イージング関数](http://easings.net/)と呼ばれる、
### グラデーションで遊ぶ
[```mix()```](../glossary/?search=mix)関数には幅広い使い道があります。3つ目の引数として単に ```float``` で割合を指定する代わりに、最初の2つの引数に対応する型の値を渡すことができます。上記のサンプルでは ```vec3``` を使いました。こうすることで ```r```, ```g```, ```b``` のそれぞれのチャンネルを個別のパーセンテージで混ぜ合わせることができます。
[```mix()```](../glossary/?search=mix) 関数には幅広い使い道があります。3つ目の引数として単に ```float``` で割合を指定する代わりに、最初の2つの引数に対応する型の値を渡すことができます。上記のサンプルでは ```vec3``` を使いました。こうすることで ```r```, ```g```, ```b``` のそれぞれのチャンネルを個別のパーセンテージで混ぜ合わせることができます。
![](mix-vec.jpg)
@ -106,7 +106,7 @@ x軸を色相、y軸を明度に割り当てると色のスペクトルを作る
### HSBと極座標
HSBはもともとデカルト座標xとyではなく、極座標中心からの角度と距離で色を示す仕組みです。私たちのHSB関数を極座標に対応させるには、ピクセル座標を元に、描画領域の中心からの角度と距離を求めなくてはなりません。そのためには [```length()```](../glossary/?search=length)関数と [```atan(y,x)```](../glossary/?search=atan)関数を使います。 ```atan(y,x)``` は一般的な言語で使われている ```atan2(y,x)``` のGLSL版です。
HSBはもともとデカルト座標xとyではなく、極座標中心からの角度と距離で色を示す仕組みです。私たちのHSB関数を極座標に対応させるには、ピクセル座標を元に、描画領域の中心からの角度と距離を求めなくてはなりません。そのためには [```length()```](../glossary/?search=length) 関数と [```atan(y,x)```](../glossary/?search=atan) 関数を使います。 ```atan(y,x)``` は一般的な言語で使われている ```atan2(y,x)``` のGLSL版です。
ベクトルや三角関数を扱う際には ```vec2```, ```vec3``` や ```vec4``` を、それらが色を表している場合でもベクトルと見なします。私たちは色とベクトルを同等に扱います。そして、このフレキシブルな考え方が様々なことを実現する支えになるのを目の当たりにするでしょう。
@ -145,7 +145,7 @@ HSBはもともとデカルト座標xとyではなく、極座標中心
![William Home Lizars - Red, blue and yellow spectra, with the solar spectrum (1834)](spectrums.jpg)
* 下の画像を見てください。カラーピッカーで使われている色の輪をよく見ると、サンプルコードとは違う[RYB色空間](https://en.wikipedia.org/wiki/RYB_color_model)に基づく色のスペクトルが使われていることに気づくでしょう(訳注:もちろんこれはアプリケーション次第です。必ずこうなっているとは限りません)。例えば赤の反対は緑のはずですが、サンプルコードではシアンになっています。これを修正して下の画像とまったく同じに見えるようにする方法を考えられるでしょうか(ヒント:シェイピング関数を使うチャンスです)。
* 下の画像を見てください。カラーピッカーで使われている色の輪をよく見ると、サンプルコードとは違う[RYB色空間](https://en.wikipedia.org/wiki/RYB_color_model)に基づく色のスペクトルが使われていることに気づくでしょう(訳注:これはアプリケーション次第です。必ずこうなっているとは限りません)。例えば赤の反対は緑のはずですが、サンプルコードではシアンになっています。これを修正して下の画像とまったく同じに見えるようにする方法を考えられるでしょうか(ヒント:シェイピング関数を使うチャンスです)。
![](colorwheel.png)

Loading…
Cancel
Save