Shaders.html (68722B)
1 <!DOCTYPE html> 2 <html lang="ja"> 3 <head> 4 <meta charset="utf-8"/> 5 <title>LearnOpenGL</title> 6 <link rel="shortcut icon" type="image/ico" href="/favicon.ico" /> 7 <link rel="stylesheet" href="../static/style.css" /> 8 <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"> </script> 9 <script src="/static/functions.js"></script> 10 </head> 11 <body> 12 <nav> 13 <ol> 14 <li id="Introduction"> 15 <a href="https://learnopengl.com/Introduction">はじめに</a> 16 </li> 17 <li id="Getting-started"> 18 <span class="closed">入門</span> 19 <ol> 20 <li id="Getting-started/OpenGL"> 21 <a href="https://learnopengl.com/Getting-started/OpenGL">OpenGL </a> 22 </li> 23 <li id="Getting-started/Creating-a-window"> 24 <a href="https://learnopengl.com/Getting-started/Creating-a-window">ウィンドウの作成</a> 25 </li> 26 <li id="Getting-started/Hello-Window"> 27 <a href="https://learnopengl.com/Getting-started/Hello-Window">最初のウィンドウ</a> 28 </li> 29 <li id="Getting-started/Hello-Triangle"> 30 <a href="https://learnopengl.com/Getting-started/Hello-Triangle">最初の三角形</a> 31 </li> 32 <li id="Getting-started/Shaders"> 33 <a href="https://learnopengl.com/Getting-started/Shaders">シェーダー</a> 34 </li> 35 <li id="Getting-started/Textures"> 36 <a href="https://learnopengl.com/Getting-started/Textures">テクスチャ</a> 37 </li> 38 <li id="Getting-started/Transformations"> 39 <a href="https://learnopengl.com/Getting-started/Transformations">座標変換</a> 40 </li> 41 <li id="Getting-started/Coordinate-Systems"> 42 <a href="https://learnopengl.com/Getting-started/Coordinate-Systems">座標系</a> 43 </li> 44 <li id="Getting-started/Camera"> 45 <a href="https://learnopengl.com/Getting-started/Camera">カメラ</a> 46 </li> 47 <li id="Getting-started/Review"> 48 <a href="https://learnopengl.com/Getting-started/Review">まとめ</a> 49 </li> 50 </ol> 51 </li> 52 <li id="Lighting"> 53 <span class="closed">Lighting </span> 54 <ol> 55 <li id="Lighting/Colors"> 56 <a href="https://learnopengl.com/Lighting/Colors">Colors </a> 57 </li> 58 <li id="Lighting/Basic-Lighting"> 59 <a href="https://learnopengl.com/Lighting/Basic-Lighting">Basic Lighting </a> 60 </li> 61 <li id="Lighting/Materials"> 62 <a href="https://learnopengl.com/Lighting/Materials">Materials </a> 63 </li> 64 <li id="Lighting/Lighting-maps"> 65 <a href="https://learnopengl.com/Lighting/Lighting-maps">Lighting maps </a> 66 </li> 67 <li id="Lighting/Light-casters"> 68 <a href="https://learnopengl.com/Lighting/Light-casters">Light casters </a> 69 </li> 70 <li id="Lighting/Multiple-lights"> 71 <a href="https://learnopengl.com/Lighting/Multiple-lights">Multiple lights </a> 72 </li> 73 <li id="Lighting/Review"> 74 <a href="https://learnopengl.com/Lighting/Review">Review </a> 75 </li> 76 </ol> 77 </li> 78 <li id="Model-Loading"> 79 <span class="closed">Model Loading </span> 80 <ol> 81 <li id="Model-Loading/Assimp"> 82 <a href="https://learnopengl.com/Model-Loading/Assimp">Assimp </a> 83 </li> 84 <li id="Model-Loading/Mesh"> 85 <a href="https://learnopengl.com/Model-Loading/Mesh">Mesh </a> 86 </li> 87 <li id="Model-Loading/Model"> 88 <a href="https://learnopengl.com/Model-Loading/Model">Model </a> 89 </li> 90 </ol> 91 </li> 92 <li id="Advanced-OpenGL"> 93 <span class="closed">Advanced OpenGL </span> 94 <ol> 95 <li id="Advanced-OpenGL/Depth-testing"> 96 <a href="https://learnopengl.com/Advanced-OpenGL/Depth-testing">Depth testing </a> 97 </li> 98 <li id="Advanced-OpenGL/Stencil-testing"> 99 <a href="https://learnopengl.com/Advanced-OpenGL/Stencil-testing">Stencil testing </a> 100 </li> 101 <li id="Advanced-OpenGL/Blending"> 102 <a href="https://learnopengl.com/Advanced-OpenGL/Blending">Blending </a> 103 </li> 104 <li id="Advanced-OpenGL/Face-culling"> 105 <a href="https://learnopengl.cm/Advanced-OpenGL/Face-culling">Face culling </a> 106 </li> 107 <li id="Advanced-OpenGL/Framebuffers"> 108 <a href="https://learnopengl.com/Advanced-OpenGL/Framebuffers">Framebuffers </a> 109 </li> 110 <li id="Advanced-OpenGL/Cubemaps"> 111 <a href="https://learnopengl.com/Advanced-OpenGL/Cubemaps">Cubemaps </a> 112 </li> 113 <li id="Advanced-OpenGL/Advanced-Data"> 114 <a href="https://learnopengl.com/Advanced-OpenGL/Advanced-Data">Advanced Data </a> 115 </li> 116 <li id="Advanced-OpenGL/Advanced-GLSL"> 117 <a href="https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL">Advanced GLSL </a> 118 </li> 119 <li id="Advanced-OpenGL/Geometry-Shader"> 120 <a href="https://learnopengl.com/Advanced-OpenGL/Geometry-Shader">Geometry Shader </a> 121 </li> 122 <li id="Advanced-OpenGL/Instancing"> 123 <a href="https://learnopengl.com/Advanced-OpenGL/Instancing">Instancing </a> 124 </li> 125 <li id="Advanced-OpenGL/Anti-Aliasing"> 126 <a href="https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing">Anti Aliasing </a> 127 </li> 128 </ol> 129 </li> 130 <li id="Advanced-Lighting"> 131 <span class="closed">Advanced Lighting </span> 132 <ol> 133 <li id="Advanced-Lighting/Advanced-Lighting"> 134 <a href="https://learnopengl.com/Advanced-Lighting/Advanced-Lighting">Advanced Lighting </a> 135 </li> 136 <li id="Advanced-Lighting/Gamma-Correction"> 137 <a href="https://learnopengl.com/Advanced-Lighting/Gamma-Correction">Gamma Correction </a> 138 </li> 139 <li id="Advanced-Lighting/Shadows"> 140 <span class="closed">Shadows </span> 141 <ol> 142 <li id="Advanced-Lighting/Shadows/Shadow-Mapping"> 143 <a href="https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping">Shadow Mapping </a> 144 </li> 145 <li id="Advanced-Lighting/Shadows/Point-Shadows"> 146 <a href="https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows">Point Shadows </a> 147 </li> 148 </ol> 149 </li> 150 <li id="Advanced-Lighting/Normal-Mapping"> 151 <a href="https://learnopengl.com/Advanced-Lighting/Normal-Mapping">Normal Mapping </a> 152 </li> 153 <li id="Advanced-Lighting/Parallax-Mapping"> 154 <a href="https://learnopengl.com/Advanced-Lighting/Parallax-Mapping">Parallax Mapping </a> 155 </li> 156 <li id="Advanced-Lighting/HDR"> 157 <a href="https://learnopengl.com/Advanced-Lighting/HDR">HDR </a> 158 </li> 159 <li id="Advanced-Lighting/Bloom"> 160 <a href="https://learnopengl.com/Advanced-Lighting/Bloom">Bloom </a> 161 </li> 162 <li id="Advanced-Lighting/Deferred-Shading"> 163 <a href="https://learnopengl.com/Advanced-Lighting/Deferred-Shading">Deferred Shading </a> 164 </li> 165 <li id="Advanced-Lighting/SSAO"> 166 <a href="https://learnopengl.com/Advanced-Lighting/SSAO">SSAO </a> 167 </li> 168 </ol> 169 </li> 170 <li id="PBR"> 171 <span class="closed">PBR </span> 172 <ol> 173 <li id="PBR/Theory"> 174 <a href="https://learnopengl.com/PBR/Theory">Theory </a> 175 </li> 176 <li id="PBR/Lighting"> 177 <a href="https://learnopengl.com/PBR/Lighting">Lighting </a> 178 </li> 179 <li id="PBR/IBL"> 180 <span class="closed">IBL </span> 181 <ol> 182 <li id="PBR/IBL/Diffuse-irradiance"> 183 <a href="https://learnopengl.com/PBR/IBL/Diffuse-irradiance">Diffuse irradiance </a> 184 </li> 185 <li id="PBR/IBL/Specular-IBL"> 186 <a href="https://learnopengl.com/PBR/IBL/Specular-IBL">Specular IBL </a> 187 </li> 188 </ol> 189 </li> 190 </ol> 191 </li> 192 <li id="In-Practice"> 193 <span class="closed">In Practice </span> 194 <ol> 195 <li id="In-Practice/Debugging"> 196 <a href="https://learnopengl.com/In-Practice/Debugging">Debugging </a> 197 </li> 198 <li id="In-Practice/Text-Rendering"> 199 <a href="https://learnopengl.com/In-Practice/Text-Rendering">Text Rendering </a> 200 </li> 201 <li id="In-Practice/2D-Game"> 202 <span class="closed">2D Game </span> 203 <ol> 204 <li id="In-Practice/2D-Game/Breakout"> 205 <a href="https://learnopengl.com/In-Practice/2D-Game/Breakout">Breakout </a> 206 </li> 207 <li id="In-Practice/2D-Game/Setting-up"> 208 <a href="https://learnopengl.com/In-Practice/2D-Game/Setting-up">Setting up </a> 209 </li> 210 <li id="In-Practice/2D-Game/Rendering-Sprites"> 211 <a href="https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites">Rendering Sprites </a> 212 </li> 213 <li id="In-Practice/2D-Game/Levels"> 214 <a href="https://learnopengl.com/In-Practice/2D-Game/Levels">Levels </a> 215 </li> 216 <li id="In-Practice/2D-Game/Collisions"> 217 <span class="closed">Collisions </span> 218 <ol> 219 <li id="In-Practice/2D-Game/Collisions/Ball"> 220 <a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Ball">Ball </a> 221 </li> 222 <li id="In-Practice/2D-Game/Collisions/Collision-detection"> 223 <a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-detection">Collision detection </a> 224 </li> 225 <li id="In-Practice/2D-Game/Collisions/Collision-resolution"> 226 <a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-resolution">Collision resolution </a> 227 </li> 228 </ol> 229 </li> 230 <li id="In-Practice/2D-Game/Particles"> 231 <a href="https://learnopengl.com/In-Practice/2D-Game/Particles">Particles </a> 232 </li> 233 <li id="In-Practice/2D-Game/Postprocessing"> 234 <a href="https://learnopengl.com/In-Practice/2D-Game/Postprocessing">Postprocessing </a> 235 </li> 236 <li id="In-Practice/2D-Game/Powerups"> 237 <a href="https://learnopengl.com/In-Practice/2D-Game/Powerups">Powerups </a> 238 </li> 239 <li id="In-Practice/2D-Game/Audio"> 240 <a href="https://learnopengl.com/In-Practice/2D-Game/Audio">Audio </a> 241 </li> 242 <li id="In-Practice/2D-Game/Render-text"> 243 <a href="https://learnopengl.com/In-Practice/2D-Game/Render-text">Render text </a> 244 </li> 245 <li id="In-Practice/2D-Game/Final-thoughts"> 246 <a href="https://learnopengl.com/In-Practice/2D-Game/Final-thoughts">Final thoughts </a> 247 </li> 248 </ol> 249 </li> 250 </ol> 251 </li> 252 <li id="Guest-Articles"> 253 <span class="closed">Guest Articles </span> 254 <ol> 255 <li id="Guest-Articles/How-to-publish"> 256 <a href="https://learnopengl.com/Guest-Articles/How-to-publish">How to publish </a> 257 </li> 258 <li id="Guest-Articles/2020"> 259 <span class="closed">2020 </span> 260 <ol> 261 <li id="Guest-Articles/2020/OIT"> 262 <span class="closed">OIT </span> 263 <ol> 264 <li id="Guest-Articles/2020/OIT/Introduction"> 265 <a href="https://learnopengl.com/Guest-Articles/2020/OIT/Introduction">Introduction </a> 266 </li> 267 <li id="Guest-Articles/2020/OIT/Weighted-Blended"> 268 <a href="https://learnopengl.com/Guest-Articles/2020/OIT/Weighted-Blended">Weighted Blended </a> 269 </li> 270 </ol> 271 </li> 272 <li id="Guest-Articles/2020/Skeletal-Animation"> 273 <a href="https://learnopengl.com/Guest-Articles/2020/Skeletal-Animation">Skeletal Animation </a> 274 </li> 275 </ol> 276 </li> 277 <li id="Guest-Articles/2021"> 278 <span class="closed">2021 </span> 279 <ol> 280 <li id="Guest-Articles/2021/CSM"> 281 <a href="https://learnopengl.com/Guest-Articles/2021/CSM">CSM </a> 282 </li> 283 <li id="Guest-Articles/2021/Scene"> 284 <span class="closed">Scene </span> 285 <ol> 286 <li id="Guest-Articles/2021/Scene/Scene-Graph"> 287 <a href="https://learnopengl.com/Guest-Articles/2021/Scene/Scene-Graph">Scene Graph </a> 288 </li> 289 <li id="Guest-Articles/2021/Scene/Frustum-Culling"> 290 <a href="https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling">Frustum Culling </a> 291 </li> 292 </ol> 293 </li> 294 <li id="Guest-Articles/2021/Tessellation"> 295 <span class="closed">Tessellation </span> 296 <ol> 297 <li id="Guest-Articles/2021/Tessellation/Height-map"> 298 <a href="https://learnopengl.com/Guest-Articles/2021/Tessellation/Height-map">Height map </a> 299 </li> 300 </ol> 301 </li> 302 </ol> 303 </li> 304 </ol> 305 </li> 306 <li id="Code-repository"> 307 <a href="https://learnopengl.com/Code-repository">Code repository </a> 308 </li> 309 <li id="Translations"> 310 <a href="https://learnopengl.com/Translations">Translations </a> 311 </li> 312 <li id="About"> 313 <a href="https://learnopengl.com/About">About </a> 314 </li> 315 </ol> 316 </nav> 317 <main> 318 <h1 id="content-title">Shaders</h1> 319 <h1 id="content-title">シェーダー</h1> 320 <h1 id="content-url" style='display:none;'>Getting-started/Shaders</h1> 321 <p> 322 As mentioned in the <a href="https://learnopengl.com/Getting-started/Hello-Triangle" target="_blank">Hello Triangle</a> chapter, shaders are little programs that rest on the GPU. These programs are run for each specific section of the graphics pipeline. In a basic sense, shaders are nothing more than programs transforming inputs to outputs. Shaders are also very isolated programs in that they're not allowed to communicate with each other; the only communication they have is via their inputs and outputs. 323 <a href="https://learnopengl.com/Getting-started/Hello-Triangle" target="_blank">はじめての三角形</a>の章で説明したように、シェーダーはGPUで実行する小さなプログラムです。このプログラムはグラフィックスパイプラインの特定の場所で実行されます。基本的にシェーダーというのは入力をなんらかの形で変換して出力するものです。シェーダーは入出力以外の手段で互いに通信できないので、非常に独立性の高いプログラムだといえます。 324 </p> 325 326 <p> 327 In the previous chapter we briefly touched the surface of shaders and how to properly use them. We will now explain shaders, and specifically the OpenGL Shading Language, in a more general fashion. 328 前章においてシェーダーの表面的な部分と適切な使い方について少し触れました。ここではシェーダーについて、特にOpenGLのシェーディング言語について、もう少し全般的に見ていきましょう。 329 </p> 330 331 <h1>GLSL</h1> 332 <p> 333 Shaders are written in the C-like language GLSL. GLSL is tailored for use with graphics and contains useful features specifically targeted at vector and matrix manipulation. 334 シェーダーはC言語に似たGLSLで記述されます。GLSLはグラフィックを扱うために作られ、便利な機能、特にベクトルと行列に関するものが含まれます。 335 </p> 336 337 <p> 338 Shaders always begin with a version declaration, followed by a list of input and output variables, uniforms and its <fun>main</fun> function. Each shader's entry point is at its <fun>main</fun> function where we process any input variables and output the results in its output variables. Don't worry if you don't know what uniforms are, we'll get to those shortly. 339 シェーダーはバージョンの宣言から始まり、入力変数と出力変数およびユニフォームの列挙、そして<fun>main</fum>関数が続きます。シェーダーは<fun>main</fun>関数から実行が開始され、その関数内で入力変数を処理しその結果を出力変数に格納して返します。ユニフォームについてはすぐ後で説明しますので、今は気にしないで下さい。 340 </p> 341 342 <p> 343 A shader typically has the following structure: 344 シェーダーは典型的には以下のような構造をしています: 345 </p> 346 347 <pre><code> 348 #version version_number 349 in type in_variable_name; 350 in type in_variable_name; 351 352 out type out_variable_name; 353 354 uniform type uniform_name; 355 356 void main() 357 { 358 // process input(s) and do some weird graphics stuff 359 // 入力の処理とグラフィックに関するいろいろ 360 ... 361 // output processed stuff to output variable 362 // 出力変数に処理したものを出力 363 out_variable_name = weird_stuff_we_processed; 364 } 365 </code></pre> 366 367 <p> 368 When we're talking specifically about the vertex shader each input variable is also known as a <def>vertex attribute</def>. There is a maximum number of vertex attributes we're allowed to declare limited by the hardware. OpenGL guarantees there are always at least 16 4-component vertex attributes available, but some hardware may allow for more which you can retrieve by querying <var>GL_MAX_VERTEX_ATTRIBS</var>: 369 頂点シェーダーにおいて、入力変数は<def>頂点属性</def>と呼ばれます。宣言できる頂点属性の最大数はハードウェアにより決定されます。OpenGLは最低でも、4要素からなる頂点属性を16個利用できることを保証していますが、ハードウェアによってはもっと利用できます。その最大数は<var>GL_MAX_VERTEX_ATTRIBS</var>から確認できます: 370 </p> 371 372 <pre><code> 373 int nrAttributes; 374 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes); 375 std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl; 376 </code></pre> 377 378 <p> 379 This often returns the minimum of <code>16</code> which should be more than enough for most purposes. 380 多くの場合この数字はOpenGLが定める最低である<code>16</code>になっていますが、ほとんどの場合それで十分です。 381 </p> 382 383 <h2>Types</h2> 384 <h2>型</h2> 385 <p> 386 GLSL has, like any other programming language, data types for specifying what kind of variable we want to work with. GLSL has most of the default basic types we know from languages like C: <code>int</code>, <code>float</code>, <code>double</code>, <code>uint</code> and <code>bool</code>. GLSL also features two container types that we'll be using a lot, namely <code>vectors</code> and <code>matrices</code>. We'll discuss matrices in a later chapter. 387 他のプログラミング言語と同様に、GLSLにも変数の型があります。C言語のようなプログラミング言語において、基本的な型といえば、<code>int</code>、<code>float</code>、<code>double</code>、<code>uint</code>そして<code>bool</code>といったものですが、GLSLはこのような基本的な型に加えて<code>ベクトル</code>と<code>行列</code>という容器のような型があります。この二つの型はこれから頻繁に利用するものです。行列については別の章で説明します。 388 </p> 389 390 <h3>Vectors</h3> 391 <h3>ベクトル</h3> 392 <p> 393 A vector in GLSL is a 1,2,3 or 4 component container for any of the basic types just mentioned. They can take the following form (<code>n</code> represents the number of components): 394 GLSLにおけるベクトルは上に記した基本的な型の数値を1から4個、要素として持つ容器です。これには以下のような形式があります(<code>n</code>は要素数です): 395 </p> 396 397 <ul> 398 <li><code>vecn</code>: the default vector of <code>n</code> floats.</li> 399 <li><code>bvecn</code>: a vector of <code>n</code> booleans.</li> 400 <li><code>ivecn</code>: a vector of <code>n</code> integers.</li> 401 <li><code>uvecn</code>: a vector of <code>n</code> unsigned integers.</li> 402 <li><code>dvecn</code>: a vector of <code>n</code> double components.</li> 403 </ul> 404 <ul> 405 <li><code>vecn</code>: <code>n</code>個の浮動小数点数からなるデフォルトのベクトル。</li> 406 <li><code>bvecn</code>: <code>n</code>個の真偽値からなるベクトル。</li> 407 <li><code>ivecn</code>: <code>n</code>個の整数からなるベクトル。</li> 408 <li><code>uvecn</code>: <code>n</code>個の符号なし整数からなるベクトル。</li> 409 <li><code>dvecn</code>: <code>n</code>個の倍精度浮動小数点数からなるベクトル。</li> 410 </ul> 411 412 <p> 413 Most of the time we will be using the basic <code>vecn</code> since floats are sufficient for most of our purposes. 414 本書においては浮動小数点数で十分間に合うので、主に<code>vecn</code>を利用します。 415 </p> 416 417 <p> 418 Components of a vector can be accessed via <code>vec.x</code> where <code>x</code> is the first component of the vector. You can use <code>.x</code>, <code>.y</code>, <code>.z</code> and <code>.w</code> to access their first, second, third and fourth component respectively. GLSL also allows you to use <code>rgba</code> for colors or <code>stpq</code> for texture coordinates, accessing the same components. 419 ベクトルの要素には<code>vec.x</code>のような形でアクセスできます。1〜4番目の要素はそれぞれ<code>.x</code>、<code>.y</code>、<code>.z</code>、<code>.w</code>と記述します。GLSLでは他にも、ベクトルを色の表現として利用する場合には<code>rgba</code>により、またテクスチャの座標には<code>stpq</code>により、各要素にアクセスすることができます。 420 </p> 421 422 <p> 423 The vector datatype allows for some interesting and flexible component selection called <def>swizzling</def>. Swizzling allows us to use syntax like this: 424 ベクトルの要素を選択する、おもしろくて柔軟性の高い方法があります。<def>スウィズリング</def>と呼ばれるこの方法は以下のように利用します: 425 </p> 426 427 <pre><code> 428 vec2 someVec; 429 vec4 differentVec = someVec.xyxx; 430 vec3 anotherVec = differentVec.zyw; 431 vec4 otherVec = someVec.xxxx + anotherVec.yxzy; 432 </code></pre> 433 434 <p> 435 You can use any combination of up to 4 letters to create a new vector (of the same type) as long as the original vector has those components; it is not allowed to access the <code>.z</code> component of a <code>vec2</code> for example. We can also pass vectors as arguments to different vector constructor calls, reducing the number of arguments required: 436 あるベクトルを用いて、その要素から好きな組み合わせにより同じ型の新しいベクトルを作れるのです。ただし例えば<code>vec2</code>の<code>.z</code>要素は存在しないので利用できません。あるいは以下のように、あるベクトルを他のベクトルのコンストラクタに渡すこともできます: 437 </p> 438 439 <pre><code> 440 vec2 vect = vec2(0.5, 0.7); 441 vec4 result = vec4(vect, 0.0, 0.0); 442 vec4 otherResult = vec4(result.xyz, 1.0); 443 </code></pre> 444 445 <p> 446 Vectors are thus a flexible datatype that we can use for all kinds of input and output. Throughout the book you'll see plenty of examples of how we can creatively manage vectors. 447 このようにベクトルは柔軟性の高い型で、いつでも入力や出力として用いることができます。本書を通じて創造的にベクトルを使う例がたくさん見られます。 448 </p> 449 450 <h2>Ins and outs</h2> 451 <h2>入力と出力</h2> 452 <p> 453 Shaders are nice little programs on their own, but they are part of a whole and for that reason we want to have inputs and outputs on the individual shaders so that we can move stuff around. GLSL defined the <code>in</code> and <code>out</code> keywords specifically for that purpose. Each shader can specify inputs and outputs using those keywords and wherever an output variable matches with an input variable of the next shader stage they're passed along. The vertex and fragment shader differ a bit though. 454 シェーダーはそれだけで完結した小さなプログラムですが、それらを組み合わて全体としてうまく機能する必要があります。そのため、互いにデータをやりとりするための入力と出力がそれぞれのシェーダーで必要になります。GLSLには入出力を宣言するための<code>in</code>と<code>out</code>というキーワードが用意されています。各シェーダーではこれらのキーワードを使って入力と出力を定義し、あるシェーダーの出力が次のシェーダーの入力と合致すればそこでデータの受け渡しが行われます。ただし頂点シェーダーとフラグメントシェーダーは少し事情が異なります。 455 </p> 456 457 <p> 458 The vertex shader <strong>should</strong> receive some form of input otherwise it would be pretty ineffective. The vertex shader differs in its input, in that it receives its input straight from the vertex data. To define how the vertex data is organized we specify the input variables with location metadata so we can configure the vertex attributes on the CPU. We've seen this in the previous chapter as <code>layout (location = 0)</code>. The vertex shader thus requires an extra layout specification for its inputs so we can link it with the vertex data. 459 頂点シェーダーは特定の形式の入力を持つことが<strong>強く推奨</strong>されます。そうしないとかなり効率が落ちます。頂点シェーダーは他のシェーダーとは違い、入力として頂点データを直接受け取ります。CPU上で設定した頂点データがどのように構成されているかをシェーダーに伝えるため、入力に対してデータの位置というメタデータを記述します。前章で<code>layout (location = 0)</code>というコードを記述したのがそれです。頂点シェーダーへの入力を頂点データと紐付けるため、このようにデータの配置を特定する必要があるのです。 460 </p> 461 462 <note> 463 It is also possible to omit the <code>layout (location = 0)</code> specifier and query for the attribute locations in your OpenGL code via <fun><function id='104'>glGetAttribLocation</function></fun>, but I'd prefer to set them in the vertex shader. It is easier to understand and saves you (and OpenGL) some work. 464 <code>layout (location = 0)</code>を使わず、<fun><function id='104'>glGetAttribLocation</function></fun>によって属性の位置を特定することも可能ですが、著者は前述の方法を好みます。理解しやすく開発者(とOpenGL)の労力を節約できるからです。 465 </note> 466 467 <p> 468 The other exception is that the fragment shader requires a <code>vec4</code> color output variable, since the fragment shaders needs to generate a final output color. If you fail to specify an output color in your fragment shader, the color buffer output for those fragments will be undefined (which usually means OpenGL will render them either black or white). 469 もう一つの例外であるフラグメントシェーダーはその出力が<code>vec4</code>型の色でなければなりません。このシェーダーは最終的な色を生成する必要があるからです。フラグメントシェーダーにおいてあるフラグメントに対して色を出力できなかった場合、そのフラグメントの色バッファがどうなるかは不定です(多くの場合黒または白で描画されます)。 470 </p> 471 472 <p> 473 So if we want to send data from one shader to the other we'd have to declare an output in the sending shader and a similar input in the receiving shader. When the types and the names are equal on both sides OpenGL will link those variables together and then it is possible to send data between shaders (this is done when linking a program object). To show you how this works in practice we're going to alter the shaders from the previous chapter to let the vertex shader decide the color for the fragment shader. 474 あるシェーダーから次のシェーダーにデータを送信する場合、送信元の出力と受信先の入力を同じ形式で宣言しなければいけません。双方の型と名前が一致した場合、OpenGLがそれを接続しデータの受け渡しが可能になります(この作業はプログラムオブジェクトのリンク時に行われます)。実際の動作を確認するために、前章で作成したシェーダーを変更して、頂点シェーダーがフラグメントシェーダーの色を決定するようにしましょう。 475 </p> 476 477 <strong>Vertex shader</strong> 478 <strong>頂点シェーダー</strong> 479 <pre><code> 480 #version 330 core 481 layout (location = 0) in vec3 aPos; // the position variable has attribute position 0 482 layout (location = 0) in vec3 aPos; // 位置変数は位置0に存在 483 484 out vec4 vertexColor; // specify a color output to the fragment shader 485 out vec4 vertexColor; // フラグメントシェーダーへの出力として色を指定 486 487 void main() 488 { 489 gl_Position = vec4(aPos, 1.0); // see how we directly give a vec3 to vec4's constructor 490 vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // set the output variable to a dark-red color 491 gl_Position = vec4(aPos, 1.0); // このようにすればvec3からvec4を直接作成できます 492 vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // 出力する色を暗い赤に 493 } 494 </code></pre> 495 496 <strong>Fragment shader</strong> 497 <strong>フラグメントシェーダー</strong> 498 <pre><code> 499 #version 330 core 500 out vec4 FragColor; 501 502 in vec4 vertexColor; // the input variable from the vertex shader (same name and same type) 503 in vec4 vertexColor; // 頂点シェーダーからの入力(同じ名前かつ同じ型) 504 505 void main() 506 { 507 FragColor = vertexColor; 508 } 509 </code></pre> 510 511 <p> 512 You can see we declared a <var>vertexColor</var> variable as a <code>vec4</code> output that we set in the vertex shader and we declare a similar <var>vertexColor</var> input in the fragment shader. Since they both have the same type and name, the <var>vertexColor</var> in the fragment shader is linked to the <var>vertexColor</var> in the vertex shader. Because we set the color to a dark-red color in the vertex shader, the resulting fragments should be dark-red as well. The following image shows the output: 513 頂点シェーダーにおいて<code>vec4</code>の変数<var>vertexColor</var>を宣言し、フラグメントシェーダーでも同様のものを定義します。双方が同じ名前で同じ型の変数なので、フラグメントシェーダーの<var>vertexColor</var>は頂点シェーダーの<var>vertexColor</var>と接続されます。頂点シェーダーにおいて暗い赤に設定したので、フラグメントシェーダーからも暗い赤が出力されます。その結果以下のような画像が生成されます: 514 </p> 515 516 <img src="/img/getting-started/shaders.png" class="clean"/> 517 518 <p> 519 There we go! We just managed to send a value from the vertex shader to the fragment shader. Let's spice it up a bit and see if we can send a color from our application to the fragment shader! 520 いかがでしょう。頂点シェーダーからフラグメントシェーダーに変数を送信できました。これに少し味付けして、アプリケーションからフラグメントシェーダーに色の情報を送信するようにしましょう。 521 </p> 522 523 <h2>Uniforms</h2> 524 <h2>ユニフォーム</h2> 525 <p> 526 <def>Uniforms</def> are another way to pass data from our application on the CPU to the shaders on the GPU. Uniforms are however slightly different compared to vertex attributes. First of all, uniforms are <def>global</def>. Global, meaning that a uniform variable is unique per shader program object, and can be accessed from any shader at any stage in the shader program. Second, whatever you set the uniform value to, uniforms will keep their values until they're either reset or updated. 527 <def>ユニフォーム</def>はCPU上のアプリケーションからGPU上のシェーダーにデータを送信するもうひとつの方法です。ユニフォームは頂点属性と少し違います。第一にユニフォームは<def>グローバル</def>です。すなわち、ユニフォームは各シェーダープログラムオブジェクトにおいて一意であり、同シェーダープログラム中の他のシェーダーからもアクセスできます。第二に、ユニフォームの値がセットされた場合、その値はリセットあるいは更新されるまで一定です。 528 </p> 529 530 <p> 531 To declare a uniform in GLSL we simply add the <code>uniform</code> keyword to a shader with a type and a name. From that point on we can use the newly declared uniform in the shader. Let's see if this time we can set the color of the triangle via a uniform: 532 GLSLにおいてユニフォームを宣言するには<code>uniform</code>キーワードを変数の型と名前に添えてシェーダーに記述するだけです。以降そのシェーダーにおいてこのユニフォームが利用できます。それではユニフォームを使って三角形の色が変更できるか試してみましょう: 533 </p> 534 535 <pre><code> 536 #version 330 core 537 out vec4 FragColor; 538 539 uniform vec4 ourColor; // we set this variable in the OpenGL code. 540 uniform vec4 ourColor; // この変数の値をOpenGLのコードで設定します。 541 542 void main() 543 { 544 FragColor = ourColor; 545 } 546 </code></pre> 547 548 <p> 549 We declared a uniform <code>vec4</code> <var>ourColor</var> in the fragment shader and set the fragment's output color to the content of this uniform value. Since uniforms are global variables, we can define them in any shader stage we'd like so no need to go through the vertex shader again to get something to the fragment shader. We're not using this uniform in the vertex shader so there's no need to define it there. 550 <code>vec4</code> <var>ourColor</var>というユニフォームをフラグメントシェーダーで宣言し、フラグメントシェーダーの出力の色をこのユニフォームの値にしました。ユニフォームはグローバル変数なので、どのシェーダーにおいて定義することも可能です。そのため頂点シェーダーにおいてフラグメントシェーダーのために何かする必要はありません。頂点シェーダーにおいてこのユニフォームを利用しないので、そこで定義する必要もありません。 551 </p> 552 553 <warning> 554 If you declare a uniform that isn't used anywhere in your GLSL code the compiler will silently remove the variable from the compiled version which is the cause for several frustrating errors; keep this in mind! 555 定義したユニフォームがどのGLSLのコードにおいて全く利用されない場合、コンパイラは黙ってその変数を削除します。この仕様は時にうっとうしいエラーの原因になります。頭の片隅に置いておいて下さい 。 556 </warning> 557 558 <p> 559 The uniform is currently empty; we haven't added any data to the uniform yet so let's try that. We first need to find the index/location of the uniform attribute in our shader. Once we have the index/location of the uniform, we can update its values. Instead of passing a single color to the fragment shader, let's spice things up by gradually changing color over time: 560 このユニフォームはまだデータを追加していないので空っぽです。ここにデータを渡す方法を見ていきましょう。まずシェーダーにおけるユニフォームの場所を探す必要があります。ユニフォームが見つかったらその値を更新します。一色だけ指定するのでは面白くないので、時間と共に色を変化させてみましょう。 561 </p> 562 563 <pre><code> 564 float timeValue = <function id='47'>glfwGetTime</function>(); 565 float greenValue = (sin(timeValue) / 2.0f) + 0.5f; 566 int vertexColorLocation = <function id='45'>glGetUniformLocation</function>(shaderProgram, "ourColor"); 567 <function id='28'>glUseProgram</function>(shaderProgram); 568 <function id='44'>glUniform</function>4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); 569 </code></pre> 570 571 <p> 572 First, we retrieve the running time in seconds via <fun><function id='47'>glfwGetTime</function>()</fun>. Then we vary the color in the range of <code>0.0</code> - <code>1.0</code> by using the <fun>sin</fun> function and store the result in <var>greenValue</var>. 573 最初に<fun><function id='47'>glfwGetTime</function>()</fun>により実行時間を秒単位で取得します。次に<fun>sin</fun>関数を利用し色の数値を<code>0.0</code>と<code>1.0</code>の間で設定し、その値を<var>greenValue</var>に保存します。 574 </p> 575 576 <p> 577 Then we query for the location of the <var>ourColor</var> uniform using <fun><function id='45'>glGetUniformLocation</function></fun>. We supply the shader program and the name of the uniform (that we want to retrieve the location from) to the query function. If <fun><function id='45'>glGetUniformLocation</function></fun> returns <code>-1</code>, it could not find the location. Lastly we can set the uniform value using the <fun><function id='44'>glUniform</function>4f</fun> function. Note that finding the uniform location does not require you to use the shader program first, but updating a uniform <strong>does</strong> require you to first use the program (by calling <fun><function id='28'>glUseProgram</function></fun>), because it sets the uniform on the currently active shader program. 578 そして<var>ourColor</var>ユニフォームの場所を<fun><function id='45'>glGetUniformLocation</function></fun>により割り出します。シェーダープログラムと、場所が知りたいユニフォームの名前をこの関数に渡します。<fun><function id='45'>glGetUniformLocation</function></fun>が<code>-1</code>を返した場合、ユニフォームが見つからなかったということです。最後に<fun><function id='44'>glUniform</function>4f</fun>を用いてユニフォームの値を設定します。ユニフォームを探す際にシェーダープログラムの利用を宣言する必要はありません。しかしユニフォームの値の更新は、現在アクティブなシェーダープログラムに対して行われるので、<fun><function id='28'>glUseProgram</function></fun>によりシェーダープログラムの利用を宣言することが<strong>必要</strong>です。このことに留意してください。 579 </p> 580 581 <note> 582 <p> 583 Because OpenGL is in its core a C library it does not have native support for function overloading, so wherever a function can be called with different types OpenGL defines new functions for each type required; <fun><function id='44'>glUniform</function></fun> is a perfect example of this. The function requires a specific postfix for the type of the uniform you want to set. A few of the possible postfixes are: 584 OpenGLの核となる部分はC言語のライブラリであり、関数のオーバーロードができないので、違う型の引数に対して同じことを行う関数が必要な場合、それぞれの型に対して別の関数として定義されています。<fun><function id='44'>glUniform</function></fun>はそのいい例です。値を設定するユニフォームの型に応じて、関数名に接尾語がつきます。例として以下のようなものが挙げられます: 585 <ul> 586 <li><code>f</code>: the function expects a <code>float</code> as its value.</li> 587 <li><code>i</code>: the function expects an <code>int</code> as its value.</li> 588 <li><code>ui</code>: the function expects an <code>unsigned int</code> as its value.</li> 589 <li><code>3f</code>: the function expects 3 <code>float</code>s as its value.</li> 590 <li><code>fv</code>: the function expects a <code>float</code> vector/array as its value.</li> 591 </ul> 592 <ul> 593 <li><code>f</code>: 関数は1つの<code>float</code>を引数に取ります。</li> 594 <li><code>i</code>: 関数は1つの<code>int</code>を引数に取ります。</li> 595 <li><code>ui</code>: 関数は1つの<code>unsigned int</code>を引数に取ります。</li> 596 <li><code>3f</code>: 関数は3つの<code>float</code>を引数に取ります。</li> 597 <li><code>fv</code>: 関数は<code>float</code>のベクトル(配列)1つを引数に取ります。</li> 598 </ul> 599 Whenever you want to configure an option of OpenGL simply pick the overloaded function that corresponds with your type. In our case we want to set 4 floats of the uniform individually so we pass our data via <fun><function id='44'>glUniform</function>4f</fun> (note that we also could've used the <code>fv</code> version). 600 OpenGLのオプションを設定したい場合、単にオーバーロードされた関数から適合する型のものを呼び出して下さい。今回はユニフォームに対して4つの浮動小数点数を割り当てたいので<fun><function id='44'>glUniform</function>4f</fun>を利用します(色を配列に格納すれば<code>fv</code>を利用することも可能です)。 601 </p> 602 </note> 603 604 <p> 605 Now that we know how to set the values of uniform variables, we can use them for rendering. If we want the color to gradually change, we want to update this uniform every frame, otherwise the triangle would maintain a single solid color if we only set it once. So we calculate the <var>greenValue</var> and update the uniform each render iteration: 606 ユニフォーム変数に値をセットしたので、これを描画に利用できるようになりました。時間と共に色を変化させるには、フレーム毎にユニフォームを更新しなければなりません。そうしないと三角形は最初に設定した色のままになります。そのため<var>greenValue</var>の計算とユニフォームの更新は描画ループの中に配置します: 607 </p> 608 609 <pre><code> 610 while(!<function id='14'>glfwWindowShouldClose</function>(window)) 611 { 612 // input 613 // 入力 614 processInput(window); 615 616 // render 617 // 描画 618 // clear the colorbuffer 619 // 色バッファの削除 620 <function id='13'><function id='10'>glClear</function>Color</function>(0.2f, 0.3f, 0.3f, 1.0f); 621 <function id='10'>glClear</function>(GL_COLOR_BUFFER_BIT); 622 623 // be sure to activate the shader 624 // シェーダーのアクティベート 625 <function id='28'>glUseProgram</function>(shaderProgram); 626 627 // update the uniform color 628 // ユニフォームの色を更新 629 float timeValue = <function id='47'>glfwGetTime</function>(); 630 float greenValue = sin(timeValue) / 2.0f + 0.5f; 631 int vertexColorLocation = <function id='45'>glGetUniformLocation</function>(shaderProgram, "ourColor"); 632 <function id='44'>glUniform</function>4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); 633 634 // now render the triangle 635 // 三角形の描画 636 <function id='27'>glBindVertexArray</function>(VAO); 637 <function id='1'>glDrawArrays</function>(GL_TRIANGLES, 0, 3); 638 639 // swap buffers and poll IO events 640 // バッファの入替えとイベントの処理 641 <function id='24'>glfwSwapBuffers</function>(window); 642 <function id='23'>glfwPollEvents</function>(); 643 } 644 </code></pre> 645 646 <p> 647 The code is a relatively straightforward adaptation of the previous code. This time, we update a uniform value each frame before drawing the triangle. If you update the uniform correctly you should see the color of your triangle gradually change from green to black and back to green. 648 コードには以前のものをほとんどそのまま適応しただけです。今回は各フレームにおいて三角形を描画する前にユニフォームの値を更新しています。ユニフォームの更新がうまく行われていれば、三角形の色が緑から黒へ、黒から緑へ変化していくのが確認できるでしょう。 649 </p> 650 651 <div class="video paused" onclick="ClickVideo(this)"> 652 <video width="600" height="450" loop> 653 <source src="/video/getting-started/shaders.mp4" type="video/mp4" /> 654 <img src="/img/getting-started/shaders2.png" class="clean"/> 655 </video> 656 </div> 657 658 659 <p> 660 Check out the source code <a href="/code_viewer_gh.php?code=src/1.getting_started/3.1.shaders_uniform/shaders_uniform.cpp" target="_blank">here</a> if you're stuck. 661 問題があれば<a href="/code_viewer_gh.php?code=src/1.getting_started/3.1.shaders_uniform/shaders_uniform.cpp" target="_blank">ここ</a>でソースコードを確認してください。 662 </p> 663 664 <p> 665 As you can see, uniforms are a useful tool for setting attributes that may change every frame, or for interchanging data between your application and your shaders, but what if we want to set a color for each vertex? In that case we'd have to declare as many uniforms as we have vertices. A better solution would be to include more data in the vertex attributes which is what we're going to do now. 666 ご覧のように、ユニフォームはフレームごとに値を変更したり、アプリケーションとシェーダーの間でデータをやりとりするうえで便利です。しかし各頂点に対してそれぞれの色を設定したい場合はどうでしょう。この場合、頂点の数だけユニフォームを宣言する必要があります。より良い方法としては頂点属性に追加の情報を含めることが挙げられます。以下、その方法を見ていきましょう。 667 </p> 668 669 <h2>More attributes!</h2> 670 <h2>属性の追加</h2> 671 <p> 672 We saw in the previous chapter how we can fill a VBO, configure vertex attribute pointers and store it all in a VAO. This time, we also want to add color data to the vertex data. We're going to add color data as 3 <code>float</code>s to the <var>vertices</var> array. We assign a red, green and blue color to each of the corners of our triangle respectively: 673 前章で、VBOにデータを割り当て、頂点属性のポインタを設定し、それをVAOに保存する方法を説明しました。ここでは頂点データに色の情報も追加しましょう。<var>頂点</var>配列に色の情報を3つの<code>float</code>として追加します。三角形の各頂点に赤、緑、青の色を割り当てましょう: 674 </p> 675 676 <pre><code> 677 float vertices[] = { 678 // positions // colors 679 // 位置 // 色 680 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下 681 -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下 682 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 上 683 }; 684 </code></pre> 685 686 <p> 687 Since we now have more data to send to the vertex shader, it is necessary to adjust the vertex shader to also receive our color value as a vertex attribute input. Note that we set the location of the <var>aColor</var> attribute to 1 with the layout specifier: 688 頂点シェーダーに送信するデータが増えたため、頂点シェーダーが頂点属性の入力から色の情報を受け取れるように設定する必要があります。<var>aColor</var>の属性位置を1に設定していることに注意して下さい: 689 </p> 690 691 <pre><code> 692 #version 330 core 693 layout (location = 0) in vec3 aPos; // the position variable has attribute position 0 694 layout (location = 1) in vec3 aColor; // the color variable has attribute position 1 695 layout (location = 0) in vec3 aPos; // 位置の変数の属性位置は0 696 layout (location = 1) in vec3 aColor; // 色の変数の属性位置は1 697 698 out vec3 ourColor; // output a color to the fragment shader 699 out vec3 ourColor; // フラグメントシェーダーへ色を出力 700 701 void main() 702 { 703 gl_Position = vec4(aPos, 1.0); 704 ourColor = aColor; // set ourColor to the input color we got from the vertex data 705 ourColor = aColor; // ourColorを頂点データから取得した色に設定 706 } 707 </code></pre> 708 709 <p> 710 Since we no longer use a uniform for the fragment's color, but now use the <var>ourColor</var> output variable we'll have to change the fragment shader as well: 711 フラグメントの色としてユニフォームではなく<var>ourColor</var>の出力を利用するので、フラグメントシェーダーを以下のように変更します: 712 </p> 713 714 <pre><code> 715 #version 330 core 716 out vec4 FragColor; 717 in vec3 ourColor; 718 719 void main() 720 { 721 FragColor = vec4(ourColor, 1.0); 722 } 723 </code></pre> 724 725 <p> 726 Because we added another vertex attribute and updated the VBO's memory we have to re-configure the vertex attribute pointers. The updated data in the VBO's memory now looks a bit like this: 727 頂点属性を追加し、VBOのメモリを更新したので、頂点属性ポインタを再設定します。更新されたデータはVBOのメモリ内で以下のような配置になっています: 728 </p> 729 730 <img src="/img/getting-started/vertex_attribute_pointer_interleaved.png" class="clean" alt="Interleaved data of position and color within VBO to be configured wtih <function id='30'>glVertexAttribPointer</function>"/> 731 732 <p> 733 Knowing the current layout we can update the vertex format with <fun><function id='30'>glVertexAttribPointer</function></fun>: 734 これお踏まえ、頂点のフォーマットを<fun><function id='30'>glVertexAttribPointer</function></fun>により以下のように変更します: 735 </p> 736 737 <pre><code> 738 // position attribute 739 // 位置属性 740 <function id='30'>glVertexAttribPointer</function>(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); 741 <function id='29'><function id='60'>glEnable</function>VertexAttribArray</function>(0); 742 // color attribute 743 // 色属性 744 <function id='30'>glVertexAttribPointer</function>(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float))); 745 <function id='29'><function id='60'>glEnable</function>VertexAttribArray</function>(1); 746 </code></pre> 747 748 <p> 749 The first few arguments of <fun><function id='30'>glVertexAttribPointer</function></fun> are relatively straightforward. This time we are configuring the vertex attribute on attribute location <code>1</code>. The color values have a size of <code>3</code> <code>float</code>s and we do not normalize the values. 750 <fun><function id='30'>glVertexAttribPointer</function></fun>の前半の引数は分かりやすいと思います。今回は、属性位置<code>1</code>の頂点属性を設定します。色の情報は<code>float</code>が<code>3</code>つ分のサイズで、正規化はしません。 751 </p> 752 753 <p> 754 Since we now have two vertex attributes we have to re-calculate the <em>stride</em> value. To get the next attribute value (e.g. the next <code>x</code> component of the position vector) in the data array we have to move <code>6</code> <code>float</code>s to the right, three for the position values and three for the color values. This gives us a stride value of 6 times the size of a <code>float</code> in bytes (= <code>24</code> bytes). <br/> 755 Also, this time we have to specify an offset. For each vertex, the position vertex attribute is first so we declare an offset of <code>0</code>. The color attribute starts after the position data so the offset is <code>3 * sizeof(float)</code> in bytes (= <code>12</code> bytes). 756 頂点属性が二種類になったので<em>ストライド</em>も計算しなおします。次の属性の値(つまり、次の位置属性の<code>x</code>要素)を得るために、データの配列上で<code>float</code><code>6</code>つ分右に移動する必要があります。位置属性の値3つ分と色属性の値3つ分です。つまりストライドは<code>float</code>のサイズの6倍(=<code>24</code>バイト)です。<br/> 757 加えて今回はデータの開始位置も設定しないといけません。各頂点において、位置を表わす頂点属性は先頭に位置するので、開始位置は<code>0</code>です。色を表わす頂点属性は位置のデータの後ろにあるので、開始位置は<code>3 * sizeof(float)</code>バイト(=<code>12</code>バイト)です。 758 </p> 759 760 <p> 761 Running the application should result in the following image: 762 アプリケーションを実行すると以下のようになります: 763 </p> 764 765 <img src="/img/getting-started/shaders3.png" class="clean"/> 766 767 <p> 768 Check out the source code <a href="/code_viewer_gh.php?code=src/1.getting_started/3.2.shaders_interpolation/shaders_interpolation.cpp" target="_blank">here</a> if you're stuck. 769 問題があれば<a href="/code_viewer_gh.php?code=src/1.getting_started/3.2.shaders_interpolation/shaders_interpolation.cpp" target="_blank">ここ</a>でソースコードを確認して下さい。 770 </p> 771 772 <p> 773 The image may not be exactly what you would expect, since we only supplied 3 colors, not the huge color palette we're seeing right now. This is all the result of something called <def>fragment interpolation</def> in the fragment shader. When rendering a triangle the rasterization stage usually results in a lot more fragments than vertices originally specified. The rasterizer then determines the positions of each of those fragments based on where they reside on the triangle shape.<br/> 774 Based on these positions, it <def>interpolates</def> all the fragment shader's input variables. Say for example we have a line where the upper point has a green color and the lower point a blue color. If the fragment shader is run at a fragment that resides around a position at <code>70%</code> of the line, its resulting color input attribute would then be a linear combination of green and blue; to be more precise: <code>30%</code> blue and <code>70%</code> green. 775 画像は読者が想像したものと少し違うと思います。3つの色を設定したのであり、この画像のようにたくさんの色のパターンを指定したわけではないからです。この結果はフラグメントシェーダーの<def>フラグメント補完</def>と呼ばれる機能によるものです。三角形を描画する時、ラスタリゼーションステージでは最初に用意した頂点の数より多くのフラグメントが生成されています。ラスタライザはそれらのフラグメントの位置を三角形内での位置に基づいて決定します。<br/> 776 この位置に基づき、フラグメントシェーダーの入力が<def>補完</def>されます。例えばここに一本の線があり、上端が緑で下端が青だとしましょう。この線上の下から70%の位置にあるフラグメントに対してフラグメントシェーダーが実行された場合、このフラグメントの色は緑と青の線形補完になります。もう少し詳しく言うと、<code>30%</code>の青と<code>70%</code>の緑になります。 777 </p> 778 779 <p> 780 This is exactly what happened at the triangle. We have 3 vertices and thus 3 colors, and judging from the triangle's pixels it probably contains around 50000 fragments, where the fragment shader interpolated the colors among those pixels. If you take a good look at the colors you'll see it all makes sense: red to blue first gets to purple and then to blue. Fragment interpolation is applied to all the fragment shader's input attributes. 781 これがまさに三角形で起こったことです。3つの頂点と3つの色があります。三角形のピクセル数から考えて、おそらくフラグメントは50000個程度存在します。このフラグメントそれぞれに対してフラグメントシェーダーが色を補完します。三角形の色をよくみると理解できるはずです。赤から青への変化は途中で紫を経由しています。フラグメント補完はフラグメントシェーダーの入力となる属性すべてに対して適応されます。 782 </p> 783 784 <h1>Our own shader class</h1> 785 <h1>独自のシェーダークラス</h1> 786 <p> 787 Writing, compiling and managing shaders can be quite cumbersome. As a final touch on the shader subject we're going to make our life a bit easier by building a shader class that reads shaders from disk, compiles and links them, checks for errors and is easy to use. This also gives you a bit of an idea how we can encapsulate some of the knowledge we learned so far into useful abstract objects. 788 シェーダーの作成、コンパイルそして管理は面倒です。シェーダーの章の最後として、独自のシェーダークラスを作成し、扱いやすくしましょう。このシェーダークラスはシェーダーをディスクから読み込み、コンパイル、リンクし、エラーを検出するものです。こうすることでここまで学んだ知識を抽象的なオブジェクトに詰め込み利便性を高める方法にも慣れることができます。 789 </p> 790 791 <p> 792 We will create the shader class entirely in a header file, mainly for learning purposes and portability. Let's start by adding the required includes and by defining the class structure: 793 学習のため、そして移植性を高めるため、シェーダークラスをひとつのヘッダーファイルに構築します。まずはじめに必要なものをインクルードしクラスの構造を定義しましょう: 794 </p> 795 796 <pre><code> 797 #ifndef SHADER_H 798 #define SHADER_H 799 800 #include <glad/glad.h> // include glad to get all the required OpenGL headers 801 #include <glad/glad.h> // gladをインクルードして必要なOpenGLヘッダーを取得 802 803 #include <string> 804 #include <fstream> 805 #include <sstream> 806 #include <iostream> 807 808 809 class Shader 810 { 811 public: 812 // the program ID 813 // プログラムID 814 unsigned int ID; 815 816 // constructor reads and builds the shader 817 // コンストラクタがシェーダーを読み込んでビルド 818 Shader(const char* vertexPath, const char* fragmentPath); 819 // use/activate the shader 820 // シェーダーをアクティベート 821 void use(); 822 // utility uniform functions 823 // ユニフォーム設定用関数 824 void setBool(const std::string &name, bool value) const; 825 void setInt(const std::string &name, int value) const; 826 void setFloat(const std::string &name, float value) const; 827 }; 828 829 #endif 830 </code></pre> 831 832 <note> 833 We used several <def>preprocessor directives</def> at the top of the header file. Using these little lines of code informs your compiler to only include and compile this header file if it hasn't been included yet, even if multiple files include the shader header. This prevents linking conflicts. 834 ヘッダファイルの先頭で<def>プリプロセッサ・ディレクティブ</def>を利用しています。これは複数のファイルからこのヘッダをインクルードしようとした時でも、このファイルがまだインクルードされていない場合に限りインクルードしてコンパイルするようにコンパイラに伝えるものです。これによりリンク時の競合を防げます。 835 </note> 836 837 <p> 838 The shader class holds the ID of the shader program. Its constructor requires the file paths of the source code of the vertex and fragment shader respectively that we can store on disk as simple text files. To add a little extra we also add several utility functions to ease our lives a little: <fun>use</fun> activates the shader program, and all <fun>set...</fun> functions query a uniform location and set its value. 839 シェーダークラスはシェーダープログラムのIDを記憶しています。頂点シェーダーとフラグメントシェーダーはディスク上にテキストファイルとして保存しておきます。シェーダークラスのコンストラクタはこれらのシェーダーのソースコードのファイルパスを必要とします。さらに利便性を高めるためいくつかの関数を追加します。シェーダープログラムをアクティベートする<fun>use</fun>関数と、ユニフォームの場所を特定してその数値を変更する<fun>set...</fun>関数です。 840 </p> 841 842 <h2>Reading from file</h2> 843 <h2>ファイルからの読込み</h2> 844 <p> 845 We're using C++ filestreams to read the content from the file into several <code>string</code> objects: 846 ファイルの内容を読み込み<code>string</code>オブジェクトに格納するため、C++のファイルストリームを利用します: 847 </p> 848 849 <pre><code> 850 Shader(const char* vertexPath, const char* fragmentPath) 851 { 852 // 1. retrieve the vertex/fragment source code from filePath 853 // 1. 頂点シェーダーとフラグメントシェーダーのソースコードをfilePathから読込み 854 std::string vertexCode; 855 std::string fragmentCode; 856 std::ifstream vShaderFile; 857 std::ifstream fShaderFile; 858 // ensure ifstream objects can throw exceptions: 859 // ifstreamオブジェクトがエラーを出せるかどうか確認: 860 vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); 861 fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); 862 try 863 { 864 // open files 865 // ファイルを開く 866 vShaderFile.open(vertexPath); 867 fShaderFile.open(fragmentPath); 868 std::stringstream vShaderStream, fShaderStream; 869 // read file's buffer contents into streams 870 // ファイルのバッファをストリームに読込み 871 vShaderStream << vShaderFile.rdbuf(); 872 fShaderStream << fShaderFile.rdbuf(); 873 // close file handlers 874 // ファイルを閉じる 875 vShaderFile.close(); 876 fShaderFile.close(); 877 // convert stream into string 878 // ストリームを文字列に変換 879 vertexCode = vShaderStream.str(); 880 fragmentCode = fShaderStream.str(); 881 } 882 catch(std::ifstream::failure e) 883 { 884 std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; 885 } 886 const char* vShaderCode = vertexCode.c_str(); 887 const char* fShaderCode = fragmentCode.c_str(); 888 [...] 889 </code></pre> 890 891 <p> 892 Next we need to compile and link the shaders. Note that we're also reviewing if compilation/linking failed and if so, print the compile-time errors. This is extremely useful when debugging (you are going to need those error logs eventually): 893 続いてシェーダーをコンパイル及びリンクします。加えて、コンパイル及びリンクが成功したかどうか確認し、失敗していた場合コンパイル時のエラーを表示させています。これはデバッグ時に非常に便利です(開発においてエラーログは必須です)。 894 </p> 895 896 <pre><code> 897 // 2. compile shaders 898 // 2. シェーダーのコンパイル 899 unsigned int vertex, fragment; 900 int success; 901 char infoLog[512]; 902 903 // vertex Shader 904 // 頂点シェーダー 905 vertex = <function id='37'>glCreateShader</function>(GL_VERTEX_SHADER); 906 <function id='42'>glShaderSource</function>(vertex, 1, &vShaderCode, NULL); 907 <function id='38'>glCompileShader</function>(vertex); 908 // print compile errors if any 909 // コンパイルエラーの表示 910 <function id='39'>glGetShaderiv</function>(vertex, GL_COMPILE_STATUS, &success); 911 if(!success) 912 { 913 <function id='40'>glGetShaderInfoLog</function>(vertex, 512, NULL, infoLog); 914 std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; 915 }; 916 917 // similiar for Fragment Shader 918 // フラグメントシェーダーに対しても同様 919 [...] 920 921 // shader Program 922 // シェーダープログラム 923 ID = <function id='36'>glCreateProgram</function>(); 924 <function id='34'>glAttachShader</function>(ID, vertex); 925 <function id='34'>glAttachShader</function>(ID, fragment); 926 <function id='35'>glLinkProgram</function>(ID); 927 // print linking errors if any 928 <function id='41'>glGetProgramiv</function>(ID, GL_LINK_STATUS, &success); 929 if(!success) 930 { 931 glGetProgramInfoLog(ID, 512, NULL, infoLog); 932 std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; 933 } 934 935 // delete the shaders as they're linked into our program now and no longer necessary 936 // リンクが終わりで必要がなくなったシェーダーを削除。 937 <function id='46'>glDeleteShader</function>(vertex); 938 <function id='46'>glDeleteShader</function>(fragment); 939 </code></pre> 940 941 <p> 942 The <fun>use</fun> function is straightforward: 943 </p> 944 945 <pre><code> 946 void use() 947 { 948 <function id='28'>glUseProgram</function>(ID); 949 } 950 </code></pre> 951 952 <p> 953 Similarly for any of the uniform setter functions: 954 </p> 955 956 <pre><code> 957 void setBool(const std::string &name, bool value) const 958 { 959 <function id='44'>glUniform</function>1i(<function id='45'>glGetUniformLocation</function>(ID, name.c_str()), (int)value); 960 } 961 void setInt(const std::string &name, int value) const 962 { 963 <function id='44'>glUniform</function>1i(<function id='45'>glGetUniformLocation</function>(ID, name.c_str()), value); 964 } 965 void setFloat(const std::string &name, float value) const 966 { 967 <function id='44'>glUniform</function>1f(<function id='45'>glGetUniformLocation</function>(ID, name.c_str()), value); 968 } 969 </code></pre> 970 971 <p> 972 And there we have it, a completed <a href="/code_viewer_gh.php?code=includes/learnopengl/shader_s.h" target="_blank">shader class</a>. Using the shader class is fairly easy; we create a shader object once and from that point on simply start using it: 973 これで<a href="/code_viewer_gh.php?code=includes/learnopengl/shader_s.h" target="_blank">シェーダークラス</a>の構築は完了です。このクラスを利用するのは簡単です。シェーダーオブジェクトを作成するだけで使えるのです: 974 </p> 975 976 <pre><code> 977 Shader ourShader("path/to/shaders/shader.vs", "path/to/shaders/shader.fs"); 978 [...] 979 while(...) 980 { 981 ourShader.use(); 982 ourShader.setFloat("someUniform", 1.0f); 983 DrawStuff(); 984 } 985 </code></pre> 986 987 <p> 988 Here we stored the vertex and fragment shader source code in two files called <code>shader.vs</code> and <code>shader.fs</code>. You're free to name your shader files however you like; I personally find the extensions <code>.vs</code> and <code>.fs</code> quite intuitive. 989 それでは頂点シェーダーとフラグメントシェーダーを<code>shader.vs</code>と<code>shader.fs</code>というファイルにそれぞれ保存しましょう。ファイルの名前は好きなものにしてください。個人的に<code>.vs</code>と<code>.fs</code>という拡張子が分かりやすいのでこのような名前にしています。 990 </p> 991 992 <p> 993 You can find the source code <a href="/code_viewer_gh.php?code=src/1.getting_started/3.3.shaders_class/shaders_class.cpp" target="_blank">here</a> using our newly created <a href="/code_viewer_gh.php?code=includes/learnopengl/shader_s.h" target="_blank">shader class</a>. Note that you can click the shader file paths to find the shaders' source code. 994 今作った<a href="/code_viewer_gh.php?code=includes/learnopengl/shader_s.h" target="_blank">シェーダークラス</a>を利用したソースコードは<a href="/code_viewer_gh.php?code=src/1.getting_started/3.3.shaders_class/shaders_class.cpp" target="_blank">ここ</a>にあります。シェーダーファイルのパスをクリックすることでシェーダーのソースコードにもアクセスできます。 995 </p> 996 997 <h1>Exercises</h1> 998 <h1>演習</h1> 999 <ol> 1000 <li>Adjust the vertex shader so that the triangle is upside down: <a href="/code_viewer_gh.php?code=src/1.getting_started/3.4.shaders_exercise1/shaders_exercise1.cpp" target="_blank">solution</a>.</li> 1001 <li>頂点シェーダーを変更して三角形を逆さに表示してください: <a href="/code_viewer_gh.php?code=src/1.getting_started/3.4.shaders_exercise1/shaders_exercise1.cpp" target="_blank">回答</a></li> 1002 <li>Specify a horizontal offset via a uniform and move the triangle to the right side of the screen in the vertex shader using this offset value: <a href="/code_viewer_gh.php?code=src/1.getting_started/3.5.shaders_exercise2/shaders_exercise2.cpp" target="_blank">solution</a>.</li> 1003 <li>水平方向の位置をユニフォームで設定し、この値を頂点シェーダーから利用して三角形をスクリーンの右に寄せて下さい: <a href="/code_viewer_gh.php?code=src/1.getting_started/3.5.shaders_exercise2/shaders_exercise2.cpp" target="_blank">solution</a>.</li> 1004 <li>Output the vertex position to the fragment shader using the <code>out</code> keyword and set the fragment's color equal to this vertex position (see how even the vertex position values are interpolated across the triangle). Once you managed to do this; try to answer the following question: why is the bottom-left side of our triangle black?: <a href="/code_viewer_gh.php?code=src/1.getting_started/3.6.shaders_exercise3/shaders_exercise3.cpp" target="_blank">solution</a>.</li> 1005 <li><code>out</code>キーワードを用いて頂点の座標をフラグメントシェーダーに出力し、フラグメントの色をその座標と同じになるようにして下さい(頂点の座標であっても補完されることを確認して下さい)。これができたら、左下がどうして黒くなっているのか考えて下さい: <a href="/code_viewer_gh.php?code=src/1.getting_started/3.6.shaders_exercise3/shaders_exercise3.cpp" target="_blank">solution</a>.</li> 1006 </ol> 1007 1008 1009 </div> 1010 </body> 1011 </html> 1012 </main> 1013 </body> 1014 </html>