LearnOpenGL

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 65cbfd5fe0c4d3cf16225077bd474602dc3b6ee7
parent 5b9cf9db80606bcff4153aa79eb12dd6b6ca624a
Author: Kenji Matsuda <ftvda283@gmail.com>
Date:   Mon,  4 Oct 2021 19:46:07 +0900

update coordinate-systems.html

Diffstat:
Areferences/150623_note09.pdf | 0
Areferences/CV09.pdf | 0
Mstyle_guide | 6+++++-
Mtranslation/Getting-started/Coordinate-Systems.html | 29++++++++++++++++++++++++++++-
4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/references/150623_note09.pdf b/references/150623_note09.pdf Binary files differ. diff --git a/references/CV09.pdf b/references/CV09.pdf Binary files differ. diff --git a/style_guide b/style_guide @@ -2,7 +2,8 @@ 2 句読点 、。 3 漢字 漢字使いたい 4 動詞の送り仮名 本則(JTF参照) 全部送る -5 カタカナ後の語尾長音は3音ルール +5 カタカナ後の語尾長音は3音ルール 以下例外 + Blender ブレンダー 6 長いカタカナ複合語は半角スペースで区切る 7 漢字、ひらがなカタカナは全角 8 数字、アルファベットは半角 @@ -10,3 +11,6 @@ 10 半角文字と全角文字の間に半角スペースは入れない 11 ピリオド、カンマ、スペースは半角 12 単位 kg, m, + +単語の翻訳はできるだけカタカナを使いたくない。 +原文の用語を括弧付きで載せる。 diff --git a/translation/Getting-started/Coordinate-Systems.html b/translation/Getting-started/Coordinate-Systems.html @@ -111,55 +111,68 @@ <h2>視野空間</h2> <p> The view space is what people usually refer to as the <def>camera</def> of OpenGL (it is sometimes also known as <def>camera space</def> or <def>eye space</def>). The view space is the result of transforming your world-space coordinates to coordinates that are in front of the user's view. The view space is thus the space as seen from the camera's point of view. This is usually accomplished with a combination of translations and rotations to translate/rotate the scene so that certain items are transformed to the front of the camera. These combined transformations are generally stored inside a <def>view matrix</def> that transforms world coordinates to view space. In the next chapter we'll extensively discuss how to create such a view matrix to simulate a camera. - 視野空間はOpenGLの<def>カメラ</def>とも言われます。また、<def>カメラ空間</def>や、<def>eye space</def>とも呼ばれるものです。視野空間は大域空間の座標を変換してユーザーの目から見た座標にしたものです。 + 視野空間はOpenGLの<def>カメラ</def>とも言われます。また、<def>カメラ空間</def>や、<def>eye space</def>とも呼ばれるものです。視野空間は大域空間の座標を変換してユーザーの目から見た座標にしたものです。つまり視野空間というのはカメラから見た空間です。この変換は通常平行移動と回転の組み合わせにより行われます。このような変換の組み合わせは一般的に<def>視野行列</def>に保存されます。この行列は大域座標系を視野空間に変換するものです。次章ではこの視野行列の作り方、カメラの動かし方を詳しく議論します。 </p> <h2>Clip space</h2> +<h2>クリップ空間</h2> <p> At the end of each vertex shader run, OpenGL expects the coordinates to be within a specific range and any coordinate that falls outside this range is <def>clipped</def>. Coordinates that are clipped are discarded, so the remaining coordinates will end up as fragments visible on your screen. This is also where <def>clip space</def> gets its name from. + 各頂点シェーダーからの出力はある範囲に納まっていることが期待され、その範囲の外の座標は<def>切り落さ</def>れます。切り落された座標は捨てられ、のこった座標が最終的に画面上に表示されます。切り抜きは英語でクリップ(clip)というのでこれがこの空間の名前の由来です。 </p> <p> Because specifying all the visible coordinates to be within the range <code>-1.0</code> and <code>1.0</code> isn't really intuitive, we specify our own coordinate set to work in and convert those back to NDC as OpenGL expects them. + <code>-1.0</code>から<code>1.0</code>の範囲だけが表示されるというのはあまり直感的とは言えません。そのためもっと分かり易い座標系で作業した後、OpenGLが期待するNDCに変換するのです。 </p> <p> To transform vertex coordinates from view to clip-space we define a so called <def>projection matrix</def> that specifies a range of coordinates e.g. <code>-1000</code> and <code>1000</code> in each dimension. The projection matrix then transforms coordinates within this specified range to normalized device coordinates (<code>-1.0</code>, <code>1.0</code>). All coordinates outside this range will not be mapped between <code>-1.0</code> and <code>1.0</code> and therefore be clipped. With this range we specified in the projection matrix, a coordinate of (<code>1250</code>, <code>500</code>, <code>750</code>) would not be visible, since the <code>x</code> coordinate is out of range and thus gets converted to a coordinate higher than <code>1.0</code> in NDC and is therefore clipped. + 頂点座標を視野空間からクリップ空間に変換する為に、<def>射影行列</def>という行列を定義します。この行列は特定の範囲、例えば<code>-1000</code>から<code>1000</code>にある座標を正規化デバイス座標(<code>-1.0</code>から<code>1.0</code>)に変換します。この範囲外の座標は<code>-1.0</code>から<code>1.0</code>の中には入らず、切り落されます。射影行列でこのような範囲を指定した場合、<code>(1250, 500, 750)</code>というような座標は、<code>x</code>座標が範囲外にあり、NDCにおいて<code>1.0</code>より大きい値になるので、切り落され、表示されません。 </p> <note> Note that if only a part of a primitive e.g. a triangle is outside the <def>clipping volume</def> OpenGL will reconstruct the triangle as one or more triangles to fit inside the clipping range. + プリミティブの一部、例えば三角形の一部が<def>クリッピングボリューム</def>の外にある場合、OpenGLは三角形を増やしてNDCに納まるように変更します。 </note> <p> This <em>viewing box</em> a projection matrix creates is called a <def>frustum</def> and each coordinate that ends up inside this frustum will end up on the user's screen. The total process to convert coordinates within a specified range to NDC that can easily be mapped to 2D view-space coordinates is called <def>projection</def> since the projection matrix <def>projects</def> 3D coordinates to the easy-to-map-to-2D normalized device coordinates. + 射影行列が生成するこの<em>可視領域</em>は<def>視錐台</def>と呼ばれます。この視錐台の中にある座標が最終的に画面に表示されます。ある範囲の座標をNDCに落とし込み、2次元の視野空間に変換しやすくする一連の処理は<def>投影</def>と呼ばれます。射影行列により3次元の座標を2次元に変換し易い正規化デバイス座標に<def>投影</def>する処理だからです。 </p> <p> Once all the vertices are transformed to clip space a final operation called <def>perspective division</def> is performed where we divide the <code>x</code>, <code>y</code> and <code>z</code> components of the position vectors by the vector's homogeneous <code>w</code> component; perspective division is what transforms the 4D clip space coordinates to 3D normalized device coordinates. This step is performed automatically at the end of the vertex shader step. + 全ての頂点がクリップ空間に変換された後、<def>透視除算</def>という操作が最後に行われます。これは位置ベクトルの<code>x</code>、<code>y</code>、<code>z</code>座標を同次座標<code>w</code>で割り算する操作です。4次元のクリップ空間の座標を3次元のNDCに変換するものであるとも言えます。透視除算は頂点シェーダーの処理の最後に自動的に行われます。 </p> <p> It is after this stage where the resulting coordinates are mapped to screen coordinates (using the settings of <fun><function id='22'>glViewport</function></fun>) and turned into fragments. + この後、出力された座標が<fun><function id='22'>glViewport</function></fun>の設定を利用して画面の座標に射影されフラグメントに加工されます。 </p> <p> The projection matrix to transform view coordinates to clip coordinates usually takes two different forms, where each form defines its own unique frustum. We can either create an <def>orthographic</def> projection matrix or a <def>perspective</def> projection matrix. + 視野座標をクリップ座標に変換する射影行列には通常2つの種類があり、それぞれ特有の視錐台を作成します。それらは<def>平行投影</def>行列、<def>透視投影</def>行列と呼ばれるものです。 </p> <h3>Orthographic projection</h3> +<h3>平行投影</h3> <p> An orthographic projection matrix defines a cube-like frustum box that defines the clipping space where each vertex outside this box is clipped. When creating an orthographic projection matrix we specify the width, height and length of the visible frustum. All the coordinates inside this frustum will end up within the NDC range after transformed by its matrix and thus won't be clipped. The frustum looks a bit like a container: + 平行投影行列は直方体の視錐台を作り、その外側を切り落します。平行投影行列の作成には視錐台の幅、高さ、長さを指定する必要があります。この視錐台の中の座標はこの行列による変換でNDCの範囲に納まり、切り落されません。この視錐台は箱のようなものです: </p> <img src="/img/getting-started/orthographic_frustum.png" class="clean"/> <p> The frustum defines the visible coordinates and is specified by a width, a height and a <def>near</def> and <def>far</def> plane. Any coordinate in front of the near plane is clipped and the same applies to coordinates behind the far plane. The orthographic frustum <strong>directly</strong> maps all coordinates inside the frustum to normalized device coordinates without any special side effects since it won't touch the <code>w</code> component of the transformed vector; if the <code>w</code> component remains equal to <code>1.0</code> perspective division won't change the coordinates. + 視錐台は可視領域を既定し、幅、高さ、そして<def>前端面(near plane)</def>と<def>後端面(far plane)</def>により決まります。前端面より手前のものや、後端面より後ろのものは切り落されます。平行投影による視錐台は<strong>直接</strong>NDCに射影され、変換されるベクトルの<code>w</code>座標には触れないのでほかの特別な効果はありません。もし<code>w</code>座標が<code>1.0</code>のままであれば透視除算によりなんの変化も起きないのです。 </p> <p> To create an orthographic projection matrix we make use of GLM's built-in function <code><function id='59'>glm::ortho</function></code>: + 平行投影行列を作成するにはGLMの組込み関数<code><function id='59'>glm::ortho</function></code>を利用します: </p> <pre><code> @@ -168,29 +181,36 @@ <p> The first two parameters specify the left and right coordinate of the frustum and the third and fourth parameter specify the bottom and top part of the frustum. With those 4 points we've defined the size of the near and far planes and the 5th and 6th parameter then define the distances between the near and far plane. This specific projection matrix transforms all coordinates between these <code>x</code>, <code>y</code> and <code>z</code> range values to normalized device coordinates. + 最初の2つの引数は視錐台の左端と右端の座標で、3つ目と4つ目は下端と上端の座標です。この4つの引数で前端面の大きさが決まり、5つ目と6つ目の引数で前端面と後端面の距離を決定します。この投影行列はここで指定した範囲にある<code>x</code>、<code>y</code>、<code>z</code>座標をNDCに変換します。 </p> <p> An orthographic projection matrix directly maps coordinates to the 2D plane that is your screen, but in reality a direct projection produces unrealistic results since the projection doesn't take <def>perspective</def> into account. That is something the <def>perspective projection</def> matrix fixes for us. + 平行投影行列は座標を直接2次元の画面に射影しますが、これはあまり現実的な映像にはなりません。<def>遠近法(perspective)</def>を考慮していない為です。この問題を解決するには<def>透視投影行列</def>を用います。 </p> <h3>Perspective projection</h3> +<h3>透視投影</h3> <p> If you ever were to enjoy the graphics the <em>real life</em> has to offer you'll notice that objects that are farther away appear much smaller. This weird effect is something we call <def>perspective</def>. Perspective is especially noticeable when looking down the end of an infinite motorway or railway as seen in the following image: + <em>現実世界</em>が提供するグラフィックスを楽しんだことがあれば、遠くの物体は小さく見えることに気が付くでしょう。この奇妙な現象は<def>遠近法</def>によるものです。遠近法は下図のような、無限に続く道路や線路を見た時に特に目立ちます: </p> <img src="/img/getting-started/perspective.png" class="clean"/> <p> As you can see, due to perspective the lines seem to coincide at a far enough distance. This is exactly the effect perspective projection tries to mimic and it does so using a <def>perspective projection matrix</def>. The projection matrix maps a given frustum range to clip space, but also manipulates the <code>w</code> value of each vertex coordinate in such a way that the further away a vertex coordinate is from the viewer, the higher this <code>w</code> component becomes. Once the coordinates are transformed to clip space they are in the range <code>-w</code> to <code>w</code> (anything outside this range is clipped). OpenGL requires that the visible coordinates fall between the range <code>-1.0</code> and <code>1.0</code> as the final vertex shader output, thus once the coordinates are in clip space, perspective division is applied to the clip space coordinates: + 見ての通り、遠近法によって2つの線が無限のかなたで交差しているように見えます。これこそが<def>透視投影行列</def>を用いて透視投影が再現しようとしている現象です。この投影行列は視錐台をクリップ空間に変換しますが、それだけでなく各頂点の<code>w</code>の値も変更します。カメラから遠い頂点座標ほど、この<code>w</code>の値が大きくなるようにするのです。クリップ空間に変換されたらその座標は<code>-w</code>と<code>w</code>の間に落ち着きます(この外のものは切り落されます)。OpenGLにおいて表示されるべき座標は頂点シェーダーからの出力の段階で、<code>-1.0</code>と<code>1.0</code>の間になければいけないので、クリップ空間の中にある座標に対して透視除算が適応されます: \[ out = \begin{pmatrix} x /w \\ y / w \\ z / w \end{pmatrix} \] Each component of the vertex coordinate is divided by its <code>w</code> component giving smaller vertex coordinates the further away a vertex is from the viewer. This is another reason why the <code>w</code> component is important, since it helps us with perspective projection. The resulting coordinates are then in normalized device space. If you're interested to figure out how the orthographic and perspective projection matrices are actually calculated (and aren't too scared of the mathematics) I can recommend <a href="http://www.songho.ca/opengl/gl_projectionmatrix.html" target="_blank">this excellent article</a> by Songho. + 頂点座標の各要素は<code>w</code>要素の値で割り算されるので、遠くの頂点ほど小さい座標になります。このように、<code>w</code>要素は透視投影において重要な役割を果たします。以上の変換の結果出力される座標はNDSに納まります。もし平行投影行列や透視投影行列の導出に興味があるのであれば(そして数学を恐れないのであれば)Songhoによる<a href="http://www.songho.ca/opengl/gl_projectionmatrix.html" target="_blank">このすばらしい記事</a>をお薦めします。 </p> <p> A perspective projection matrix can be created in GLM as follows: + 透視投影行列はGLMにおいて以下のように作成できます: </p> <pre><code> @@ -199,6 +219,7 @@ glm::mat4 proj = <function id='58'>glm::perspective</function>(<function id='63' <p> What <code><function id='58'>glm::perspective</function></code> does is again create a large <em>frustum</em> that defines the visible space, anything outside the frustum will not end up in the clip space volume and will thus become clipped. A perspective frustum can be visualized as a non-uniformly shaped box from where each coordinate inside this box will be mapped to a point in clip space. An image of a perspective frustum is seen below: + <code><function id='58'>glm::perspective</function></code>が行うのは、可視領域である大きな<em>視錐台</em>を作ることです。この視錐台の外のものはクリップ空間に入らず、切り落とされてしまいます。透視投影による視錐台は歪んだ箱のようになります。この箱の中身がクリップ空間に射影されます。透視投影の視錐台は以下の画像のようなものです: </p> <img src="/img/getting-started/perspective_frustum.png" class="clean"/> @@ -206,25 +227,31 @@ glm::mat4 proj = <function id='58'>glm::perspective</function>(<function id='63' <p> Its first parameter defines the <def>fov</def> value, that stands for <def>field of view</def> and sets how large the viewspace is. For a realistic view it is usually set to 45 degrees, but for more doom-style results you could set it to a higher value. The second parameter sets the aspect ratio which is calculated by dividing the viewport's width by its height. The third and fourth parameter set the <em>near</em> and <em>far</em> plane of the frustum. We usually set the near distance to <code>0.1</code> and the far distance to <code>100.0</code>. All the vertices between the near and far plane and inside the frustum will be rendered. +1つ目の引数で<def>視野角(fov)</def>を定義します。これは<def>field of view</def>の省略で、見える範囲の広さを規定します。現実に近い値として通常45度を指定しますが、doomというゲームのような雰囲気にしたい場合もっと大きな値にすることもできます。2つ目の変数ではアスペクト比を指定します。アスペクト比は表示領域の幅を高さで割った値です。3つ目と4つ目の引数は視錐台の<em>前端面</em>と<em>後端面</em>を規定します。通常前端面までの距離には<code>0.1</code>を、後端面までの距離には<code>100.0</code>を指定します。視錐台においてこの前端面と後端面の間にある全ての頂点が描画されます。 </p> <note> Whenever the <em>near</em> value of your perspective matrix is set too high (like <code>10.0</code>), OpenGL will clip all coordinates close to the camera (between <code>0.0</code> and <code>10.0</code>), which can give a visual result you maybe have seen before in videogames where you could see through certain objects when moving uncomfortably close to them. + 透視投影行列において<em>前端面</em>までの距離としてもっと大きな値(例えば<code>10.0</code>)を与えると、OpenGLはそれよりカメラに近い座標(<code>0.0</code>と<code>10.0</code>の間のもの)は切り捨てられます。ゲームで遊んでいる時、何かに異常に近付くとその物体の中が見えた経験があるかと思いますが、そのような結果になります。 </note> <p> When using orthographic projection, each of the vertex coordinates are directly mapped to clip space without any fancy perspective division (it still does perspective division, but the <code>w</code> component is not manipulated (it stays <code>1</code>) and thus has no effect). Because the orthographic projection doesn't use perspective projection, objects farther away do not seem smaller, which produces a weird visual output. For this reason the orthographic projection is mainly used for 2D renderings and for some architectural or engineering applications where we'd rather not have vertices distorted by perspective. Applications like <em>Blender</em> that are used for 3D modeling sometimes use orthographic projection for modeling, because it more accurately depicts each object's dimensions. Below you'll see a comparison of both projection methods in Blender: + 平行投影では各頂点は直接クリップ空間に射影され、透視除算による面白い効果は得られません(透視除算は行なわれていますが、<code>w</code>が<code>1.0</code>のままなので影響がないのです)。平行投影は遠近法を適応していないので、遠くの物も小さくならず、奇妙な視覚効果が得られます。その為、平行投影は主に2次元の描画や、建築あるいは設計といった、遠近法による歪みが無い方がいい用途のアプリケーションで利用されます。<em>ブレンダー</em>のような3次元のモデリングに利用されるアプリケーションでも平行投影は時として利用されます。物体の寸法が正確に表示される為です。下図はブレンダーにおける両方の投影方法の比較です: </p> <img src="/img/getting-started/perspective_orthographic.png" class="clean"/> <p> You can see that with perspective projection, the vertices farther away appear much smaller, while in orthographic projection each vertex has the same distance to the user. + ご覧の様に透視投影では遠くの頂点は小さくなり、平行投影では各頂点のユーザーからの距離は同じままです。 </p> <h2>Putting it all together</h2> +<h2>まとめ</h2> <p> We create a transformation matrix for each of the aforementioned steps: model, view and projection matrix. A vertex coordinate is then transformed to clip coordinates as follows: + 各段階に対する変換行列である、モデル変換行列、視野行列、投影行列を作成しました。これらを用いると、頂点の座標はクリップ座標に対して以下のように変換されます: \[ V_{clip} = M_{projection} \cdot M_{view} \cdot M_{model} \cdot V_{local} \]