diff options
Diffstat (limited to 'files/ja/web/api/webgl_api')
20 files changed, 7797 insertions, 0 deletions
diff --git a/files/ja/web/api/webgl_api/basic_2d_animation_example/index.html b/files/ja/web/api/webgl_api/basic_2d_animation_example/index.html new file mode 100644 index 0000000000..5330c36d31 --- /dev/null +++ b/files/ja/web/api/webgl_api/basic_2d_animation_example/index.html @@ -0,0 +1,324 @@ +--- +title: 基本的な 2D WebGL アニメーションの例 +slug: Web/API/WebGL_API/Basic_2D_animation_example +tags: + - 2D Animation + - 2D Graphics + - Animation + - Drawing + - Example + - WebGL + - WebGL API +translation_of: Web/API/WebGL_API/Basic_2D_animation_example +--- +<div>{{WebGLSidebar}}</div> + +<div id="live-sample"> +<p>この WebGL の例では、キャンバスを作成し、その中に WebGL を使用して回転する四角形をレンダリングします。シーンを表すために使用する座標系は、キャンバスの座標系と同じです。つまり、(0, 0) は左上隅にあり、右下隅は (600, 460) となります。</p> + +<h2 id="Vertex_shader" name="Vertex_shader">頂点シェーダー</h2> + +<p>まず頂点シェーダーを見てみましょう。いつものように、シーンに使用している座標をクリップスペース座標に変換することです (つまり (0, 0) がコンテキストの中心にあり、コンテキストの実際のサイズに関係なく各軸が -1.0 から 1.0 に伸びるシステムです)</p> + +<pre class="brush: html"><script id="vertex-shader" type="x-shader/x-vertex"> + attribute vec2 aVertexPosition; + + uniform vec2 uScalingFactor; + uniform vec2 uRotationVector; + + void main() { + vec2 rotatedPosition = vec2( + aVertexPosition.x * uRotationVector.y + + aVertexPosition.y * uRotationVector.x, + aVertexPosition.y * uRotationVector.y - + aVertexPosition.x * uRotationVector.x + ); + + gl_Position = vec4(rotatedPosition * uScalingFactor, 0.0, 1.0); + } +</script></pre> + +<p>メインプログラムは属性 <code>aVertexPosition</code> を共有します。これは使用している座標系の頂点の位置です。位置の両方のコンポーネントが -1.0 から 1.0 の範囲になるように、これらの値を変換する必要があります。これは、コンテキストのアスペクト比に基づいたスケーリング係数を掛けることで簡単に実行できます。この計算については、後ほど説明します。</p> + +<p>形状も回転し、変換を適用することでそれを行うことができます。最初にそれを行います。頂点の回転位置は、JavaScript コードによって計算された均一な <code>uRotationVector</code> にある回転ベクトルを適用して計算されます。</p> + +<p>次に、<code>uScalingFactor</code> の JavaScript コードによって提供されるスケーリングベクトルを回転位置に乗算することにより、最終位置が計算されます。2D で描画しているため、<code>z</code> と <code>w</code> の値はそれぞれ 0.0 と 1.0 に固定されています。</p> + +<p>次に、標準 WebGL グローバル変数の <code>gl_Position</code> へ変換および回転された頂点の位置を設定します。</p> + +<h2 id="Fragment_shader" name="Fragment_shader">フラグメントシェーダー</h2> + +<p>次はフラグメントシェーダーです。その役割はレンダリングされる形状の各ピクセルの色を返すことです。ライティングが適用されていない、テクスチャのないソリッドオブジェクトを描画しているため、これは非常に簡単です:</p> + +<pre class="brush: html"><script id="fragment-shader" type="x-shader/x-fragment"> + #ifdef GL_ES + precision highp float; + #endif + + uniform vec4 uGlobalColor; + + void main() { + gl_FragColor = uGlobalColor; + } +</script></pre> + +<p>これは必要に応じて <code>float</code> 型の精度を指定することから始まります次に uniform 修飾子付きの <code>uGlobalColor</code> の値をグローバル変数 <code>gl_FragColor</code> へ設定します。これは、JavaScript コードにより正方形の描画に使用される色に設定されます。</p> + +<h2 id="HTML" name="HTML">HTML</h2> + +<p>HTML は、WebGL コンテキストを取得する {{HTMLElement("canvas")}} のみで構成されています。</p> + +<pre class="brush: html"><canvas id="glcanvas" width="600" height="460"> + Oh no! Your browser doesn't support canvas! +</canvas></pre> + +<h2 id="JavaScript" name="JavaScript">JavaScript</h2> + +<h3 id="Globals_and_initialization" name="Globals_and_initialization">グローバル変数と初期化</h3> + +<p>まず、グローバル変数。ここではこれらについては説明しません。代わりに、今後のコードで使用される場合について説明します。</p> + +<pre class="brush: js">let gl = null; +let glCanvas = null; + +// Aspect ratio and coordinate system +// details + +let aspectRatio; +let currentRotation = [0, 1]; +let currentScale = [1.0, 1.0]; + +// Vertex information + +let vertexArray; +let vertexBuffer; +let vertexNumComponents; +let vertexCount; + +// Rendering data shared with the +// scalers. + +let uScalingFactor; +let uGlobalColor; +let uRotationVector; +let aVertexPosition; + +// Animation timing + +let previousTime = 0.0; +let degreesPerSecond = 90.0; +</pre> + +<p>プログラムの初期化は <code>startup()</code> と呼ばれる {{event("load")}} イベントハンドラーによって処理します:</p> + +<pre class="brush: js">window.addEventListener("load", startup, false); + +function startup() { + glCanvas = document.getElementById("glcanvas"); + gl = glCanvas.getContext("webgl"); + + const shaderSet = [ + { + type: gl.VERTEX_SHADER, + id: "vertex-shader" + }, + { + type: gl.FRAGMENT_SHADER, + id: "fragment-shader" + } + ]; + + shaderProgram = buildShaderProgram(shaderSet); + + aspectRatio = glCanvas.width/glCanvas.height; + currentRotation = [0, 1]; + currentScale = [1.0, aspectRatio]; + + vertexArray = new Float32Array([ + -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, + -0.5, 0.5, 0.5, -0.5, -0.5, -0.5 + ]); + + vertexBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, vertexArray, gl.STATIC_DRAW); + + vertexNumComponents = 2; + vertexCount = vertexArray.length/vertexNumComponents; + + currentAngle = 0.0; + rotationRate = 6; + + animateScene(); +}</pre> + +<p>WebGL コンテキスト <code>gl</code> を取得し、シェーダープログラムを構築することから始める必要があります。ここでは、プログラムに複数のシェーダーを非常に簡単に追加できるように設計されたコードを使用しています。配列 <code>shaderSet</code> にはオブジェクトのリストが含まれ、各オブジェクトはプログラムにコンパイルされる 1 つのシェーダー関数を記述しています。各関数には、タイプ (<code>gl.VERTEX_SHADER</code> または <code>gl.FRAGMENT_SHADER</code> のいずれか) と ID (シェーダーのコードを含む {{HTMLElement("script")}} 要素の ID)。</p> + +<p>シェーダーセットは <code>buildShaderProgram()</code> 関数に渡され、コンパイルされリンクされたシェーダープログラムを返します。次にこれがどのように機能するかを見ていきます。</p> + +<p>シェーダープロシェグラムが構築し、幅を高さで割ってからコンテキストのアスペクト比を計算します。次に、アニメーションの現在の回転ベクトルを <code>[0, 1]</code> に設定し、スケーリングベクトルを <code>[1.0, aspectRatio]</code> に設定します。頂点シェーダーで見たスケーリングベクトルは、-1.0 から 1.0 の範囲に合うように座標をスケーリングするために使用されます。</p> + +<p>次に頂点の配列が {{jsxref("Float32Array")}} として作成され、三角形ごとに 6 つの座標 (3 つの 2D 頂点) が描画され、合計 12 個の値が作成されます。</p> + +<p>ご覧のとおり、各軸に -1.0 〜 1.0 の座標系を使用しています。なぜ調整する必要があるのでしょうか?これは単にコンテキストが正方形ではないためです。幅 600 ピクセル、高さ 460 のコンテキストを使用しています。これらの各ディメンションは、-1.0 〜 1.0 の範囲にマッピングされます。2 つの軸は同じ長さではないため、2 つの軸のいずれかの値を調整しないと、正方形は一方または他方に引き伸ばされます。したがって、これらの値を正規化する必要があります。</p> + +<p>頂点配列が作成されたら、{{domxref("WebGLRenderingContext.createBuffer", "gl.createBuffer()")}} を呼び出し、それらを含む新しい GL バッファーを作成します。{{domxref("WebGLRenderingContext.bindBuffer", "gl.bindBuffer()")}} を呼び出して標準の WebGL 配列バッファー参照をバインドし、{{domxref("WebGLRenderingContext.bufferData", "gl.bufferData()")}} を使用して頂点データをバッファーにコピーします。<code>gl.STATIC_DRAW</code> の使用法が指定されており、データは 1 回だけ設定され、変更されることはありませんが、繰り返し使用されることを WebGL に伝えます。これにより、WebGL は、その情報に基づいてパフォーマンスを向上させる可能性のある、適用可能な最適化を検討します。</p> + +<p>WebGL に提供される頂点データを使用して、<code>vertexNumComponents</code> を各頂点のコンポーネントの数 (2D 頂点であるため 2) に設定し、<code>vertexCount</code> を頂点リストの頂点の数に設定します。</p> + +<p>次に、まだ回転を実行していないため、現在の回転角度 (度) を 0.0 に設定し、回転速度 (画面の更新期間ごとの度、通常 60 FPS) を 6 に設定します。</p> + +<p>最後に、<code>animateScene()</code> が呼び出されて、最初のフレームをレンダリングし、アニメーションの次のフレームのレンダリングをスケジュールします。</p> + +<h3 id="Compiling_and_linking_the_shader_program" name="Compiling_and_linking_the_shader_program">シェーダープログラムのコンパイルとリンク</h3> + +<h4 id="Constructing_and_linking_the_program" name="Constructing_and_linking_the_program">プログラムの構築とリンク</h4> + +<p><code>buildShaderProgram()</code> 関数は、シェーダープログラムにコンパイルおよびリンクされるシェーダー関数のセットを記述するオブジェクトの配列を入力として受け取り、ビルドおよびリンク後にシェーダープログラムを返します。</p> + +<pre class="brush: js">function buildShaderProgram(shaderInfo) { + let program = gl.createProgram(); + + shaderInfo.forEach(function(desc) { + let shader = compileShader(desc.id, desc.type); + + if (shader) { + gl.attachShader(program, shader); + } + }); + + gl.linkProgram(program) + + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + console.log("Error linking shader program:"); + console.log(gl.getProgramInfoLog(program)); + } + + return program; +}</pre> + +<p>まず、{{domxref("WebGLRenderingContext.createProgram", "gl.createProgram()")}} は新しい空の GLSL プログラムを作成するために呼び出されます。</p> + +<p>次に、指定されたシェーダーのリスト内の各シェーダーに対して、<code>compileShader()</code> 関数を呼び出してコンパイルし、ビルドするシェーダー関数のIDとタイプを渡します。前述のように、これらの各オブジェクトには、シェーダーコードが存在する <code><script></code> 要素の ID とシェーダーのタイプが含まれます。コンパイルされたシェーダーは、{{domxref("WebGLRenderingContext.attachShader", "gl.attachShader()")}} へ渡すことでシェーダープログラムにアタッチされます。</p> + +<div class="note"> +<p>実際には、ここよりさらに一歩進んで、<code><script></code> 要素の <code>type</code> 属性の値を見て、シェーダーのタイプを判断できます。</p> +</div> + +<p>すべてのシェーダーがコンパイルされると、{{domxref("WebGLRenderingContext.linkProgram", "gl.linkProgram()")}} を使用してプログラムがリンクされます。</p> + +<p>プログラムのリンク中にエラーが発生した場合、エラーメッセージはコンソールに記録されます。</p> + +<p>最後に、コンパイルされたプログラムが呼び出し元に返されます。</p> + +<h4 id="Compiling_an_individual_shader" name="Compiling_an_individual_shader">個々のシェーダーをコンパイルする</h4> + +<p>以下の <code>compileShader()</code> 関数は、単一のシェーダーをコンパイルするために <code>buildShaderProgram()</code> によって呼び出されます。</p> + +<pre class="brush: js">function compileShader(id, type) { + let code = document.getElementById(id).firstChild.nodeValue; + let shader = gl.createShader(type); + + gl.shaderSource(shader, code); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + console.log(`Error compiling ${type === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader:`); + console.log(gl.getShaderInfoLog(shader)); + } + return shader; +}</pre> + +<p>コードは指定された ID を持つ {{HTMLElement("script")}} 要素内に含まれるテキストノードの値を取得することにより、HTML ドキュメントから取得されます。次に {{domxref("WebGLRenderingContext.createShader", "gl.createShader()")}} を使用して、指定されたタイプの新しいシェーダーが作成されます。</p> + +<p>ソースコードは {{domxref("WebGLRenderingContext.shaderSource", "gl.shaderSource()")}} を通して新しいシェーダーに送信され、そのときシェーダーは {{domxref("WebGLRenderingContext.compileShader", "gl.compileShader()")}} を使用してコンパイルされます。</p> + +<p>コンパイルエラーはコンソールに記録されます。生成されるメッセージに正しいシェーダータイプの文字列を挿入するための<a href="/docs/Web/JavaScript/Reference/Template_literals">テンプレートリテラル</a>文字列の使用に注意してください。実際のエラーの詳細は、{{domxref("WebGLRenderingContext.getShaderInfoLog", "gl.getShaderInfoLog()")}}を呼び出すことによって取得されます。</p> + +<p>最後に、コンパイルされたシェーダーが呼び出し元 (<code>buildShaderProgram()</code> 関数) へ返します。</p> + +<h3 id="Drawing_and_animating_the_scene" name="Drawing_and_animating_the_scene">シーンの描画とアニメーション化</h3> + +<p><code>animateScene()</code> 関数は各アニメーションフレームをレンダリングするために呼び出されます。</p> + +<pre class="brush: js">function animateScene() { + gl.viewport(0, 0, glCanvas.width, glCanvas.height); + gl.clearColor(0.8, 0.9, 1.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + + let radians = currentAngle * Math.PI / 180.0; + currentRotation[0] = Math.sin(radians); + currentRotation[1] = Math.cos(radians); + + gl.useProgram(shaderProgram); + + uScalingFactor = + gl.getUniformLocation(shaderProgram, "uScalingFactor"); + uGlobalColor = + gl.getUniformLocation(shaderProgram, "uGlobalColor"); + uRotationVector = + gl.getUniformLocation(shaderProgram, "uRotationVector"); + + gl.uniform2fv(uScalingFactor, currentScale); + gl.uniform2fv(uRotationVector, currentRotation); + gl.uniform4fv(uGlobalColor, [0.1, 0.7, 0.2, 1.0]); + + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + + aVertexPosition = + gl.getAttribLocation(shaderProgram, "aVertexPosition"); + + gl.enableVertexAttribArray(aVertexPosition); + gl.vertexAttribPointer(aVertexPosition, vertexNumComponents, + gl.FLOAT, false, 0, 0); + + gl.drawArrays(gl.TRIANGLES, 0, vertexCount); + + window.requestAnimationFrame(function(currentTime) { + let deltaAngle = ((currentTime - previousTime) / 1000.0) + * degreesPerSecond; + + currentAngle = (currentAngle + deltaAngle) % 360; + + previousTime = currentTime; + animateScene(); + }); +}</pre> + +<p>アニメーションのフレームを描画するために最初に行う必要があるのは、背景を目的の色にクリアすることです。この場合、{{HTMLElement("canvas")}} のサイズに基づいてビューポートを設定し、{{domxref("WebGLRenderingContext.clearColor", "clearColor()")}} を呼び出して使用する色を設定します。コンテンツをクリアするとき、{{domxref("WebGLRenderingContext.clear", "clear()")}} でバッファーをクリアします。</p> + +<p>次に、現在の回転ベクトルは、現在の回転角度 (<code>currentAngle</code>) を {{interwiki("wikipedia", "ラジアン")}} に変換し、回転ベクトルの最初のコンポーネントを {{interwiki("wikipedia", "三角関数", "sin")}} に設定し、2 番目のコンポーネントを {{interwiki("wikipedia", "三角関数", "cos")}} へ設定します。<code>currentRotation</code> ベクトルは、現在の角度 <code>currentAngle</code> にある {{interwiki("wikipedia", "単位円")}} 上のポイントの位置です。</p> + +<p>{{domxref("WebGLRenderingContext.useProgram", "useProgram()")}} は、以前に確立した GLSL シェーディングプログラムをアクティブにするために呼び出されます。次に、JavaScript コードとシェーダー間 ({{domxref("WebGLRenderingContext.getUniformLocation", "getUniformLocation()")}} を使用) で情報を共有するために使用される各 uniform の位置を取得します。</p> + +<p><code>uScalingFactor</code> という名前の uniform は、以前に計算された <code>currentScale</code> 値に設定されます。覚えているかもしれませんが、これはコンテキストのアスペクト比に基づいて座標系を調整するために使用される値です。これは {{domxref("WebGLRenderingContext.uniform2fv", "uniform2fv()")}} を使用して行われます (これは 2 値の浮動小数点ベクトルであるため)。</p> + +<p><code>uRotationVector</code> は、同じく <code>uniform2fv()</code> を使用して、現在の回転ベクトル (<code>currentRotation</code>) に設定されます。</p> + +<p><code>uGlobalColor</code> は {{domxref("WebGLRenderingContext.uniform4fv", "uniform4fv()")}} を使用して、正方形を描画するときに使用する色に設定されます。これは 4 コンポーネントの浮動小数点ベクトルです (赤、緑、青、およびアルファごとに 1 つのコンポーネント)。</p> + +<p>これですべてが終ったので、頂点バッファーを設定して形状を描画できます。まず、{{domxref("WebGLRenderingContext.bindBuffer", "bindBuffer()")}} を呼び出すことにより、形状の三角形の描画に使用される頂点のバッファーを設定します。次に、{{domxref("WebGLRenderingContext.getAttribLocation", "getAttribLocation()")}} を呼び出して、シェーダープログラムから頂点位置属性のインデックスを取得します。</p> + +<p>頂点位置属性のインデックスが <code>aVertexPosition</code> で利用可能になったので、<code>enableVertexAttribArray()</code> を呼び出して位置属性を有効にし、シェーダープログラム (特に頂点シェーダー) で使用できるようにします。</p> + +<p>次に、{{domxref("WebGLRenderingContext.vertexAttribPointer", "vertexAttribPointer()")}} を呼び出すことにより、頂点バッファーが <code>aVertexPosition</code> 属性にバインドされます。このステップはほとんど副作用であるため、このステップは明らかではありません。ただし、結果として、<code>aVertexPosition</code> にアクセスすると、頂点バッファーからデータを取得するようになります。</p> + +<p>シェイプの頂点バッファーと頂点を 1 つずつ頂点シェーダーに配信するために使用される <code>aVertexPosition</code> 属性との間に関連付けがあれば、{{domxref("WebGLRenderingContext.drawArrays", "drawArrays()")}} を呼び出してシェイプを描画する準備が整います。</p> + +<p>この時点で、フレームが描画されました。あとは、次の描画をスケジュールするだけです。ここでは {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} を呼び出して、ブラウザーが画面を更新する準備ができたときにコールバック関数を実行するように要求します。</p> + +<p><code>requestAnimationFrame()</code> コールバックは、フレーム描画が開始された時間を指定する単一のパラメーター <code>currentTime</code> を入力として受け取ります。それと、最後のフレームが描画された保存時間、<code>previousTime</code>、および正方形が回転する1秒あたりの度数 (<code>degreesPerSecond</code>) を使用して、<code>currentAngle</code> の新しい値を計算します。次に、<code>previousTime</code> の値が更新され、<code>animateScene()</code> を呼び出して次のフレームを描画します (そして、次のフレームが描画されるように無限にスケジュールします )。</p> +</div> + +<h2 id="Result" name="Result">結果</h2> + +<p>これは 1 つの単純なオブジェクトを描画しているだけの非常に単純な例ですが、ここで使用されている概念ははるかに複雑なアニメーションに拡張されます。</p> + +<p>{{EmbedLiveSample("live-sample", 660, 500)}}</p> + +<h2 id="See_also" name="See_also">参照</h2> + +<ul> + <li><a href="/ja/docs/Web/API/WebGL_API">WebGL API</a></li> + <li><a href="/ja/docs/Web/API/WebGL_API/Tutorial">WebGL チュートリアル</a></li> +</ul> diff --git a/files/ja/web/api/webgl_api/by_example/index.html b/files/ja/web/api/webgl_api/by_example/index.html new file mode 100644 index 0000000000..cc930d9284 --- /dev/null +++ b/files/ja/web/api/webgl_api/by_example/index.html @@ -0,0 +1,81 @@ +--- +title: 実例による WebGL +slug: Web/API/WebGL_API/By_example +tags: + - Beginner + - Example + - Graphics + - Learn + - WebGL +translation_of: Web/API/WebGL_API/By_example +--- +<div>{{learnsidebar}}{{IncludeSubnav("/ja/Learn")}}</div> + +<p>{{Next("Learn/WebGL/By_example/Detect_WebGL")}}</p> + +<div id="webgl-by-example"> +<div class="summary"> +<p>実例による WebGL は、WebGL の概念と機能を短く説明する一連の実例サンプルです<span class="seoSummary">。</span>実例はトピックと難易度順に従って並んでおり、WebGL レンダリングコンテキスト、シェダープログラミング、テクスチャ、ジオメトリ、ユーザーインタラクションなどを網羅しています。</p> +</div> + +<div id="webgl-by-example-big-list"> +<h2 id="Examples_by_topic" name="Examples_by_topic">トピック別の実例</h2> + +<p>実例は難易度の低い順に並んでいます。単なる長い一覧ではなく、トピックごとにさらに分割された内容になっています。最初に基本レベル、後に中級や上級レベルで話し合う必要がある時など、トピックを何度か見直す事があります。</p> + +<p>シェーダー、ジオメトリ、{{Glossary("GPU")}}メモリーを使って処理する代わりに、最初のプログラムでは実例で WebGL を少しずつ理解を深めていきます。私たちはそれがより効果的な学習体験に繋がり、最終的には概念の深い理解に繋がると信じています。</p> + +<p>実例に関する説明は本文とコード内のコメントの両方にあります。より高度な実例では、以前に説明したコードのコメントは繰り返さないため、すべてのコメントを読んでコードを理解しておく必要があります。</p> + +<div> +<h3 id="Getting_to_know_the_rendering_context" name="Getting_to_know_the_rendering_context">レンダリングコンテキストを知る</h3> + +<dl> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Detect_WebGL">WebGL を検出する</a></dt> + <dd>この例では{{Glossary("WebGL")}}レンダリングコンテキストを検出して、結果をユーザーに描画します</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Clearing_with_colors">カラーのクリア</a></dt> + <dd>単色でレンダリングコンテキストをクリアします</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Clearing_by_clicking">クリックしてクリア</a></dt> + <dd>ユーザー操作とグラフィック操作を組み合わせる方法です。ユーザーがクリックした時にレンダリングコンテキストをランダムなカラーでクリアします</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Simple_color_animation">単純なカラーアニメーション</a></dt> + <dd>基本的なカラーアニメーションで、毎秒ごとに異なったランダムなカラーで{{Glossary("WebGL")}}描画バッファをクリアする事によって行われます</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Color_masking">カラーマスキング</a></dt> + <dd>カラーマスキングを適用して、表示色の範囲を特定の色合いに制限する事によってランダムな色を修正します</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Basic_scissoring">基本的な切り取り</a></dt> + <dd>切り取り操作で単純な長方形や正方形を描きます</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Canvas_size_and_WebGL">キャンバスサイズと WebGL</a></dt> + <dd>この例ではブラウザーウィンドウに描画されるように、キャンバスサイズを{{Glossary("CSS")}}ピクセル単位の要素サイズに設定する(または設定しない)影響について理解を深めていきます</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Boilerplate_1">定型文1</a></dt> + <dd>WebGL の初期化をより簡単に行う JavaScript ユーティリティ関数の定義について説明します。このコードは繰り返しになるためこれから表示しなくなります</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Scissor_animation">切り取りアニメーション</a></dt> + <dd>切り取りやクリア操作の楽しいアニメーション</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Raining_rectangles">雨のように長方形を降らせる</a></dt> + <dd>単色のクリア、切り取り、アニメーション、ユーザーインタラクションをデモする単純なゲーム</dd> +</dl> +</div> + +<div> +<h3 id="Shader_programming_basics" name="Shader_programming_basics">シェーダープログラミングの基本</h3> + +<dl> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Hello_GLSL">Hello GLSL</a></dt> + <dd>単色の正方形を描画する基本的なシェーダープログラミング</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Hello_vertex_attributes">Hello vertex attributes</a></dt> + <dd>頂点属性によるシェーダプログラミングとユーザーインタラクションの結合</dd> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Textures_from_code">Textures from code</a></dt> + <dd>フラグメントシェーダを使用した手続き型テクスチャリングの簡単なデモ</dd> +</dl> +</div> + +<div> +<h3 id="Miscellaneous_advanced_examples" name="Miscellaneous_advanced_examples">その他、高度な実例</h3> + +<dl> + <dt><a href="/ja/docs/Learn/WebGL/By_example/Video_textures">Video textures</a></dt> + <dd>この例ではビデオファイルをテクスチャとして使用します</dd> +</dl> +</div> +</div> +</div> + +<p>{{Next("Learn/WebGL/By_example/Detect_WebGL")}}</p> diff --git a/files/ja/web/api/webgl_api/constants/index.html b/files/ja/web/api/webgl_api/constants/index.html new file mode 100644 index 0000000000..2a847fe845 --- /dev/null +++ b/files/ja/web/api/webgl_api/constants/index.html @@ -0,0 +1,3930 @@ +--- +title: WebGL の定数 +slug: Web/API/WebGL_API/Constants +translation_of: Web/API/WebGL_API/Constants +--- +<div>{{WebGLSidebar}}</div> + +<p><a href="/ja/docs/Web/API/WebGL_API">WebGL API</a> は、関数に渡されるか、または関数から返される様々な定数を提供しています。すべての定数は {{domxref("GLenum")}} 型です。</p> + +<p>標準の WebGL 定数は {{domxref("WebGLRenderingContext")}}, {{domxref("WebGL2RenderingContext")}} オブジェクトに用意されていますが、これは定数を <code>gl.CONSTANT_NAME</code> のように利用するためです:</p> + +<pre class="brush: js">var canvas = document.getElementById('myCanvas'); +var gl = canvas.getContext('webgl'); + +gl.getParameter(gl.LINE_WIDTH); +</pre> + +<p>一部の定数については、<a href="/ja/docs/Web/API/WebGL_API/Using_Extensions">WebGL 拡張機能</a>から提供されることもあります。<a href="#Constants_defined_in_WebGL_extensions">リスト</a>が以下に記載されています。</p> + +<pre class="brush: js">var debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); +var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);</pre> + +<p><a href="/ja/docs/Web/API/WebGL_API/Tutorial">WebGL チュートリアル</a>には、WebGL の入門方法に関してより多くの情報や例、リソースがあります。</p> + +<h2 id="Table_of_contents">Table of contents</h2> + +<ul> + <li><a href="#Standard_WebGL_1_constants">Standard WebGL 1 constants</a></li> + <li><a href="#Additional_constants_defined_WebGL_2">Standard WebGL 2 constants</a></li> + <li><a href="#Constants_defined_in_WebGL_extensions">WebGL extension constants</a></li> +</ul> + +<h2 id="Standard_WebGL_1_constants">Standard WebGL 1 constants</h2> + +<p>These constants are defined on the {{domxref("WebGLRenderingContext")}} interface.</p> + +<h3 id="Clearing_buffers">Clearing buffers</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.clear()")}} to clear buffer masks.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>DEPTH_BUFFER_BIT</code></td> + <td>0x00000100</td> + <td>Passed to <code>clear</code> to clear the current depth buffer.</td> + </tr> + <tr> + <td><code>STENCIL_BUFFER_BIT</code></td> + <td>0x00000400</td> + <td>Passed to <code>clear</code> to clear the current stencil buffer.</td> + </tr> + <tr> + <td><code>COLOR_BUFFER_BIT</code></td> + <td>0x00004000</td> + <td>Passed to <code>clear</code> to clear the current color buffer.</td> + </tr> + </tbody> +</table> + +<h3 id="Rendering_primitives">Rendering primitives</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.drawElements()")}} or {{domxref("WebGLRenderingContext.drawArrays()")}} to specify what kind of primitive to render.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>POINTS</code></td> + <td>0x0000</td> + <td>Passed to <code>drawElements</code> or <code>drawArrays</code> to draw single points.</td> + </tr> + <tr> + <td><code>LINES</code></td> + <td>0x0001</td> + <td>Passed to <code>drawElements</code> or <code>drawArrays</code> to draw lines. Each vertex connects to the one after it.</td> + </tr> + <tr> + <td><code>LINE_LOOP</code></td> + <td>0x0002</td> + <td>Passed to <code>drawElements</code> or <code>drawArrays</code> to draw lines. Each set of two vertices is treated as a separate line segment.</td> + </tr> + <tr> + <td><code>LINE_STRIP</code></td> + <td>0x0003</td> + <td>Passed to <code>drawElements</code> or <code>drawArrays</code> to draw a connected group of line segments from the first vertex to the last.</td> + </tr> + <tr> + <td><code>TRIANGLES</code></td> + <td>0x0004</td> + <td>Passed to <code>drawElements</code> or <code>drawArrays</code> to draw triangles. Each set of three vertices creates a separate triangle.</td> + </tr> + <tr> + <td><code>TRIANGLE_STRIP</code></td> + <td>0x0005</td> + <td>Passed to <code>drawElements</code> or <code>drawArrays</code> to draw a connected group of triangles.</td> + </tr> + <tr> + <td><code>TRIANGLE_FAN</code></td> + <td>0x0006</td> + <td>Passed to <code>drawElements</code> or <code>drawArrays</code> to draw a connected group of triangles. Each vertex connects to the previous and the first vertex in the fan.</td> + </tr> + </tbody> +</table> + +<h3 id="Blending_modes">Blending modes</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.blendFunc()")}} or {{domxref("WebGLRenderingContext.blendFuncSeparate()")}} to specify the blending mode (for both, RBG and alpha, or separately).</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>ZERO</code></td> + <td>0</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to turn off a component.</td> + </tr> + <tr> + <td><code>ONE</code></td> + <td>1</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to turn on a component.</td> + </tr> + <tr> + <td><code>SRC_COLOR</code></td> + <td>0x0300</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by the source elements color.</td> + </tr> + <tr> + <td><code>ONE_MINUS_SRC_COLOR</code></td> + <td>0x0301</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by one minus the source elements color.</td> + </tr> + <tr> + <td><code>SRC_ALPHA</code></td> + <td>0x0302</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by the source's alpha.</td> + </tr> + <tr> + <td><code>ONE_MINUS_SRC_ALPHA</code></td> + <td>0x0303</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by one minus the source's alpha.</td> + </tr> + <tr> + <td><code>DST_ALPHA</code></td> + <td>0x0304</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by the destination's alpha.</td> + </tr> + <tr> + <td><code>ONE_MINUS_DST_ALPHA</code></td> + <td>0x0305</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by one minus the destination's alpha.</td> + </tr> + <tr> + <td><code>DST_COLOR</code></td> + <td>0x0306</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by the destination's color.</td> + </tr> + <tr> + <td><code>ONE_MINUS_DST_COLOR</code></td> + <td>0x0307</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by one minus the destination's color.</td> + </tr> + <tr> + <td><code>SRC_ALPHA_SATURATE</code></td> + <td>0x0308</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to multiply a component by the minimum of source's alpha or one minus the destination's alpha.</td> + </tr> + <tr> + <td><code>CONSTANT_COLOR</code></td> + <td>0x8001</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to specify a constant color blend function.</td> + </tr> + <tr> + <td><code>ONE_MINUS_CONSTANT_COLOR</code></td> + <td>0x8002</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to specify one minus a constant color blend function.</td> + </tr> + <tr> + <td><code>CONSTANT_ALPHA</code></td> + <td>0x8003</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to specify a constant alpha blend function.</td> + </tr> + <tr> + <td><code>ONE_MINUS_CONSTANT_ALPHA</code></td> + <td>0x8004</td> + <td>Passed to <code>blendFunc</code> or <code>blendFuncSeparate</code> to specify one minus a constant alpha blend function.</td> + </tr> + </tbody> +</table> + +<h3 id="Blending_equations">Blending equations</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.blendEquation()")}} or {{domxref("WebGLRenderingContext.blendEquationSeparate()")}} to control how the blending is calculated (for both, RBG and alpha, or separately).</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>FUNC_ADD</code></td> + <td>0x8006</td> + <td>Passed to <code>blendEquation</code> or <code>blendEquationSeparate</code> to set an addition blend function.</td> + </tr> + <tr> + <td><code>FUNC_SUBTRACT</code></td> + <td>0x800A</td> + <td>Passed to <code>blendEquation</code> or <code>blendEquationSeparate</code> to specify a subtraction blend function (source - destination).</td> + </tr> + <tr> + <td><code>FUNC_REVERSE_SUBTRACT</code></td> + <td>0x800B</td> + <td>Passed to <code>blendEquation</code> or <code>blendEquationSeparate</code> to specify a reverse subtraction blend function (destination - source).</td> + </tr> + </tbody> +</table> + +<h3 id="Getting_GL_parameter_information">Getting GL parameter information</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.getParameter()")}} to specify what information to return.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>BLEND_EQUATION</code></td> + <td>0x8009</td> + <td>Passed to <code>getParameter</code> to get the current RGB blend function.</td> + </tr> + <tr> + <td><code>BLEND_EQUATION_RGB</code></td> + <td>0x8009</td> + <td>Passed to <code>getParameter</code> to get the current RGB blend function. Same as BLEND_EQUATION</td> + </tr> + <tr> + <td><code>BLEND_EQUATION_ALPHA</code></td> + <td>0x883D</td> + <td>Passed to <code>getParameter</code> to get the current alpha blend function. Same as BLEND_EQUATION</td> + </tr> + <tr> + <td><code>BLEND_DST_RGB</code></td> + <td>0x80C8</td> + <td>Passed to <code>getParameter</code> to get the current destination RGB blend function.</td> + </tr> + <tr> + <td><code>BLEND_SRC_RGB</code></td> + <td>0x80C9</td> + <td>Passed to <code>getParameter</code> to get the current destination RGB blend function.</td> + </tr> + <tr> + <td><code>BLEND_DST_ALPHA</code></td> + <td>0x80CA</td> + <td>Passed to <code>getParameter</code> to get the current destination alpha blend function.</td> + </tr> + <tr> + <td><code>BLEND_SRC_ALPHA</code></td> + <td>0x80CB</td> + <td>Passed to <code>getParameter</code> to get the current source alpha blend function.</td> + </tr> + <tr> + <td><code>BLEND_COLOR</code></td> + <td>0x8005</td> + <td>Passed to <code>getParameter</code> to return a the current blend color.</td> + </tr> + <tr> + <td><code>ARRAY_BUFFER_BINDING</code></td> + <td>0x8894</td> + <td>Passed to <code>getParameter</code> to get the array buffer binding.</td> + </tr> + <tr> + <td><code>ELEMENT_ARRAY_BUFFER_BINDING</code></td> + <td>0x8895</td> + <td>Passed to <code>getParameter</code> to get the current element array buffer.</td> + </tr> + <tr> + <td><code>LINE_WIDTH</code></td> + <td>0x0B21</td> + <td>Passed to <code>getParameter</code> to get the current <code>lineWidth</code> (set by the <code>lineWidth</code> method).</td> + </tr> + <tr> + <td><code>ALIASED_POINT_SIZE_RANGE</code></td> + <td>0x846D</td> + <td>Passed to <code>getParameter</code> to get the current size of a point drawn with <code>gl.POINTS</code></td> + </tr> + <tr> + <td><code>ALIASED_LINE_WIDTH_RANGE</code></td> + <td>0x846E</td> + <td>Passed to <code>getParameter</code> to get the range of available widths for a line. Returns a length-2 array with the lo value at 0, and hight at 1.</td> + </tr> + <tr> + <td><code>CULL_FACE_MODE</code></td> + <td>0x0B45</td> + <td>Passed to <code>getParameter</code> to get the current value of <code>cullFace</code>. Should return <code>FRONT</code>, <code>BACK</code>, or <code>FRONT_AND_BACK</code></td> + </tr> + <tr> + <td><code>FRONT_FACE</code></td> + <td>0x0B46</td> + <td>Passed to <code>getParameter</code> to determine the current value of <code>frontFace</code>. Should return <code>CW</code> or <code>CCW</code>.</td> + </tr> + <tr> + <td><code>DEPTH_RANGE</code></td> + <td>0x0B70</td> + <td>Passed to <code>getParameter</code> to return a length-2 array of floats giving the current depth range.</td> + </tr> + <tr> + <td><code>DEPTH_WRITEMASK</code></td> + <td>0x0B72</td> + <td>Passed to <code>getParameter</code> to determine if the depth write mask is enabled.</td> + </tr> + <tr> + <td><code>DEPTH_CLEAR_VALUE</code></td> + <td>0x0B73</td> + <td>Passed to <code>getParameter</code> to determine the current depth clear value.</td> + </tr> + <tr> + <td><code>DEPTH_FUNC</code></td> + <td>0x0B74</td> + <td>Passed to <code>getParameter</code> to get the current depth function. Returns <code>NEVER</code>, <code>ALWAYS</code>, <code>LESS</code>, <code>EQUAL</code>, <code>LEQUAL</code>, <code>GREATER</code>, <code>GEQUAL</code>, or <code>NOTEQUAL</code>.</td> + </tr> + <tr> + <td><code>STENCIL_CLEAR_VALUE</code></td> + <td>0x0B91</td> + <td>Passed to <code>getParameter</code> to get the value the stencil will be cleared to.</td> + </tr> + <tr> + <td><code>STENCIL_FUNC</code></td> + <td>0x0B92</td> + <td>Passed to <code>getParameter</code> to get the current stencil function. Returns <code>NEVER</code>, <code>ALWAYS</code>, <code>LESS</code>, <code>EQUAL</code>, <code>LEQUAL</code>, <code>GREATER</code>, <code>GEQUAL</code>, or <code>NOTEQUAL</code>.</td> + </tr> + <tr> + <td><code>STENCIL_FAIL</code></td> + <td>0x0B94</td> + <td>Passed to <code>getParameter</code> to get the current stencil fail function. Should return <code>KEEP</code>, <code>REPLACE</code>, <code>INCR</code>, <code>DECR</code>, <code>INVERT</code>, <code>INCR_WRAP</code>, or <code>DECR_WRAP</code>.</td> + </tr> + <tr> + <td><code>STENCIL_PASS_DEPTH_FAIL</code></td> + <td>0x0B95</td> + <td>Passed to <code>getParameter</code> to get the current stencil fail function should the depth buffer test fail. Should return <code>KEEP</code>, <code>REPLACE</code>, <code>INCR</code>, <code>DECR</code>, <code>INVERT</code>, <code>INCR_WRAP</code>, or <code>DECR_WRAP</code>.</td> + </tr> + <tr> + <td><code>STENCIL_PASS_DEPTH_PASS</code></td> + <td>0x0B96</td> + <td>Passed to <code>getParameter</code> to get the current stencil fail function should the depth buffer test pass. Should return KEEP, REPLACE, INCR, DECR, INVERT, INCR_WRAP, or DECR_WRAP.</td> + </tr> + <tr> + <td><code>STENCIL_REF</code></td> + <td>0x0B97</td> + <td>Passed to <code>getParameter</code> to get the reference value used for stencil tests.</td> + </tr> + <tr> + <td><code>STENCIL_VALUE_MASK</code></td> + <td>0x0B93</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_WRITEMASK</code></td> + <td>0x0B98</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_BACK_FUNC</code></td> + <td>0x8800</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_BACK_FAIL</code></td> + <td>0x8801</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_BACK_PASS_DEPTH_FAIL</code></td> + <td>0x8802</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_BACK_PASS_DEPTH_PASS</code></td> + <td>0x8803</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_BACK_REF</code></td> + <td>0x8CA3</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_BACK_VALUE_MASK</code></td> + <td>0x8CA4</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_BACK_WRITEMASK</code></td> + <td>0x8CA5</td> + <td></td> + </tr> + <tr> + <td><code>VIEWPORT</code></td> + <td>0x0BA2</td> + <td>Returns an {{jsxref("Int32Array")}} with four elements for the current viewport dimensions.</td> + </tr> + <tr> + <td><code>SCISSOR_BOX</code></td> + <td>0x0C10</td> + <td>Returns an {{jsxref("Int32Array")}} with four elements for the current scissor box dimensions.</td> + </tr> + <tr> + <td><code>COLOR_CLEAR_VALUE</code></td> + <td>0x0C22</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_WRITEMASK</code></td> + <td>0x0C23</td> + <td></td> + </tr> + <tr> + <td><code>UNPACK_ALIGNMENT</code></td> + <td>0x0CF5</td> + <td></td> + </tr> + <tr> + <td><code>PACK_ALIGNMENT</code></td> + <td>0x0D05</td> + <td></td> + </tr> + <tr> + <td><code>MAX_TEXTURE_SIZE</code></td> + <td>0x0D33</td> + <td></td> + </tr> + <tr> + <td><code>MAX_VIEWPORT_DIMS</code></td> + <td>0x0D3A</td> + <td></td> + </tr> + <tr> + <td><code>SUBPIXEL_BITS</code></td> + <td>0x0D50</td> + <td></td> + </tr> + <tr> + <td><code>RED_BITS</code></td> + <td>0x0D52</td> + <td></td> + </tr> + <tr> + <td><code>GREEN_BITS</code></td> + <td>0x0D53</td> + <td></td> + </tr> + <tr> + <td><code>BLUE_BITS</code></td> + <td>0x0D54</td> + <td></td> + </tr> + <tr> + <td><code>ALPHA_BITS</code></td> + <td>0x0D55</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_BITS</code></td> + <td>0x0D56</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_BITS</code></td> + <td>0x0D57</td> + <td></td> + </tr> + <tr> + <td><code>POLYGON_OFFSET_UNITS</code></td> + <td>0x2A00</td> + <td></td> + </tr> + <tr> + <td><code>POLYGON_OFFSET_FACTOR</code></td> + <td>0x8038</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_BINDING_2D</code></td> + <td>0x8069</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLE_BUFFERS</code></td> + <td>0x80A8</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLES</code></td> + <td>0x80A9</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLE_COVERAGE_VALUE</code></td> + <td>0x80AA</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLE_COVERAGE_INVERT</code></td> + <td>0x80AB</td> + <td></td> + </tr> + <tr> + <td><code>COMPRESSED_TEXTURE_FORMATS</code></td> + <td>0x86A3</td> + <td></td> + </tr> + <tr> + <td><code>VENDOR</code></td> + <td>0x1F00</td> + <td></td> + </tr> + <tr> + <td><code>RENDERER</code></td> + <td>0x1F01</td> + <td></td> + </tr> + <tr> + <td><code>VERSION</code></td> + <td>0x1F02</td> + <td></td> + </tr> + <tr> + <td><code>IMPLEMENTATION_COLOR_READ_TYPE</code></td> + <td>0x8B9A</td> + <td></td> + </tr> + <tr> + <td><code>IMPLEMENTATION_COLOR_READ_FORMAT</code></td> + <td>0x8B9B</td> + <td></td> + </tr> + <tr> + <td><code>BROWSER_DEFAULT_WEBGL</code></td> + <td>0x9244</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Buffers">Buffers</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.bufferData()")}}, {{domxref("WebGLRenderingContext.bufferSubData()")}}, {{domxref("WebGLRenderingContext.bindBuffer()")}}, or {{domxref("WebGLRenderingContext.getBufferParameter()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>STATIC_DRAW</code></td> + <td>0x88E4</td> + <td>Passed to <code>bufferData</code> as a hint about whether the contents of the buffer are likely to be used often and not change often.</td> + </tr> + <tr> + <td><code>STREAM_DRAW</code></td> + <td>0x88E0</td> + <td>Passed to <code>bufferData</code> as a hint about whether the contents of the buffer are likely to not be used often.</td> + </tr> + <tr> + <td><code>DYNAMIC_DRAW</code></td> + <td>0x88E8</td> + <td>Passed to <code>bufferData</code> as a hint about whether the contents of the buffer are likely to be used often and change often.</td> + </tr> + <tr> + <td><code>ARRAY_BUFFER</code></td> + <td>0x8892</td> + <td>Passed to <code>bindBuffer</code> or <code>bufferData</code> to specify the type of buffer being used.</td> + </tr> + <tr> + <td><code>ELEMENT_ARRAY_BUFFER</code></td> + <td>0x8893</td> + <td>Passed to <code>bindBuffer</code> or <code>bufferData</code> to specify the type of buffer being used.</td> + </tr> + <tr> + <td><code>BUFFER_SIZE</code></td> + <td>0x8764</td> + <td>Passed to <code>getBufferParameter</code> to get a buffer's size.</td> + </tr> + <tr> + <td><code>BUFFER_USAGE</code></td> + <td>0x8765</td> + <td>Passed to <code>getBufferParameter</code> to get the hint for the buffer passed in when it was created.</td> + </tr> + </tbody> +</table> + +<h3 id="Vertex_attributes">Vertex attributes</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.getVertexAttrib()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>CURRENT_VERTEX_ATTRIB</code></td> + <td>0x8626</td> + <td>Passed to <code>getVertexAttrib</code> to read back the current vertex attribute.</td> + </tr> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_ENABLED</code></td> + <td>0x8622</td> + <td></td> + </tr> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_SIZE</code></td> + <td>0x8623</td> + <td></td> + </tr> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_STRIDE</code></td> + <td>0x8624</td> + <td></td> + </tr> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_TYPE</code></td> + <td>0x8625</td> + <td></td> + </tr> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_NORMALIZED</code></td> + <td>0x886A</td> + <td></td> + </tr> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_POINTER</code></td> + <td>0x8645</td> + <td></td> + </tr> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_BUFFER_BINDING</code></td> + <td>0x889F</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Culling">Culling</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.cullFace()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>CULL_FACE</code></td> + <td>0x0B44</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off culling. Can also be used with <code>getParameter</code> to find the current culling method.</td> + </tr> + <tr> + <td><code>FRONT</code></td> + <td>0x0404</td> + <td>Passed to <code>cullFace</code> to specify that only front faces should be culled.</td> + </tr> + <tr> + <td><code>BACK</code></td> + <td>0x0405</td> + <td>Passed to <code>cullFace</code> to specify that only back faces should be culled.</td> + </tr> + <tr> + <td><code>FRONT_AND_BACK</code></td> + <td>0x0408</td> + <td>Passed to <code>cullFace</code> to specify that front and back faces should be culled.</td> + </tr> + </tbody> +</table> + +<h3 id="有効化と無効化">有効化と無効化</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.enable()")}} or {{domxref("WebGLRenderingContext.disable()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>BLEND</code></td> + <td>0x0BE2</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off blending. Can also be used with <code>getParameter</code> to find the current blending method.</td> + </tr> + <tr> + <td><code>DEPTH_TEST</code></td> + <td>0x0B71</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off the depth test. Can also be used with <code>getParameter</code> to query the depth test.</td> + </tr> + <tr> + <td><code>DITHER</code></td> + <td>0x0BD0</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off dithering. Can also be used with <code>getParameter</code> to find the current dithering method.</td> + </tr> + <tr> + <td><code>POLYGON_OFFSET_FILL</code></td> + <td>0x8037</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off the polygon offset. Useful for rendering hidden-line images, decals, and or solids with highlighted edges. Can also be used with <code>getParameter</code> to query the scissor test.</td> + </tr> + <tr> + <td><code>SAMPLE_ALPHA_TO_COVERAGE</code></td> + <td>0x809E</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off the alpha to coverage. Used in multi-sampling alpha channels.</td> + </tr> + <tr> + <td><code>SAMPLE_COVERAGE</code></td> + <td>0x80A0</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off the sample coverage. Used in multi-sampling.</td> + </tr> + <tr> + <td><code>SCISSOR_TEST</code></td> + <td>0x0C11</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off the scissor test. Can also be used with <code>getParameter</code> to query the scissor test.</td> + </tr> + <tr> + <td><code>STENCIL_TEST</code></td> + <td>0x0B90</td> + <td>Passed to <code>enable</code>/<code>disable</code> to turn on/off the stencil test. Can also be used with <code>getParameter</code> to query the stencil test.</td> + </tr> + <tr> + </tr> + </tbody> +</table> + +<h3 id="エラー">エラー</h3> + +<p>Constants returned from {{domxref("WebGLRenderingContext.getError()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>NO_ERROR</code></td> + <td>0</td> + <td>Returned from <code>getError</code>.</td> + </tr> + <tr> + <td><code>INVALID_ENUM</code></td> + <td>0x0500</td> + <td>Returned from <code>getError</code>.</td> + </tr> + <tr> + <td><code>INVALID_VALUE</code></td> + <td>0x0501</td> + <td>Returned from <code>getError</code>.</td> + </tr> + <tr> + <td><code>INVALID_OPERATION</code></td> + <td>0x0502</td> + <td>Returned from <code>getError</code>.</td> + </tr> + <tr> + <td><code>OUT_OF_MEMORY</code></td> + <td>0x0505</td> + <td>Returned from <code>getError</code>.</td> + </tr> + <tr> + <td><code>CONTEXT_LOST_WEBGL</code></td> + <td>0x9242</td> + <td>Returned from <code>getError</code>.</td> + </tr> + </tbody> +</table> + +<h3 id="Front_face_directions">Front face directions</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.frontFace()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>CW</code></td> + <td>0x0900</td> + <td>Passed to <code>frontFace</code> to specify the front face of a polygon is drawn in the clockwise direction</td> + </tr> + <tr> + <td><code>CCW</code></td> + <td>0x0901</td> + <td>Passed to <code>frontFace</code> to specify the front face of a polygon is drawn in the counter clockwise direction</td> + </tr> + </tbody> +</table> + +<h3 id="Hints">Hints</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.hint()")}}</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>DONT_CARE</code></td> + <td>0x1100</td> + <td>There is no preference for this behavior.</td> + </tr> + <tr> + <td><code>FASTEST</code></td> + <td>0x1101</td> + <td>The most efficient behavior should be used.</td> + </tr> + <tr> + <td><code>NICEST</code></td> + <td>0x1102</td> + <td>The most correct or the highest quality option should be used.</td> + </tr> + <tr> + <td><code>GENERATE_MIPMAP_HINT</code></td> + <td>0x8192</td> + <td>Hint for the quality of filtering when generating mipmap images with {{domxref("WebGLRenderingContext.generateMipmap()")}}.</td> + </tr> + </tbody> +</table> + +<h3 id="データ型">データ型</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>BYTE</code></td> + <td>0x1400</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_BYTE</code></td> + <td>0x1401</td> + <td></td> + </tr> + <tr> + <td><code>SHORT</code></td> + <td>0x1402</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_SHORT</code></td> + <td>0x1403</td> + <td></td> + </tr> + <tr> + <td><code>INT</code></td> + <td>0x1404</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT</code></td> + <td>0x1405</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT</code></td> + <td>0x1406</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Pixel_formats">Pixel formats</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>DEPTH_COMPONENT</code></td> + <td>0x1902</td> + <td></td> + </tr> + <tr> + <td><code>ALPHA</code></td> + <td>0x1906</td> + <td></td> + </tr> + <tr> + <td><code>RGB</code></td> + <td>0x1907</td> + <td></td> + </tr> + <tr> + <td><code>RGBA</code></td> + <td>0x1908</td> + <td></td> + </tr> + <tr> + <td><code>LUMINANCE</code></td> + <td>0x1909</td> + <td></td> + </tr> + <tr> + <td><code>LUMINANCE_ALPHA</code></td> + <td>0x190A</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Pixel_types">Pixel types</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>UNSIGNED_BYTE</code></td> + <td>0x1401</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_SHORT_4_4_4_4</code></td> + <td>0x8033</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_SHORT_5_5_5_1</code></td> + <td>0x8034</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_SHORT_5_6_5</code></td> + <td>0x8363</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="シェーダー">シェーダー</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.createShader()")}} or {{domxref("WebGLRenderingContext.getShaderParameter()")}}</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>FRAGMENT_SHADER</code></td> + <td>0x8B30</td> + <td>Passed to <code>createShader</code> to define a fragment shader.</td> + </tr> + <tr> + <td><code>VERTEX_SHADER</code></td> + <td>0x8B31</td> + <td>Passed to <code>createShader</code> to define a vertex shader</td> + </tr> + <tr> + <td><code>COMPILE_STATUS</code></td> + <td>0x8B81</td> + <td>コンパイルの状態を取得するために <code>getShaderParamter</code> に渡されます。シェーダーがコンパイルされなかった場合、false が返ります。その場合は <code>getShaderInfoLog</code> に問い合わせて正確なエラーを見つけられます。</td> + </tr> + <tr> + <td><code>DELETE_STATUS</code></td> + <td>0x8B80</td> + <td>Passed to <code>getShaderParamter</code> to determine if a shader was deleted via <code>deleteShader</code>. Returns true if it was, false otherwise.</td> + </tr> + <tr> + <td><code>LINK_STATUS</code></td> + <td>0x8B82</td> + <td>Passed to <code>getProgramParameter</code> after calling <code>linkProgram</code> to determine if a program was linked correctly. Returns false if there were errors. Use <code>getProgramInfoLog</code> to find the exact error.</td> + </tr> + <tr> + <td><code>VALIDATE_STATUS</code></td> + <td>0x8B83</td> + <td>Passed to <code>getProgramParameter</code> after calling <code>validateProgram</code> to determine if it is valid. Returns false if errors were found.</td> + </tr> + <tr> + <td><code>ATTACHED_SHADERS</code></td> + <td>0x8B85</td> + <td>Passed to <code>getProgramParameter</code> after calling <code>attachShader</code> to determine if the shader was attached correctly. Returns false if errors occurred.</td> + </tr> + <tr> + <td><code>ACTIVE_ATTRIBUTES</code></td> + <td>0x8B89</td> + <td>Passed to <code>getProgramParameter</code> to get the number of attributes active in a program.</td> + </tr> + <tr> + <td><code>ACTIVE_UNIFORMS</code></td> + <td>0x8B86</td> + <td>Passed to <code>getProgramParamter</code> to get the number of uniforms active in a program.</td> + </tr> + <tr> + <td><code>MAX_VERTEX_ATTRIBS</code></td> + <td>0x8869</td> + <td>The maximum number of entries possible in the vertex attribute list.</td> + </tr> + <tr> + <td><code>MAX_VERTEX_UNIFORM_VECTORS</code></td> + <td>0x8DFB</td> + <td></td> + </tr> + <tr> + <td><code>MAX_VARYING_VECTORS</code></td> + <td>0x8DFC</td> + <td></td> + </tr> + <tr> + <td><code>MAX_COMBINED_TEXTURE_IMAGE_UNITS</code></td> + <td>0x8B4D</td> + <td></td> + </tr> + <tr> + <td><code>MAX_VERTEX_TEXTURE_IMAGE_UNITS</code></td> + <td>0x8B4C</td> + <td></td> + </tr> + <tr> + <td><code>MAX_TEXTURE_IMAGE_UNITS</code></td> + <td>0x8872</td> + <td>Implementation dependent number of maximum texture units. At least 8.</td> + </tr> + <tr> + <td><code>MAX_FRAGMENT_UNIFORM_VECTORS</code></td> + <td>0x8DFD</td> + <td></td> + </tr> + <tr> + <td><code>SHADER_TYPE</code></td> + <td>0x8B4F</td> + <td></td> + </tr> + <tr> + <td><code>SHADING_LANGUAGE_VERSION</code></td> + <td>0x8B8C</td> + <td></td> + </tr> + <tr> + <td><code>CURRENT_PROGRAM</code></td> + <td>0x8B8D</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Depth_or_stencil_tests">Depth or stencil tests</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.depthFunc()")}} or {{domxref("WebGLRenderingContext.stencilFunc()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>NEVER</code></td> + <td>0x0200</td> + <td>Passed to <code>depthFunction</code> or <code>stencilFunction</code> to specify depth or stencil tests will never pass. i.e. Nothing will be drawn.</td> + </tr> + <tr> + <td><code>LESS</code></td> + <td>0x0201</td> + <td>Passed to <code>depthFunction</code> or <code>stencilFunction</code> to specify depth or stencil tests will pass if the new depth value is less than the stored value.</td> + </tr> + <tr> + <td><code>EQUAL</code></td> + <td>0x0202</td> + <td>Passed to <code>depthFunction</code> or <code>stencilFunction</code> to specify depth or stencil tests will pass if the new depth value is equals to the stored value.</td> + </tr> + <tr> + <td><code>LEQUAL</code></td> + <td>0x0203</td> + <td>Passed to <code>depthFunction</code> or <code>stencilFunction</code> to specify depth or stencil tests will pass if the new depth value is less than or equal to the stored value.</td> + </tr> + <tr> + <td><code>GREATER</code></td> + <td>0x0204</td> + <td>Passed to <code>depthFunction</code> or <code>stencilFunction</code> to specify depth or stencil tests will pass if the new depth value is greater than the stored value.</td> + </tr> + <tr> + <td><code>NOTEQUAL</code></td> + <td>0x0205</td> + <td>Passed to <code>depthFunction</code> or <code>stencilFunction</code> to specify depth or stencil tests will pass if the new depth value is not equal to the stored value.</td> + </tr> + <tr> + <td><code>GEQUAL</code></td> + <td>0x0206</td> + <td>Passed to <code>depthFunction</code> or <code>stencilFunction</code> to specify depth or stencil tests will pass if the new depth value is greater than or equal to the stored value.</td> + </tr> + <tr> + <td><code>ALWAYS</code></td> + <td>0x0207</td> + <td>Passed to <code>depthFunction</code> or <code>stencilFunction</code> to specify depth or stencil tests will always pass. i.e. Pixels will be drawn in the order they are drawn.</td> + </tr> + </tbody> +</table> + +<h3 id="Stencil_actions">Stencil actions</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.stencilOp()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>KEEP</code></td> + <td>0x1E00</td> + <td></td> + </tr> + <tr> + <td><code>REPLACE</code></td> + <td>0x1E01</td> + <td></td> + </tr> + <tr> + <td><code>INCR</code></td> + <td>0x1E02</td> + <td></td> + </tr> + <tr> + <td><code>DECR</code></td> + <td>0x1E03</td> + <td></td> + </tr> + <tr> + <td><code>INVERT</code></td> + <td>0x150A</td> + <td></td> + </tr> + <tr> + <td><code>INCR_WRAP</code></td> + <td>0x8507</td> + <td></td> + </tr> + <tr> + <td><code>DECR_WRAP</code></td> + <td>0x8508</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Textures">Textures</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.texParameteri()")}}, {{domxref("WebGLRenderingContext.texParameterf()")}}, {{domxref("WebGLRenderingContext.bindTexture()")}}, {{domxref("WebGLRenderingContext.texImage2D()")}}, and others.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>NEAREST</code></td> + <td>0x2600</td> + <td></td> + </tr> + <tr> + <td><code>LINEAR</code></td> + <td>0x2601</td> + <td></td> + </tr> + <tr> + <td><code>NEAREST_MIPMAP_NEAREST</code></td> + <td>0x2700</td> + <td></td> + </tr> + <tr> + <td><code>LINEAR_MIPMAP_NEAREST</code></td> + <td>0x2701</td> + <td></td> + </tr> + <tr> + <td><code>NEAREST_MIPMAP_LINEAR</code></td> + <td>0x2702</td> + <td></td> + </tr> + <tr> + <td><code>LINEAR_MIPMAP_LINEAR</code></td> + <td>0x2703</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_MAG_FILTER</code></td> + <td>0x2800</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_MIN_FILTER</code></td> + <td>0x2801</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_WRAP_S</code></td> + <td>0x2802</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_WRAP_T</code></td> + <td>0x2803</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_2D</code></td> + <td>0x0DE1</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE</code></td> + <td>0x1702</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_CUBE_MAP</code></td> + <td>0x8513</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_BINDING_CUBE_MAP</code></td> + <td>0x8514</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_CUBE_MAP_POSITIVE_X</code></td> + <td>0x8515</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_CUBE_MAP_NEGATIVE_X</code></td> + <td>0x8516</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_CUBE_MAP_POSITIVE_Y</code></td> + <td>0x8517</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_CUBE_MAP_NEGATIVE_Y</code></td> + <td>0x8518</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_CUBE_MAP_POSITIVE_Z</code></td> + <td>0x8519</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_CUBE_MAP_NEGATIVE_Z</code></td> + <td>0x851A</td> + <td></td> + </tr> + <tr> + <td><code>MAX_CUBE_MAP_TEXTURE_SIZE</code></td> + <td>0x851C</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE0 - 31</code></td> + <td>0x84C0 - 0x84DF</td> + <td>A texture unit.</td> + </tr> + <tr> + <td><code>ACTIVE_TEXTURE</code></td> + <td>0x84E0</td> + <td>The current active texture unit.</td> + </tr> + <tr> + <td><code>REPEAT</code></td> + <td>0x2901</td> + <td></td> + </tr> + <tr> + <td><code>CLAMP_TO_EDGE</code></td> + <td>0x812F</td> + <td></td> + </tr> + <tr> + <td><code>MIRRORED_REPEAT</code></td> + <td>0x8370</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Uniform_types">Uniform types</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>FLOAT_VEC2</code></td> + <td>0x8B50</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_VEC3</code></td> + <td>0x8B51</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_VEC4</code></td> + <td>0x8B52</td> + <td></td> + </tr> + <tr> + <td><code>INT_VEC2</code></td> + <td>0x8B53</td> + <td></td> + </tr> + <tr> + <td><code>INT_VEC3</code></td> + <td>0x8B54</td> + <td></td> + </tr> + <tr> + <td><code>INT_VEC4</code></td> + <td>0x8B55</td> + <td></td> + </tr> + <tr> + <td><code>BOOL</code></td> + <td>0x8B56</td> + <td></td> + </tr> + <tr> + <td><code>BOOL_VEC2</code></td> + <td>0x8B57</td> + <td></td> + </tr> + <tr> + <td><code>BOOL_VEC3</code></td> + <td>0x8B58</td> + <td></td> + </tr> + <tr> + <td><code>BOOL_VEC4</code></td> + <td>0x8B59</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_MAT2</code></td> + <td>0x8B5A</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_MAT3</code></td> + <td>0x8B5B</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_MAT4</code></td> + <td>0x8B5C</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLER_2D</code></td> + <td>0x8B5E</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLER_CUBE</code></td> + <td>0x8B60</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Shader_precision-specified_types">Shader precision-specified types</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>LOW_FLOAT</code></td> + <td>0x8DF0</td> + <td></td> + </tr> + <tr> + <td><code>MEDIUM_FLOAT</code></td> + <td>0x8DF1</td> + <td></td> + </tr> + <tr> + <td><code>HIGH_FLOAT</code></td> + <td>0x8DF2</td> + <td></td> + </tr> + <tr> + <td><code>LOW_INT</code></td> + <td>0x8DF3</td> + <td></td> + </tr> + <tr> + <td><code>MEDIUM_INT</code></td> + <td>0x8DF4</td> + <td></td> + </tr> + <tr> + <td><code>HIGH_INT</code></td> + <td>0x8DF5</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Framebuffers_and_renderbuffers">Framebuffers and renderbuffers</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>FRAMEBUFFER</code></td> + <td>0x8D40</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER</code></td> + <td>0x8D41</td> + <td></td> + </tr> + <tr> + <td><code>RGBA4</code></td> + <td>0x8056</td> + <td></td> + </tr> + <tr> + <td><code>RGB5_A1</code></td> + <td>0x8057</td> + <td></td> + </tr> + <tr> + <td><code>RGB565</code></td> + <td>0x8D62</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_COMPONENT16</code></td> + <td>0x81A5</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_INDEX8</code></td> + <td>0x8D48</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_STENCIL</code></td> + <td>0x84F9</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_WIDTH</code></td> + <td>0x8D42</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_HEIGHT</code></td> + <td>0x8D43</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_INTERNAL_FORMAT</code></td> + <td>0x8D44</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_RED_SIZE</code></td> + <td>0x8D50</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_GREEN_SIZE</code></td> + <td>0x8D51</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_BLUE_SIZE</code></td> + <td>0x8D52</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_ALPHA_SIZE</code></td> + <td>0x8D53</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_DEPTH_SIZE</code></td> + <td>0x8D54</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_STENCIL_SIZE</code></td> + <td>0x8D55</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE</code></td> + <td>0x8CD0</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_OBJECT_NAME</code></td> + <td>0x8CD1</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL</code></td> + <td>0x8CD2</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE</code></td> + <td>0x8CD3</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT0</code></td> + <td>0x8CE0</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_ATTACHMENT</code></td> + <td>0x8D00</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL_ATTACHMENT</code></td> + <td>0x8D20</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_STENCIL_ATTACHMENT</code></td> + <td>0x821A</td> + <td></td> + </tr> + <tr> + <td><code>NONE</code></td> + <td>0</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_COMPLETE</code></td> + <td>0x8CD5</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_INCOMPLETE_ATTACHMENT</code></td> + <td>0x8CD6</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT</code></td> + <td>0x8CD7</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_INCOMPLETE_DIMENSIONS</code></td> + <td>0x8CD9</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_UNSUPPORTED</code></td> + <td>0x8CDD</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_BINDING</code></td> + <td>0x8CA6</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_BINDING</code></td> + <td>0x8CA7</td> + <td></td> + </tr> + <tr> + <td><code>MAX_RENDERBUFFER_SIZE</code></td> + <td>0x84E8</td> + <td></td> + </tr> + <tr> + <td><code>INVALID_FRAMEBUFFER_OPERATION</code></td> + <td>0x0506</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Pixel_storage_modes">Pixel storage modes</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.pixelStorei()")}}.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>UNPACK_FLIP_Y_WEBGL</code></td> + <td>0x9240</td> + <td></td> + </tr> + <tr> + <td><code>UNPACK_PREMULTIPLY_ALPHA_WEBGL</code></td> + <td>0x9241</td> + <td></td> + </tr> + <tr> + <td><code>UNPACK_COLORSPACE_CONVERSION_WEBGL</code></td> + <td>0x9243</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Additional_constants_defined_WebGL_2">Additional constants defined WebGL 2</h2> + +<p>These constants are defined on the {{domxref("WebGL2RenderingContext")}} interface. All WebGL 1 constants are also available in a WebGL 2 context.</p> + +<h3 id="Getting_GL_parameter_information_2">Getting GL parameter information</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.getParameter()")}} to specify what information to return.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>READ_BUFFER</code></td> + <td>0x0C02</td> + <td></td> + </tr> + <tr> + <td><code>UNPACK_ROW_LENGTH</code></td> + <td>0x0CF2</td> + <td></td> + </tr> + <tr> + <td><code>UNPACK_SKIP_ROWS</code></td> + <td>0x0CF3</td> + <td></td> + </tr> + <tr> + <td><code>UNPACK_SKIP_PIXELS</code></td> + <td>0x0CF4</td> + <td></td> + </tr> + <tr> + <td><code>PACK_ROW_LENGTH</code></td> + <td>0x0D02</td> + <td></td> + </tr> + <tr> + <td><code>PACK_SKIP_ROWS</code></td> + <td>0x0D03</td> + <td></td> + </tr> + <tr> + <td><code>PACK_SKIP_PIXELS</code></td> + <td>0x0D04</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_BINDING_3D</code></td> + <td>0x806A</td> + <td></td> + </tr> + <tr> + <td><code>UNPACK_SKIP_IMAGES</code></td> + <td>0x806D</td> + <td></td> + </tr> + <tr> + <td><code>UNPACK_IMAGE_HEIGHT</code></td> + <td>0x806E</td> + <td></td> + </tr> + <tr> + <td><code>MAX_3D_TEXTURE_SIZE</code></td> + <td>0x8073</td> + <td></td> + </tr> + <tr> + <td><code>MAX_ELEMENTS_VERTICES</code></td> + <td>0x80E8</td> + <td></td> + </tr> + <tr> + <td><code>MAX_ELEMENTS_INDICES</code></td> + <td>0x80E9</td> + <td></td> + </tr> + <tr> + <td><code>MAX_TEXTURE_LOD_BIAS</code></td> + <td>0x84FD</td> + <td></td> + </tr> + <tr> + <td><code>MAX_FRAGMENT_UNIFORM_COMPONENTS</code></td> + <td>0x8B49</td> + <td></td> + </tr> + <tr> + <td><code>MAX_VERTEX_UNIFORM_COMPONENTS</code></td> + <td>0x8B4A</td> + <td></td> + </tr> + <tr> + <td><code>MAX_ARRAY_TEXTURE_LAYERS</code></td> + <td>0x88FF</td> + <td></td> + </tr> + <tr> + <td><code>MIN_PROGRAM_TEXEL_OFFSET</code></td> + <td>0x8904</td> + <td></td> + </tr> + <tr> + <td><code>MAX_PROGRAM_TEXEL_OFFSET</code></td> + <td>0x8905</td> + <td></td> + </tr> + <tr> + <td><code>MAX_VARYING_COMPONENTS</code></td> + <td>0x8B4B</td> + <td></td> + </tr> + <tr> + <td><code>FRAGMENT_SHADER_DERIVATIVE_HINT</code></td> + <td>0x8B8B</td> + <td></td> + </tr> + <tr> + <td><code>RASTERIZER_DISCARD</code></td> + <td>0x8C89</td> + <td></td> + </tr> + <tr> + <td><code>VERTEX_ARRAY_BINDING</code></td> + <td>0x85B5</td> + <td></td> + </tr> + <tr> + <td><code>MAX_VERTEX_OUTPUT_COMPONENTS</code></td> + <td>0x9122</td> + <td></td> + </tr> + <tr> + <td><code>MAX_FRAGMENT_INPUT_COMPONENTS</code></td> + <td>0x9125</td> + <td></td> + </tr> + <tr> + <td><code>MAX_SERVER_WAIT_TIMEOUT</code></td> + <td>0x9111</td> + <td></td> + </tr> + <tr> + <td><code>MAX_ELEMENT_INDEX</code></td> + <td>0x8D6B</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Textures_2">Textures</h3> + +<p>Constants passed to {{domxref("WebGLRenderingContext.texParameteri()")}}, {{domxref("WebGLRenderingContext.texParameterf()")}}, {{domxref("WebGLRenderingContext.bindTexture()")}}, {{domxref("WebGLRenderingContext.texImage2D()")}}, and others.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>RED</code></td> + <td>0x1903</td> + <td></td> + </tr> + <tr> + <td><code>RGB8</code></td> + <td>0x8051</td> + <td></td> + </tr> + <tr> + <td><code>RGBA8</code></td> + <td>0x8058</td> + <td></td> + </tr> + <tr> + <td><code>RGB10_A2</code></td> + <td>0x8059</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_3D</code></td> + <td>0x806F</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_WRAP_R</code></td> + <td>0x8072</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_MIN_LOD</code></td> + <td>0x813A</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_MAX_LOD</code></td> + <td>0x813B</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_BASE_LEVEL</code></td> + <td>0x813C</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_MAX_LEVEL</code></td> + <td>0x813D</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_COMPARE_MODE</code></td> + <td>0x884C</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_COMPARE_FUNC</code></td> + <td>0x884D</td> + <td></td> + </tr> + <tr> + <td><code>SRGB</code></td> + <td>0x8C40</td> + <td></td> + </tr> + <tr> + <td><code>SRGB8</code></td> + <td>0x8C41</td> + <td></td> + </tr> + <tr> + <td><code>SRGB8_ALPHA8</code></td> + <td>0x8C43</td> + <td></td> + </tr> + <tr> + <td><code>COMPARE_REF_TO_TEXTURE</code></td> + <td>0x884E</td> + <td></td> + </tr> + <tr> + <td><code>RGBA32F</code></td> + <td>0x8814</td> + <td></td> + </tr> + <tr> + <td><code>RGB32F</code></td> + <td>0x8815</td> + <td></td> + </tr> + <tr> + <td><code>RGBA16F</code></td> + <td>0x881A</td> + <td></td> + </tr> + <tr> + <td><code>RGB16F</code></td> + <td>0x881B</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_2D_ARRAY</code></td> + <td>0x8C1A</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_BINDING_2D_ARRAY</code></td> + <td>0x8C1D</td> + <td></td> + </tr> + <tr> + <td><code>R11F_G11F_B10F</code></td> + <td>0x8C3A</td> + <td></td> + </tr> + <tr> + <td><code>RGB9_E5</code></td> + <td>0x8C3D</td> + <td></td> + </tr> + <tr> + <td><code>RGBA32UI</code></td> + <td>0x8D70</td> + <td></td> + </tr> + <tr> + <td><code>RGB32UI</code></td> + <td>0x8D71</td> + <td></td> + </tr> + <tr> + <td><code>RGBA16UI</code></td> + <td>0x8D76</td> + <td></td> + </tr> + <tr> + <td><code>RGB16UI</code></td> + <td>0x8D77</td> + <td></td> + </tr> + <tr> + <td><code>RGBA8UI</code></td> + <td>0x8D7C</td> + <td></td> + </tr> + <tr> + <td><code>RGB8UI</code></td> + <td>0x8D7D</td> + <td></td> + </tr> + <tr> + <td><code>RGBA32I</code></td> + <td>0x8D82</td> + <td></td> + </tr> + <tr> + <td><code>RGB32I</code></td> + <td>0x8D83</td> + <td></td> + </tr> + <tr> + <td><code>RGBA16I</code></td> + <td>0x8D88</td> + <td></td> + </tr> + <tr> + <td><code>RGB16I</code></td> + <td>0x8D89</td> + <td></td> + </tr> + <tr> + <td><code>RGBA8I</code></td> + <td>0x8D8E</td> + <td></td> + </tr> + <tr> + <td><code>RGB8I</code></td> + <td>0x8D8F</td> + <td></td> + </tr> + <tr> + <td><code>RED_INTEGER</code></td> + <td>0x8D94</td> + <td></td> + </tr> + <tr> + <td><code>RGB_INTEGER</code></td> + <td>0x8D98</td> + <td></td> + </tr> + <tr> + <td><code>RGBA_INTEGER</code></td> + <td>0x8D99</td> + <td></td> + </tr> + <tr> + <td><code>R8</code></td> + <td>0x8229</td> + <td></td> + </tr> + <tr> + <td><code>RG8</code></td> + <td>0x822B</td> + <td></td> + </tr> + <tr> + <td>R16F</td> + <td>0x822D</td> + <td></td> + </tr> + <tr> + <td>R32F</td> + <td>0x822E</td> + <td></td> + </tr> + <tr> + <td>RG16F</td> + <td>0x822F</td> + <td></td> + </tr> + <tr> + <td>RG32F</td> + <td>0x8230</td> + <td></td> + </tr> + <tr> + <td>R8I</td> + <td>0x8231</td> + <td></td> + </tr> + <tr> + <td>R8UI</td> + <td>0x8232</td> + <td></td> + </tr> + <tr> + <td>R16I</td> + <td>0x8233</td> + <td></td> + </tr> + <tr> + <td>R16UI</td> + <td>0x8234</td> + <td></td> + </tr> + <tr> + <td>R32I</td> + <td>0x8235</td> + <td></td> + </tr> + <tr> + <td>R32UI</td> + <td>0x8236</td> + <td></td> + </tr> + <tr> + <td>RG8I</td> + <td>0x8237</td> + <td></td> + </tr> + <tr> + <td>RG8UI</td> + <td>0x8238</td> + <td></td> + </tr> + <tr> + <td>RG16I</td> + <td>0x8239</td> + <td></td> + </tr> + <tr> + <td>RG16UI</td> + <td>0x823A</td> + <td></td> + </tr> + <tr> + <td>RG32I</td> + <td>0x823B</td> + <td></td> + </tr> + <tr> + <td>RG32UI</td> + <td>0x823C</td> + <td></td> + </tr> + <tr> + <td>R8_SNORM</td> + <td>0x8F94</td> + <td></td> + </tr> + <tr> + <td>RG8_SNORM</td> + <td>0x8F95</td> + <td></td> + </tr> + <tr> + <td>RGB8_SNORM</td> + <td>0x8F96</td> + <td></td> + </tr> + <tr> + <td>RGBA8_SNORM</td> + <td>0x8F97</td> + <td></td> + </tr> + <tr> + <td><code>RGB10_A2UI</code></td> + <td>0x906F</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_IMMUTABLE_FORMAT </code></td> + <td>0x912F</td> + <td></td> + </tr> + <tr> + <td><code>TEXTURE_IMMUTABLE_LEVELS</code></td> + <td>0x82DF</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Pixel_types_2">Pixel types</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>UNSIGNED_INT_2_10_10_10_REV</code></td> + <td>0x8368</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_10F_11F_11F_REV</code></td> + <td>0x8C3B</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_5_9_9_9_REV</code></td> + <td>0x8C3E</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_32_UNSIGNED_INT_24_8_REV</code></td> + <td>0x8DAD</td> + <td></td> + </tr> + <tr> + <td>UNSIGNED_INT_24_8</td> + <td>0x84FA</td> + <td></td> + </tr> + <tr> + <td><code>HALF_FLOAT</code></td> + <td>0x140B</td> + <td></td> + </tr> + <tr> + <td><code>RG</code></td> + <td>0x8227</td> + <td></td> + </tr> + <tr> + <td><code>RG_INTEGER</code></td> + <td>0x8228</td> + <td></td> + </tr> + <tr> + <td><code>INT_2_10_10_10_REV</code></td> + <td>0x8D9F</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Queries">Queries</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>CURRENT_QUERY</code></td> + <td>0x8865</td> + <td></td> + </tr> + <tr> + <td><code>QUERY_RESULT </code></td> + <td>0x8866</td> + <td></td> + </tr> + <tr> + <td><code>QUERY_RESULT_AVAILABLE</code></td> + <td>0x8867</td> + <td></td> + </tr> + <tr> + <td><code>ANY_SAMPLES_PASSED</code></td> + <td>0x8C2F</td> + <td></td> + </tr> + <tr> + <td><code>ANY_SAMPLES_PASSED_CONSERVATIVE</code></td> + <td>0x8D6A</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Draw_buffers">Draw buffers</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>MAX_DRAW_BUFFERS</code></td> + <td>0x8824</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER0</code></td> + <td>0x8825</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER1</code></td> + <td>0x8826</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER2</code></td> + <td>0x8827</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER3</code></td> + <td>0x8828</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER4</code></td> + <td>0x8829</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER5</code></td> + <td>0x882A</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER6</code></td> + <td>0x882B</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER7</code></td> + <td>0x882C</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER8</code></td> + <td>0x882D</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER9</code></td> + <td>0x882E</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER10</code></td> + <td>0x882F</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER11</code></td> + <td>0x8830</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER12</code></td> + <td>0x8831</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER13</code></td> + <td>0x8832</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER14</code></td> + <td>0x8833</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_BUFFER15</code></td> + <td>0x8834</td> + <td></td> + </tr> + <tr> + <td><code>MAX_COLOR_ATTACHMENTS</code></td> + <td>0x8CDF</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT1</code></td> + <td>0x8CE1</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT2</code></td> + <td>0x8CE2</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT3</code></td> + <td>0x8CE3</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT4</code></td> + <td>0x8CE4</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT5</code></td> + <td>0x8CE5</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT6</code></td> + <td>0x8CE6</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT7</code></td> + <td>0x8CE7</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT8</code></td> + <td>0x8CE8</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT9</code></td> + <td>0x8CE9</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT10</code></td> + <td>0x8CEA</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT11</code></td> + <td>0x8CEB</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT12</code></td> + <td>0x8CEC</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT13</code></td> + <td>0x8CED</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT14</code></td> + <td>0x8CEE</td> + <td></td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT15</code></td> + <td>0x8CEF</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Samplers">Samplers</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>SAMPLER_3D</code></td> + <td>0x8B5F</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLER_2D_SHADOW</code></td> + <td>0x8B62</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLER_2D_ARRAY</code></td> + <td>0x8DC1</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLER_2D_ARRAY_SHADOW</code></td> + <td>0x8DC4</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLER_CUBE_SHADOW</code></td> + <td>0x8DC5</td> + <td></td> + </tr> + <tr> + <td><code>INT_SAMPLER_2D</code></td> + <td>0x8DCA</td> + <td></td> + </tr> + <tr> + <td><code>INT_SAMPLER_3D</code></td> + <td>0x8DCB</td> + <td></td> + </tr> + <tr> + <td><code>INT_SAMPLER_CUBE</code></td> + <td>0x8DCC</td> + <td></td> + </tr> + <tr> + <td><code>INT_SAMPLER_2D_ARRAY</code></td> + <td>0x8DCF</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_SAMPLER_2D</code></td> + <td>0x8DD2</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_SAMPLER_3D</code></td> + <td>0x8DD3</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_SAMPLER_CUBE</code></td> + <td>0x8DD4</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_SAMPLER_2D_ARRAY</code></td> + <td>0x8DD7</td> + <td></td> + </tr> + <tr> + <td><code>MAX_SAMPLES</code></td> + <td>0x8D57</td> + <td></td> + </tr> + <tr> + <td><code>SAMPLER_BINDING</code></td> + <td>0x8919</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Buffers_2">Buffers</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>PIXEL_PACK_BUFFER</code></td> + <td>0x88EB</td> + <td></td> + </tr> + <tr> + <td><code>PIXEL_UNPACK_BUFFER</code></td> + <td>0x88EC</td> + <td></td> + </tr> + <tr> + <td><code>PIXEL_PACK_BUFFER_BINDING</code></td> + <td>0x88ED</td> + <td></td> + </tr> + <tr> + <td><code>PIXEL_UNPACK_BUFFER_BINDING </code></td> + <td>0x88EF</td> + <td></td> + </tr> + <tr> + <td><code>COPY_READ_BUFFER</code></td> + <td>0x8F36</td> + <td></td> + </tr> + <tr> + <td><code>COPY_WRITE_BUFFER</code></td> + <td>0x8F37</td> + <td></td> + </tr> + <tr> + <td><code>COPY_READ_BUFFER_BINDING</code></td> + <td>0x8F36</td> + <td></td> + </tr> + <tr> + <td><code>COPY_WRITE_BUFFER_BINDING</code></td> + <td>0x8F37</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Data_types">Data types</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>FLOAT_MAT2x3</code></td> + <td>0x8B65</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_MAT2x4</code></td> + <td>0x8B66</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_MAT3x2</code></td> + <td>0x8B67</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_MAT3x4 </code></td> + <td>0x8B68</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_MAT4x2</code></td> + <td>0x8B69</td> + <td></td> + </tr> + <tr> + <td><code>FLOAT_MAT4x3</code></td> + <td>0x8B6A</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_VEC2</code></td> + <td>0x8DC6</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_VEC3</code></td> + <td>0x8DC7</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_INT_VEC4</code></td> + <td>0x8DC8</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_NORMALIZED</code></td> + <td>0x8C17</td> + <td></td> + </tr> + <tr> + <td><code>SIGNED_NORMALIZED</code></td> + <td>0x8F9C</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Vertex_attributes_2">Vertex attributes</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_INTEGER </code></td> + <td>0x88FD</td> + <td></td> + </tr> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_DIVISOR</code></td> + <td>0x88FE</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Transform_feedback">Transform feedback</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>TRANSFORM_FEEDBACK_BUFFER_MODE</code></td> + <td>0x8C7F</td> + <td></td> + </tr> + <tr> + <td><code>MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS</code></td> + <td>0x8C80</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_VARYINGS</code></td> + <td>0x8C83</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_BUFFER_START</code></td> + <td>0x8C84</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_BUFFER_SIZE</code></td> + <td>0x8C85</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN</code></td> + <td>0x8C88</td> + <td></td> + </tr> + <tr> + <td><code>MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS</code></td> + <td>0x8C8A</td> + <td></td> + </tr> + <tr> + <td><code>MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS</code></td> + <td>0x8C8B</td> + <td></td> + </tr> + <tr> + <td><code>INTERLEAVED_ATTRIBS</code></td> + <td>0x8C8C</td> + <td></td> + </tr> + <tr> + <td><code>SEPARATE_ATTRIBS</code></td> + <td>0x8C8D</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_BUFFER</code></td> + <td>0x8C8E</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_BUFFER_BINDING</code></td> + <td>0x8C8F</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK</code></td> + <td>0x8E22</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_PAUSED</code></td> + <td>0x8E23</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_ACTIVE</code></td> + <td>0x8E24</td> + <td></td> + </tr> + <tr> + <td><code>TRANSFORM_FEEDBACK_BINDING</code></td> + <td>0x8E25</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Framebuffers_and_renderbuffers_2">Framebuffers and renderbuffers</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING</code></td> + <td>0x8210</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE</code></td> + <td>0x8211</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_RED_SIZE</code></td> + <td>0x8212</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_GREEN_SIZE</code></td> + <td>0x8213</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_BLUE_SIZE</code></td> + <td>0x8214</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE</code></td> + <td>0x8215</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE</code></td> + <td>0x8216</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE</code></td> + <td>0x8217</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_DEFAULT</code></td> + <td>0x8218</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_STENCIL_ATTACHMENT</code></td> + <td>0x821A</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_STENCIL</code></td> + <td>0x84F9</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH24_STENCIL8</code></td> + <td>0x88F0</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_FRAMEBUFFER_BINDING</code></td> + <td>0x8CA6</td> + <td></td> + </tr> + <tr> + <td><code>READ_FRAMEBUFFER</code></td> + <td>0x8CA8</td> + <td></td> + </tr> + <tr> + <td><code>DRAW_FRAMEBUFFER</code></td> + <td>0x8CA9</td> + <td></td> + </tr> + <tr> + <td><code>READ_FRAMEBUFFER_BINDING</code></td> + <td>0x8CAA</td> + <td></td> + </tr> + <tr> + <td><code>RENDERBUFFER_SAMPLES</code></td> + <td>0x8CAB</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER</code></td> + <td>0x8CD4</td> + <td></td> + </tr> + <tr> + <td><code>FRAMEBUFFER_INCOMPLETE_MULTISAMPLE</code></td> + <td>0x8D56</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Uniforms">Uniforms</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>UNIFORM_BUFFER</code></td> + <td>0x8A11</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BUFFER_BINDING</code></td> + <td>0x8A28</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BUFFER_START</code></td> + <td>0x8A29</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BUFFER_SIZE</code></td> + <td>0x8A2A</td> + <td></td> + </tr> + <tr> + <td><code>MAX_VERTEX_UNIFORM_BLOCKS</code></td> + <td>0x8A2B</td> + <td></td> + </tr> + <tr> + <td><code>MAX_FRAGMENT_UNIFORM_BLOCKS</code></td> + <td>0x8A2D</td> + <td></td> + </tr> + <tr> + <td><code>MAX_COMBINED_UNIFORM_BLOCKS</code></td> + <td>0x8A2E</td> + <td></td> + </tr> + <tr> + <td><code>MAX_UNIFORM_BUFFER_BINDINGS</code></td> + <td>0x8A2F</td> + <td></td> + </tr> + <tr> + <td><code>MAX_UNIFORM_BLOCK_SIZE</code></td> + <td>0x8A30</td> + <td></td> + </tr> + <tr> + <td><code>MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS</code></td> + <td>0x8A31</td> + <td></td> + </tr> + <tr> + <td><code>MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS</code></td> + <td>0x8A33</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BUFFER_OFFSET_ALIGNMENT</code></td> + <td>0x8A34</td> + <td></td> + </tr> + <tr> + <td><code>ACTIVE_UNIFORM_BLOCKS</code></td> + <td>0x8A36</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_TYPE </code></td> + <td>0x8A37</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_SIZE</code></td> + <td>0x8A38</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BLOCK_INDEX</code></td> + <td>0x8A3A</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_OFFSET</code></td> + <td>0x8A3B</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_ARRAY_STRIDE</code></td> + <td>0x8A3C</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_MATRIX_STRIDE</code></td> + <td>0x8A3D</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_IS_ROW_MAJOR</code></td> + <td>0x8A3E</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BLOCK_BINDING</code></td> + <td>0x8A3F</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BLOCK_DATA_SIZE</code></td> + <td>0x8A40</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BLOCK_ACTIVE_UNIFORMS</code></td> + <td>0x8A42</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES</code></td> + <td>0x8A43</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER</code></td> + <td>0x8A44</td> + <td></td> + </tr> + <tr> + <td><code>UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER</code></td> + <td>0x8A46</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Sync_objects">Sync objects</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>OBJECT_TYPE</code></td> + <td>0x9112</td> + <td></td> + </tr> + <tr> + <td><code>SYNC_CONDITION</code></td> + <td>0x9113</td> + <td></td> + </tr> + <tr> + <td><code>SYNC_STATUS</code></td> + <td>0x9114</td> + <td></td> + </tr> + <tr> + <td><code>SYNC_FLAGS</code></td> + <td>0x9115</td> + <td></td> + </tr> + <tr> + <td><code>SYNC_FENCE</code></td> + <td>0x9116</td> + <td></td> + </tr> + <tr> + <td><code>SYNC_GPU_COMMANDS_COMPLETE</code></td> + <td>0x9117</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNALED</code></td> + <td>0x9118</td> + <td></td> + </tr> + <tr> + <td><code>SIGNALED</code></td> + <td>0x9119</td> + <td></td> + </tr> + <tr> + <td><code>ALREADY_SIGNALED</code></td> + <td>0x911A</td> + <td></td> + </tr> + <tr> + <td><code>TIMEOUT_EXPIRED</code></td> + <td>0x911B</td> + <td></td> + </tr> + <tr> + <td><code>CONDITION_SATISFIED</code></td> + <td>0x911C</td> + <td></td> + </tr> + <tr> + <td><code>WAIT_FAILED</code></td> + <td>0x911D</td> + <td></td> + </tr> + <tr> + <td><code>SYNC_FLUSH_COMMANDS_BIT</code></td> + <td>0x00000001</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="Miscellaneous_constants">Miscellaneous constants</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>COLOR</code></td> + <td>0x1800</td> + <td></td> + </tr> + <tr> + <td>DEPTH</td> + <td>0x1801</td> + <td></td> + </tr> + <tr> + <td><code>STENCIL</code></td> + <td>0x1802</td> + <td></td> + </tr> + <tr> + <td><code>MIN</code></td> + <td>0x8007</td> + <td></td> + </tr> + <tr> + <td>MAX</td> + <td>0x8008</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_COMPONENT24</code></td> + <td>0x81A6</td> + <td></td> + </tr> + <tr> + <td><code>STREAM_READ</code></td> + <td>0x88E1</td> + <td></td> + </tr> + <tr> + <td><code>STREAM_COPY</code></td> + <td>0x88E2</td> + <td></td> + </tr> + <tr> + <td><code>STATIC_READ</code></td> + <td>0x88E5</td> + <td></td> + </tr> + <tr> + <td><code>STATIC_COPY</code></td> + <td>0x88E6</td> + <td></td> + </tr> + <tr> + <td><code>DYNAMIC_READ</code></td> + <td>0x88E9</td> + <td></td> + </tr> + <tr> + <td><code>DYNAMIC_COPY</code></td> + <td>0x88EA</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH_COMPONENT32F</code></td> + <td>0x8CAC</td> + <td></td> + </tr> + <tr> + <td><code>DEPTH32F_STENCIL8</code></td> + <td>0x8CAD</td> + <td></td> + </tr> + <tr> + <td><code>INVALID_INDEX</code></td> + <td>0xFFFFFFFF</td> + <td></td> + </tr> + <tr> + <td><code>TIMEOUT_IGNORED</code></td> + <td>-1</td> + <td></td> + </tr> + <tr> + <td><code>MAX_CLIENT_WAIT_TIMEOUT_WEBGL</code></td> + <td>0x9247</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Constants_defined_in_WebGL_extensions">Constants defined in WebGL extensions</h2> + +<h3 id="domxrefANGLE_instanced_arrays">{{domxref("ANGLE_instanced_arrays")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE</code></td> + <td>0x88FE</td> + <td>Describes the frequency divisor used for instanced rendering.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_debug_renderer_info">{{domxref("WEBGL_debug_renderer_info")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>UNMASKED_VENDOR_WEBGL</code></td> + <td>0x9245</td> + <td>Passed to <code>getParameter</code> to get the vendor string of the graphics driver.</td> + </tr> + <tr> + <td><code>UNMASKED_RENDERER_WEBGL</code></td> + <td>0x9246</td> + <td>Passed to <code>getParameter</code> to get the renderer string of the graphics driver.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefEXT_texture_filter_anisotropic">{{domxref("EXT_texture_filter_anisotropic")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>MAX_TEXTURE_MAX_ANISOTROPY_EXT</code></td> + <td>0x84FF</td> + <td>Returns the maximum available anisotropy.</td> + </tr> + <tr> + <td><code>TEXTURE_MAX_ANISOTROPY_EXT</code></td> + <td>0x84FE</td> + <td>Passed to <code>texParameter</code> to set the desired maximum anisotropy for a texture.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_compressed_texture_s3tc">{{domxref("WEBGL_compressed_texture_s3tc")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>COMPRESSED_RGB_S3TC_DXT1_EXT</code></td> + <td>0x83F0</td> + <td>A DXT1-compressed image in an RGB image format.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGBA_S3TC_DXT1_EXT</code></td> + <td>0x83F1</td> + <td>A DXT1-compressed image in an RGB image format with a simple on/off alpha value.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGBA_S3TC_DXT3_EXT</code></td> + <td>0x83F2</td> + <td>A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGBA_S3TC_DXT5_EXT</code></td> + <td>0x83F3</td> + <td>A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3 compression in how the alpha compression is done.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_compressed_texture_etc">{{domxref("WEBGL_compressed_texture_etc")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>COMPRESSED_R11_EAC</code></td> + <td>0x9270</td> + <td>One-channel (red) unsigned format compression.</td> + </tr> + <tr> + <td><code>COMPRESSED_SIGNED_R11_EAC</code></td> + <td>0x9271</td> + <td>One-channel (red) signed format compression.</td> + </tr> + <tr> + <td><code>COMPRESSED_RG11_EAC</code></td> + <td>0x9272</td> + <td>Two-channel (red and green) unsigned format compression.</td> + </tr> + <tr> + <td><code>COMPRESSED_SIGNED_RG11_EAC</code></td> + <td>0x9273</td> + <td>Two-channel (red and green) signed format compression.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGB8_ETC2</code></td> + <td>0x9274</td> + <td>Compresses RBG8 data with no alpha channel.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGBA8_ETC2_EAC</code></td> + <td>0x9275</td> + <td>Compresses RGBA8 data. The RGB part is encoded the same as <code>RGB_ETC2</code>, but the alpha part is encoded separately.</td> + </tr> + <tr> + <td><code>COMPRESSED_SRGB8_ETC2</code></td> + <td>0x9276</td> + <td>Compresses sRBG8 data with no alpha channel.</td> + </tr> + <tr> + <td><code>COMPRESSED_SRGB8_ALPHA8_ETC2_EAC</code></td> + <td>0x9277</td> + <td>Compresses sRGBA8 data. The sRGB part is encoded the same as <code>SRGB_ETC2</code>, but the alpha part is encoded separately.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2</code></td> + <td>0x9278</td> + <td>Similar to <code>RGB8_ETC</code>, but with ability to punch through the alpha channel, which means to make it completely opaque or transparent.</td> + </tr> + <tr> + <td><code>COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2</code></td> + <td>0x9279</td> + <td>Similar to <code>SRGB8_ETC</code>, but with ability to punch through the alpha channel, which means to make it completely opaque or transparent.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_compressed_texture_pvrtc">{{domxref("WEBGL_compressed_texture_pvrtc")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>COMPRESSED_RGB_PVRTC_4BPPV1_IMG</code></td> + <td>0x8C00</td> + <td>RGB compression in 4-bit mode. One block for each 4×4 pixels.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGBA_PVRTC_4BPPV1_IMG</code></td> + <td>0x8C02</td> + <td>RGBA compression in 4-bit mode. One block for each 4×4 pixels.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGB_PVRTC_2BPPV1_IMG</code></td> + <td>0x8C01</td> + <td>RGB compression in 2-bit mode. One block for each 8×4 pixels.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGBA_PVRTC_2BPPV1_IMG</code></td> + <td>0x8C03</td> + <td>RGBA compression in 2-bit mode. One block for each 8×4 pixe</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_compressed_texture_etc1">{{domxref("WEBGL_compressed_texture_etc1")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>COMPRESSED_RGB_ETC1_WEBGL</code></td> + <td>0x8D64</td> + <td>Compresses 24-bit RGB data with no alpha channel.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_compressed_texture_atc">{{domxref("WEBGL_compressed_texture_atc")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>COMPRESSED_RGB_ATC_WEBGL</code></td> + <td>0x8C92</td> + <td>Compresses RGB textures with no alpha channel.</td> + </tr> + <tr> + <td><code>COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL</code></td> + <td>0x8C92</td> + <td>Compresses RGBA textures using explicit alpha encoding (useful when alpha transitions are sharp).</td> + </tr> + <tr> + <td><code>COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL</code></td> + <td>0x87EE</td> + <td>Compresses RGBA textures using interpolated alpha encoding (useful when alpha transitions are gradient).</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_depth_texture">{{domxref("WEBGL_depth_texture")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>UNSIGNED_INT_24_8_WEBGL</code></td> + <td>0x84FA</td> + <td>Unsigned integer type for 24-bit depth texture data.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefOES_texture_half_float">{{domxref("OES_texture_half_float")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>HALF_FLOAT_OES</code></td> + <td>0x8D61</td> + <td>Half floating-point type (16-bit).</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_color_buffer_float">{{domxref("WEBGL_color_buffer_float")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>RGBA32F_EXT</code></td> + <td>0x8814</td> + <td>RGBA 32-bit floating-point color-renderable format.</td> + </tr> + <tr> + <td><code>RGB32F_EXT</code></td> + <td>0x8815</td> + <td>RGB 32-bit floating-point color-renderable format.</td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT</code></td> + <td>0x8211</td> + <td></td> + </tr> + <tr> + <td><code>UNSIGNED_NORMALIZED_EXT</code></td> + <td>0x8C17</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="domxrefEXT_blend_minmax">{{domxref("EXT_blend_minmax")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>MIN_EXT</code></td> + <td>0x8007</td> + <td>Produces the minimum color components of the source and destination colors.</td> + </tr> + <tr> + <td><code>MAX_EXT</code></td> + <td>0x8008</td> + <td>Produces the maximum color components of the source and destination colors.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefEXT_sRGB">{{domxref("EXT_sRGB")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>SRGB_EXT</code></td> + <td>0x8C40</td> + <td>Unsized sRGB format that leaves the precision up to the driver.</td> + </tr> + <tr> + <td><code>SRGB_ALPHA_EXT</code></td> + <td>0x8C42</td> + <td>Unsized sRGB format with unsized alpha component.</td> + </tr> + <tr> + <td><code>SRGB8_ALPHA8_EXT</code></td> + <td>0x8C43</td> + <td>Sized (8-bit) sRGB and alpha formats.</td> + </tr> + <tr> + <td><code>FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT</code></td> + <td>0x8210</td> + <td>Returns the framebuffer color encoding.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefOES_standard_derivatives">{{domxref("OES_standard_derivatives")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>FRAGMENT_SHADER_DERIVATIVE_HINT_OES</code></td> + <td>0x8B8B</td> + <td>Indicates the accuracy of the derivative calculation for the GLSL built-in functions: <code>dFdx</code>, <code>dFdy</code>, and <code>fwidth</code>.</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefWEBGL_draw_buffers">{{domxref("WEBGL_draw_buffers")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>COLOR_ATTACHMENT0_WEBGL</code></td> + <td>0x8CE0</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT1_WEBGL</code></td> + <td>0x8CE1</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT2_WEBGL</code></td> + <td>0x8CE2</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT3_WEBGL</code></td> + <td>0x8CE3</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT4_WEBGL</code></td> + <td>0x8CE4</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT5_WEBGL</code></td> + <td>0x8CE5</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT6_WEBGL</code></td> + <td>0x8CE6</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT7_WEBGL</code></td> + <td>0x8CE7</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT8_WEBGL</code></td> + <td>0x8CE8</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT9_WEBGL</code></td> + <td>0x8CE9</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT10_WEBGL</code></td> + <td>0x8CEA</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT11_WEBGL</code></td> + <td>0x8CEB</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT12_WEBGL</code></td> + <td>0x8CEC</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT13_WEBGL</code></td> + <td>0x8CED</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT14_WEBGL</code></td> + <td>0x8CEE</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>COLOR_ATTACHMENT15_WEBGL</code></td> + <td>0x8CEF</td> + <td>Framebuffer color attachment point</td> + </tr> + <tr> + <td><code>DRAW_BUFFER0_WEBGL</code></td> + <td>0x8825</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER1_WEBGL</code></td> + <td>0x8826</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER2_WEBGL</code></td> + <td>0x8827</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER3_WEBGL</code></td> + <td>0x8828</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER4_WEBGL</code></td> + <td>0x8829</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER5_WEBGL</code></td> + <td>0x882A</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER6_WEBGL</code></td> + <td>0x882B</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER7_WEBGL</code></td> + <td>0x882C</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER8_WEBGL</code></td> + <td>0x882D</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER9_WEBGL</code></td> + <td>0x882E</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER10_WEBGL</code></td> + <td>0x882F</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER11_WEBGL</code></td> + <td>0x8830</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER12_WEBGL</code></td> + <td>0x8831</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER13_WEBGL</code></td> + <td>0x8832</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER14_WEBGL</code></td> + <td>0x8833</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>DRAW_BUFFER15_WEBGL</code></td> + <td>0x8834</td> + <td>Draw buffer</td> + </tr> + <tr> + <td><code>MAX_COLOR_ATTACHMENTS_WEBGL</code></td> + <td>0x8CDF</td> + <td>Maximum number of framebuffer color attachment points</td> + </tr> + <tr> + <td><code>MAX_DRAW_BUFFERS_WEBGL</code></td> + <td>0x8824</td> + <td>Maximum number of draw buffers</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefOES_vertex_array_object">{{domxref("OES_vertex_array_object")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>VERTEX_ARRAY_BINDING_OES</code></td> + <td>0x85B5</td> + <td>The bound vertex array object (VAO).</td> + </tr> + </tbody> +</table> + +<h3 id="domxrefEXT_disjoint_timer_query">{{domxref("EXT_disjoint_timer_query")}}</h3> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Constant name</th> + <th scope="col">Value</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>QUERY_COUNTER_BITS_EXT</code></td> + <td>0x8864</td> + <td>The number of bits used to hold the query result for the given target.</td> + </tr> + <tr> + <td><code>CURRENT_QUERY_EXT</code></td> + <td>0x8865</td> + <td>The currently active query.</td> + </tr> + <tr> + <td><code>QUERY_RESULT_EXT</code></td> + <td>0x8866</td> + <td>The query result.</td> + </tr> + <tr> + <td><code>QUERY_RESULT_AVAILABLE_EXT</code></td> + <td>0x8867</td> + <td>A Boolean indicating whether or not a query result is available.</td> + </tr> + <tr> + <td><code>TIME_ELAPSED_EXT</code></td> + <td>0x88BF</td> + <td>Elapsed time (in nanoseconds).</td> + </tr> + <tr> + <td><code>TIMESTAMP_EXT</code></td> + <td>0x8E28</td> + <td>The current time.</td> + </tr> + <tr> + <td><code>GPU_DISJOINT_EXT</code></td> + <td>0x8FBB</td> + <td>A Boolean indicating whether or not the GPU performed any disjoint operation.</td> + </tr> + </tbody> +</table> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('WebGL', "#5.14", "WebGLRenderingContext")}}</td> + <td>{{Spec2('WebGL')}}</td> + <td>Initial definition</td> + </tr> + <tr> + <td>{{SpecName('WebGL2', "#3.7", "WebGL2RenderingContext")}}</td> + <td>{{Spec2('WebGL2')}}</td> + <td>Defines additional constants.</td> + </tr> + </tbody> +</table> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{domxref("WebGLRenderingContext")}}</li> +</ul> diff --git a/files/ja/web/api/webgl_api/cross-domain_textures/index.html b/files/ja/web/api/webgl_api/cross-domain_textures/index.html new file mode 100644 index 0000000000..05908fed61 --- /dev/null +++ b/files/ja/web/api/webgl_api/cross-domain_textures/index.html @@ -0,0 +1,15 @@ +--- +title: Cross-Domain Textures +slug: Web/API/WebGL_API/Cross-Domain_Textures +translation_of: Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL#Cross-domain_textures +--- +<p>WebGL のテクスチャの読み込みは、クロスドメインアクセス制御に従います。コンテンツで他のドメインからテクスチャを読み込むためには、CORS で許可を得る必要があります。CORS について詳しくは、<a href="/Ja/HTTP_access_control" title="ja/HTTP access control">HTTP access control</a> をご覧ください。</p> +<p>CORS で許可された画像を WebGL のテクスチャとして使用する方法の説明を <a class="external" href="http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/" title="http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/">こちらの hacks.mozilla.org の記事</a> に掲載していますので、<a class="external" href="http://people.mozilla.org/~bjacob/webgltexture-cors-js.html" title="http://people.mozilla.org/~bjacob/webgltexture-cors-js.html">サンプル</a> と合わせてご覧ください。</p> +<div class="geckoVersionNote"> <p>{{ gecko_callout_heading("8.0") }}</p> <p>WebGL テクスチャ向けの CORS サポートと、画像要素の <code>crossOrigin</code> 属性が Gecko 8 {{ geckoRelease("8.0") }} で実装されました。</p> +</div> +<p>汚染された (書き込みのみ) 2D canvas を WebGL のテクスチャとして使用することはできません。2D {{ HTMLElement("canvas") }} が汚染されたとは例えば、クロスドメインの画像が canvas 上に描画された状態を指します。</p> +<div class="geckoVersionNote"> <p>{{ gecko_callout_heading("9.0") }}</p> <p>Canvas 2D <code>drawImage</code> 向けの CORS サポートが Gecko 9 {{ geckoRelease("9.0") }} で実装されました。これは、CORS で許可されたクロスドメインの画像が 2D canvas を汚染しないので、2D canvas を WebGL のテクスチャ素材として使用することが可能であり続けることを意味します。</p> +</div> +<div class="geckoVersionNote"> <p>{{ gecko_callout_heading("12.0") }}</p> <p>クロスドメインの動画に対する CORS サポートと、{{ HTMLElement("video") }} 要素の<code>crossorigin</code> 属性を Gecko 12 {{ geckoRelease("12.0") }} で実装しました。</p> +</div> +<p>{{ languages( { "en": "en/WebGL/Cross-Domain_Textures"} ) }}</p> diff --git a/files/ja/web/api/webgl_api/data/index.html b/files/ja/web/api/webgl_api/data/index.html new file mode 100644 index 0000000000..03aa0b7b6a --- /dev/null +++ b/files/ja/web/api/webgl_api/data/index.html @@ -0,0 +1,75 @@ +--- +title: WebGL でのデータ +slug: Web/API/WebGL_API/Data +translation_of: Web/API/WebGL_API/Data +--- +<div>{{WebGLSidebar}}{{draft}}</div> + +<p>シェーダープログラムは 3 種類のデータストレージにアクセスでき、それぞれに特定のユースケースがあります。それぞれの種類の変数はデータストアの種類に応じて 1 つまたは両方の種類のシェーダープログラムからアクセスでき、特定の変数の種類に応じてサイトの JavaScript コードからもアクセスできます。</p> + +<h2 id="GLSL_データ型">GLSL データ型</h2> + +<p><<基本型、ベクトルなどを文書化します。Khronos WebGL wiki の<a href="https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)">データ型 (GLSL)</a> を参照してください>></p> + +<h2 id="GLSL_変数">GLSL 変数</h2> + +<p>GLSL には3種類の「変数」またはデータストレージがあり、それぞれに <strong>{{anch("Attributes", "attributes")}}</strong>、<strong>{{anch("Varyings", "varyings")}}</strong> <strong>および</strong> <strong>{{anch("Uniforms", "uniforms")}}</strong> といった独自の目的とユースケースがあります。</p> + +<h3 id="Attributes">Attributes</h3> + +<p><strong>Attributes</strong> は GLSL 変数であり、(変数としての) 頂点シェーダーおよび JavaScript コードでのみ使用可能です。属性は通常、色情報、テクスチャ座標、および JavaScript コードと頂点シェーダー間で共有する必要がある計算または取得されたその他のデータを格納するために使用されます。</p> + +<pre class="brush: js">//init colors + var vertexColors = [ + vec4( 0.0, 0.0, 0.0, 1.0 ), // black + vec4( 1.0, 0.0, 0.0, 1.0 ), // red + vec4( 1.0, 1.0, 0.0, 1.0 ), // yellow + vec4( 0.0, 1.0, 0.0, 1.0 ), // green + vec4( 0.0, 0.0, 0.0, 1.0 ), // black + vec4( 1.0, 0.0, 0.0, 1.0 ), // red + vec4( 1.0, 1.0, 0.0, 1.0 ), // yellow + vec4( 0.0, 1.0, 0.0, 1.0 ), // green + ]; + var cBuffer = gl.createBuffer(); +</pre> + +<pre class="brush: js">//continued +//create buffer to store colors and reference it to "vColor" which is in GLSL + gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer ); + gl.bufferData( gl.ARRAY_BUFFER, flatten(vertexColors), gl.STATIC_DRAW ); + + var vColor = gl.getAttribLocation( program, "vColor" ); + gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 ); + gl.enableVertexAttribArray( vColor ); +</pre> + +<pre class="brush: cpp">//glsl +attribute vec4 vColor; + +void main() +{ + +fColor = vColor; +} + +</pre> + +<h3 id="Varyings">Varyings</h3> + +<p><strong>Varyings</strong> は頂点シェーダーによって宣言され、頂点シェーダーからフラグメントシェーダーにデータを渡すために使用される変数です。これは、頂点シェーダーによって計算された後、頂点の {{interwiki("wikipedia", "Normal_(geometry)", "normal vector")}} を共有するために通常使用されます。</p> + +<p><<使用方法>></p> + +<h3 id="Uniforms">Uniforms</h3> + +<p><strong>Uniforms</strong> は JavaScript コードによって設定され、頂点シェーダーとフラグメントシェーダーの両方で使用できます。これらは照明の位置と大きさ、グローバル変換と遠近法の詳細など、フレームに描画されるすべてのものに対して同じ値を提供するために使用されます。</p> + +<p><<詳細の追加>></p> + +<h2 id="Buffers">Buffers</h2> + +<p><<情報の追加>></p> + +<h2 id="Textures">Textures</h2> + +<p><<情報の追加>></p> diff --git a/files/ja/web/api/webgl_api/index.html b/files/ja/web/api/webgl_api/index.html new file mode 100644 index 0000000000..0429e257aa --- /dev/null +++ b/files/ja/web/api/webgl_api/index.html @@ -0,0 +1,261 @@ +--- +title: 'WebGL: ウェブの 2D および 3D グラフィック' +slug: Web/API/WebGL_API +tags: + - 3D + - 3D Graphics + - Advanced + - Graphics + - Media + - Overview + - WebGL + - WebGL API +translation_of: Web/API/WebGL_API +--- +<div>{{WebGLSidebar}}</div> + +<div class="summary"> +<p><span class="seoSummary">WebGL (Web Graphics Library) は、互換性があるウェブブラウザーでプラグインを使用せずにインタラクティブな 3D グラフィックスや 2D グラフィックスをレンダリングするための JavaScript API です。HTML5 {{HTMLElement("canvas")}} 要素へ OpenGL ES 2.0 に密接に従った API を導入することにより、WebGL を実現します。</span>これにより、ユーザーの端末が提供するハードウェアのグラフィックアクセラレーションを API で利用することが可能になります。</p> +</div> + +<p>WebGL は <a href="/ja/Firefox" title="Firefox 4 for developers">Firefox</a> 4 以降、<a href="https://www.google.com/chrome/">Google Chrome</a> 9 以降、<a href="https://www.opera.com/">Opera</a> 12 以降、<a href="https://www.apple.com/jp/safari/">Safari</a> 5.1 以降、<a href="http://windows.microsoft.com/ja-jp/internet-explorer/browser-ie">Internet Explorer</a> 11 以降、<a href="https://www.microsoft.com/ja-jp/edge">Microsoft Edge</a> build 10240 以降でサポートしていますが、ユーザーの端末がこの機能をサポートするハードウェアであることも必要です。</p> + +<p>{{HTMLElement("canvas")}} 要素は、ウェブページで 2D グラフィックスを表示する <a href="/ja/docs/Web/API/Canvas_API">Canvas 2D</a> でも使用します。</p> + +<p>ウェブページ上の 2D グラフィックを実現するには、 {{HTMLElement("canvas")}} 要素で <a href="/ja/docs/Web/API/Canvas_API">Canvas API</a> を使用する方法もあります。</p> + +<h2 id="Reference" name="Reference">リファレンス</h2> + +<h3 id="Standard_interfaces" name="Standard_interfaces">標準インターフェイス</h3> + +<div class="index"> +<ul> + <li>{{domxref("WebGLRenderingContext")}}</li> + <li>{{domxref("WebGL2RenderingContext")}}</li> + <li>{{domxref("WebGLActiveInfo")}}</li> + <li>{{domxref("WebGLBuffer")}}</li> + <li>{{domxref("WebGLContextEvent")}}</li> + <li>{{domxref("WebGLFramebuffer")}}</li> + <li>{{domxref("WebGLProgram")}}</li> + <li>{{domxref("WebGLQuery")}}</li> + <li>{{domxref("WebGLRenderbuffer")}}</li> + <li>{{domxref("WebGLSampler")}}</li> + <li>{{domxref("WebGLShader")}}</li> + <li>{{domxref("WebGLShaderPrecisionFormat")}}</li> + <li>{{domxref("WebGLSync")}}</li> + <li>{{domxref("WebGLTexture")}}</li> + <li>{{domxref("WebGLTransformFeedback")}}</li> + <li>{{domxref("WebGLUniformLocation")}}</li> + <li>{{domxref("WebGLVertexArrayObject")}}</li> +</ul> +</div> + +<h3 id="Extension_interfaces" name="Extension_interfaces">拡張機能</h3> + +<div class="index"> +<ul> + <li>{{domxref("ANGLE_instanced_arrays")}}</li> + <li>{{domxref("EXT_blend_minmax")}}</li> + <li>{{domxref("EXT_color_buffer_float")}}</li> + <li>{{domxref("EXT_color_buffer_half_float")}}</li> + <li>{{domxref("EXT_disjoint_timer_query")}}</li> + <li>{{domxref("EXT_float_blend")}} {{experimental_inline}}</li> + <li>{{domxref("EXT_frag_depth")}}</li> + <li>{{domxref("EXT_sRGB")}}</li> + <li>{{domxref("EXT_shader_texture_lod")}}</li> + <li>{{domxref("EXT_texture_compression_bptc")}}</li> + <li>{{domxref("EXT_texture_compression_rgtc")}}</li> + <li>{{domxref("EXT_texture_filter_anisotropic")}}</li> + <li>{{domxref("OES_element_index_uint")}}</li> + <li>{{domxref("OES_fbo_render_mipmap")}}</li> + <li>{{domxref("OES_standard_derivatives")}}</li> + <li>{{domxref("OES_texture_float")}}</li> + <li>{{domxref("OES_texture_float_linear")}}</li> + <li>{{domxref("OES_texture_half_float")}}</li> + <li>{{domxref("OES_texture_half_float_linear")}}</li> + <li>{{domxref("OES_vertex_array_object")}}</li> + <li>{{domxref("OVR_multiview2")}}</li> + <li>{{domxref("WEBGL_color_buffer_float")}}</li> + <li>{{domxref("WEBGL_compressed_texture_astc")}}</li> + <li>{{domxref("WEBGL_compressed_texture_atc")}}</li> + <li>{{domxref("WEBGL_compressed_texture_etc")}}</li> + <li>{{domxref("WEBGL_compressed_texture_etc1")}}</li> + <li>{{domxref("WEBGL_compressed_texture_pvrtc")}}</li> + <li>{{domxref("WEBGL_compressed_texture_s3tc")}}</li> + <li>{{domxref("WEBGL_compressed_texture_s3tc_srgb")}}</li> + <li>{{domxref("WEBGL_debug_renderer_info")}}</li> + <li>{{domxref("WEBGL_debug_shaders")}}</li> + <li>{{domxref("WEBGL_depth_texture")}}</li> + <li>{{domxref("WEBGL_draw_buffers")}}</li> + <li>{{domxref("WEBGL_lose_context")}}</li> +</ul> +</div> + +<h3 id="Events" name="Events">イベント</h3> + +<ul> + <li>{{domxref("HTMLCanvasElement/webglcontextlost_event", "webglcontextlost")}}</li> + <li>{{domxref("HTMLCanvasElement/webglcontextrestored_event", "webglcontextrestored")}}</li> + <li>{{domxref("HTMLCanvasElement/webglcontextcreationerror_event", "webglcontextcreationerror")}}</li> +</ul> + +<h3 id="Constants_and_types" name="Constants_and_types">定数と型</h3> + +<ul> + <li><a href="/ja/docs/Web/API/WebGL_API/Constants">WebGL の定数</a></li> + <li><a href="/ja/docs/Web/API/WebGL_API/Types">WebGL の型</a></li> +</ul> + +<h3 id="WebGL_2" name="WebGL_2">WebGL 2</h3> + +<p>WebGL 2 は {{domxref("WebGL2RenderingContext")}} インターフェイスによって提供される、WebGL の大規模なアップデートです。これは OpenGL ES 3.0 に基づいており、以下の新機能を含みます:</p> + +<ul> + <li><a href="/ja/docs/Web/API/WebGL2RenderingContext/texImage3D">3D テクスチャ</a>、</li> + <li><a href="/ja/docs/Web/API/WebGLSampler">Sampler object</a>、</li> + <li><a href="/ja/docs/Web/API/WebGL2RenderingContext#Uniform_buffer_objects">Uniform Buffer object</a>、</li> + <li><a href="/ja/docs/Web/API/WebGLSync">Sync object</a>、</li> + <li><a href="/ja/docs/Web/API/WebGLQuery">Query object</a>、</li> + <li><a href="/ja/docs/Web/API/WebGLTransformFeedback">Transform Feedback object</a>、</li> + <li>WebGL 2 のコア機能に昇格した拡張: <a href="/ja/docs/Web/API/WebGLVertexArrayObject">Vertex Array object</a>、<a href="/ja/docs/Web/API/WebGL2RenderingContext/drawArraysInstanced">instancing</a>、<a href="/ja/docs/Web/API/WebGL2RenderingContext/drawBuffers">Multiple Render Targets</a>、<a href="/ja/docs/Web/API/EXT_frag_depth">fragment depth</a>。</li> +</ul> + +<p><a href="https://hacks.mozilla.org/2017/01/webgl-2-lands-in-firefox/">"WebGL 2 lands in Firefox"</a> のブログ記事や、<a href="http://webglsamples.org/WebGL2Samples/">webglsamples.org/WebGL2Samples</a> のデモもご覧ください。</p> + +<h2 id="Guides_and_tutorials" name="Guides_and_tutorials">ガイドとチュートリアル</h2> + +<p>下記に、WebGL の概念を学習するのに役立つガイド一式とステップ毎のレッスンや例のあるチュートリアルがあります。</p> + +<h3 id="Guides" name="Guides">ガイド</h3> + +<dl> + <dt><a href="/ja/docs/Web/API/WebGL_API/Data">WebGL でのデータ</a></dt> + <dd>変数、バッファ、その他の WebGL コードを書く時に使うデータタイプのガイド</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/WebGL_best_practices">WebGL ベストプラクティス</a></dt> + <dd>WebGL のコンテンツの品質、パフォーマンス、信頼性を改善するためのヒントと提案です</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Using_Extensions">拡張機能</a></dt> + <dd>WebGL で利用可能な拡張機能の使用方法です</dd> +</dl> + +<h3 id="Advanced_tutorials" name="Advanced_tutorials">チュートリアル</h3> + +<dl> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial">WebGL チュートリアル</a></dt> + <dd>WebGL のコアコンセプトに関する、ビギナー向けのガイドです。WebGL の経験がない場合におすすめするガイドです</dd> +</dl> + +<h3 id="Examples" name="Examples">例</h3> + +<dl> + <dt><a href="/ja/docs/Web/API/WebGL_API/Basic_2D_animation_example">基本的な 2D WebGL アニメーションの例</a></dt> + <dd>この例では、単一色の形状のシンプルなアニメーションをデモします。検査するトピックはアスペクト比の違いや、複数のシェーダーの集合からシェーダープログラムを生成する機能や、WebGL での描画の基本を扱います</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/By_example">WebGL by example</a></dt> + <dd>WebGL のコンセプトと機能を紹介する短い解説付きのライブサンプルのシリーズです。サンプルはトピックと難易度に応じて分類されており、WebGL レンダリングコンテキスト、シェーダプログラミング、テクスチャ、ジオメトリ、ユーザー操作などをカバーしています。</dd> +</dl> + +<h3 id="Advanced_tutorials" name="Advanced_tutorials">高度なチュートリアル</h3> + +<dl> + <dt><a href="/ja/docs/Web/API/WebGL_API/WebGL_model_view_projection">WebGL model view projection</a></dt> + <dd>3D オブジェクトビューを表現するためによく使用する 3 つの主要な行列 (モデル行列、ビュー行列、プロジェクション行列) について、詳しく説明します</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Matrix_math_for_the_web">Matrix math for the web</a></dt> + <dd>3D 変換行列がどのように働くか、および Web (WebGL の演算や、CSS3 Transform) でどのように使用できるかのガイドです</dd> +</dl> + +<h2 id="Resources" name="Resources">リソース</h2> + +<ul> + <li><a href="https://www.youtube.com/embed/H4c8t6myAWU/?feature=player_detailpage">Raw WebGL: An introduction to WebGL</a>: WebGL の基礎を Nick Desaulniers が紹介します。低レベルのグラフィックスプログラミングを行ったことがない方におすすめします。</li> + <li><a href="http://www.khronos.org/webgl/" title="http://www.khronos.org/webgl/">Khronos WebGL サイト</a>: Khronos Group の WebGL についてのメインサイト</li> + <li><a href="http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/" title="http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/">WebGL Fundamentals</a>: WebGL の基礎と、基本的なチュートリアルがあります。</li> + <li><a href="http://webglplayground.net" title="http://webglplayground.net">WebGL playground</a>: WebGL プロジェクトの作成と共有ができるオンラインツール。迅速なプロトタイピングや実験に最適です。</li> + <li><a href="http://www.webglacademy.com" title="http://www.webglacademy.com">WebGL Academy</a>: WebGL プログラミングの基礎を学ぶチュートリアルがある、 HTML/JavaScript エディターです。</li> + <li><a href="http://webglstats.com/">WebGL Stats</a>: さまざまなプラットフォームのブラウザーについて、WebGL の機能性の状況を示すサイトです。</li> +</ul> + +<h3 id="Libraries" name="Libraries">ライブラリー</h3> + +<ul> + <li><a class="link-https" href="https://github.com/toji/gl-matrix" title="https://github.com/toji/gl-matrix">glMatrix</a>: 高性能 WebGL アプリ製作のための、行列とベクトルの JavaScript ライブラリー</li> + <li><a href="http://senchalabs.github.com/philogl/">PhiloGL</a> is a WebGL framework for data visualization, creative coding, and game development.</li> + <li><a href="http://www.pixijs.com/">Pixi.js</a> is a fast, open-source 2D WebGL renderer.</li> + <li><a href="https://playcanvas.com/">PlayCanvas</a> is an open-source game engine.</li> + <li><a href="http://sylvester.jcoglan.com/" title="http://sylvester.jcoglan.com/">Sylvester</a>: ベクトルや行列を操作するためのオープンソースライブラリー。WebGL 用として最適化されたものではありませんが、非常に堅牢です。</li> + <li><a href="https://threejs.org/">three.js</a> is an open-source, fully featured 3D WebGL library.</li> + <li><a href="https://phaser.io/">Phaser</a> is a fast, free and fun open source framework for Canvas and WebGL powered browser games.</li> + <li><a href="https://github.com/redcamel/RedGL2">RedGL</a> is an open-source 3D WebGL library.</li> + <li><a href="https://kitware.github.io/vtk-js/">vtk.js</a> is a JavaScript library for scientific visualization in your browser.</li> +</ul> + +<h2 id="Specifications" name="Specifications">仕様書</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">仕様書</th> + <th scope="col">状態</th> + <th scope="col">備考</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('OpenGL ES 3.0')}}</td> + <td>{{Spec2('OpenGL ES 3.0')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('OpenGL ES 2.0')}}</td> + <td>{{Spec2('OpenGL ES 2.0')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('WebGL2')}}</td> + <td>{{Spec2('WebGL2')}}</td> + <td>WebGL 1 の上に構築。OpenGL ES 3.0 に基づく。</td> + </tr> + <tr> + <td>{{SpecName('WebGL')}}</td> + <td>{{Spec2('WebGL')}}</td> + <td>初回定義。OpenGL ES 2.0 に基づく。</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<h3 id="WebGL_1">WebGL 1</h3> + +<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div> + +<p>{{Compat("api.WebGLRenderingContext", 0)}}</p> + +<h3 id="WebGL_2_2">WebGL 2</h3> + +<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div> + +<p>{{Compat("api.WebGL2RenderingContext", 0)}}</p> + + +<h3 id="Compatibility_notes" name="Compatibility_notes">互換性に関する注記</h3> + +<p>ブラウザだけでなく、GPU も機能をサポートしていなければなりません。よって、例えば S3 Texture Compression (S3TC) は Tegra ベースのタブレットでしか使用できません。ほとんどのブラウザーでは WebGL コンテキストを、コンテキスト名 <code>webgl</code> で作成しますが、古いブラウザーでは <code>experimental-webgl</code> も必要です。さらに将来の <a href="/ja/docs/Web/API/WebGL2RenderingContext">WebGL 2</a> では完全な下位互換性があり、コンテキスト名 <code>webgl2</code> を持ちます。</p> + +<h3 id="Gecko_notes" name="Gecko_notes">Gecko に関する注記</h3> + +<h4 id="WebGL_debugging_and_testing" name="WebGL_debugging_and_testing">WebGL のデバッグおよびテスト</h4> + +<p>Gecko 10.0 {{geckoRelease("10.0")}} 以降には、テストなどの目的で WebGL の機能を制限する 2 つの設定項目があります。</p> + +<dl> + <dt><code>webgl.min_capability_mode</code></dt> + <dd>この論理属性に <code>true</code> を指定すると、最小互換性モードが有効となります。このモードでは、必要最低限の機能セットと WebGL の仕様で指定された機能のみが使用可能です。このモードで動作確認を行うことにより、より多くの閲覧環境での動作を保証することができます。初期値は <code>false</code> です。</dd> + <dt><code>webgl.disable_extensions</code></dt> + <dd>この論理属性に <code>true</code> を指定すると、すべての WebGL 拡張が無効になります。初期値は <code>false</code> です。</dd> +</dl> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Web/API/Canvas_API">Canvas</a></li> + <li><a href="/ja/docs/Web/API/WebGLRenderingContext/getSupportedExtensions#Browser_compatibility">WebGL 拡張の互換性情報</a></li> +</ul> diff --git a/files/ja/web/api/webgl_api/matrix_math_for_the_web/index.html b/files/ja/web/api/webgl_api/matrix_math_for_the_web/index.html new file mode 100644 index 0000000000..adbe58d34a --- /dev/null +++ b/files/ja/web/api/webgl_api/matrix_math_for_the_web/index.html @@ -0,0 +1,342 @@ +--- +title: ウェブの行列計算 +slug: Web/API/WebGL_API/Matrix_math_for_the_web +tags: + - 3D + - 3D2D + - Animation + - CSS + - GLSL + - Graphics + - Guide + - WebGL + - WebXR + - matrices + - matrix + - rendering + - transform3d +translation_of: Web/API/WebGL_API/Matrix_math_for_the_web +--- +<p>{{WebGLSidebar}}</p> + +<p class="summary"><span class="seoSummary">行列は、空間内のオブジェクトの変換を表すために使用でき、画像を構築したり、ウェブ上でデータを視覚化したりするときに、多くの主要な種類の計算を実行するために使用されます。 この記事では、行列を作成する方法と、<a href="/ja/docs/Web/Guide/CSS/Using_CSS_transforms">CSS transform</a> および <code>matrix3d</code> transform 型でそれらを使用する方法について説明します。</span></p> + +<p>この記事では <a href="/ja/docs/Web/CSS">CSS</a> を使用して説明を簡略化しますが、行列は <a href="/ja/docs/Web/API/WebGL_API">WebGL</a>、<a href="/ja/docs/Web/API/WebXR_Device_API">WebXR</a>(VR および AR)API、<a href="/ja/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders">GLSL シェーダー</a>などのさまざまなテクノロジーで使用されるコアコンセプトです。 この記事は、<a href="https://github.com/TatumCreative/mdn-matrix-math">MDN コンテンツキット</a>としても入手できます。 実際の例では、<code>MDN</code> という名前のグローバルオブジェクトで使用できる<a href="https://github.com/TatumCreative/mdn-webgl">ユーティリティ関数</a>のコレクションを使用しています。</p> + +<h2 id="Transformation_matrices" name="Transformation_matrices">変換行列</h2> + +<p>行列には多くの種類がありますが、私たちが興味を持っているのは 3D 変換行列です。 これらの行列は、4x4 のグリッドに配置された 16 個の値のセットで構成されています。 <a href="/ja/docs/Web/JavaScript">JavaScript</a> では、行列を配列として表すのは簡単です。</p> + +<p>まず、<strong>単位行列</strong>(identity matrix)について検討します。 これは特別な変換行列であり、スカラー乗算での 1 と同じように機能します。 n * 1 = n と同様に、任意の行列に単位行列を乗算すると、元の行列と値が一致する結果の行列が得られます。</p> + +<p>単位行列は JavaScript では次のようになります。</p> + +<pre class="brush: js notranslate">let identityMatrix = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +]; +</pre> + +<p>単位行列の乗算とはどのようなものでしょうか? 最も簡単な例は、単一の点に単位行列を乗算することです。 3D の点に必要なのは3つの値(x、y、z)だけであり、変換行列は 4x4 の値の行列なので、点には 4 番目の次元を追加する必要があります。 慣例により、この次元は<strong>パースペクティブ</strong>(perspective)と呼ばれ、文字 w で表されます。 一般的には、w を 1 に設定すると、計算がうまくいきます。</p> + +<p>w 成分を点に追加した後、行列と点がどのようにきれいに並んでいるかに注目してください。</p> + +<pre class="brush: js notranslate">[1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1] + +[4, 3, 2, 1] // Point at [x, y, z, w] +</pre> + +<p>w 成分には、この記事の範囲外のいくつかの追加の用途があります。 <a href="/ja/docs/Web/API/WebGL_API/WebGL_model_view_projection">WebGL モデルビュー投影</a>に関する記事を調べて、どのように役立つかを覗いてみてください。</p> + +<h3 id="Multiplying_a_matrix_and_a_point" name="Multiplying_a_matrix_and_a_point">行列と点の乗算</h3> + +<p>このサンプルコードでは、行列と点を乗算する関数 <code>multiplyMatrixAndPoint()</code> を定義しています。</p> + +<pre class="brush: js notranslate">// 点 • 行列 +function multiplyMatrixAndPoint(matrix, point) { + // 行列の各部分に、列 c、行 r の番号で単純な変数名を付けます + let c0r0 = matrix[ 0], c1r0 = matrix[ 1], c2r0 = matrix[ 2], c3r0 = matrix[ 3]; + let c0r1 = matrix[ 4], c1r1 = matrix[ 5], c2r1 = matrix[ 6], c3r1 = matrix[ 7]; + let c0r2 = matrix[ 8], c1r2 = matrix[ 9], c2r2 = matrix[10], c3r2 = matrix[11]; + let c0r3 = matrix[12], c1r3 = matrix[13], c2r3 = matrix[14], c3r3 = matrix[15]; + + // 次に、点にある単純な名前を設定します + let x = point[0]; + let y = point[1]; + let z = point[2]; + let w = point[3]; + + // 1番目の列の各部分に対して点を乗算し、次に合計します + let resultX = (x * c0r0) + (y * c0r1) + (z * c0r2) + (w * c0r3); + + // 2番目の列の各部分に対して点を乗算し、次に合計します + let resultY = (x * c1r0) + (y * c1r1) + (z * c1r2) + (w * c1r3); + + // 3番目の列の各部分に対して点を乗算し、次に合計します + let resultZ = (x * c2r0) + (y * c2r1) + (z * c2r2) + (w * c2r3); + + // 4番目の列の各部分に対して点を乗算し、次に合計します + let resultW = (x * c3r0) + (y * c3r1) + (z * c3r2) + (w * c3r3); + + return [resultX, resultY, resultZ, resultW]; +} +</pre> + +<p>上記の関数を使用して、点に行列を掛けることができます。 単位行列を使用すると、元の行列と同じ行列が返されます。 これは、単位行列を掛けた行列は常にそれ自体と等しいためです。</p> + +<pre class="brush: js notranslate">// identityResult を [4,3,2,1] に設定します +let identityResult = multiplyMatrixAndPoint(identityMatrix, [4, 3, 2, 1]); +</pre> + +<p>同じ点を返すことはあまり役に立ちませんが、点に対して便利な操作を実行できる他の種類の行列があります。 次のセクションでは、これらの行列のいくつかを示します。</p> + +<h3 id="Multiplying_two_matrices" name="Multiplying_two_matrices">2つの行列の乗算</h3> + +<p>行列と点を乗算することに加えて、2つの行列を乗算することもできます。 上記の関数は、このプロセスを支援するために再利用できます。</p> + +<pre class="brush: js notranslate">// 行列B • 行列A +function multiplyMatrices(matrixA, matrixB) { + // 2番目の行列を行にスライスします + let row0 = [matrixB[ 0], matrixB[ 1], matrixB[ 2], matrixB[ 3]]; + let row1 = [matrixB[ 4], matrixB[ 5], matrixB[ 6], matrixB[ 7]]; + let row2 = [matrixB[ 8], matrixB[ 9], matrixB[10], matrixB[11]]; + let row3 = [matrixB[12], matrixB[13], matrixB[14], matrixB[15]]; + + // 各行に行列Aを掛けます + let result0 = multiplyMatrixAndPoint(matrixA, row0); + let result1 = multiplyMatrixAndPoint(matrixA, row1); + let result2 = multiplyMatrixAndPoint(matrixA, row2); + let result3 = multiplyMatrixAndPoint(matrixA, row3); + + // 結果の行を単一の行列に戻します + return [ + result0[0], result0[1], result0[2], result0[3], + result1[0], result1[1], result1[2], result1[3], + result2[0], result2[1], result2[2], result2[3], + result3[0], result3[1], result3[2], result3[3] + ]; +} +</pre> + +<p id="Usage">この関数の動作を見てみましょう。</p> + +<pre class="brush: js notranslate">let someMatrix = [ + 4, 0, 0, 0, + 0, 3, 0, 0, + 0, 0, 5, 0, + 4, 8, 4, 1 +] + +let identityMatrix = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +]; + +// someMatrix と同等の新しい配列を返します +let someMatrixResult = multiplyMatrices(identityMatrix, someMatrix); +</pre> + +<div class="warning"> +<p><strong>重要</strong>: これらの行列関数は、説明を明確にするために書かれており、速度やメモリ管理のためには書かれていません。 これらの関数は多くの新しい配列を作成しますが、これはガベージコレクションのために、リアルタイム操作に特にコストがかかる可能性があります。 実際の製品コードでは、最適化された関数を使用するのが最善です。 <a href="http://glmatrix.net/">glMatrix</a> は、速度とパフォーマンスに重点を置いたライブラリーの例です。 glMatrix ライブラリーの焦点は、更新ループの前に割り当てられるターゲット配列を持つことです。</p> +</div> + +<h2 id="Translation_matrix" name="Translation_matrix">平行移動行列</h2> + +<p><strong>平行移動行列</strong>(translation matrix)は単位行列に基づいており、3D グラフィックスで使用され、3つの方向(x、y、z)の1つまたは複数に点またはオブジェクトを移動します。 平行移動を考える最も簡単な方法は、コーヒーカップを手に取るようなものです。 コーヒーがこぼれないように、コーヒーカップは直立させ、同じ方向に向ける必要があります。 それは、テーブルから離れて空中をあちこちと移動できます。</p> + +<p>コーヒーを口の中に注ぐには、カップを傾けたり回転させたりする必要があるため、実際には平行移動行列だけを使用してコーヒーを飲むことはできません。 これを行うために使用する行列の種類(巧妙に<strong>{{anch("Rotation matrix", "回転行列")}}</strong>と呼ばれます)を後で見ていきます。</p> + +<pre class="brush: js notranslate">let x = 50; +let y = 100; +let z = 0; + +let translationMatrix = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + x, y, z, 1 +]; +</pre> + +<p>3つの軸に沿った距離を平行移動行列の対応する位置に配置し、3D 空間を移動するために必要な点または行列に掛けます。</p> + +<h2 id="Manipulating_the_DOM_with_a_matrix" name="Manipulating_the_DOM_with_a_matrix">行列で DOM を操作する</h2> + +<p>行列を使い始める本当に簡単な方法は、CSS {{cssxref("transform-function/matrix3d","matrix3d()")}} {{cssxref("transform")}} を使用することです。 まず、コンテンツを含む単純な {{htmlelement("div")}} を設定します。 スタイルは示しませんが、幅と高さが固定され、ページの中央に配置されます。 <code><div></code> には transform 用の遷移セットがあるため、何が行われているかを簡単に確認できるように行列がアニメーション化されます。</p> + +<pre class="brush: html notranslate"><div id='move-me' class='transformable'> + <h2>Move me with a matrix</h2> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p> +</div> +</pre> + +<p>最後に、各例で 4x4 マトリックスを生成し、<code><div></code> のスタイルを更新して、transform を適用し、<code>matrix3d</code> に設定します。 行列が4行4列で構成されている場合でも、行列は16個の値の1行につぶされていることに注意してください。 行列は常に JavaScript の1次元のリストに格納されます。</p> + +<pre class="brush: js notranslate">// 行列の配列から matrix3d スタイルプロパティを作成します +function matrixArrayToCssMatrix(array) { + return 'matrix3d(' + array.join(',') + ')'; +} + +// DOM 要素を取得します +let moveMe = document.getElementById('move-me'); + +// 次のような結果を返します: "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 50, 100, 0, 1);" +let matrix3dRule = matrixArrayToCssMatrix(translationMatrix); + +// transform を設定します +moveMe.style.transform = matrix3dRule; +</pre> + +<p><a href="https://jsfiddle.net/g24mgw6y">JSFiddle で観る</a></p> + +<p><img alt="行列による平行移動の例" src="https://mdn.mozillademos.org/files/11409/matrix-translation.jpg" style="height: 385px; width: 339px;"></p> + +<h2 id="Scale_matrix" name="Scale_matrix">拡大縮小行列</h2> + +<p><strong>拡大縮小行列</strong>(scale matrix)は、幅、高さ、奥行きの3つの次元の1つ以上で何かを大きくまたは小さくします。 典型的な(デカルト)座標では、これによりオブジェクトが対応する方向に伸縮します。</p> + +<p>幅、高さ、奥行きのそれぞれに適用する変更の量は、左上隅から右下に向かって斜めに配置されます。</p> + +<pre class="brush: js notranslate">let w = 1.5; // width (x) +let h = 0.7; // height (y) +let d = 1; // depth (z) + +let scaleMatrix = [ + w, 0, 0, 0, + 0, h, 0, 0, + 0, 0, d, 0, + 0, 0, 0, 1 +]; +</pre> + +<p><a href="https://jsfiddle.net/fndd6e1b">JSFiddle で観る</a></p> + +<p><img alt="行列による拡大縮小の例" src="https://mdn.mozillademos.org/files/11407/matrix-scale.jpg" style="height: 291px; width: 398px;"></p> + +<h2 id="Rotation_matrix" name="Rotation_matrix">回転行列</h2> + +<p><strong>回転行列</strong>(rotation matrix)は、点またはオブジェクトを回転させるために使用します。 回転行列は、拡大縮小行列や平行移動行列よりも少し複雑に見えます。 これは、三角関数を使用して回転を実行します。 このセクションでは、手順を完全な詳細に分解しませんが(<a href="http://mathworld.wolfram.com/RotationMatrix.html">Wolfram MathWorld のこの記事</a>を調べてください)、説明のためにこの例を取り上げます。</p> + +<p>まず、行列を使用せずに原点を中心に点を回転させるコードを次に示します。</p> + +<pre class="brush: js notranslate">// 行列なしで原点を中心に手動で点を回転 +let point = [10, 2]; + +// 原点からの距離を計算します +let distance = Math.sqrt(point[0] * point[0] + point[1] * point[1]); + +// ラジアンで60度に相当 +let rotationInRadians = Math.PI / 3; + +let transformedPoint = [ + Math.cos(rotationInRadians) * distance, + Math.sin(rotationInRadians) * distance +]; +</pre> + +<p>これらのタイプのステップを行列にエンコードし、x、y、z の各次元に対してそれを行うことができます。 以下は、X 軸を中心とした回転の表現です。</p> + +<pre class="brush: js notranslate">let sin = Math.sin; +let cos = Math.cos; + +// 注: これらの変換にはパースペクティブがないため、 +// この時点での回転は div を縮小するためにのみ示されます + +let a = Math.PI * 0.3; // ラジアンでの回転量 + +// Z 軸を中心に回転 +let rotateZMatrix = [ + cos(a), -sin(a), 0, 0, + sin(a), cos(a), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +]; +</pre> + +<p><a href="https://jsfiddle.net/9vr2dorz">JSFiddle で観る</a></p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11405/matrix-rotation.jpg" style="height: 363px; width: 417px;"></p> + +<p>3つの軸のそれぞれを中心に回転するための回転行列を返す関数のセットを次に示します。 大きな注意点の1つは、パースペクティブが適用されていないため、まだとても 3D に感じられない可能性があることです。 平面度(flatness)は、カメラが遠くのオブジェクトにズームインで非常に接近したときと同じです — 遠近感(sense of perspective)がなくなります。</p> + +<pre class="brush: js notranslate">function rotateAroundXAxis(a) { + return [ + 1, 0, 0, 0, + 0, cos(a), -sin(a), 0, + 0, sin(a), cos(a), 0, + 0, 0, 0, 1 + ]; +} + +function rotateAroundYAxis(a) { + return [ + cos(a), 0, sin(a), 0, + 0, 1, 0, 0, + -sin(a), 0, cos(a), 0, + 0, 0, 0, 1 + ]; +} + +function rotateAroundZAxis(a) { + return [ + cos(a), -sin(a), 0, 0, + sin(a), cos(a), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ]; +} +</pre> + +<p><a href="https://jsfiddle.net/tk072doc">JSFiddle で観る</a></p> + +<h2 id="Matrix_composition" name="Matrix_composition">行列合成</h2> + +<p>行列の本当の力は、<strong>行列合成</strong>(matrix composition)に由来します。 特定のクラスの行列を掛け合わせると、変換の履歴が保持され、元に戻すことができます。 つまり、平行移動、回転、拡大縮小の行列がすべて組み合わされている場合、行列の順序を逆にして再適用すると、元の点が返されます。</p> + +<p>行列を乗算する順序は重要です。 数値を乗算する場合、a * b = c と b * a = c はどちらも真です。 例えば、3 * 4 = 12 と 4 * 3 = 12 です。 数学では、これらの数値は<strong>可換</strong>(commutative)であると説明されます。 順序が入れ替わった場合、行列では同じであることが保証されないため、行列は<strong>非可換</strong>(non-commutative)です。</p> + +<p>もう1つのマインドベンダーは、WebGL および CSS での行列乗算は、操作が直感的に発生するのとは逆の順序で発生する必要があることです。 例えば、何かを80%縮小し、200ピクセル下に移動してから、原点を中心に90度回転すると、疑似コードでは次のようになります。</p> + +<pre class="notranslate"> transformation = rotate * translate * scale +</pre> + +<h3 id="Composing_multiple_transformations" name="Composing_multiple_transformations">複数の変換の合成</h3> + +<p>行列の合成に使用する関数は <code>multiplyArrayOfMatrices()</code> です。 これは、この記事の冒頭で紹介した<a href="https://github.com/TatumCreative/mdn-webgl">ユーティリティ関数</a>のセットの一部です。 行列の配列を取り、それらを掛け合わせて結果を返します。 WebGL シェーダーコードでは、これは言語に組み込まれており、<code>*</code> 演算子を使用できます。 さらに、この例では、上で定義した行列を返す <code>scale()</code> 関数と <code>translate()</code> 関数を使用しています。</p> + +<pre class="brush: js notranslate">let transformMatrix = MDN.multiplyArrayOfMatrices([ + rotateAroundZAxis(Math.PI * 0.5), // ステップ 3: 90度回転 + translate(0, 200, 0), // ステップ 2: 100ピクセル下に移動 + scale(0.8, 0.8, 0.8), // ステップ 1: 縮小 +]); + +</pre> + +<p><a href="https://jsfiddle.net/qxxg3yvc">JSFiddle で観る</a></p> + +<p><img alt="行列合成の例" src="https://mdn.mozillademos.org/files/11403/matrix-composition.jpg" style="height: 292px; width: 488px;"></p> + +<p>最後に、行列がどのように機能するかを示す楽しい手順は、手順を逆にして、行列を元の単位行列に戻すことです。</p> + +<pre class="brush: js notranslate">let transformMatrix = MDN.multiplyArrayOfMatrices([ + scale(1.25, 1.25, 1.25), // ステップ 6: 縮小を元に戻す + translate(0, -200, 0), // ステップ 5: 移動を元に戻す + rotateAroundZAxis(-Math.PI * 0.5), // ステップ 4: 回転を元に戻す + rotateAroundZAxis(Math.PI * 0.5), // ステップ 3: 90度回転 + translate(0, 200, 0), // ステップ 2: 100ピクセル下に移動 + scale(0.8, 0.8, 0.8), // ステップ 1: 縮小 +]); +</pre> + +<h2 id="Why_matrices_are_important" name="Why_matrices_are_important">行列が重要な理由</h2> + +<p>行列は、空間での幅広い変換を表すことができる数の小さなセットで構成されるため、重要です。 それらはプログラム内で簡単に共有できます。 さまざまな座標空間を行列で記述できます。 一部の行列乗算では、1つのデータのセットを1つの座標空間から別の座標空間に移動します。 行列は、それらを生成するために使用された以前の変形のすべての部分を効果的に記憶します。</p> + +<p>WebGL で使用する場合、グラフィックスカードは、空間内の多数の点に行列を乗算するのに特に適しています。 点の配置、照明の計算、アニメのキャラクターのポーズなどのさまざまな操作はすべて、この基本的なツールに依存しています。</p> diff --git a/files/ja/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.html b/files/ja/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.html new file mode 100644 index 0000000000..678560a2bf --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.html @@ -0,0 +1,299 @@ +--- +title: WebGL コンテキストへの平面コンテンツの追加 +slug: Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context +tags: + - Tutorial + - WebGL +translation_of: Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context +--- +<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}}</p> + +<p><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL">WebGL コンテキストの作成</a>に成功したら、レンダリングを開始できます。もっとも簡単にできることは、テクスチャが貼り付けられていない単純な正方形を描画することです。そこで、正方形の平面を描画するコードを作成することから始めましょう。</p> + +<h2 id="Drawing_the_scene" name="Drawing_the_scene">シーンを描画する</h2> + +<p>レンダリングを始める前に理解しておくべきもっとも重要なことは、今回の例では正方形の平面オブジェクトのみをレンダリングしていますが、それは 3 次元の空間に描画されるということです。正方形を描いているだけで、カメラの正面に視線方向に垂直に直接配置しています。単純なシーンの色を作成し、オブジェクトを描画するシェーダーを定義する必要があります。これらは正方形の平面が画面にどのように表示されるかを確立します。</p> + +<h3 id="The_shaders" name="The_shaders">シェーダー</h3> + +<p><strong>シェーダー</strong> は、 <a href="https://www.khronos.org/files/opengles_shading_language.pdf">OpenGL ES Shading Language</a> (<strong>GLSL</strong>) を使用して記述されたプログラムであり、形状を構成する頂点に関する情報を取得し、画面上にピクセルをレンダリングするために必要なデータ、すなわち<span class="tlid-translation translation" lang="ja"><span title="">ピクセルの位置とその色</span></span>を生成します。</p> + +<p>WebGL コンテンツを描画するときに実行される2つのシェーダー関数があります。<strong>頂点シェーダー</strong>と<strong>フラグメントシェーダー</strong>です。これらを GLSL で記述し、コードのテキストを WebGL に渡して、GPU で実行するためにコンパイルします。 頂点シェーダーとフラグメントシェーダーのセットを合わせて、<strong>シェーダープログラム</strong>と呼びます。</p> + +<p>2種類のシェーダーを WebGL コンテキストに描画する例を念頭に置いて、2種類のシェーダーを簡単に見てみましょう。</p> + +<h4 id="頂点シェーダー">頂点シェーダー</h4> + +<p>シェイプがレンダリングされるたびに、頂点シェーダーがシェイプの各頂点に対して実行されます。その仕事は、入力頂点を元の座標系から WebGL が使用する <strong>clipspace</strong> 座標系に変換することです。各軸の範囲はアスペクト比、実際のサイズ、またはその他の要因に関係なく -1.0 〜 1.0 です。</p> + +<p>頂点シェーダーは頂点の位置で必要な変換を実行し、頂点ごとに行う必要がある他の調整または計算を行い、GLSL によって提供される <code>gl_Position</code> と呼ばれる特別な変数に保存して、変換された頂点を返す必要があります。</p> + +<p>シェーダーは必要に応じて {{interwiki("wikipedia", "texel_(graphics)", "texel")}} の面のテクスチャ内の座標を決定して頂点に適用したり、法線を適用して頂点に適用する照明係数を決定したりすることもできます。この情報は、フラグメントシェーダーと共有するために、必要に応じて <a href="/ja/docs/Web/API/WebGL_API/Data#Varyings">varyings</a> または <a href="/ja/docs/Web/API/WebGL_API/Data#Attributes">attributes</a> に保存できます。</p> + +<p>以下の頂点シェーダーは <code>aVertexPosition</code> と呼ばれる定義した属性から頂点位置の値を受け取ります。次に、その位置に <code>uProjectionMatrix</code> および <code>uModelViewMatrix</code>という 2 つの 4 x 4 行列を乗算します。<code>gl_Position</code> は結果に設定されます。投影法およびその他のマトリックスの詳細については、<a href="https://webglfundamentals.org/webgl/lessons/ja/webgl-3d-perspective.html">この記事が役立つ場合があります</a>。</p> + +<pre class="brush: html line-numbers language-html"><code class="language-html"> // 頂点シェーダーのプログラム + + const vsSource = ` + attribute vec4 aVertexPosition; + + uniform mat4 uModelViewMatrix; + uniform mat4 uProjectionMatrix; + + void main() { + gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; + } + `;</code></pre> + +<p>頂点の位置に <code>vec4</code> 属性を使用していることに注意してください。実際には 4 コンポーネントベクトルを使用していません。つまり、状況に応じて <code>vec2</code> または <code>vec3</code> として処理できます。ただし、数学を実行するときは <code>vec4</code> である必要があります。したがって、数学を実行するたびに <code>vec4</code> に変換するのではなく、最初から <code>vec4</code> を使用します。これにより、シェーダーで行うすべての計算から操作が排除されます。 パフォーマンスが重要です。</p> + +<p>この例ではシーンにまだ何も適用していないため、ライティングをまったく計算していません。これは、<a href="/ja/docs/Web/API/WebGL_API/Tutorial/Lighting_in_WebGL">WebGL でのライティング</a>の例で後ほど説明します。また、ここではテクスチャを使用した作業がないことに注意してください。これは、<a href="/ja/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL">WebGL でのテクスチャの使用</a>に追加されます。</p> + +<h4 id="フラグメントシェーダー">フラグメントシェーダー</h4> + +<p><strong>フラグメントシェーダー</strong>は、図形の頂点が頂点シェーダーによって処理された後、描画される各図形のすべてのピクセルに対して1回呼び出されます。その仕事は、ピクセルに適用するテクセル (つまり、シェイプのテクスチャ内のピクセル) を特定し、そのテクセルの色を取得し、その色に適切な照明を適用することによりそのピクセルの色を決定することです。色は特別な変数 <code>gl_FragColor</code> に保存することにより、WebGL レイヤーに返されます。その色は、図形の対応するピクセルの正しい位置で画面に描画されます。</p> + +<p>この場合、照明を使用せずに白い正方形を描画するだけなので、毎回単純に白を返します。</p> + +<pre class="brush: html line-numbers language-html"><code class="language-html"> const fsSource = ` + void main() { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + `;</code></pre> + +<h3 id="Initializing_the_shaders" name="Initializing_the_shaders">シェーダーの初期化</h3> + +<p>2つのシェーダーを定義したので、それらを WebGL に渡してコンパイルし、リンクする必要があります。以下のコードは <code>loadShader()</code> を呼び出して2つのシェーダーを作成し、シェーダーのタイプとソースを渡します。次にプログラムを作成し、シェーダーを接続してそれらをリンクします。コンパイルまたはリンクが失敗した場合、コードはアラートを表示します。</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="comment token">//</span> +<span class="comment token">// Initialize a shader program, so WebGL knows how to draw our data</span> +<span class="comment token">//</span> +<span class="keyword token">function</span> <span class="function token">initShaderProgram</span><span class="punctuation token">(</span><span class="parameter token">gl<span class="punctuation token">,</span> vsSource<span class="punctuation token">,</span> fsSource</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">const</span> vertexShader <span class="operator token">=</span> <span class="function token">loadShader</span><span class="punctuation token">(</span>gl<span class="punctuation token">,</span> gl<span class="punctuation token">.</span><span class="constant token">VERTEX_SHADER</span><span class="punctuation token">,</span> vsSource<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">const</span> fragmentShader <span class="operator token">=</span> <span class="function token">loadShader</span><span class="punctuation token">(</span>gl<span class="punctuation token">,</span> gl<span class="punctuation token">.</span><span class="constant token">FRAGMENT_SHADER</span><span class="punctuation token">,</span> fsSource<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Create the shader program</span> + + <span class="keyword token">const</span> shaderProgram <span class="operator token">=</span> gl<span class="punctuation token">.</span><span class="function token">createProgram</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + gl<span class="punctuation token">.</span><span class="function token">attachShader</span><span class="punctuation token">(</span>shaderProgram<span class="punctuation token">,</span> vertexShader<span class="punctuation token">)</span><span class="punctuation token">;</span> + gl<span class="punctuation token">.</span><span class="function token">attachShader</span><span class="punctuation token">(</span>shaderProgram<span class="punctuation token">,</span> fragmentShader<span class="punctuation token">)</span><span class="punctuation token">;</span> + gl<span class="punctuation token">.</span><span class="function token">linkProgram</span><span class="punctuation token">(</span>shaderProgram<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// If creating the shader program failed, alert</span> + + <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="operator token">!</span>gl<span class="punctuation token">.</span><span class="function token">getProgramParameter</span><span class="punctuation token">(</span>shaderProgram<span class="punctuation token">,</span> gl<span class="punctuation token">.</span><span class="constant token">LINK_STATUS</span><span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">alert</span><span class="punctuation token">(</span><span class="string token">'Unable to initialize the shader program: '</span> <span class="operator token">+</span> gl<span class="punctuation token">.</span><span class="function token">getProgramInfoLog</span><span class="punctuation token">(</span>shaderProgram<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span> <span class="keyword token">null</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">return</span> shaderProgram<span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="comment token">//</span> +<span class="comment token">// creates a shader of the given type, uploads the source and</span> +<span class="comment token">// compiles it.</span> +<span class="comment token">//</span> +<span class="keyword token">function</span> <span class="function token">loadShader</span><span class="punctuation token">(</span><span class="parameter token">gl<span class="punctuation token">,</span> type<span class="punctuation token">,</span> source</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">const</span> shader <span class="operator token">=</span> gl<span class="punctuation token">.</span><span class="function token">createShader</span><span class="punctuation token">(</span>type<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Send the source to the shader object</span> + + gl<span class="punctuation token">.</span><span class="function token">shaderSource</span><span class="punctuation token">(</span>shader<span class="punctuation token">,</span> source<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Compile the shader program</span> + + gl<span class="punctuation token">.</span><span class="function token">compileShader</span><span class="punctuation token">(</span>shader<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// See if it compiled successfully</span> + + <span class="keyword token">if</span> <span class="punctuation token">(</span><span class="operator token">!</span>gl<span class="punctuation token">.</span><span class="function token">getShaderParameter</span><span class="punctuation token">(</span>shader<span class="punctuation token">,</span> gl<span class="punctuation token">.</span><span class="constant token">COMPILE_STATUS</span><span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="function token">alert</span><span class="punctuation token">(</span><span class="string token">'An error occurred compiling the shaders: '</span> <span class="operator token">+</span> gl<span class="punctuation token">.</span><span class="function token">getShaderInfoLog</span><span class="punctuation token">(</span>shader<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + gl<span class="punctuation token">.</span><span class="function token">deleteShader</span><span class="punctuation token">(</span>shader<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span> <span class="keyword token">null</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="keyword token">return</span> shader<span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p>The <code>loadShader()</code> function takes as input the WebGL context, the shader type, and the source code, then creates and compiles the shader as follows:</p> + +<ol> + <li>A new shader is created by calling {{domxref("WebGLRenderingContext.createShader", "gl.createShader()")}}.</li> + <li>The shader's source code is sent to the shader by calling {{domxref("WebGLRenderingContext.shaderSource", "gl.shaderSource()")}}.</li> + <li>Once the shader has the source code, it's compiled using {{domxref("WebGLRenderingContext.compileShader", "gl.compileShader()")}}.</li> + <li>To check to be sure the shader successfully compiled, the shader parameter <code>gl.COMPILE_STATUS</code> is checked. To get its value, we call {{domxref("WebGLRenderingContext.getShaderParameter", "gl.getShaderParameter()")}}, specifying the shader and the name of the parameter we want to check (<code>gl.COMPILE_STATUS</code>). If that's <code>false</code>, we know the shader failed to compile, so show an alert with log information obtained from the compiler using {{domxref("WebGLRenderingContext.getShaderInfoLog", "gl.getShaderInfoLog()")}}, then delete the shader and return <code>null</code> to indicate a failure to load the shader.</li> + <li>If the shader was loaded and successfully compiled, the compiled shader is returned to the caller.</li> +</ol> + +<p>To use this code we call it like this</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"> <span class="keyword token">const</span> shaderProgram <span class="operator token">=</span> <span class="function token">initShaderProgram</span><span class="punctuation token">(</span>gl<span class="punctuation token">,</span> vsSource<span class="punctuation token">,</span> fsSource<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>After we've created a shader program we need to look up the locations that WebGL assigned to our inputs. In this case we have one attribute and two uniforms. Attributes receive values from buffers. Each iteration of the vertex shader receives the next value from the buffer assigned to that attribute. <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Data#Uniforms">Uniforms</a> are similar to JavaScript global variables. They stay the same value for all iterations of a shader. Since the attribute and uniform locations are specific to a single shader program we'll store them together to make them easy to pass around</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"> <span class="keyword token">const</span> programInfo <span class="operator token">=</span> <span class="punctuation token">{</span> + program<span class="punctuation token">:</span> shaderProgram<span class="punctuation token">,</span> + attribLocations<span class="punctuation token">:</span> <span class="punctuation token">{</span> + vertexPosition<span class="punctuation token">:</span> gl<span class="punctuation token">.</span><span class="function token">getAttribLocation</span><span class="punctuation token">(</span>shaderProgram<span class="punctuation token">,</span> <span class="string token">'aVertexPosition'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> + <span class="punctuation token">}</span><span class="punctuation token">,</span> + uniformLocations<span class="punctuation token">:</span> <span class="punctuation token">{</span> + projectionMatrix<span class="punctuation token">:</span> gl<span class="punctuation token">.</span><span class="function token">getUniformLocation</span><span class="punctuation token">(</span>shaderProgram<span class="punctuation token">,</span> <span class="string token">'uProjectionMatrix'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> + modelViewMatrix<span class="punctuation token">:</span> gl<span class="punctuation token">.</span><span class="function token">getUniformLocation</span><span class="punctuation token">(</span>shaderProgram<span class="punctuation token">,</span> <span class="string token">'uModelViewMatrix'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> + <span class="punctuation token">}</span><span class="punctuation token">,</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span></code></pre> + +<h2 id="Creating_the_square_plane">Creating the square plane</h2> + +<p>Before we can render our square plane, we need to create the buffer that contains its vertex positions and put the vertex positions in it. We'll do that using a function we call <code>initBuffers()</code>; as we explore more advanced WebGL concepts, this routine will be augmented to create more -- and more complex -- 3D objects.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">initBuffers</span><span class="punctuation token">(</span><span class="parameter token">gl</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + + <span class="comment token">// Create a buffer for the square's positions.</span> + + <span class="keyword token">const</span> positionBuffer <span class="operator token">=</span> gl<span class="punctuation token">.</span><span class="function token">createBuffer</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Select the positionBuffer as the one to apply buffer</span> + <span class="comment token">// operations to from here out.</span> + + gl<span class="punctuation token">.</span><span class="function token">bindBuffer</span><span class="punctuation token">(</span>gl<span class="punctuation token">.</span><span class="constant token">ARRAY_BUFFER</span><span class="punctuation token">,</span> positionBuffer<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Now create an array of positions for the square.</span> + + <span class="keyword token">const</span> positions <span class="operator token">=</span> <span class="punctuation token">[</span> + <span class="operator token">-</span><span class="number token">1.0</span><span class="punctuation token">,</span> <span class="number token">1.0</span><span class="punctuation token">,</span> + <span class="number token">1.0</span><span class="punctuation token">,</span> <span class="number token">1.0</span><span class="punctuation token">,</span> + <span class="operator token">-</span><span class="number token">1.0</span><span class="punctuation token">,</span> <span class="operator token">-</span><span class="number token">1.0</span><span class="punctuation token">,</span> + <span class="number token">1.0</span><span class="punctuation token">,</span> <span class="operator token">-</span><span class="number token">1.0</span><span class="punctuation token">,</span> + <span class="punctuation token">]</span><span class="punctuation token">;</span> + + <span class="comment token">// Now pass the list of positions into WebGL to build the</span> + <span class="comment token">// shape. We do this by creating a Float32Array from the</span> + <span class="comment token">// JavaScript array, then use it to fill the current buffer.</span> + + gl<span class="punctuation token">.</span><span class="function token">bufferData</span><span class="punctuation token">(</span>gl<span class="punctuation token">.</span><span class="constant token">ARRAY_BUFFER</span><span class="punctuation token">,</span> + <span class="keyword token">new</span> <span class="class-name token">Float32Array</span><span class="punctuation token">(</span>positions<span class="punctuation token">)</span><span class="punctuation token">,</span> + gl<span class="punctuation token">.</span><span class="constant token">STATIC_DRAW</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">return</span> <span class="punctuation token">{</span> + position<span class="punctuation token">:</span> positionBuffer<span class="punctuation token">,</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p>This routine is pretty simplistic given the basic nature of the scene in this example. It starts by calling the <code>gl</code> object's {{domxref("WebGLRenderingContext.createBuffer()", "createBuffer()")}} method to obtain a buffer into which we'll store the vertex positions. This is then bound to the context by calling the {{domxref("WebGLRenderingContext.bindBuffer()", "bindBuffer()")}} method.</p> + +<p>Once that's done, we create a JavaScript array containing the position for each vertex of the square plane. This is then converted into an array of floats and passed into the <code>gl</code> object's {{domxref("WebGLRenderingContext.bufferData()", "bufferData()")}} method to establish the vertex positions for the object.</p> + +<h2 id="Rendering_the_scene">Rendering the scene</h2> + +<p>Once the shaders are established, the locations are looked up, and the square plane's vertex positions put in a buffer, we can actually render the scene. Since we're not animating anything in this example, our <code>drawScene()</code> function is very simple. It uses a few utility routines we'll cover shortly.</p> + +<div class="blockIndicator note"> +<p><strong>Note</strong>: You might get a JavaScript error saying " mat4 is not defined". This means there is a dependency on <code>glmatrix</code>. You can include <a href="https://mdn.github.io/webgl-examples/tutorial/gl-matrix.js">gl-matrix.js</a><a href="https://mdn.github.io/webgl-examples/tutorial/gl-matrix.js"> </a>to resolve this issue, as suggested <a href="https://github.com/mdn/webgl-examples/issues/20">here</a>.</p> +</div> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">drawScene</span><span class="punctuation token">(</span><span class="parameter token">gl<span class="punctuation token">,</span> programInfo<span class="punctuation token">,</span> buffers</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + gl<span class="punctuation token">.</span><span class="function token">clearColor</span><span class="punctuation token">(</span><span class="number token">0.0</span><span class="punctuation token">,</span> <span class="number token">0.0</span><span class="punctuation token">,</span> <span class="number token">0.0</span><span class="punctuation token">,</span> <span class="number token">1.0</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Clear to black, fully opaque</span> + gl<span class="punctuation token">.</span><span class="function token">clearDepth</span><span class="punctuation token">(</span><span class="number token">1.0</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Clear everything</span> + gl<span class="punctuation token">.</span><span class="function token">enable</span><span class="punctuation token">(</span>gl<span class="punctuation token">.</span><span class="constant token">DEPTH_TEST</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Enable depth testing</span> + gl<span class="punctuation token">.</span><span class="function token">depthFunc</span><span class="punctuation token">(</span>gl<span class="punctuation token">.</span><span class="constant token">LEQUAL</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Near things obscure far things</span> + + <span class="comment token">// Clear the canvas before we start drawing on it.</span> + + gl<span class="punctuation token">.</span><span class="function token">clear</span><span class="punctuation token">(</span>gl<span class="punctuation token">.</span><span class="constant token">COLOR_BUFFER_BIT</span> <span class="operator token">|</span> gl<span class="punctuation token">.</span><span class="constant token">DEPTH_BUFFER_BIT</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Create a perspective matrix, a special matrix that is</span> + <span class="comment token">// used to simulate the distortion of perspective in a camera.</span> + <span class="comment token">// Our field of view is 45 degrees, with a width/height</span> + <span class="comment token">// ratio that matches the display size of the canvas</span> + <span class="comment token">// and we only want to see objects between 0.1 units</span> + <span class="comment token">// and 100 units away from the camera.</span> + + <span class="keyword token">const</span> fieldOfView <span class="operator token">=</span> <span class="number token">45</span> <span class="operator token">*</span> Math<span class="punctuation token">.</span><span class="constant token">PI</span> <span class="operator token">/</span> <span class="number token">180</span><span class="punctuation token">;</span> <span class="comment token">// in radians</span> + <span class="keyword token">const</span> aspect <span class="operator token">=</span> gl<span class="punctuation token">.</span>canvas<span class="punctuation token">.</span>clientWidth <span class="operator token">/</span> gl<span class="punctuation token">.</span>canvas<span class="punctuation token">.</span>clientHeight<span class="punctuation token">;</span> + <span class="keyword token">const</span> zNear <span class="operator token">=</span> <span class="number token">0.1</span><span class="punctuation token">;</span> + <span class="keyword token">const</span> zFar <span class="operator token">=</span> <span class="number token">100.0</span><span class="punctuation token">;</span> + <span class="keyword token">const</span> projectionMatrix <span class="operator token">=</span> mat4<span class="punctuation token">.</span><span class="function token">create</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// note: glmatrix.js always has the first argument</span> + <span class="comment token">// as the destination to receive the result.</span> + mat4<span class="punctuation token">.</span><span class="function token">perspective</span><span class="punctuation token">(</span>projectionMatrix<span class="punctuation token">,</span> + fieldOfView<span class="punctuation token">,</span> + aspect<span class="punctuation token">,</span> + zNear<span class="punctuation token">,</span> + zFar<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Set the drawing position to the "identity" point, which is</span> + <span class="comment token">// the center of the scene.</span> + <span class="keyword token">const</span> modelViewMatrix <span class="operator token">=</span> mat4<span class="punctuation token">.</span><span class="function token">create</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Now move the drawing position a bit to where we want to</span> + <span class="comment token">// start drawing the square.</span> + + mat4<span class="punctuation token">.</span><span class="function token">translate</span><span class="punctuation token">(</span>modelViewMatrix<span class="punctuation token">,</span> <span class="comment token">// destination matrix</span> + modelViewMatrix<span class="punctuation token">,</span> <span class="comment token">// matrix to translate</span> + <span class="punctuation token">[</span><span class="operator token">-</span><span class="number token">0.0</span><span class="punctuation token">,</span> <span class="number token">0.0</span><span class="punctuation token">,</span> <span class="operator token">-</span><span class="number token">6.0</span><span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// amount to translate</span> + + <span class="comment token">// Tell WebGL how to pull out the positions from the position</span> + <span class="comment token">// buffer into the vertexPosition attribute.</span> + <span class="punctuation token">{</span> + <span class="keyword token">const</span> numComponents <span class="operator token">=</span> <span class="number token">2</span><span class="punctuation token">;</span> <span class="comment token">// pull out 2 values per iteration</span> + <span class="keyword token">const</span> type <span class="operator token">=</span> gl<span class="punctuation token">.</span><span class="constant token">FLOAT</span><span class="punctuation token">;</span> <span class="comment token">// the data in the buffer is 32bit floats</span> + <span class="keyword token">const</span> normalize <span class="operator token">=</span> <span class="boolean token">false</span><span class="punctuation token">;</span> <span class="comment token">// don't normalize</span> + <span class="keyword token">const</span> stride <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> <span class="comment token">// how many bytes to get from one set of values to the next</span> + <span class="comment token">// 0 = use type and numComponents above</span> + <span class="keyword token">const</span> offset <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> <span class="comment token">// how many bytes inside the buffer to start from</span> + gl<span class="punctuation token">.</span><span class="function token">bindBuffer</span><span class="punctuation token">(</span>gl<span class="punctuation token">.</span><span class="constant token">ARRAY_BUFFER</span><span class="punctuation token">,</span> buffers<span class="punctuation token">.</span>position<span class="punctuation token">)</span><span class="punctuation token">;</span> + gl<span class="punctuation token">.</span><span class="function token">vertexAttribPointer</span><span class="punctuation token">(</span> + programInfo<span class="punctuation token">.</span>attribLocations<span class="punctuation token">.</span>vertexPosition<span class="punctuation token">,</span> + numComponents<span class="punctuation token">,</span> + type<span class="punctuation token">,</span> + normalize<span class="punctuation token">,</span> + stride<span class="punctuation token">,</span> + offset<span class="punctuation token">)</span><span class="punctuation token">;</span> + gl<span class="punctuation token">.</span><span class="function token">enableVertexAttribArray</span><span class="punctuation token">(</span> + programInfo<span class="punctuation token">.</span>attribLocations<span class="punctuation token">.</span>vertexPosition<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="comment token">// Tell WebGL to use our program when drawing</span> + + gl<span class="punctuation token">.</span><span class="function token">useProgram</span><span class="punctuation token">(</span>programInfo<span class="punctuation token">.</span>program<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Set the shader uniforms</span> + + gl<span class="punctuation token">.</span><span class="function token">uniformMatrix4fv</span><span class="punctuation token">(</span> + programInfo<span class="punctuation token">.</span>uniformLocations<span class="punctuation token">.</span>projectionMatrix<span class="punctuation token">,</span> + <span class="boolean token">false</span><span class="punctuation token">,</span> + projectionMatrix<span class="punctuation token">)</span><span class="punctuation token">;</span> + gl<span class="punctuation token">.</span><span class="function token">uniformMatrix4fv</span><span class="punctuation token">(</span> + programInfo<span class="punctuation token">.</span>uniformLocations<span class="punctuation token">.</span>modelViewMatrix<span class="punctuation token">,</span> + <span class="boolean token">false</span><span class="punctuation token">,</span> + modelViewMatrix<span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="punctuation token">{</span> + <span class="keyword token">const</span> offset <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> + <span class="keyword token">const</span> vertexCount <span class="operator token">=</span> <span class="number token">4</span><span class="punctuation token">;</span> + gl<span class="punctuation token">.</span><span class="function token">drawArrays</span><span class="punctuation token">(</span>gl<span class="punctuation token">.</span><span class="constant token">TRIANGLE_STRIP</span><span class="punctuation token">,</span> offset<span class="punctuation token">,</span> vertexCount<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<p>The first step is to clear the canvas to our background color; then we establish the camera's perspective. We set a field of view of 45°, with a width to height ratio that match the display dimensions of our canvas. We also specify that we only want objects between 0.1 and 100 units from the camera to be rendered.</p> + +<p>Then we establish the position of the square plane by loading the identity position and translating away from the camera by 6 units. After that, we bind the square's vertex buffer to the attribute the shader is using for <code>aVertexPosition</code> and we tell WebGL how to pull the data out of it. Finally we draw the object by calling the {{domxref("WebGLRenderingContext.drawArrays()", "drawArrays()")}} method.</p> + +<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample2/index.html', 670, 510) }}</p> + +<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample2">View the complete code</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample2/">Open this demo on a new page</a></p> + +<h2 id="Matrix_utility_operations">Matrix utility operations</h2> + +<p>Matrix operations might seem complicated but <a href="https://webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html">they are actually pretty simple if you take them one step at a time</a>. Generally people use a matrix library rather than writing their own. In our case we're using the popular <a href="http://glmatrix.net/">glMatrix library</a>.</p> + +<p>See also</p> + +<ul> + <li><a href="https://webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html">Matrices</a> on WebGLFundamentals</li> + <li><a class="external external-icon" href="http://mathworld.wolfram.com/Matrix.html">Matrices</a> on Wolfram MathWorld</li> + <li><a class="external external-icon" href="http://en.wikipedia.org/wiki/Matrix_(mathematics)">Matrix</a> on Wikipedia</li> +</ul> + +<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}}</p> diff --git a/files/ja/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html b/files/ja/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html new file mode 100644 index 0000000000..196a0e9879 --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.html @@ -0,0 +1,126 @@ +--- +title: WebGL でのオブジェクトのアニメーティング +slug: Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL +tags: + - Tutorial + - WebGL +translation_of: Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL +--- +<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL") }}</p> + +<p>前の例で作成したコードはすでに、WebGL のシーンを 15 ミリ秒ごとに再描画するよう設定されています。今までは単純に、毎回同じものをそのまま再描画していました。これから、正方形が実際に動くようにコードを変えていきます。</p> + +<p>今回の例では 2D の正方形を 3 次元空間で、実際に回転や移動させます。これにより、作成したのは 2D のオブジェクトですが、それは 3D 空間に存在していることが証明されます。</p> + +<h2 id="Making_the_square_rotate" name="Making_the_square_rotate">正方形を回転させる</h2> + +<p>正方形を回転させてみましょう。始めに、正方形の回転をたどる変数が必要です:</p> + +<pre class="brush: js">var squareRotation = 0.0; +</pre> + +<p>そして、描画する際に正方形に回転を適用するよう、<code>drawScene()</code> 関数を更新することが必要です。正方形の初期描画位置に移した後、回転を以下のように適用します:</p> + +<pre class="brush: js">mvPushMatrix(); +mvRotate(squareRotation, [1, 0, 1]); +</pre> + +<p>これを現在のモデルビュー行列に保存し、そして行列を現在の <code>squareRotation</code> の値を基に、X 軸および Z 軸で回転させます。</p> + +<p>描画後は、元の行列に戻さなければなりません:</p> + +<pre class="brush: js"> mvPopMatrix(); +</pre> + +<p>後に描画する別のオブジェクトを回転させてしまうことを防ぐために、元の行列を保存および復元します。今回の例では他に描画するものがありませんので、これは役目がありません。</p> + +<p>実際に動かすために、時間がたつにつれて <code>squareRotation</code> の値を変えていくコードを追加しなければなりません。これは最後にアニメーションを行った時刻を追跡する新たな変数 (<code>lastSquareUpdateTime</code> と呼びましょう) を作成することで実現できるので、<code>drawScene()</code> 関数の末尾に以下のコードを追加します。:</p> + +<pre class="brush: js"> var currentTime = Date.now(); + if (lastSquareUpdateTime) { + var delta = currentTime - lastSquareUpdateTime; + + squareRotation += (30 * delta) / 1000.0; + } + + lastSquareUpdateTime = currentTime; +</pre> + +<p>このコードは正方形をどれだけ回転させるかを決めるために、最後に <code>squareRotation</code> の値を更新してから経過した時間を使用しています。</p> + +<h2 id="Making_the_square_move" name="Making_the_square_move">正方形を動かす</h2> + +<p>同様に、描画前に位置情報を変えていくことで正方形を移動させることができます。以下の例で、いくつかの基本的なアニメーションを行ってみます (当然ながら、実際はここまで極端に動かそうとは思わないでしょう) 。</p> + +<p>新しい変数で、移動する際の各軸のオフセットをたどりましょう:</p> + +<pre class="brush: js">var squareXOffset = 0.0; +var squareYOffset = 0.0; +var squareZOffset = 0.0; +</pre> + +<p>また、各軸の値をどれだけ変化させるかを以下の変数で示します:</p> + +<pre class="brush: js">var xIncValue = 0.2; +var yIncValue = -0.4; +var zIncValue = 0.3; +</pre> + +<p>そして先ほどの回転させるサンプルコードを、以下のコードを追加して更新します:</p> + +<pre class="brush: js"> squareXOffset += xIncValue * ((30 * delta) / 1000.0); + squareYOffset += yIncValue * ((30 * delta) / 1000.0); + squareZOffset += zIncValue * ((30 * delta) / 1000.0); + + if (Math.abs(squareYOffset) > 2.5) { + xIncValue = -xIncValue; + yIncValue = -yIncValue; + zIncValue = -zIncValue; + } +</pre> + +<p>最後に、以下のコードを <code>drawScene()</code> 関数に追加します:</p> + +<pre class="brush: js">mvTranslate([squareXOffset, squareYOffset, squareZOffset]);</pre> + +<p>以上で、正方形が回転するとともにズームイン・ズームアウトしながら、環境内を近づいたり遠ざかったりするようランダムに動き回ります。これはスクリーンセーバーのようです。</p> + +<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample4/index.html', 670, 510)}}</p> + +<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample4">コードを確認する</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample4/">新しいページでデモを開く</a></p> + +<h2 id="More_matrix_operations" name="More_matrix_operations">さらに行列を操作する</h2> + +<p>この例は、行列をスタックから取り出す・スタックへ格納する 2 つのルーチンや、与えられた角度の値に基づいて行列を回転させるルーチンといった、高度な行列操作を行っています。参考として、以下にそれを掲載します:</p> + +<pre class="brush: js">var mvMatrixStack = []; + +function mvPushMatrix(m) { + if (m) { + mvMatrixStack.push(m.dup()); + mvMatrix = m.dup(); + } else { + mvMatrixStack.push(mvMatrix.dup()); + } +} + +function mvPopMatrix() { + if (!mvMatrixStack.length) { + throw("空の行列スタックからポップすることはできません。"); + } + + mvMatrix = mvMatrixStack.pop(); + return mvMatrix; +} + +function mvRotate(angle, v) { + var inRadians = angle * Math.PI / 180.0; + + var m = Matrix.Rotation(inRadians, $V([v[0], v[1], v[2]])).ensure4x4(); + multMatrix(m); +} +</pre> + +<p>これらのルーチンは、以前 Vlad Vukićević 氏が記述されたサンプルより取り入れています。</p> + +<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL") }}</p> diff --git a/files/ja/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.html b/files/ja/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.html new file mode 100644 index 0000000000..b3a841fc63 --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.html @@ -0,0 +1,107 @@ +--- +title: WebGL でのテクスチャのアニメーティング +slug: Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL +tags: + - Media + - Tutorial + - Video + - WebGL +translation_of: Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL +--- +<p>{{WebGLSidebar("Tutorial") }} {{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}</p> + +<p>今回のデモンストレーションでは、前回の例で用いた静的なテクスチャを Ogg ビデオファイルのフレームに置き換えます。実はこれを行うのはとても簡単ですが、見ていて楽しいです。さっそく始めましょう。なお同様のコードを、どんな種類のデータ ({{HTMLElement("canvas")}} など) をテクスチャのソースとして用いる場合でも使用することができます。</p> + +<h2 id="Getting_access_to_the_video" name="Getting_access_to_the_video">ビデオにアクセスする</h2> + +<p>始めに、ビデオフレームを取り出すのに使う {{HTMLElement("video")}} 要素を作成する HTML を追加します:</p> + +<pre class="brush: html"><video id="video"> + HTML5 <code>&lt;video&gt;</code> 要素をサポートしていません。 +</video> +</pre> + +<p>これは単純に、ビデオファイル "Firefox.ogv" を再生する要素を作成します。この video 要素が表示されないようにするため、以下の CSS を使用します:</p> + +<pre class="brush: css">video { + display: none; +} +</pre> + +<p>続いて、JavaScript のコードに注意を向けます。まずは <code>start()</code> 関数に、<code>video</code> 要素への参照を取得するコードを追加します:</p> + +<pre class="brush: js">videoElement = document.getElementById("video"); +</pre> + +<p>次に、インターバル駆動による <code>drawScene()</code> の呼び出しを設定しているコードを以下のコードに置き換えます:</p> + +<pre class="brush: js">videoElement.addEventListener("canplaythrough", startVideo, true); +videoElement.addEventListener("ended", videoDone, true); +</pre> + +<p>最後に、ビデオの読み込みを始めるために <code>src</code> 属性を設定します。FIXME (bjacob): ここで <code>preload="auto"</code> も必要です。そうしなければ、Firefox で <code>canplaythrough</code> が発生しません。Chrome では、<code>preload="auto"</code> の有無に関わらずビデオを読み込みます。</p> + +<pre class="brush: js">video.preload = "auto"; +videoElement.src = "Firefox.ogv";</pre> + +<p>これには、ビデオの再生が中断されないよう充分にバッファリングされるまではアニメーションを始めたくないという考え方があります。そこで、データが充分にバッファリングされてビデオが切れ目なく再生できると期待できることを、<code>video</code> 要素が通知するまで待つためのイベントリスナを追加します。</p> + +<p><code>startVideo()</code> 関数は以下のようにします:</p> + +<pre class="brush: js">function startVideo() { + videoElement.play(); + intervalID = setInterval(drawScene, 15); +} +</pre> + +<p>これは単にビデオの再生を開始して、キューブの描画を制御するために <code>drawScene()</code> のインターバル駆動による呼び出しを定義します。</p> + +<p>また、ビデオの再生が終わったときにアニメーションを停止できるように、video の "ended" イベントにイベントリスナを追加します。そうしなければ、正当な理由がないのに CPU 時間を浪費することになってしまうためです。</p> + +<pre class="brush: js">function videoDone() { + clearInterval(intervalID); +}</pre> + +<p><code>videoDone()</code> 関数は単純に、アニメーションの更新を終わらせるために {{domxref("window.clearInterval()")}} を呼び出します。</p> + +<h2 id="Using_the_video_frames_as_a_texture" name="Using_the_video_frames_as_a_texture">ビデオフレームをテクスチャとして使用する</h2> + +<p>次に変更するのは <code>initTexture()</code> です。画像ファイルを読み込む必要がなくなったため、とても単純になります。画像を読み込む代わりに、空のテクスチャオブジェクトを作成して、後で使用するフィルタを設定します:</p> + +<pre class="brush: js">function initTextures() { + cubeTexture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, cubeTexture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); +} +</pre> + +<p><code>updateTexture()</code> 関数は以下のようになります。ここで実際の処理を行います:</p> + +<pre class="brush: js">function updateTexture() { + gl.bindTexture(gl.TEXTURE_2D, cubeTexture); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, + gl.UNSIGNED_BYTE, videoElement); +} +</pre> + +<p>このコードは、以前見たことがあります。これは以前の例にあった <code>handleTextureLoaded()</code> ルーチンとほぼ同じであり、<code>texImage2D()</code> を呼び出すときに <code>Image</code> オブジェクトに代わり {{HTMLElement("video")}} 要素を渡すところが異なります。WebGL は、現在のフレームを取り出してテクスチャとして使用する方法がわかります。</p> + +<p><code>updateTexture()</code> はシーンを再描画する準備が整ったときに毎回、<code>drawScene()</code> によって呼び出されます。<code>drawScene()</code> の唯一の変更点は、処理の最初に <code>updateTexture()</code> の呼び出しを追加することです。</p> + +<p>以上で完了です!</p> + +<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample8/index.html', 670, 510)}}</p> + +<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample8">コードを確認する</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample8/">新しいページでデモを開く</a></p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Using_HTML5_audio_and_video" title="Using audio and video in Firefox">HTML5 の audio 要素と video 要素の使用</a></li> +</ul> + +<p>{{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}</p> diff --git a/files/ja/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html b/files/ja/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html new file mode 100644 index 0000000000..876b04e03e --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.html @@ -0,0 +1,131 @@ +--- +title: WebGL を用いた 3D オブジェクトの作成 +slug: Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL +tags: + - Tutorial + - WebGL +translation_of: Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL +--- +<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}</p> + +<p>正方形に 5 つの面を追加して立体化し、キューブを作成しましょう。これを効率的に行うために、<code>gl.drawArrays()</code> メソッドを呼び出して頂点情報を直接使用する描画方法から、頂点の配列をテーブルとして扱い、<code>gl.drawElements()</code> を呼び出して、そのテーブルの各頂点情報を参照して各面の頂点を定義する方法に切り替えます。</p> + +<p>留意点: それぞれの面について 4 個の頂点を定義しなければなりませんが、各頂点は 3 つの面で共有されます。24 個の頂点すべてのリスト構築することで、やり取りするデータを少なくできます。そして座標を指示するには、座標の完全なセットを渡すのではなく、リストのインデックスを用いて座標を指し示します。なぜ頂点が 8 個ではなく 24 個必要かと考えるかもしれません。これは、それぞれの角に色が異なる 3 つの面が接しており、ひとつの頂点は特定の 1 色しか持たないためです。従って各頂点について、面ごとに色が異なる 3 つのコピーを作成します。</p> + +<h2 id="Define_the_positions_of_the_cube's_vertices" name="Define_the_positions_of_the_cube's_vertices">キューブの頂点の位置を定義する</h2> + +<p>始めに <code>initBuffers()</code> のコードを更新して、キューブの頂点の位置のバッファを作成します。この方法は正方形を作る場合と同じですが、24 個の座標 (1 面につき 4 個) がありますのでコードはとても長くなります:</p> + +<pre class="brush: js">var vertices = [ + // 前面 + -1.0, -1.0, 1.0, + 1.0, -1.0, 1.0, + 1.0, 1.0, 1.0, + -1.0, 1.0, 1.0, + + // 背面 + -1.0, -1.0, -1.0, + -1.0, 1.0, -1.0, + 1.0, 1.0, -1.0, + 1.0, -1.0, -1.0, + + // 上面 + -1.0, 1.0, -1.0, + -1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, -1.0, + + // 底面 + -1.0, -1.0, -1.0, + 1.0, -1.0, -1.0, + 1.0, -1.0, 1.0, + -1.0, -1.0, 1.0, + + // 右側面 + 1.0, -1.0, -1.0, + 1.0, 1.0, -1.0, + 1.0, 1.0, 1.0, + 1.0, -1.0, 1.0, + + // 左側面 + -1.0, -1.0, -1.0, + -1.0, -1.0, 1.0, + -1.0, 1.0, 1.0, + -1.0, 1.0, -1.0 +]; +</pre> + +<h2 id="Define_the_vertices'_colors" name="Define_the_vertices'_colors">頂点の色を定義する</h2> + +<p>24 個の座標それぞれについて、色の配列を作成しなければなりません。このコードでは始めに各面の色を定義します。次にループを用いてこれらの配列を各頂点の色情報に変換しています。</p> + +<pre class="brush: js">var colors = [ + [1.0, 1.0, 1.0, 1.0], // 前面: 白 + [1.0, 0.0, 0.0, 1.0], // 背面: 赤 + [0.0, 1.0, 0.0, 1.0], // 上面: 緑 + [0.0, 0.0, 1.0, 1.0], // 底面: 青 + [1.0, 1.0, 0.0, 1.0], // 右側面: 黄 + [1.0, 0.0, 1.0, 1.0] // 左側面: 紫 +]; + +var generatedColors = []; + +for (j=0; j<6; j++) { + var c = colors[j]; + + for (var i=0; i<4; i++) { + generatedColors = generatedColors.concat(c); + } +} + +var cubeVerticesColorBuffer = gl.createBuffer(); +gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesColorBuffer); +gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(generatedColors), gl.STATIC_DRAW); +</pre> + +<h2 id="Define_the_element_array" name="Define_the_element_array">エレメント配列を定義する</h2> + +<p>頂点の配列を生成したら、次にエレメントの配列を作成します。</p> + +<pre class="brush: js">var cubeVerticesIndexBuffer = gl.createBuffer(); +gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer); + +// この配列はそれぞれの面を 2 つの三角形として定義しており、 +// 各三角形の位置を指定するために、頂点の配列を指し示す +// インデックスを使用します。 + +var cubeVertexIndices = [ + 0, 1, 2, 0, 2, 3, // 前面 + 4, 5, 6, 4, 6, 7, // 背面 + 8, 9, 10, 8, 10, 11, // 上面 + 12, 13, 14, 12, 14, 15, // 底面 + 16, 17, 18, 16, 18, 19, // 右側面 + 20, 21, 22, 20, 22, 23 // 左側面 +]; + +// エレメントの配列を GL に渡す + +gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, + new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); +</pre> + +<p><code>cubeVertexIndices</code> 配列はそれぞれの面を 2 つの三角形として定義し、それら三角形の頂点はキューブの頂点の配列に対するインデックスで指定しています。よって、キューブは 12 個の三角形の集合体として表されます。</p> + +<h2 id="Drawing_the_cube" name="Drawing_the_cube">キューブを描画する</h2> + +<p>次に <code>drawScene()</code> 関数に、キューブのインデックスバッファを用いて描画するためのコードを追加する必要がありますので、新たな <code>bindBuffer()</code> および <code>drawElements()</code> の呼び出しを追加します:</p> + +<pre class="brush: js">gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer); +setMatrixUniforms(); +gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0); +</pre> + +<p>キューブの各面は 2 個の三角形で構成されますので、1 面あたり 6 個・キューブ全体では 36個の頂点が存在することになります。ただし、それらの多くは重複しています。しかし、インデックスの配列は単なる数値のみで構成されていますので、アニメーションのフレームごとに渡すデータの量が過度に多くなることはありません。</p> + +<p>以上で、6 つの面が鮮やかな色で塗られたキューブが回転しながら跳ね回るアニメーションが完成しました。</p> + +<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample5/index.html', 670, 510)}}</p> + +<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample5">コードを確認する</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample5/">新しいページでデモを開く</a></p> + +<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}}</p> diff --git a/files/ja/web/api/webgl_api/tutorial/getting_started_with_webgl/index.html b/files/ja/web/api/webgl_api/tutorial/getting_started_with_webgl/index.html new file mode 100644 index 0000000000..62d91b8b63 --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/getting_started_with_webgl/index.html @@ -0,0 +1,75 @@ +--- +title: WebGL 入門 +slug: Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL +tags: + - Tutorial + - WebGL +translation_of: Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL +--- +<p>{{WebGLSidebar("Tutorial")}} {{Next("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context")}}<br> + <a href="http://www.khronos.org/webgl/" title="http://www.khronos.org/webgl/">WebGL</a> をサポートするブラウザーでは、プラグインを使用することなく HTML <a href="/ja/docs/Web/API/Canvas_API"><code>canvas</code></a> 内で 3D グラフィックスをレンダリングするための、<a href="http://www.khronos.org/opengles/" title="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0 に基づく API をウェブコンテンツで使用できます。WebGL のプログラムは JavaScript で記述する制御コードと、コンピュータの Graphics Processing Unit (GPU) で実行する特殊効果コード (シェーダーコード) で構成されます。WebGL 要素は他の HTML 要素と混ぜられ、他のページ部品やページの背景と合成されます。</p> + +<p>この記事では、WebGL の基礎を紹介します。ここでは、3D グラフィックスに関する数学的な知識を理解していることを前提とします。よって、OpenGL そのものの説明は行いません。</p> + +<p>このチュートリアルで使用するコード例は、<a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial">GitHub の webgl-examples リポジトリー</a>で確認できます。</p> + +<p>この一連の記事が WebGL 自体を紹介していることに注意してください。ただし <a href="https://threejs.org/">THREE.js</a> など、WebGL の機能をカプセル化する多くのフレームワークが利用でき、3D アプリケーションとゲームを簡単に構築することが可能です。</p> + +<h2 id="Preparing_to_render_in_3D" name="Preparing_to_render_in_3D">3D 描画の準備</h2> + +<p>レンダリングに WebGL を使用するために最初に必要なのは canvas です。以下の HTML フラグメントは、サンプルが描画される canvas を宣言します。</p> + +<pre class="brush: html notranslate"><body> + <canvas id="glCanvas" width="640" height="480"></canvas> +</body> +</pre> + +<h3 id="Preparing_the_WebGL_context" name="Preparing_the_WebGL_context">WebGL コンテキストの準備</h3> + +<p>JavaScript コードの <code>main()</code> 関数は、スクリプトがロードされるときに呼び出されます。その目的は、WebGL コンテキストをセットアップし、コンテンツのレンダリングを開始することです。</p> + +<pre class="brush: js notranslate">// +// ここからスタート +// +function main() { + const canvas = document.querySelector("#glCanvas"); + // GL コンテキストを初期化する + const gl = canvas.getContext("webgl"); + + // WebGL が使用可能で動作している場合にのみ続行します + if (gl === null) { + alert("WebGL を初期化できません。ブラウザーまたはマシンがサポートしていない可能性があります。"); + return; + } + + // クリアカラーを黒に設定し、完全に不透明にします + gl.clearColor(0.0, 0.0, 0.0, 1.0); + // 指定されたクリアカラーでカラーバッファをクリアします + gl.clear(gl.COLOR_BUFFER_BIT); +} + +window.onload = main; + +</pre> + +<p>ここで最初に行うことはキャンバスへの参照を取得し、それを <code>canvas</code> という名前の変数に割り当てることです。</p> + +<p>キャンバスを取得したら、<a href="/ja/docs/Web/API/HTMLCanvasElement/getContext">getContext</a> を呼び出して文字列 <code>"webgl"</code> を渡すことにより、キャンバスの <a href="/ja/docs/Web/API/WebGLRenderingContext">WebGLRenderingContext</a> を取得しようとします。ブラウザーが webgl をサポートしていない場合、<code>getContext</code> は <code>null</code> を返します。その場合はユーザーにメッセージを表示して終了します。</p> + +<p>コンテキストが正常に初期化された場合、変数 <code>gl</code> はそれへの参照です。この場合、クリアカラーを黒に設定し、そのカラーのコンテキストをクリア (背景色でキャンバスを再描画) します。</p> + +<p>この時点で、WebGL コンテキストが正常に初期化されるのに十分なコードがあり、コンテンツを受信する準備ができて待機している大きな黒い空のボックスになります。</p> + +<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample1/index.html', 670, 510) }}</p> + +<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample1">コードを確認する</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample1/">新しいページでデモを開く</a></p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="https://dev.opera.com/articles/introduction-to-webgl-part-1/">An introduction to WebGL</a>: Luz Caballero が著し、dev.opera.com で公開しています。この記事では WebGL とは何かやどのように WebGL が動作するか (レンダリングパイプラインの概念を含む) を説明して、WebGL ライブラリーをいくつか紹介しています。</li> + <li><a href="http://webglfundamentals.org/">WebGL Fundamentals</a></li> + <li><a href="http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Table-of-Contents.html">An intro to modern OpenGL:</a> Joe Groff が OpenGL に関するすばらしい記事シリーズを著しており、OpenGL の歴史から重要なグラフィックスパイプラインの概念までの説明、およびどのように OpenGL が動作するかを示すデモを紹介しています。OpenGL の知識を持っていない場合は、ここから始めるとよいでしょう。</li> +</ul> + +<div>{{Next("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context")}}</div> diff --git a/files/ja/web/api/webgl_api/tutorial/index.html b/files/ja/web/api/webgl_api/tutorial/index.html new file mode 100644 index 0000000000..b4e362538e --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/index.html @@ -0,0 +1,42 @@ +--- +title: WebGL チュートリアル +slug: Web/API/WebGL_API/Tutorial +tags: + - Overview + - Tutorial + - WebGL + - WebGL API +translation_of: Web/API/WebGL_API/Tutorial +--- +<div>{{WebGLSidebar}}</div> + +<div class="summary"> +<p><a href="http://www.khronos.org/webgl/" title="http://www.khronos.org/webgl/">WebGL</a> は互換性があるブラウザで、プラグインを使用することなく HTML {{HTMLElement("canvas")}} 内で 3D グラフィックスをレンダリングするための、<a href="http://www.khronos.org/opengles/" title="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0 に基づく API を Web コンテンツで使用できるようにします。WebGL のプログラムは JavaScript で記述する制御コードと、コンピュータの Graphics Processing Unit (GPU) で実行する特殊効果コード (シェーダーコード) で構成されます。WebGL 要素は他の HTML 要素と混ぜられ、他のページ部品やページの背景と合成されます。</p> +</div> + +<p><span class="seoSummary">このチュートリアルでは WebGL グラフィックスを描画するために <code><canvas></code> を使用する方法について、基礎から説明します。ここで提供するサンプルは WebGL で何ができるかの明確な見解をもたらし、また独自のコンテンツを構築し始められるようにするコード部品も提供します。</span></p> + +<h2 id="Before_you_start" name="Before_you_start">始める前に</h2> + +<p><code><canvas></code> 要素を使用することはそれほど難しくありませんが、<a href="/ja/docs/Web/HTML" title="HTML">HTML</a> や <a href="/ja/docs/Web/JavaScript" title="JavaScript">JavaScript</a> の基礎を理解していなければなりません。<code><canvas></code> 要素や WebGL は古いブラウザでサポートされていませんが、最近のバージョンではすべての主要なブラウザがサポートしています。canvas にグラフィックスを描画するためには、JavaScript コンテキストオブジェクトを使用します。このオブジェクトは、グラフィックスをオンザフライで生成します。</p> + +<h2 id="In_this_tutorial" name="In_this_tutorial">チュートリアル</h2> + +<dl> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL">WebGL 入門</a></dt> + <dd>WebGL コンテキストのセットアップ方法</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context">WebGL コンテキストへの平面コンテンツの追加</a></dt> + <dd>WebGL を使用して単純なフラット図形を描画する方法</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL">シェーダーを用いた WebGL での色の指定</a></dt> + <dd>シェーダーを用いた図形への色の設定方法についてのデモンストレーション</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL">WebGL でのオブジェクトのアニメーティング</a></dt> + <dd>単純なアニメーションの作成の為のオブジェクトの回転と移動の方法について</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL">WebGL を用いた 3D オブジェクトの作成</a></dt> + <dd>3D オブジェクトの作成とアニメーションの方法について (立方体を用いた例)</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL">WebGL でのテクスチャの使用</a></dt> + <dd>オブジェクトの表面にテクスチャをマッピングする方法についてのデモンストレーション</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Lighting_in_WebGL">WebGL でのライティング</a></dt> + <dd>WebGL コンテキストにおいて光のエフェクトをシミュレートする方法について。</dd> + <dt><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL">WebGL でのテクスチャのアニメーティング</a></dt> + <dd>テクスチャをアニメーションさせる方法について。ここでは、回転する立方体の表面に Ogg ビデオをマッピングする手法を紹介します。</dd> +</dl> diff --git a/files/ja/web/api/webgl_api/tutorial/lighting_in_webgl/index.html b/files/ja/web/api/webgl_api/tutorial/lighting_in_webgl/index.html new file mode 100644 index 0000000000..20de0d4012 --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/lighting_in_webgl/index.html @@ -0,0 +1,176 @@ +--- +title: WebGL でのライティング +slug: Web/API/WebGL_API/Tutorial/Lighting_in_WebGL +tags: + - Tutorial + - WebGL +translation_of: Web/API/WebGL_API/Tutorial/Lighting_in_WebGL +--- +<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}}</p> + +<p>始めに WebGL について理解すべきことは、より広い OpenGL 標準とは異なり、WebGL はライティングをサポートしていないということです。これは自分自身で行う必要があります。幸いそれは難しいことではありませんので、この記事では基礎的な内容を扱います。</p> + +<h2 id="Simulating_lighting_and_shading_in_3D" name="Simulating_lighting_and_shading_in_3D">3D のライティングとシェーディングをシミュレートする</h2> + +<p>3D グラフィックにおけるシミュレートされたライティングの理論に詳しく触れるのはこの記事の範囲を大きく超えますが、その働きを知るのに役立ちます。ここでは深く触れませんので詳しくは、よく使われるライティングモデルについて解説している Wikipedia の <a href="http://en.wikipedia.org/wiki/Phong_shading" title="http://en.wikipedia.org/wiki/Phong_shading">Phong shading</a> (<a class="external" href="http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A9%E3%83%B3%E3%82%B7%E3%82%A7%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0" title="http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A9%E3%83%B3%E3%82%B7%E3%82%A7%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0">日本語版</a>) の記事をご覧ください。</p> + +<p>ライティングには 3 種類の基本タイプがあります。</p> + +<p><strong>環境光</strong> は環境全体に当たる光です。これは指向性がなく、環境内の表面に対して、その向きに関係なく均等に効果を与えます。</p> + +<p><strong>指向性光源</strong> は特定の方向から投射される光源です。これは遠方から照らされる光源であり、すべての光線はお互い平行に届きます。例えば太陽光が指向性光源になります。</p> + +<p><strong>点光源</strong> はある一点から全方向に向かって投射される光源です。これは現実にある多くの光源の通常動作です。例えば、電球は全方向に光を投射します。</p> + +<p>今回は、単純な指向性光源と環境光のみを考慮することでライティングモデルを単純化します。反射光や点光源は扱いません。そして、環境光と1つの指向性光源を<a href="/ja/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL">前のデモ</a>の回転するキューブに当てます。</p> + +<p>点光源と反射光の概念を外したことにより、指向性光源を実装するために必要な情報は以下の 2 点になります:</p> + +<ol> + <li>各々の頂点と <strong>面法線</strong> を関連づける必要があります。これは頂点の表面に垂直なベクトルです。</li> + <li>光線が向かう方向を知る必要があります。これは <strong>方向ベクトル</strong> として定義されます。</li> +</ol> + +<p>そしてバーテックスシェーダーを、環境光および表面に当たった角度による指向性光源の効果を考慮して各頂点の色を調整するように更新します。シェーダーのコードを見て、ライティングを行う方法を見ていきましょう。</p> + +<h2 id="Building_the_normals_for_the_vertices" name="Building_the_normals_for_the_vertices">頂点の法線を構築する</h2> + +<p>始めに行うべきことは、キューブを構成する全頂点の法線の配列を作成することです。キューブは単純なオブジェクトですので、これは簡単にできます。より複雑なオブジェクトの場合は、明らかに法線の計算が難しくなります。</p> + +<pre class="brush: js">cubeVerticesNormalBuffer = gl.createBuffer(); +gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer); + +var vertexNormals = [ + // 前面 + 0.0, 0.0, 1.0, + 0.0, 0.0, 1.0, + 0.0, 0.0, 1.0, + 0.0, 0.0, 1.0, + + // 背面 + 0.0, 0.0, -1.0, + 0.0, 0.0, -1.0, + 0.0, 0.0, -1.0, + 0.0, 0.0, -1.0, + + // 上面 + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + + // 底面 + 0.0, -1.0, 0.0, + 0.0, -1.0, 0.0, + 0.0, -1.0, 0.0, + 0.0, -1.0, 0.0, + + // 右側面 + 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + + // 左側面 + -1.0, 0.0, 0.0, + -1.0, 0.0, 0.0, + -1.0, 0.0, 0.0, + -1.0, 0.0, 0.0 +]; + +gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertexNormals), gl.STATIC_DRAW); +</pre> + +<p>これは、今ではもう見慣れたものでしょう。新しいバッファを作成し、これを作業用の配列にバインドします。そして、<code>bufferData()</code> を呼び出して頂点の法線の配列をバッファに送り込みます。</p> + +<p>次に、法線の配列をシェーダーの属性にバインドして、シェーダーのコードがその配列にアクセスできるようにするためのコードを <code>drawScene()</code> に追加します:</p> + +<pre class="brush: js">gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer); +gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0); +</pre> + +<p>最後に、シェーダーに対して <strong>正規行列</strong> を生成して渡すための、一様な行列を構築するコードを更新する必要があります。これは、光源に関するキューブの現在の向きを処理する際に法線を変換するのに使用されます:</p> + +<pre class="brush: js">var normalMatrix = mvMatrix.inverse(); +normalMatrix = normalMatrix.transpose(); +var nUniform = gl.getUniformLocation(shaderProgram, "uNormalMatrix"); +gl.uniformMatrix4fv(nUniform, false, new WebGLFloatArray(normalMatrix.flatten())); +</pre> + +<h2 id="Update_the_shaders" name="Update_the_shaders">シェーダーを更新する</h2> + +<p>シェーダーが必要とするデータがすべて用意できましたので、次はシェーダーのコードを更新する必要があります。</p> + +<h3 id="The_vertex_shader" name="The_vertex_shader">バーテックスシェーダー</h3> + +<p>まずはバーテックスシェーダーを、環境光および指向性光源に基づいて各頂点のシェーディング値を生成するように更新します。以下のコードをご覧ください:</p> + +<pre class="brush: html"><script id="shader-vs" type="x-shader/x-vertex"> + attribute highp vec3 aVertexNormal; + attribute highp vec3 aVertexPosition; + attribute highp vec2 aTextureCoord; + + uniform highp mat4 uNormalMatrix; + uniform highp mat4 uMVMatrix; + uniform highp mat4 uPMatrix; + + varying highp vec2 vTextureCoord; + varying highp vec3 vLighting; + + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + + // ライティング効果を適用する + + highp vec3 ambientLight = vec3(0.6, 0.6, 0.6); + highp vec3 directionalLightColor = vec3(0.5, 0.5, 0.75); + highp vec3 directionalVector = vec3(0.85, 0.8, 0.75); + + highp vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0); + + highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0); + vLighting = ambientLight + (directionalLightColor * directional); + } +</script> +</pre> + +<p>頂点の位置が算出されると、頂点に対応するテクセルの座標が算出され、頂点のシェーディングの計算ができるようになります。</p> + +<p>始めに行うのは、頂点の法線に正規行列を乗じることで、法線を現在のキューブの向きと位置に基づくものに変換することです。次に、変換された法線と方向ベクトル (光線が来る方向) の点乗積を計算することにより、頂点に適用されるべき指向性光源の光量を算出することができます。光量を 0 より小さくすることはできませんので、算出結果が 0 より小さくなった場合は、その値を 0 に固定します。</p> + +<p>指向性光源の光量が算出されたら、環境光を取り込みさらに指向性光源の色と光量を足し込むことでライティングの値を決めることができます。この結果、フラグメントシェーダーが描画する各ピクセルの色を調整するために用いる RGB 値を得ることができます。</p> + +<h3 id="The_fragment_shader" name="The_fragment_shader">フラグメントシェーダー</h3> + +<p>フラグメントシェーダーは、バーテックスシェーダーが算出した光量の値を考慮するように更新する必要があります:</p> + +<pre class="brush: js"><script id="shader-fs" type="x-shader/x-fragment"> + varying highp vec2 vTextureCoord; + varying highp vec3 vLighting; + + uniform sampler2D uSampler; + + void main(void) { + mediump vec4 texelColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); + + gl_FragColor = vec4(texelColor.rgb * vLighting, texelColor.a); + } +</script> +</pre> + +<p>ここでは以前の例で行ったようにテクセルの色を取り出しますが、フラグメントの色を設定する前に、光源の影響を考慮してテクセルの色を調整するため、テクセルの色に光量の値を掛け合わせます。</p> + +<p>以上で完成です!</p> + +<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample7/index.html', 670, 510)}}</p> + +<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample7">コードを確認する</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample7/">新しいページでデモを開く</a></p> + +<h2 id="Exercises_for_the_reader" name="Exercises_for_the_reader">読者への課題</h2> + +<p>基本的な頂点ごとのライティングを実装した今回の例は、単純なものであることは明らかです。より高度なグラフィックとしてピクセルごとのライティングを実装したいと考えるのは、正しい方向性です。</p> + +<p>同様に、光源の方向、光源の色などについても実験してみるとよいでしょう。</p> + +<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}}</p> diff --git a/files/ja/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.html b/files/ja/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.html new file mode 100644 index 0000000000..cb0c035f3c --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.html @@ -0,0 +1,96 @@ +--- +title: シェーダーを用いた WebGL での色の指定 +slug: Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL +tags: + - Tutorial + - WebGL +translation_of: Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL +--- +<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL")}}</p> + +<p><a href="/ja/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context">前のデモンストレーション</a>で正方形を作り出すことができたら、次に明らかなステップは、それに色をつけることです。これは、シェーダーを変更することで実現できます。</p> + +<h2 id="Applying_color_to_the_vertices" name="Applying_color_to_the_vertices">頂点に色を適用する</h2> + +<p>GL ではオブジェクトは頂点のセットを用いて構築され、各頂点は位置と色の情報を持っています。デフォルトでは、他のピクセルの色 (および位置など、その他の属性すべて) は線形補完法を用いて計算され、自動的になめらかなグラデーションを生成します。前に使用したバーテックスシェーダーでは頂点に色の情報を適用していませんでした。バーテックスシェーダーとフラグメントシェーダーで各ピクセルに白色を固定で割り当てており、正方形全体が白一色で描画されました。</p> + +<p>例えば、四隅が異なる色 (赤、青、緑、白) である正方形にグラデーションを作成したいとします。始めに行うことは、4 つの頂点にこれらの色を設定することです。これを行うには、まず頂点の色の配列を作成し、次にその配列を WebGL のバッファに格納します。これらは、以下に挙げるコードを <code>initBuffers()</code> 関数に追加することで実行します:</p> + +<pre class="brush: js"> var colors = [ + 1.0, 1.0, 1.0, 1.0, // 白 + 1.0, 0.0, 0.0, 1.0, // 赤 + 0.0, 1.0, 0.0, 1.0, // 緑 + 0.0, 0.0, 1.0, 1.0 // 青 + ]; + + squareVerticesColorBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); +} +</pre> + +<p>このコードは 4 つの値が 4 組含まれている JavaScript の配列を作成することから始まります。各組は、それぞれの頂点の色を示します。続いてこれらの色情報を格納する WebGL バッファを新たに割り当てます。そして、配列を WebGL 浮動小数点数に変換してバッファに格納します。</p> + +<p>これらの色情報を実際に使うためには、カラーバッファから適切な色情報を取り出すようにバーテックスシェーダーを変更しなければなりません:</p> + +<pre class="brush: html"> <script id="shader-vs" type="x-shader/x-vertex"> + attribute vec3 aVertexPosition; + attribute vec4 aVertexColor; + + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + + varying lowp vec4 vColor; + + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vColor = aVertexColor; + } + </script> +</pre> + +<p>ここでの各頂点に関する重要な違いは、色の配列内で対応する値を、頂点の色情報として設定していることです。</p> + +<h2 id="Coloring_the_fragments" name="Coloring_the_fragments">フラグメントに色をつける</h2> + +<p>復習として、以前はフラグメントシェーダーを以下のようにしていました:</p> + +<pre class="brush: html"> <script id="shader-fs" type="x-shader/x-fragment"> + void main(void) { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + </script> +</pre> + +<p>各ピクセルが補完された色を取り込むようにするため、<code>vColor</code> 変数から値を取り出すようにシェーダーを変更しなければなりません:</p> + +<pre class="brush: html"> <script id="shader-fs" type="x-shader/x-fragment"> + varying lowp vec4 vColor; + + void main(void) { + gl_FragColor = vColor; + } + </script> +</pre> + +<p>これは単純な変更です。これにより各フラグメントは固定値ではなく、頂点からの相対的な位置に基づいて補完された色情報を受け取ります。</p> + +<h2 id="Drawing_using_the_colors" name="Drawing_using_the_colors">色情報を用いて描画する</h2> + +<p>次に、シェーダープログラムの色属性を初期化するコードを <code>initShaders()</code> ルーチンに追加しなければなりません:</p> + +<pre class="brush: js"> vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor"); + gl.enableVertexAttribArray(vertexColorAttribute); +</pre> + +<p>そして、実際に色情報を用いて正方形を描画するように drawScene() を変更することが可能になります:</p> + +<pre class="brush: js"> gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer); + gl.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0); +</pre> + +<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample3/index.html', 670, 510)}}</p> + +<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample3">コードを確認する</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample3/">新しいページでデモを開く</a></p> + +<div>{{PreviousNext("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL")}}</div> diff --git a/files/ja/web/api/webgl_api/tutorial/using_textures_in_webgl/index.html b/files/ja/web/api/webgl_api/tutorial/using_textures_in_webgl/index.html new file mode 100644 index 0000000000..76a80a87e9 --- /dev/null +++ b/files/ja/web/api/webgl_api/tutorial/using_textures_in_webgl/index.html @@ -0,0 +1,209 @@ +--- +title: WebGL でのテクスチャの使用 +slug: Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL +tags: + - Tutorial + - WebGL +translation_of: Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL +--- +<p>{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}</p> + +<p>現在、サンプルプログラムは回転する 3D キューブを描画します。今回はキューブの表面を単色で塗りつぶすのではなく、テクスチャをマッピングしてみましょう。</p> + +<h2 id="Loading_textures" name="Loading_textures">テクスチャを読み込む</h2> + +<p>始めに、テクスチャを読み込むコードを追加します。今回は 1 個のテクスチャを用いて、そのテクスチャをキューブの 6 面に貼り付けますが、テクスチャがいくつある場合でも同じ方法を適用できます。</p> + +<div class="note"><strong>注記:</strong> テクスチャの読み込みは<a href="/ja/docs/Web/HTTP/Access_control_CORS">クロスドメインの規則</a>に従うことへの注意が重要です。従ってコンテンツが CORS で認可されているサイトからのみ、テクスチャを読み込むことができます。クロスドメインのテクスチャについては、後ほど説明します。</div> + +<p>テクスチャを読み込むコードは以下のようになります:</p> + +<pre class="brush: js">function initTextures() { + cubeTexture = gl.createTexture(); + cubeImage = new Image(); + cubeImage.onload = function() { handleTextureLoaded(cubeImage, cubeTexture); } + cubeImage.src = "cubetexture.png"; +} + +function handleTextureLoaded(image, texture) { + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); + gl.generateMipmap(gl.TEXTURE_2D); + gl.bindTexture(gl.TEXTURE_2D, null); +} +</pre> + +<p><code>initTextures()</code> ルーチンは GL の <code>createTexture()</code> 関数を呼び出して、GL のテクスチャオブジェクト <code>cubeTexture</code> を作成することから始まります。そして、テクスチャを画像ファイルから読み込むために <code>Image</code> オブジェクトを作成して、そのオブジェクトにテクスチャとして使用したい画像ファイルをロードします。<code>handleTextureLoaded()</code> コールバックルーチンは、画像の読み込みが完了したときに実行されます。</p> + +<p>実際にテクスチャを作成するために、新しいテクスチャが操作したいカレントのテクスチャであることを、<code>gl.TEXTURE_2D</code> にバインドすることで指定します。その後読み込んだ画像は、テクスチャとして書き込むために <code>texImage2D()</code> へ渡されます。</p> + +<div class="note"><strong>注記:</strong> テクスチャの幅と高さのピクセル数は<strong>ほとんどの場合</strong>において、それぞれ 2 のべき乗 (1、2、4、8、16……) にしなければなりません。例外については、"<a href="/ja/docs/Web/WebGL/Using_textures_in_WebGL#Non_power-of-two_textures" title="Web/WebGL/Using_textures_in_WebGL#Using_non_Power-Of-Two_textures">2 のべき乗ではないテクスチャ</a>" のセクションをご覧ください。</div> + +<p>その次の 2 行はテクスチャのフィルタリングを設定しています。これは画像が拡大縮小される際に適用するフィルタの設定です。今回は、画像を拡大する場合はリニアフィルタ、縮小する場合はミップマップを使用します。ミップマップは <code>generateMipMap()</code> を呼び出すことで生成され、最後は null を <code>gl.TEXTURE_2D</code> にバインドしてテクスチャの操作を終了することで完了します。</p> + +<h3 id="Non_power-of-two_textures" name="Non_power-of-two_textures">2 のべき乗ではないテクスチャ</h3> + +<p>一般的に、辺の長さが 2 のべき乗であるテクスチャを使うことが理想的です。これはビデオメモリへ効率よく保存され、また使用方法が制限されません。制作されたテクスチャを近い 2 のべき乗のサイズにスケーリングするか、2 のべき乗のサイズで制作を始めます。それぞれの辺の長さを 1、2、4、8、16、32、64、128、256、512、1024、あるいは 2048 ピクセルにすべきです。また、多くのデバイス (すべてではありません) が 4096 ピクセルをサポートします。さらに、8192 ピクセル以上をサポートするものもあります。</p> + +<p>ときおり、特殊な事情で 2 のべき乗のテクスチャを使用することが困難な場合があります。サードパーティーの素材を使用する場合はたいてい、WebGL へ渡す前に HTML5 canvas を使用して 2 のべき乗のサイズに変換すると最良の結果を得られます。引き伸ばしが明白である場合は、UV 座標も必要でしょう。</p> + +<p>一方、2 のべき乗ではない (NPOT) テクスチャが<strong>不可欠である</strong>場合でも、WebGL は限定的にネイティブサポートしています。NPOT テクスチャは主に、テクスチャの寸法をモニターなど他の解像度に揃えなければならない場合や、前出の提案に従うだけの価値がない場合に有用です。しかし、このようなテクスチャはミップマッピングで使用することが<strong>できません</strong>。また、"繰り返し" (タイルまたはラップ) を<strong>行ってはいけません</strong>。</p> + +<p>テクスチャの繰り返しは、例えば小さなレンガの画像をタイリングしてレンガの壁を作ることです。</p> + +<p>ミップマッピングや UV リピートは、<code>bindTexture()</code> を使用してテクスチャを作成する際に <code>texParameteri()</code> で無効化できます。これによりミップマッピング、UV ラッピング、UV タイリングを犠牲にして NPOT テクスチャを使用できます。また、デバイスがテクスチャをどのように扱うかを制御できます。</p> + +<pre class="brush: js">// gl.LINEAR の代わりに gl.NEAREST も可能。ミップマップは不可 +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); +// S 座標のラッピング (繰り返し) を禁止 +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); +// T 座標のラッピング (繰り返し) を禁止 +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);</pre> + +<p>繰り返しますがこれらのパラメータを付加すると、WebGL デバイスは自動的に (サポートする最大サイズまでの) 任意の解像度のテクスチャを受け入れます。しかしこれらの設定を行わないと、WebGL は黒色 (<code>rgba(0,0,0,1)</code>) を返すことになり、NPOT テクスチャの全サンプルを受け入れてはなりません。</p> + +<h2 id="Mapping_the_texture_onto_the_faces" name="Mapping_the_texture_onto_the_faces">テクスチャを表面にマッピングする</h2> + +<p>以上で、テクスチャの読み込みと使用する準備ができました。しかしテクスチャが使用できるようになるには、まずキューブの面の頂点にテクスチャの座標をマッピングする必要があります。これは <code>initBuffers()</code> にある、キューブの各面に色を設定する既存のコードの置き換えになります。</p> + +<pre class="brush: js"> cubeVerticesTextureCoordBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesTextureCoordBuffer); + + var textureCoordinates = [ + // 前面 + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // 背面 + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // 上面 + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // 底面 + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // 右側面 + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + // 左側面 + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0 + ]; + + gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(textureCoordinates), + gl.STATIC_DRAW); +</pre> + +<p>このコードは始めに各面のテクスチャの座標を収める GL のバッファを作成して、そのバッファを書き込みを行う配列としてバインドします。</p> + +<p><code>textureCoordinates</code> 配列は、各面の各座標に対応するテクスチャの座標を定義します。テクスチャの座標の範囲は 0.0 から 1.0 であることに注意してください。テクスチャマッピングのために、テクスチャの寸法は実際の大きさに関わらず 0.0 から 1.0 の範囲に正規化されます。</p> + +<p>テクスチャマッピングの配列を設定したら、配列をバッファに渡すことで GL がそのデータを使用する準備が完了します。</p> + +<div class="note">注記: WebKit ベースのブラウザでは、<code>WebGLFloatArray</code> の代わりに <code>Float32Array</code> を使用しなければならないでしょう。</div> + +<h2 id="Updating_the_shaders" name="Updating_the_shaders">シェーダーを更新する</h2> + +<p>シェーダープログラム (およびシェーダーを初期化するコード) も、単色に代わりテクスチャを使用するように更新する必要があります。</p> + +<p>始めに <code>initShaders()</code> で必要になる、シンプルな変更点を見てみましょう:</p> + +<pre class="brush: js"> textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); + gl.enableVertexAttribArray(textureCoordAttribute); +</pre> + +<p>これは頂点の色属性を設定するコードを、各頂点のテクスチャ座標を包含するコードに置き換えます。</p> + +<h3 id="The_vertex_shader" name="The_vertex_shader">バーテックスシェーダー</h3> + +<p>次にバーテックスシェーダーを、色のデータを取り出すものからテクスチャ座標のデータを取り出すものに置き換える必要があります。</p> + +<pre class="brush: html"> <script id="shader-vs" type="x-shader/x-vertex"> + attribute vec3 aVertexPosition; + attribute vec2 aTextureCoord; + + uniform mat4 uMVMatrix; + uniform mat4 uPMatrix; + + varying highp vec2 vTextureCoord; + + void main(void) { + gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); + vTextureCoord = aTextureCoord; + } + </script> +</pre> + +<p>重要な変更点は、頂点の色を取り出すのに代わりテクスチャ座標を設定していることです。これは頂点に対応する、テクスチャ内の位置を指し示します。</p> + +<h3 id="The_fragment_shader" name="The_fragment_shader">フラグメントシェーダー</h3> + +<p>フラグメントシェーダーも同様に更新する必要があります:</p> + +<pre class="brush: html"> <script id="shader-fs" type="x-shader/x-fragment"> + varying highp vec2 vTextureCoord; + + uniform sampler2D uSampler; + + void main(void) { + gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); + } + </script> +</pre> + +<p>色の値をフラグメントの色に割り当てるのに代わり、フラグメントの色は、サンプラーが最適とするフラグメントの位置のテクセル (テクスチャ内のピクセル) を取り出すことで算出されます。</p> + +<h2 id="Drawing_the_textured_cube" name="Drawing_the_textured_cube">テクスチャを貼り付けたキューブを描画する</h2> + +<p><code>drawScene()</code> 関数の変更点は簡単です (コードを明瞭にするために、キューブを空間中で動かすアニメーションのコードを取り除いて単に回転するようにした点は除きます)。</p> + +<p>色を割り当てるコードをテクスチャを割り当てるようにするためには、以下のように置き換えます:</p> + +<pre class="brush: js"> gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, cubeTexture); + gl.uniform1i(gl.getUniformLocation(shaderProgram, "uSampler"), 0); +</pre> + +<p>GL は 32 個のテクスチャレジスタを提供し、その 1 つ目が <code>gl.TEXTURE0</code> です。前に読み込んだテクスチャをそのレジスタに結びつけて、そのテクスチャを使用するためにシェーダーサンプラー <code>uSampler</code> (シェーダープログラムにより明示されます) を設定します。</p> + +<p>以上でテクスチャが貼り付けられた、回転するキューブが完成します。</p> + +<p>{{EmbedGHLiveSample('webgl-examples/tutorial/sample6/index.html', 670, 510)}}</p> + +<p><a href="https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample6">コードを確認する</a> | <a href="http://mdn.github.io/webgl-examples/tutorial/sample6/">新しいページでデモを開く</a></p> + +<h2 id="Cross-domain_textures" name="Cross-domain_textures">クロスドメインのテクスチャ</h2> + +<p>WebGL のテクスチャの読み込みは、クロスドメインアクセス制御に従います。コンテンツで他のドメインからテクスチャを読み込むためには、CORS で許可を得なければなりません。CORS について詳しくは、<a href="/ja/docs/HTTP_access_control" title="HTTP access control">HTTP access control</a> をご覧ください。</p> + +<p>CORS で許可された画像を WebGL のテクスチャとして使用する方法の説明を <a href="http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/" title="http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/">こちらの hacks.mozilla.org の記事</a> に掲載していますので、<a href="http://people.mozilla.org/~bjacob/webgltexture-cors-js.html" title="http://people.mozilla.org/~bjacob/webgltexture-cors-js.html">サンプル</a> と合わせてご覧ください。</p> + +<div class="note"> +<p><strong>注記:</strong> WebGL テクスチャ向けの CORS サポートと、画像要素の <code>crossOrigin</code> 属性は {{Gecko("8.0")}} で実装されました。</p> +</div> + +<p>汚染された (書き込みのみ) 2D canvas を WebGL のテクスチャとして使用することはできません。2D {{HTMLElement("canvas")}} が汚染されたとは例えば、クロスドメインの画像が canvas 上に描画された状態を指します。</p> + +<div class="note"> +<p><strong>注記:</strong> Canvas 2D <code>drawImage</code> 向けの CORS サポートを {{Gecko("9.0")}} で実装しました。これは、CORS で許可されたクロスドメインの画像が 2D canvas を汚染しないので、2D canvas を WebGL のテクスチャ素材として引き続き使用できることを意味します。</p> +</div> + +<div class="note"> +<p><strong>注記:</strong> クロスドメインの動画に対する CORS サポートと、{{HTMLElement("video")}} 要素の<code>crossorigin</code> 属性は {{Gecko("12.0")}} で実装されました。</p> +</div> + +<p>{{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}}</p> diff --git a/files/ja/web/api/webgl_api/types/index.html b/files/ja/web/api/webgl_api/types/index.html new file mode 100644 index 0000000000..92ee3d1120 --- /dev/null +++ b/files/ja/web/api/webgl_api/types/index.html @@ -0,0 +1,165 @@ +--- +title: WebGL の型 +slug: Web/API/WebGL_API/Types +translation_of: Web/API/WebGL_API/Types +--- +<div>{{WebGLSidebar}}</div> + +<p><a href="/ja/docs/Web/API/WebGL_API">WebGL</a> インターフェースでは次の型が使用されます。</p> + +<h2 id="WebGL_1">WebGL 1</h2> + +<p>これらの型は {{domxref("WebGLRenderingContext")}} 内で使用されます。</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">型</td> + <td class="header">Web IDL 型</td> + <td class="header">説明</td> + </tr> + <tr> + <td><code>GLenum</code></td> + <td><code>unsigned long</code></td> + <td> + <p>列挙に使用されます。<a href="/ja/docs/Web/API/WebGL_API/Constants">定数</a>のリストも参照してください。</p> + </td> + </tr> + <tr> + <td><code>GLboolean</code></td> + <td><code>boolean</code></td> + <td>A {{jsxref("Boolean")}}.</td> + </tr> + <tr> + <td><code>GLbitfield</code></td> + <td><code>unsigned long</code></td> + <td>A bit field that stores multiple, logical bits. Used for example in {{domxref("WebGLRenderingContext.clear()")}}.</td> + </tr> + <tr> + <td><code>GLbyte</code></td> + <td><code>byte</code></td> + <td>8-bit twos complement signed integer.</td> + </tr> + <tr> + <td><code>GLshort</code></td> + <td><code>short</code></td> + <td>16-bit twos complement signed integer.</td> + </tr> + <tr> + <td><code>GLint</code></td> + <td><code>long</code></td> + <td>32-bit twos complement signed integer.</td> + </tr> + <tr> + <td><code>GLsizei</code></td> + <td><code>long</code></td> + <td>Used for sizes (e.g. width and height of the drawing buffer).</td> + </tr> + <tr> + <td><code>GLintptr</code></td> + <td><code>long long</code></td> + <td>Special type for pointer arithmetic.</td> + </tr> + <tr> + <td><code>GLsizeiptr</code></td> + <td><code>long long</code></td> + <td>Special type for pointer arithmetic.</td> + </tr> + <tr> + <td><code>GLubyte</code></td> + <td><code>octet</code></td> + <td>8-bit twos complement unsigned integer.</td> + </tr> + <tr> + <td><code>GLushort</code></td> + <td><code>unsigned short</code></td> + <td>16-bit twos complement unsigned integer.</td> + </tr> + <tr> + <td><code>GLuint</code></td> + <td><code>unsigned long</code></td> + <td>32-bit twos complement unsigned integer.</td> + </tr> + <tr> + <td><code>GLfloat</code></td> + <td><code>unrestricted float</code></td> + <td>32-bit IEEE floating point number.</td> + </tr> + <tr> + <td><code>GLclampf</code></td> + <td><code>unrestricted float</code></td> + <td>Clamped 32-bit IEEE floating point number.</td> + </tr> + </tbody> +</table> + +<h2 id="WebGL_2">WebGL 2</h2> + +<p>これらの型は {{domxref("WebGL2RenderingContext")}} で使用されます。すべての WebGL 1 タイプも使用されます。</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">型</td> + <td class="header">Web IDL 型</td> + <td class="header">説明</td> + </tr> + <tr> + <td><code>GLint64</code></td> + <td><code>long long</code></td> + <td>符号付き 64 ビット整数</td> + </tr> + </tbody> +</table> + +<h2 id="WebGL_拡張">WebGL 拡張</h2> + +<p>これらの型は、<a href="/ja/docs/Web/API/WebGL_API/Using_Extensions">WebGL 拡張</a>内で使用されます。</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">型</td> + <td class="header">Web IDL 型</td> + <td class="header">説明</td> + </tr> + <tr> + <td><code>GLuint64EXT</code></td> + <td><code>long long</code></td> + <td>符号なし 64 ビット整数</td> + </tr> + </tbody> +</table> + +<h2 id="仕様">仕様</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様書</th> + <th scope="col">ステータス</th> + <th scope="col">コメント</th> + </tr> + <tr> + <td>{{SpecName('WebGL', "#5.1", "Types")}}</td> + <td>{{Spec2('WebGL')}}</td> + <td>初期定義</td> + </tr> + <tr> + <td>{{SpecName('WebGL2', "#3.1", "Types")}}</td> + <td>{{Spec2('WebGL2')}}</td> + <td>追加のタイプを定義</td> + </tr> + <tr> + <td>{{SpecName('EXT_disjoint_timer_query', "", "GLuint64EXT")}}</td> + <td>{{Spec2('EXT_disjoint_timer_query')}}</td> + <td><code>GLuint64EXT</code> の追加</td> + </tr> + </tbody> +</table> + +<h2 id="あわせて参照">あわせて参照</h2> + +<ul> + <li>{{domxref("WebGLRenderingContext")}}</li> +</ul> diff --git a/files/ja/web/api/webgl_api/using_extensions/index.html b/files/ja/web/api/webgl_api/using_extensions/index.html new file mode 100644 index 0000000000..0c3ebad2ed --- /dev/null +++ b/files/ja/web/api/webgl_api/using_extensions/index.html @@ -0,0 +1,608 @@ +--- +title: WebGL 拡張機能を使用する +slug: Web/API/WebGL_API/Using_Extensions +tags: + - Advanced + - WebGL +translation_of: Web/API/WebGL_API/Using_Extensions +--- +<div>{{WebGLSidebar}}</div> + +<p>WebGL は姉妹 API (OpenGL や OpenGL ES) と同様に、拡張機能をサポートします。拡張機能の完全な一覧は <a href="http://www.khronos.org/registry/webgl/extensions/" title="http://www.khronos.org/registry/webgl/extensions/">khronos webgl extension registry</a> で確認できます。</p> + +<div class="note"><strong>注記:</strong> 他の GL API とは異なり、WebGL の拡張機能は明示的に要求した場合に限り使用できます。</div> + +<h2 id="Canonical_extension_names_vendor_prefixes_and_preferences" name="Canonical_extension_names_vendor_prefixes_and_preferences">Canonical 拡張機能名とベンダー接頭辞と設定</h2> + +<p>拡張機能は公式に認められる前に、ブラウザベンダーがサポートする場合があります (ただし、草案段階にあるときに限ります)。このとき、拡張機能名にベンダー接頭辞 (<code>MOZ_</code> や <code>WEBKIT_</code> など) を付加するか、ブラウザの設定を切り替えた場合に限り使用できるようにする可能性があります。</p> + +<p>最先端の拡張機能を使用したい場合、および公認されたときにも動作し続けるようにしたい (もちろん、その拡張機能が互換性を失うように変更されていないものとします) 場合は、ベンダー拡張機能名だけでなく canonical 拡張機能名も問い合わせます。例えば以下のようにします:</p> + +<pre class="brush:js">var ext = ( + gl.getExtension('OES_vertex_array_object') || + gl.getExtension('MOZ_OES_vertex_array_object') || + gl.getExtension('WEBKIT_OES_vertex_array_object') +); +</pre> + +<p>ベンダー接頭辞は次第に採用されなくなっており、ほとんどのブラウザは実験的な拡張機能をベンダー接頭辞ではなく機能フラグで制御するように実装しています。</p> + +<p>機能フラグは以下のようなものです:</p> + +<ul> + <li>Firefox では <code>webgl.enable-draft-extensions</code></li> + <li>Chromium ベースのブラウザ (Chrome、Opera) では <code>chrome://flags/#enable-webgl-draft-extensions</code></li> +</ul> + +<h2 id="Querying_available_extensions" name="Querying_available_extensions">使用可能な拡張機能を問い合わせる</h2> + +<p>WebGL コンテキストは、使用できる拡張機能を問い合わせる機能をサポートしています。</p> + +<pre class="brush:js">var available_extensions = gl.getSupportedExtensions();</pre> + +<p>{{domxref("WebGLRenderingContext.getSupportedExtensions()")}} メソッドは、サポートする拡張機能を収めた文字列配列を返します。</p> + +<h2 id="Extension_list" name="Extension_list">拡張機能一覧</h2> + +<p>現行の拡張機能の一覧:</p> + +<p>{{page("ja/docs/Web/API/WebGL_API", "Extension_interfaces")}}</p> + +<h2 id="Enabling_an_extension" name="Enabling_an_extension">拡張機能を有効化する</h2> + +<p>拡張機能を使用する前に、{{domxref("WebGLRenderingContext.getExtension()")}} を使用して機能を有効化しなければなりません。例えば:</p> + +<pre class="brush:js">var float_texture_ext = gl.getExtension('OES_texture_float');</pre> + +<p>拡張機能をサポートしていない場合の戻り値は <code>null</code>、サポートしている場合の戻り値は拡張機能オブジェクトです。</p> + +<h2 id="Extension_objects" name="Extension_objects">拡張機能オブジェクト</h2> + +<p>WebGL のコア仕様で使用できないシンボルや関数を拡張機能で定義している場合は、<code>gl.getExtension()</code> の呼び出しによって返される拡張機能オブジェクトでそれらを使用できます。</p> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザ実装状況</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>機能</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>基本サポート</td> + <td>9</td> + <td>{{CompatGeckoDesktop("2.0")}}</td> + <td>11</td> + <td>12</td> + <td>5.1</td> + </tr> + <tr> + <td><code>ANGLE_instanced_arrays</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("33.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_blend_minmax</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("33.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_color_buffer_half_float</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("30.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_disjoint_timer_query</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("41.0")}} [1]</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_frag_depth</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("30.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_sRGB</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("28.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_shader_texture_lod</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("34.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_texture_filter_anisotropic</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("17.0")}} [2]</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_element_index_uint</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("24.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_standard_derivatives</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("10.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_texture_float</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("6.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_texture_float_linear</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("24.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_texture_half_float</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("29.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_texture_half_float_linear</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("30.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_vertex_array_object</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("25.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_color_buffer_float</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("30.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_compressed_texture_atc</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("18.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_compressed_texture_etc1</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("30.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_compressed_texture_pvrtc</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("18.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_compressed_texture_s3tc</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("15.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_debug_renderer_info</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("19.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_debug_shaders</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("30.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_depth_texture</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("17.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_draw_buffers</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("28.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_lose_context</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("19.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>機能</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>基本サポート</td> + <td>{{CompatVersionUnknown}}</td> + <td>25</td> + <td>{{CompatGeckoMobile("2.0")}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>12</td> + <td>8.0</td> + </tr> + <tr> + <td><code>ANGLE_instanced_arrays</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_blend_minmax</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_color_buffer_half_float</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_disjoint_timer_query</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_frag_depth</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_sRGB</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_shader_texture_lod</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>EXT_texture_filter_anisotropic</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_element_index_uint</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_standard_derivatives</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_texture_float</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_texture_float_linear</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_texture_half_float</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_texture_half_float_linear</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>OES_vertex_array_object</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_color_buffer_float</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_compressed_texture_atc</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_compressed_texture_etc1</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_compressed_texture_pvrtc</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_compressed_texture_s3tc</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_debug_renderer_info</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_debug_shaders</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_depth_texture</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_draw_buffers</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td><code>WEBGL_lose_context</code></td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<p>[1] about:config で設定項目 <code>webgl.enable-draft-extensions</code> を切り替えなければなりません。</p> + +<p>[2] これより前のバージョンでは接頭辞付きの <code>MOZ_EXT_texture_filter_anisotropic</code> になっています。</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{domxref("WebGLRenderingContext.getSupportedExtensions()")}}</li> + <li>{{domxref("WebGLRenderingContext.getExtension()")}}</li> + <li><a class="external external-icon" href="http://webglreport.com">webglreport.com</a></li> + <li><a href="http://webglstats.com">webglstats.com</a></li> +</ul> + +<p>--- 以降の内容は個別のページに移動する ---</p> + +<h2 id="EXT_texture_filter_anisotropic" name="EXT_texture_filter_anisotropic">EXT_texture_filter_anisotropic</h2> + +<p>異方性フィルタリングは、テクスチャを貼り付けた物体を斜めの角度から見る場合の、ミップマップテクスチャの品質を向上させます。ミップマップしか使用しないと、外見が全体的にグレーへ寄る傾向があります。</p> + +<p>この<a href="http://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/" title="http://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/">拡張機能</a>では 2 つのシンボルを定義しています:</p> + +<ul> + <li><code>extension_object.MAX_TEXTURE_MAX_ANISOTROPY_EXT</code>: これは <code>gl.getParameter()</code> の呼び出し用の pname パラメータであり、使用できる最大の異方性を返します。</li> + <li><code>extension_object.TEXTURE_MAX_ANISOTROPY_EXT</code>: これは <code>gl.texParameter()</code> や <code>gl.getTexParameter{f,i}()</code> の呼び出し用の pname パラメータであり、テクスチャに対して希望する異方性を設定します。</li> +</ul> + +<h3 id="Example" name="Example">例</h3> + +<pre class="brush:js">var texture = gl.createTexture(); +gl.bindTexture(gl.TEXTURE_2D, texture); +var ext = ( + gl.getExtension('EXT_texture_filter_anisotropic') || + gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || + gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic') +); +if (ext){ + var max = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT); + gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max); +} +</pre> + +<h2 id="WEBGL_compressed_texture_s3tc" name="WEBGL_compressed_texture_s3tc">WEBGL_compressed_texture_s3tc</h2> + +<p>圧縮テクスチャは、GPU がテクスチャを保存するために必要なメモリ量を削減します。より高解像のテクスチャを使用する、あるいは同じ解像度でより多くのテクスチャを使用することができます。</p> + +<p>この<a href="http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/" title="http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/">拡張機能</a>では 4 種類のテクスチャタイプを新たに定義します:</p> + +<ul> + <li><code>extension_object.COMPRESSED_RGB_S3TC_DXT1_EXT</code></li> + <li><code>extension_object.COMPRESSED_RGBA_S3TC_DXT1_EXT</code></li> + <li><code>extension_object.COMPRESSED_RGBA_S3TC_DXT3_EXT</code></li> + <li><code>extension_object.COMPRESSED_RGBA_S3TC_DXT5_EXT</code></li> +</ul> + +<p>圧縮テクスチャのフォーマットは、2 つの関数で使用できます: compressedTexImage2D および compressedTexSubImage2D</p> + +<h3 id="Example_2" name="Example_2">例</h3> + +<pre class="brush:js">var ext = ( + gl.getExtension("WEBGL_compressed_texture_s3tc") || + gl.getExtension("MOZ_WEBGL_compressed_texture_s3tc") || + gl.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc") +); +var texture = gl.createTexture(); +gl.bindTexture(gl.TEXTURE_2D, texture); +gl.compressedTexImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_RGBA_S3TC_DXT5_EXT, 512, 512, 0, textureData); +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); +gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); +</pre> diff --git a/files/ja/web/api/webgl_api/webgl_best_practices/index.html b/files/ja/web/api/webgl_api/webgl_best_practices/index.html new file mode 100644 index 0000000000..6ff0290612 --- /dev/null +++ b/files/ja/web/api/webgl_api/webgl_best_practices/index.html @@ -0,0 +1,43 @@ +--- +title: WebGL best practices +slug: Web/API/WebGL_API/WebGL_best_practices +tags: + - WebGL +translation_of: Web/API/WebGL_API/WebGL_best_practices +--- +<p>{{WebGLSidebar}}</p> + +<p>この文書は WebGL を使ったコンテンツの向上のための Tips について書きます。これらの提案に従うことで、多くの機器への互換性を高めたり、パフォーマンスを上げることにもなります。</p> + +<h2 id="避けたほうがいいこと">避けたほうがいいこと</h2> + +<ul> + <li>WebGL のエラーを出さないように注意しましょう。エラーは <code>getError()</code> で得られますが、Firefox では <code>webgl.verbose</code> の設定を有効にすることで、ウェブコンソールに WebGL のエラーと警告を出力します。ユーザーのコンソールにエラーを吐き出す必要はないでしょう?(訳註:パフォーマンスの理由もある。下参照)</li> + <li><code>#ifdef GL_ES</code> は絶対に使ってはいけません。初期の例ではこれが使われていましたが、WebGL では必ず true になるので必要ありません。</li> + <li>フラグメントシェーダで <code>highp</code> 精度を使うのはやめましょう。<code>mediump</code> を代わりに使いましょう。<code>highp</code> を使うと今のモバイルのハードウェアのほとんどで動きません。Firefox 11 からは <code>getShaderPrecisionFormat()</code> 関数が実装されるので、<code>highp</code> 精度が使えるかどうかだけでなく、それぞれの精度の名称について実際の精度を知ることができます。</li> +</ul> + +<h2 id="覚えておいたほうがいいこと">覚えておいたほうがいいこと</h2> + +<ul> + <li>WebGL の機能の中にはクライアントによって制限があるものがあります。そういうものを使う前には <code>getParameter()</code> を使って調べましょう。例えば、2D テクスチャのサイズは <code>webgl.getParameter(webgl.MAX_TEXTURE_SIZE)</code> でわかります。Firefox 10 からは <code>webgl.min_capability_mode</code> の設定があり、最低限の機能の環境をシミュレートすることができます。</li> + <li>特に、頂点シェーダでのテクスチャの使用は <code>webgl.getParameter(webgl.MAX_VERTEX_TEXTURE_IMAGE_UNITS)</code>がゼロより大きくなければ使えません。現在のモバイルのハードウェアではまず使えないでしょう。</li> + <li>WebGL の拡張が使えるかどうかはクライアントに依存します。できるならそれらの使用をオプションとし、サポートされていない環境にも対応できるようにしましょう。Firefox 10 からは <code>webgl.disable-extensions</code> の設定があり、拡張のない環境をシミュレートすることができます。</li> + <li><code>OES_texture_float</code> 拡張がサポートされていたとしても、浮動小数点数テクスチャへのレンダリングはサポートされていないかもしれません。モバイルのハードウェアではまず動かないでしょう。サポートされているかを調べるには <code>checkFramebufferStatus()</code> を使ってください。</li> +</ul> + +<h2 id="一般的なパフォーマンスの_tips">一般的なパフォーマンスの tips</h2> + +<ul> + <li>CPU と GPU の同期を必要とするものはすべて、とても遅い可能性があり、メインのレンダリングループでは避けたほうがいいでしょう。<code>getError()</code>、<code>readPixels()</code>、<code>finish()</code> などの関数がそれです。<code>getParameter()</code> や <code>getUniformLocation()</code> といった WebGL のゲッタも遅いので、JS 側で変数にキャッシュしてください。</li> + <li>大きい描画を少数だけしたほうがパフォーマンスが向上します(訳註:小さな描画をたくさん行うより)。1000 回の小さなものを描画するなら、一回の <code>drawArrays()</code> や <code>drawElements()</code> でやりましょう。一回の <code>drawArrays()</code> で離れたオブジェクトを描画するなら、3 点が一直線上にある三角形が使えます。</li> + <li>状態の変更が少ないほどパフォーマンスが向上します。特に、複数の画像をひとつのテクスチャにまとめて適切な座標を使うことでバインドしているテクスチャの変更が少なくて済みます。</li> + <li>小さなテクスチャは大きなテクスチャよりパフォーマンスが良いです。そのため mipmap が有効です。</li> + <li>簡単なシェーダーは複雑なものよりもパフォーマンスが良いです。特に、<code>if</code> 文を減らせば速くなります。割り算や <code>log()</code> などの数学の演算もコストが高いです。</li> +</ul> + +<h2 id="参照">参照</h2> + +<ul> + <li><a href="/ja/WebGL" title="WebGL">WebGL</a></li> +</ul> diff --git a/files/ja/web/api/webgl_api/webgl_model_view_projection/index.html b/files/ja/web/api/webgl_api/webgl_model_view_projection/index.html new file mode 100644 index 0000000000..d686e310bd --- /dev/null +++ b/files/ja/web/api/webgl_api/webgl_model_view_projection/index.html @@ -0,0 +1,692 @@ +--- +title: WebGL モデル ビュー 射影 +slug: Web/API/WebGL_API/WebGL_model_view_projection +translation_of: Web/API/WebGL_API/WebGL_model_view_projection +--- +<p>{{WebGLSidebar}}</p> + +<p class="summary">この記事では、<a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> プロジェクト内でデータを取得し、それを適切な空間に投影して画面に表示する方法について説明します。並進、拡縮、回転行列を使用した基本的な行列計算の知識があることを前提としています。3Dシーンを構成するときに通常使用される中心的な3つの行列である、モデル、ビュー、射影行列について説明します。</p> + +<div class="note"> +<p><strong>Note</strong>: This article is also available as an <a href="https://github.com/TatumCreative/mdn-model-view-projection">MDN content kit</a>. It also uses a collection of <a href="https://github.com/TatumCreative/mdn-webgl">utility functions</a> available under the <code>MDN</code> global object.</p> +</div> + +<h2 id="モデル、ビュー、射影行列">モデル、ビュー、射影行列</h2> + +<p>WebGLの空間内の点とポリゴンの個々の変換は、並進、拡縮、回転などの基本的な変換行列によって処理されます。 <span class="tlid-translation translation" lang="ja"><span title="">これらの行列は、複雑な3Dシーンの描画に役立つように、一緒に構成し、特別な方法でグループ化できます。</span></span>これらの構成された行列は、最終的に元のモデルデータを<strong>クリップ空間</strong>と呼ばれる特別な座標空間に移動します。これは2ユニットの幅の立方体で、中心が (0,0,0) 、対角が (-1,-1,-1) から (1,1,1) になります。このクリップ空間は2次元平面に圧縮され、画像へラスタライズされます。</p> + +<p><span class="tlid-translation translation" lang="ja"><span title="">以下で説明する最初の行列は<strong>モデル行列</strong>です。これは、元のモデルデータを取得して3次元ワールド空間内で移動する方法を定義します。</span></span> <span class="tlid-translation translation" lang="ja"><span title=""><strong>射影行列</strong>は、ワールド空間座標をクリップ空間座標に変換するために使用されます。</span></span> <span class="tlid-translation translation" lang="ja"><span title="">一般的に使用される射影行列である<strong>透視投影射影行列</strong>は、3D仮想世界の視聴者の代理として機能する一般的なカメラの<em>効果</em>を模倣するために使用されます。</span></span> <span class="tlid-translation translation" lang="ja"><span title=""><strong>ビュー行列</strong>は、変更されるカメラの位置をシミュレートし、シーン内のオブジェクトを移動して視聴者が現在何を見られるかを変更します</span></span>。</p> + +<p><span class="tlid-translation translation" lang="ja"><span title="">以下のセクションでは、モデル、ビュー、射影行列の背景にある考え方と実装について詳説します。</span> <span title="">これらの行列は、画面上でデータを移動するための根幹であり、個々のフレームワークやエンジンを超える概念です。</span></span></p> + +<h2 id="クリップ空間">クリップ空間</h2> + +<p>WebGLプログラムでは、通常、データは自分の座標系でGPUにアップロードされ、次に頂点シェーダーがそれらの点を<strong>クリップ空間</strong>と呼ばれる特別な座標系に変換します。クリップ空間の外側にあるデータは切り取られ、描画されません。ただし、三角形がこのスペースの境界を跨ぐ場合は、新しい三角形に分割され、クリップスペースにある新しい三角形の部分のみが残ります。</p> + +<p><img alt="A 3d graph showing clip space in WebGL." src="https://mdn.mozillademos.org/files/11371/clip-space-graph.svg" style="height: 432px; width: 500px;"></p> + +<p>上の図は、全ての点が収まる必要のあるクリップ空間を視覚化したものです。これは、各辺が2の立方体であり、片方の角が (-1,-1,-1) にあり、対角が (1,1,1) にあります。立方体の中心は点 (0,0,0) です。 クリップ空間に使用されるこの8立方メートルの座標系は、正規化デバイス座標(NDC)と呼ばれます。WebGLコードを調べて作業している間、その用語を時々耳にするかもしれません。</p> + +<p><span class="tlid-translation translation" lang="ja"><span title="">このセクションでは、データをクリップ空間座標系に直接配置する仕組みを説明します。</span> <span title="">通常、任意の座標系にあるモデルデータが使用され、その後、行列を使用して変換され、モデル座標がクリップ空間座標系に変換されます。この例では、クリップ空間がどのように機能するかを最も簡単に説明する為、単純に (-1, -1, -1) から (1,1,1) までの範囲のモデル座標を使用します。</span><span title="">以下のコードは、画面上に正方形を描く為に2つの三角形を作成します。</span><span title="">正方形のZ深度は、正方形が同じ空間を共有するときに何が上に描画されるかを決定します。</span><span title="">小さいZ値は大きいZ値の上にレンダリングされます。</span></span></p> + +<h3 id="WebGLBox_の例">WebGLBox の例</h3> + +<p><span class="tlid-translation translation" lang="ja">この例では、画面上に2Dボックスを描画するカスタム</span> <code>WebGLBox</code> <span class="tlid-translation translation" lang="ja">オブジェクトを作成します</span>。</p> + +<div class="note"> +<p><strong>Note</strong>: The code for each WebGLBox example is available in this <a href="https://github.com/TatumCreative/mdn-model-view-projection/tree/master/lessons">github repo</a> and is organized by section. In addition there is a JSFiddle link at the bottom of each section.</p> +</div> + +<h4 id="WebGLBox_コンストラクタ">WebGLBox コンストラクタ</h4> + +<p><span class="tlid-translation translation" lang="ja">コンストラクターは次のようになります。</span></p> + +<pre class="brush: js notranslate">function WebGLBox() { + // Setup the canvas and WebGL context + this.canvas = document.getElementById('canvas'); + this.canvas.width = window.innerWidth; + this.canvas.height = window.innerHeight; + this.gl = MDN.createContext(canvas); + + var gl = this.gl; + + // Setup a WebGL program, anything part of the MDN object is defined outside of this article + this.webglProgram = MDN.createWebGLProgramFromIds(gl, 'vertex-shader', 'fragment-shader'); + gl.useProgram(this.webglProgram); + + // Save the attribute and uniform locations + this.positionLocation = gl.getAttribLocation(this.webglProgram, 'position'); + this.colorLocation = gl.getUniformLocation(this.webglProgram, 'color'); + + // Tell WebGL to test the depth when drawing, so if a square is behind + // another square it won't be drawn + gl.enable(gl.DEPTH_TEST); + +} +</pre> + +<h4 id="WebGLBox_描画">WebGLBox 描画</h4> + +<p><span class="tlid-translation translation" lang="ja">次に、画面上にボックスを描画するメソッドを作成します</span>。</p> + +<pre class="brush: js notranslate">WebGLBox.prototype.draw = function(settings) { + // Create some attribute data; these are the triangles that will end being + // drawn to the screen. There are two that form a square. + + var data = new Float32Array([ + + //Triangle 1 + settings.left, settings.bottom, settings.depth, + settings.right, settings.bottom, settings.depth, + settings.left, settings.top, settings.depth, + + //Triangle 2 + settings.left, settings.top, settings.depth, + settings.right, settings.bottom, settings.depth, + settings.right, settings.top, settings.depth + ]); + + // Use WebGL to draw this onto the screen. + + // Performance Note: Creating a new array buffer for every draw call is slow. + // This function is for illustration purposes only. + + var gl = this.gl; + + // Create a buffer and bind the data + var buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); + + // Setup the pointer to our attribute data (the triangles) + gl.enableVertexAttribArray(this.positionLocation); + gl.vertexAttribPointer(this.positionLocation, 3, gl.FLOAT, false, 0, 0); + + // Setup the color uniform that will be shared across all triangles + gl.uniform4fv(this.colorLocation, settings.color); + + // Draw the triangles to the screen + gl.drawArrays(gl.TRIANGLES, 0, 6); +} +</pre> + +<p><span class="tlid-translation translation" lang="ja">シェーダーは GLSL で記述されたコードの一部であり、データポイントを取得して最終的に画面に描画します。便宜上、これらのシェーダーは、カスタム関数 </span><code>MDN.createWebGLProgramFromIds()</code> <span class="tlid-translation translation" lang="ja">を介してプログラムに取り込まれる要素</span> {{htmlelement("script")}} <span class="tlid-translation translation" lang="ja">に格納されます。この関数は、これらのチュートリアル用に作成された</span> <a href="https://github.com/TatumCreative/mdn-webgl">ユーティリティ関数群</a> <span class="tlid-translation translation" lang="ja">の一部であり、ここでは詳しく説明しません。この関数は、いくつかの GLSL ソースコードを取得して WebGL プログラムにコンパイルする基本を処理します。関数は3つのパラメーターを取ります。プロ</span>グ<span class="tlid-translation translation" lang="ja">ラムをレンダリングするコンテキスト、頂点シェーダーを含む要素のID </span>{{htmlelement("script")}}<span class="tlid-translation translation" lang="ja">、フラグメントシェーダーを含む要素のID </span>{{htmlelement("script")}} <span class="tlid-translation translation" lang="ja">です。頂点シェーダーは頂点を配置し、フラグメントシェーダーは各ピクセルに色を付けます。</span></p> + +<p><span class="tlid-translation translation" lang="ja">最初に、</span><span class="tlid-translation translation" lang="ja"><span class="alt-edited" title="">画面上で頂点を移動させる頂点シェーダーを見てみましょう。</span></span></p> + +<pre class="brush: glsl notranslate">// The individual position vertex +attribute vec3 position; + +void main() { + // the gl_Position is the final position in clip space after the vertex shader modifies it + gl_Position = vec4(position, 1.0); +} +</pre> + +<p><span class="tlid-translation translation" lang="ja"><span title="">次に、データを実際にピクセルにラスタライズするために、フラグメントシェーダーはピクセルごとに全てを評価し、一つの色を設定します。</span><span title="">GPUは、レンダリングする必要があるピクセルごとにシェーダー関数を呼び出します。</span><span title="">シェーダーの仕事は、そのピクセルに使用する色を返すことです。</span></span></p> + +<pre class="brush: glsl notranslate">precision mediump float; +uniform vec4 color; + +void main() { + gl_FragColor = color; +} +</pre> + +<p><span class="tlid-translation translation" lang="ja"><span title="">これらの設定が含まれているので、クリップ空間座標を使用して画面に直接描画します。</span></span></p> + +<pre class="brush: js notranslate">var box = new WebGLBox(); +</pre> + +<p><span class="tlid-translation translation" lang="ja"><span title="">最初に中央に赤いボックスを描きます。</span></span></p> + +<pre class="brush: js notranslate">box.draw({ + top : 0.5, // x + bottom : -0.5, // x + left : -0.5, // y + right : 0.5, // y + + depth : 0, // z + color : [1, 0.4, 0.4, 1] // red +}); +</pre> + +<p>次に、緑色のボックスを赤いボックスの上部に描画します。</p> + +<pre class="brush: js notranslate">box.draw({ + top : 0.9, // x + bottom : 0, // x + left : -0.9, // y + right : 0.9, // y + + depth : 0.5, // z + color : [0.4, 1, 0.4, 1] // green +}); +</pre> + +<p>最後に、クリッピングが実際に行われていることを示すために、このボックスは完全にクリップ空間の外側にあるため、描画されません。深さが -1.0 から 1.0 の範囲外です。</p> + +<pre class="brush: js notranslate">box.draw({ + top : 1, // x + bottom : -1, // x + left : -1, // y + right : 1, // y + + depth : -1.5, // z + color : [0.4, 0.4, 1, 1] // blue +}); +</pre> + +<h4 id="結果">結果</h4> + +<p><a href="https://jsfiddle.net/mff99yu5">JSFiddle で表示</a></p> + +<p><img alt="The results of drawing to clip space using WebGL." src="https://mdn.mozillademos.org/files/11373/part1.png" style="height: 530px; width: 800px;"></p> + +<h4 id="演習">演習</h4> + +<p><span class="tlid-translation translation" lang="ja"><span title="">この時点で役立つ演習は、コードを変更してボックスをクリップ空間内で移動し、点がクリップ空間内でどのようにクリップされ、移動されるかを感じ取ることです。</span><span title="">背景を持つボックス状のスマイルのような絵を描いてみてください。</span></span></p> + +<h2 id="斉次座標"><span class="ILfuVd">斉<strong>次座標</strong></span></h2> + +<p>前のクリップ空間の頂点シェーダのメインラインは、このコードを含んでいました。</p> + +<pre class="brush: js notranslate">gl_Position = vec4(position, 1.0); +</pre> + +<p><span class="tlid-translation translation" lang="ja"><span title="">変数</span></span> <code>position</code> <span class="tlid-translation translation" lang="ja"><span title="">は、</span></span> <code>draw()</code> <span class="tlid-translation translation" lang="ja"><span title="">メソッドで定義され、属性としてシェーダーに渡されました。</span><span title="">これは3次元の点ですが、パイプラインを介して渡されることになる変数</span></span> <code>gl_Position</code> <span class="tlid-translation translation" lang="ja"><span title="">は実際には4次元です</span></span>。すなわち、 <code>(x, y, z)</code> <span class="tlid-translation translation" lang="ja"><span title="">の代わりに</span></span> <code>(x, y, z, w)</code><span class="tlid-translation translation" lang="ja"><span title=""> となっています</span></span><span class="tlid-translation translation" lang="ja"><span title="">。</span></span><code>z</code> <span class="tlid-translation translation" lang="ja"><span title="">の後には文字がないため、慣例により、この4番目の次元には</span></span> <code>w</code> <span class="tlid-translation translation" lang="ja"><span title="">というラベルが付いています。</span> <span title="">上記の例では、</span></span> <code>w</code> <span class="tlid-translation translation" lang="ja"><span title="">座標は 1.0 に設定されています。</span></span></p> + +<p><span class="tlid-translation translation" lang="ja"><span title="">明らかな疑問は、「なぜ余分な次元があるのか?」です。</span><span title="">この追加により、3Dデータを操作するための多くの優れた手法が可能になることが分かります。</span><span title="">この追加された次元により、遠近法の概念が座標系に導入されます。</span><span title="">それを配置すると、3D座標を2D空間にマッピングできます。これにより、2本の平行線が遠くに離れるときに交差するようになります。</span><span title="">値</span></span> <code>w</code> <span class="tlid-translation translation" lang="ja"><span title="">は、座標の他のコンポーネントの除数として使用されるため、</span></span> <code>x</code><span class="tlid-translation translation" lang="ja"><span title="">、</span></span><code>y</code><span class="tlid-translation translation" lang="ja"><span title="">、</span></span><code>z</code><span class="tlid-translation translation" lang="ja"><span title="">の真の値は、</span></span><code>x/w</code><span class="tlid-translation translation" lang="ja"><span title="">、</span></span><code>y/w</code><span class="tlid-translation translation" lang="ja"><span title="">、</span></span><code>z/w</code><span class="tlid-translation translation" lang="ja"><span title="">として計算されます(そして、</span></span><code>w</code><span class="tlid-translation translation" lang="ja"><span title="">も</span> </span><code>w/w</code><span class="tlid-translation translation" lang="ja"><span title="">で1になる)。</span></span></p> + +<p>A three dimensional point is defined in a typical Cartesian coordinate system. The added fourth dimension changes this point into a {{interwiki("wikipedia", "homogeneous coordinates", "homogeneous coordinate")}}. It still represents a point in 3D space and it can easily be demonstrated how to construct this type of coordinate through a pair of simple functions.</p> + +<pre class="brush: js notranslate">function cartesianToHomogeneous(point) + let x = point[0]; + let y = point[1]; + let z = point[2]; + + return [x, y, z, 1]; +} + +function homogeneousToCartesian(point) { + let x = point[0]; + let y = point[1]; + let z = point[2]; + let w = point[3]; + + return [x/w, y/w, z/w]; +} +</pre> + +<p>As previously mentioned and shown in the functions above, the w component divides the x, y, and z components. When the w component is a non-zero real number then homogeneous coordinate easily translates back into a normal point in Cartesian space. Now what happens if the w component is zero? In JavaScript the value returned would be as follows.</p> + +<pre class="brush: js notranslate">homogeneousToCartesian([10, 4, 5, 0]); +</pre> + +<p>This evaluates to: <code>[Infinity, Infinity, Infinity]</code>.</p> + +<p>This homogeneous coordinate represents some point at infinity. This is a handy way to represent a ray shooting off from the origin in a specific direction. In addition to a ray, it could also be thought of as a representation of a directional vector. If this homogeneous coordinate is multiplied against a matrix with a translation then the translation is effectively stripped out.</p> + +<p>When numbers are extremely large (or extremely small) on computers they begin to become less and less precise because there are only so many ones and zeros that are used to represent them. The more operations that are done on larger numbers, the more and more errors accumulate into the result. When dividing by w, this can effectively increase the precision of very large numbers by operating on two potentially smaller, less error-prone numbers.</p> + +<p>The final benefit of using homogeneous coordinates is that they fit very nicely for multiplying against 4x4 matrices. A vertex must match at least one of the dimensions of a matrix in order to be multiplied against it. The 4x4 matrix can be used to encode a variety of useful transformations. In fact, the typical perspective projection matrix uses the division by the w component to achieve its transformation.</p> + +<p>The clipping of points and polygons from clip space actually happens after the homogeneous coordinates have been transformed back into Cartesian coordinates (by dividing by w). This final space is known as <strong>normalized device coordinates</strong> or NDC.</p> + +<p>To start playing with this idea the previous example can be modified to allow for the use of the <code>w</code> component.</p> + +<pre class="brush: js notranslate">//Redefine the triangles to use the W component +var data = new Float32Array([ + //Triangle 1 + settings.left, settings.bottom, settings.depth, settings.w, + settings.right, settings.bottom, settings.depth, settings.w, + settings.left, settings.top, settings.depth, settings.w, + + //Triangle 2 + settings.left, settings.top, settings.depth, settings.w, + settings.right, settings.bottom, settings.depth, settings.w, + settings.right, settings.top, settings.depth, settings.w +]); +</pre> + +<p>Then the vertex shader uses the 4 dimensional point passed in.</p> + +<pre class="brush: js notranslate">attribute vec4 position; + +void main() { + gl_Position = position; +} +</pre> + +<p>First, we draw a red box in the middle, but set W to 0.7. As the coordinates get divided by 0.7 they will all be enlarged.</p> + +<pre class="brush: js notranslate">box.draw({ + top : 0.5, // y + bottom : -0.5, // y + left : -0.5, // x + right : 0.5, // x + w : 0.7, // w - enlarge this box + + depth : 0, // z + color : [1, 0.4, 0.4, 1] // red +}); +</pre> + +<p>Now, we draw a green box up top, but shrink it by setting the w component to 1.1</p> + +<pre class="brush: js notranslate">box.draw({ + top : 0.9, // y + bottom : 0, // y + left : -0.9, // x + right : 0.9, // x + w : 1.1, // w - shrink this box + + depth : 0.5, // z + color : [0.4, 1, 0.4, 1] // green +}); +</pre> + +<p>This last box doesn't get drawn because it's outside of clip space. The depth is outside of the -1.0 to 1.0 range.</p> + +<pre class="brush: js notranslate">box.draw({ + top : 1, // y + bottom : -1, // y + left : -1, // x + right : 1, // x + w : 1.5, // w - Bring this box into range + + depth : -1.5, // z + color : [0.4, 0.4, 1, 1] // blue +}); +</pre> + +<h3 id="The_results">The results</h3> + +<p><a href="https://jsfiddle.net/mff99yu">View on JSFiddle</a></p> + +<p id="sect1"><img alt="The results of using homogeneous coordinates to move the boxes around in WebGL." src="https://mdn.mozillademos.org/files/11375/part2.png" style="height: 530px; width: 800px;"></p> + +<h3 id="Exercises">Exercises</h3> + +<ul> + <li>Play around with these values to see how it affects what is rendered on the screen. Note how the previously clipped blue box is brought back into range by setting its w component.</li> + <li>Try creating a new box that is outside of clip space and bring it back in by dividing by w.</li> +</ul> + +<h2 id="Model_transform">Model transform</h2> + +<p>Placing points directly into clip space is of limited use. In real world applications, you don't have all your source coordinates already in clip space coordinates. So most of the time, you need to transform the model data and other coordinates into clip space. The humble cube is an easy example of how to do this. Cube data consists of vertex positions, the colors of the faces of the cube, and the order of the vertex positions that make up the individual polygons (in groups of 3 vertices to construct the triangles composing the cube's faces). The positions and colors are stored in GL buffers, sent to the shader as attributes, and then operated upon individually.</p> + +<p>Finally a single model matrix is computed and set. This matrix represents the transformations to be performed on every point making up the model in order to move it into the correct space, and to perform any other needed transforms on each point in the model. This applies not just to each vertex, but to every single point on every surface of the model as well.</p> + +<p>In this case, for every frame of the animation a series of scale, rotation, and translation matrices move the data into the desired spot in clip space. The cube is the size of clip space (-1,-1,-1) to (1,1,1) so it will need to be shrunk down in order to not fill the entirety of clip space. This matrix is sent directly to the shader, having been multiplied in JavaScript beforehand.</p> + +<p>The following code sample defines a method on the <code>CubeDemo</code> object that will create the model matrix. It uses custom functions to create and multiply matrices as defined in the <a href="https://github.com/TatumCreative/mdn-webgl">MDN WebGL</a> shared code. The new function looks like this:</p> + +<pre class="brush: js notranslate">CubeDemo.prototype.computeModelMatrix = function(now) { + //Scale down by 50% + var scale = MDN.scaleMatrix(0.5, 0.5, 0.5); + + // Rotate a slight tilt + var rotateX = MDN.rotateXMatrix(now * 0.0003); + + // Rotate according to time + var rotateY = MDN.rotateYMatrix(now * 0.0005); + + // Move slightly down + var position = MDN.translateMatrix(0, -0.1, 0); + + // Multiply together, make sure and read them in opposite order + this.transforms.model = MDN.multiplyArrayOfMatrices([ + position, // step 4 + rotateY, // step 3 + rotateX, // step 2 + scale // step 1 + ]); +}; +</pre> + +<p>In order to use this in the shader it must be set to a uniform location. The locations for the uniforms are saved in the <code>locations</code> object shown below:</p> + +<pre class="brush: js notranslate">this.locations.model = gl.getUniformLocation(webglProgram, 'model'); +</pre> + +<p>And finally the uniform is set to that location. This hands off the matrix to the GPU.</p> + +<pre class="brush: js notranslate">gl.uniformMatrix4fv(this.locations.model, false, new Float32Array(this.transforms.model)); +</pre> + +<p>In the shader, each position vertex is first transformed into a homogeneous coordinate (a <code>vec4</code> object), and then multiplied against the model matrix.</p> + +<pre class="brush: glsl notranslate">gl_Position = model * vec4(position, 1.0); +</pre> + +<div class="note"> +<p><strong>Note</strong>: In JavaScript, matrix multiplication requires a custom function, while in the shader it is built into the language with the simple * operator.</p> +</div> + +<h3 id="The_results_2">The results</h3> + +<p><a href="https://jsfiddle.net/5jofzgsh">View on JSFiddle</a></p> + +<p><img alt="Using a model matrix" src="https://mdn.mozillademos.org/files/11377/part3.png" style="height: 530px; width: 800px;"></p> + +<p>At this point the w value of the transformed point is still 1.0. The cube still doesn't have any perspective. The next section will take this setup and modify the w values to provide some perspective.</p> + +<h3 id="Exercises_2">Exercises</h3> + +<ul> + <li>Shrink down the box using the scale matrix and position it in different places within clip space.</li> + <li>Try moving it outside of clip space.</li> + <li>Resize the window and watch as the box skews out of shape.</li> + <li>Add a <code>rotateZ</code> matrix.</li> +</ul> + +<h2 id="Divide_by_W">Divide by W</h2> + +<p>An easy way to start getting some perspective on our model of the cube is to take the Z coordinate and copy it over to the w coordinate. Normally when converting a cartesian point to homogeneous it becomes <code>(x,y,z,1)</code>, but we're going to set it to something like <code>(x,y,z,z)</code>. In reality we want to make sure that z is greater than 0 for points in view, so we'll modify it slightly by changing the value to <code>((1.0 + z) * scaleFactor)</code>. This will take a point that is normally in clip space (-1 to 1) and move it into a space more like (0 to 1) depending on what the scale factor is set to. The scale factor changes the final w value to be either higher or lower overall.</p> + +<p>The shader code looks like this.</p> + +<pre class="brush: js notranslate">// First transform the point +vec4 transformedPosition = model * vec4(position, 1.0); + +// How much effect does the perspective have? +float scaleFactor = 0.5; + +// Set w by taking the z value which is typically ranged -1 to 1, then scale +// it to be from 0 to some number, in this case 0-1. +float w = (1.0 + transformedPosition.z) * scaleFactor; + +// Save the new gl_Position with the custom w component +gl_Position = vec4(transformedPosition.xyz, w); +</pre> + +<h3 id="The_results_3">The results</h3> + +<p><a href="https://jsfiddle.net/vk9r8h2c">View on JSFiddle</a></p> + +<p><img alt="Filling the W component and creating some projection." src="https://mdn.mozillademos.org/files/11379/part4.png" style="height: 531px; width: 800px;"></p> + +<p>See that small dark blue triangle? That's an additional face added to our object because the rotation of our shape has caused that corner to extend outside clip space, thus causing the corner to be clipped away. See {{anch("Perspective projection matrix")}} below for an introduction to how to use more complex matrices to help control and prevent clipping.</p> + +<h3 id="Exercise">Exercise</h3> + +<p>If that sounds a little abstract, open up the vertex shader and play around with the scale factor and watch how it shrinks vertices more towards the surface. Completely change the w component values for really trippy representations of space.</p> + +<p>In the next section we'll take this step of copying Z into the w slot and turn it into a matrix.</p> + +<h2 id="Simple_projection">Simple projection</h2> + +<p>The last step of filling in the w component can actually be accomplished with a simple matrix. Start with the identity matrix:</p> + +<pre class="brush: js notranslate">var identity = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, +]; + +MDN.multiplyPoint(identity, [2, 3, 4, 1]); +//> [2, 3, 4, 1] +</pre> + +<p>Then move the last column's 1 up one space.</p> + +<pre class="brush: js notranslate">var copyZ = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 1, + 0, 0, 0, 0, +]; + +MDN.multiplyPoint(copyZ, [2, 3, 4, 1]); +//> [2, 3, 4, 4] +</pre> + +<p>However in the last example we performed <code>(z + 1) * scaleFactor</code>:</p> + +<pre class="notranslate">var scaleFactor = 0.5; + +var simpleProjection = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, scaleFactor, + 0, 0, 0, scaleFactor, +]; + +MDN.multiplyPoint(simpleProjection, [2, 3, 4, 1]); +//> [2, 3, 4, 2.5] +</pre> + +<p>Breaking it out a little further we can see how this works:</p> + +<pre class="brush: js notranslate">var x = (2 * 1) + (3 * 0) + (4 * 0) + (1 * 0) +var y = (2 * 0) + (3 * 1) + (4 * 0) + (1 * 0) +var z = (2 * 0) + (3 * 0) + (4 * 1) + (1 * 0) +var w = (2 * 0) + (3 * 0) + (4 * scaleFactor) + (1 * scaleFactor) +</pre> + +<p>The last line could be simplified to:</p> + +<pre class="brush: js notranslate">w = (4 * scaleFactor) + (1 * scaleFactor) +</pre> + +<p>Then factoring out the scaleFactor, we get this:</p> + +<pre class="brush: js notranslate">w = (4 + 1) * scaleFactor +</pre> + +<p>Which is exactly the same as the <code>(z + 1) * scaleFactor</code> that we used in the previous example.</p> + +<p>In the box demo, an additional <code>computeSimpleProjectionMatrix()</code> method is added. This is called in the <code>draw()</code> method and has the scale factor passed to it. The result should be identical to the last example:</p> + +<pre class="brush: js notranslate">CubeDemo.prototype.computeSimpleProjectionMatrix = function(scaleFactor) { + this.transforms.projection = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, scaleFactor, + 0, 0, 0, scaleFactor + ]; +}; +</pre> + +<p>Although the result is identical, the important step here is in the vertex shader. Rather than modifying the vertex directly, it gets multiplied by an additional <strong>{{anch("Projection matrix", "projection matrix")}}</strong>, which (as the name suggests) projects 3D points onto a 2D drawing surface:</p> + +<pre class="brush: glsl notranslate">// Make sure to read the transformations in reverse order +gl_Position = projection * model * vec4(position, 1.0); +</pre> + +<h3 id="The_results_4">The results</h3> + +<p><a href="https://jsfiddle.net/zwyLLcbw">View on JSFiddle</a></p> + +<p><img alt="A simple projection matrix" src="https://mdn.mozillademos.org/files/11381/part5.png" style="height: 531px; width: 800px;"></p> + +<h2 id="The_viewing_frustum">The viewing frustum</h2> + +<p>Before we move on to covering how to compute a perspective projection matrix, we need to introduce the concept of the <strong>{{interwiki("wikipedia", "viewing frustum")}}</strong> (also known as the <strong>view frustum</strong>). This is the region of space whose contents are visible to the user at the current time. It's the 3D region of space defined by the field of view and the distances specified as the nearest and farthest content that should be rendered.</p> + +<p>While rendering, we need to determine which polygons need to be rendered in order to represent the scene. This is what the viewing frustum defines. But what's a frustum in the first place?</p> + +<p>A {{interwiki("wikipedia", "frustum")}} is the 3D solid that results from taking any solid and slicing off two sections of it using two parallel planes. Consider our camera, which is viewing an area that starts immediately in front of its lens and extends off into the distance. The viewable area is a four-sided pyramid with its peak at the lens, its four sides corresponding to the extents of its peripheral vision range, and its base at the farthest distance it can see, like this:</p> + +<div style="width: 42em; margin-bottom: 1em;"><img alt="A depiction of the entire viewing area of a camera. This area is a four-sided pyramid with its peak at the lens and its base at the world's maximum viewable distance." src="https://mdn.mozillademos.org/files/17295/FullCameraFOV.svg" style="display: block; margin: 0 auto; width: 36em;"></div> + +<p>If we simply used this to determine the polygons to be rendered each frame, our renderer would need to render every polygon within this pyramid, all the way off into infinity, including also polygons that are very close to the lens—likely too close to be useful (and certainly including things that are so close that a real human wouldn't be able to focus on them in the same setting).</p> + +<p>So the first step in reducing the number of polygons we need to compute and render, we turn this pyramid into the viewing frustum. The two planes we'll use to chop away vertices in order to reduce the polygon count are the <strong>near clipping plane</strong> and the <strong>far clipping plane</strong>.</p> + +<p>In WebXR, the near and far clipping planes are defined by specifying the distance from the lens to the closest point on a plane which is perpendicular to the viewing direction. <span>Anything closer to the lens than the near clipping plane or farther from it than the far clipping plane is removed. This results in the viewing frustum, which looks like this:</span></p> + +<div style="width: 42em; margin-bottom: 1em;"><img alt="A depiction of the camera's view frustum; the near and far planes have removed part of the volume, reducing the polygon count." src="https://mdn.mozillademos.org/files/17296/CameraViewFustum.svg" style="display: block; margin: 0 auto; width: 36em;"></div> + +<p>The set of objects to be rendered for each frame is essentially created by starting with the set of all objects in the scene. Then any objects which are <em>entirely</em> outside the viewing frustum are removed from the set. Next, objects which partially extrude outside the viewing frustum are clipped by dropping any polygons which are entirely outside the frustum, and by clipping the polygons which cross outside the frustrum so that they no longer exit it.</p> + +<p>Once that's been done, we have the largest set of polygons which are entirely within the viewing frustum. This list is usually further reduced using processes like {{interwiki("wikipedia", "back-face culling")}} (removing polygons whose back side is facing the camera) and occlusion culling using {{interwiki("wikipedia", "hidden-surface determination")}} (removing polygons which can't be seen because they're entirely blocked by polygons that are closer to the lens).</p> + +<h2 id="Perspective_projection_matrix">Perspective projection matrix</h2> + +<p>Up to this point, we've built up our own 3D rendering setup, step by step. However the current code as we've built it has some issues. For one, it gets skewed whenever we resize our window. Another is that our simple projection doesn't handle a wide range of values for the scene data. Most scenes don't work in clip space. It would be helpful to define what distance is relevant to the scene so that precision isn't lost in converting the numbers. Finally it's very helpful to have a fine-tuned control over what points get placed inside and outside of clip space. In the previous examples the corners of the cube occasionally get clipped.</p> + +<p>The <strong>perspective projection matrix</strong> is a type of projection matrix that accomplishes all of these requirements. The math also starts to get a bit more involved and won't be fully explained in these examples. In short, it combines dividing by w (as done with the previous examples) with some ingenious manipulations based on <a href="https://en.wikipedia.org/wiki/Similarity_%28geometry%29">similar triangles</a>. If you want to read a full explanation of the math behind it check out some of the following links:</p> + +<ul> + <li><a href="http://www.songho.ca/opengl/gl_projectionmatrix.html">OpenGL Projection Matrix</a></li> + <li><a href="http://ogldev.atspace.co.uk/www/tutorial12/tutorial12.html">Perspective Projection</a></li> + <li><a href="http://stackoverflow.com/questions/28286057/trying-to-understand-the-math-behind-the-perspective-matrix-in-webgl/28301213#28301213">Trying to understand the math behind the perspective projection matrix in WebGL</a></li> +</ul> + +<p>One important thing to note about the perspective projection matrix used below is that it flips the z axis. In clip space the z+ goes away from the viewer, while with this matrix it comes towards the viewer.</p> + +<p>The reason to flip the z axis is that the clip space coordinate system is a left-handed coordinate system (wherein the z-axis points away from the viewer and into the screen), while the convention in mathematics, physics and 3D modeling, as well as for the view/eye coordinate system in OpenGL, is to use a right-handed coordinate system (z-axis points out of the screen towards the viewer) . More on that in the relevant Wikipedia articles: <a href="https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness">Cartesian coordinate system</a>, <a href="https://en.wikipedia.org/wiki/Right-hand_rule">Right-hand rule</a>.</p> + +<p>Let's take a look at a <code>perspectiveMatrix()</code> function, which computes the perspective projection matrix.</p> + +<pre class="brush:js notranslate">MDN.perspectiveMatrix = function(fieldOfViewInRadians, aspectRatio, near, far) { + var f = 1.0 / Math.tan(fieldOfViewInRadians / 2); + var rangeInv = 1 / (near - far); + + return [ + f / aspectRatio, 0, 0, 0, + 0, f, 0, 0, + 0, 0, (near + far) * rangeInv, -1, + 0, 0, near * far * rangeInv * 2, 0 + ]; +} +</pre> + +<p>The four parameters into this function are:</p> + +<dl> + <dt><code>fieldOfviewInRadians</code></dt> + <dd>An angle, given in radians, indicating how much of the scene is visible to the viewer at once. The larger the number is, the more is visible by the camera. The geometry at the edges becomes more and more distorted, equivalent to a wide angle lens. When the field of view is larger, the objects typically get smaller. When the field of view is smaller, then the camera can see less and less in the scene. The objects are distorted much less by perspective and objects seem much closer to the camera</dd> + <dt><code>aspectRatio</code></dt> + <dd>The scene's aspect ratio, which is equivalent to its width divided by its height. In these examples, that's the window's width divided by the window height. The introduction of this parameter finally solves the problem wherein the model gets warped as the canvas is resized and reshaped.</dd> + <dt><code>nearClippingPlaneDistance</code></dt> + <dd>A positive number indicating the distance into the screen to a plane which is perpendicular to the floor, nearer than which everything gets clipped away. This is mapped to -1 in clip space, and should not be set to 0.</dd> + <dt><code>farClippingPlaneDistance</code></dt> + <dd>A positive number indicating the distance to the plane beyond which geometry is clipped away. This is mapped to 1 in clip space. This value should be kept reasonably close to the distance of the geometry in order to avoid precision errors creeping in while rendering.</dd> +</dl> + +<p>In the latest version of the box demo, the <code>computeSimpleProjectionMatrix()</code> method has been replaced with the <code>computePerspectiveMatrix()</code> method.</p> + +<pre class="brush: js notranslate">CubeDemo.prototype.computePerspectiveMatrix = function() { + var fieldOfViewInRadians = Math.PI * 0.5; + var aspectRatio = window.innerWidth / window.innerHeight; + var nearClippingPlaneDistance = 1; + var farClippingPlaneDistance = 50; + + this.transforms.projection = MDN.perspectiveMatrix( + fieldOfViewInRadians, + aspectRatio, + nearClippingPlaneDistance, + farClippingPlaneDistance + ); +}; +</pre> + +<p>The shader code is identical to the previous example:</p> + +<pre class="brush: js notranslate">gl_Position = projection * model * vec4(position, 1.0); +</pre> + +<p>Additionally (not shown), the position and scale matrices of the model have been changed to take it out of clip space and into the larger coordinate system.</p> + +<h3 id="The_results_5">The results</h3> + +<p><a href="https://jsfiddle.net/Lzxw7e1q">View on JSFiddle</a></p> + +<p><img alt="A true perspective matrix" src="https://mdn.mozillademos.org/files/11383/part6.png" style="height: 531px; width: 800px;"></p> + +<h3 id="Exercises_3">Exercises</h3> + +<ul> + <li>Experiment with the parameters of the perspective projection matrix and the model matrix.</li> + <li>Swap out the perspective projection matrix to use {{interwiki("wikipedia", "orthographic projection")}}. In the MDN WebGL shared code you'll find the <code>MDN.orthographicMatrix()</code>. This can replace the <code>MDN.perspectiveMatrix()</code> function in <code>CubeDemo.prototype.computePerspectiveMatrix()</code>.</li> +</ul> + +<h2 id="View_matrix">View matrix</h2> + +<p>While some graphics libraries have a virtual camera that can be positioned and pointed while composing a scene, OpenGL (and by extension WebGL) does not. This is where the <strong>view matrix</strong> comes in. Its job is to translate, rotate, and scale the objects in the scene so that they are located in the right place relative to the viewer given the viewer's position and orientation.</p> + +<h3 id="Simulating_a_camera">Simulating a camera</h3> + +<p>This makes use of one of the fundamental facets of Einstein's special relativity theory: the principle of reference frames and relative motion says that, from the perspective of a viewer, you can simulate changing the position and orientation of the viewer by applying the opposite change to the objects in the scene. Either way, the result appears to be identical to the viewer.</p> + +<p>Consider a box sitting on a table and a camera resting on the table one meter away, pointed at the box, the front of which is pointed toward the camera. Then consider moving the camera away from the box until it's two meters away (by adding a meter to the camera's Z position), then sliding it 10 centimeters to the its left. The box recedes from the camera by that amount and slides to the right slightly, thereby appearing smaller to the camera and exposing a small amount of its left side to the camera.</p> + +<p>Now let's reset the scene, placing the box back in its starting point, with the camera two meters from, and directly facing, the box. This time, however, the camera is locked down on the table and cannot be moved or turned. This is what working in WebGL is like. So how do we simulate moving the camera through space?</p> + +<p>Instead of moving the camera backward and to the left, we apply the inverse transform to the box: we move the <em>box</em> backward one meter, and then 10 centimeters to its right. The result, from the perspective of each of the two objects, is identical.</p> + +<p><strong><<< insert image(s) here >>></strong></p> + +<p>The final step in all of this is to create the <strong>view matrix</strong>, which transforms the objects in the scene so they're positioned to simulate the camera's current location and orientation. Our code as it stands can move the cube around in world space and project everything to have perspective, but we still can't move the camera.</p> + +<p>Imagine shooting a movie with a physical camera. You have the freedom to place the camera essentially anywhere you wish, and to aim the camera in whichever direction you choose. To simulate this in 3D graphics, we use a view matrix to simulate the position and rotation of that physical camera.</p> + +<p>Unlike the model matrix, which directly transforms the model vertices, the view matrix moves an abstract camera around. In reality, the vertex shader is still only moving the models while the "camera" stays in place. In order for this to work out correctly, the inverse of the transform matrix must be used. The inverse matrix essentially reverses a transformation, so if we move the camera view forward, the inverse matrix causes the objects in the scene to move back.</p> + +<p>The following <code>computeViewMatrix()</code> method animates the view matrix by moving it in and out, and left and right.</p> + +<pre class="brush: js notranslate">CubeDemo.prototype.computeViewMatrix = function(now) { + var moveInAndOut = 20 * Math.sin(now * 0.002); + var moveLeftAndRight = 15 * Math.sin(now * 0.0017); + + // Move the camera around + var position = MDN.translateMatrix(moveLeftAndRight, 0, 50 + moveInAndOut ); + + // Multiply together, make sure and read them in opposite order + var matrix = MDN.multiplyArrayOfMatrices([ + // Exercise: rotate the camera view + position + ]); + + // Inverse the operation for camera movements, because we are actually + // moving the geometry in the scene, not the camera itself. + this.transforms.view = MDN.invertMatrix(matrix); +}; +</pre> + +<p>The shader now uses three matrices.</p> + +<pre class="brush: glsl notranslate">gl_Position = projection * view * model * vec4(position, 1.0); +</pre> + +<p>After this step, the GPU pipeline will clip the out of range vertices, and send the model down to the fragment shader for rasterization.</p> + +<h3 id="The_results_6">The results</h3> + +<p><a href="https://jsfiddle.net/86fd797g">View on JSFiddle</a></p> + +<p><img alt="The view matrix" src="https://mdn.mozillademos.org/files/11385/part7.png" style="height: 531px; width: 800px;"></p> + +<h3 id="Relating_the_coordinate_systems">Relating the coordinate systems</h3> + +<p>At this point it would be beneficial to take a step back and look at and label the various coordinate systems we use. First off, the cube's vertices are defined in <strong>model space</strong>. To move the model around the scene. these vertices need to be converted into <strong>world space</strong> by applying the model matrix.</p> + +<p>model space → model matrix → world space</p> + +<p>The camera hasn't done anything yet, and the points need to be moved again. Currently they are in world space, but they need to be moved to <strong>view space</strong> (using the view matrix) in order to represent the camera placement.</p> + +<p>world space → view matrix → view space</p> + +<p>Finally a <strong>projection</strong> (in our case the perspective projection matrix) needs to be added in order to map the world coordinates into clip space coordinates.</p> + +<p>view space → projection matrix → clip space</p> + +<h3 id="Exercise_2">Exercise</h3> + +<ul> + <li>Move the camera around the scene.</li> + <li>Add some rotation matrices to the view matrix to look around.</li> + <li>Finally, track the mouse's position. Use 2 rotation matrices to have the camera look up and down based on where the user's mouse is on the screen.</li> +</ul> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/API/WebGL_API">WebGL</a></li> + <li>{{interwiki("wikipedia", "3D projection")}}</li> +</ul> |