GLSL Shaderを扱う際の基本的な用語のメモ
※追加編集2020/12/20/00:00
間違ってたり、こっちの方が便利等ありましたらぜひ教えて下さい。
厳密なことは、Referencesのサイトに乗っています。
かなり感覚的な、ざっくりとしたメモです。
ここでは、私は、openFrameworksやp5.js、GLSLエディター等でのクリエイティブコーディング、ライブコーディング、ジェネレイティブ系での用途でshaderを使いたい目線での記入をしていく
GLSL自体のプログラミングについてはあまり触れない。
そこに興味がないからだ。
shader周りの情報についてメモしていく。
GLSL / OpenGL version
GLSLないし、OpenGLのバージョンで用語、書き方みたいのが変わってくる。
大事だと思ったこと
OpenGLそのものを使っていく、
processing、p5.js, openFrameWorks ...etc
で使う場合でも、まず自分はどのバージョンを使うべき、使わざるおえないのかを把握するのが大事。
ネットでGLSLやShaderと検索するとたくさんの情報が出てくる、
絞られた検索ができないとなかなか挫折するので、
まずは何を使うのかを調べよう
初学の私は、これにめちゃくちゃ頭が壊されて、モチベーションも持って行かれている。何でこんな複雑なの。
GPUやOSみたいなハードウェアに関わってくるところで、使えるバージョン等々が異なってくるらしい。
それを確認するのもめんどくさい。
GLSLとOpenGLとshaderのバージョン表記の書き方がまとまっている。
openFrameworksのGLのバージョンの調べ方のいいまとめがあったので、
書いときます。
公式のサンプルにglのバージョンを確認する exaples/gl/glInfoExample というプロジェクトがあります。実行した後の画面はこんな感じ
メインウィンドウの一番上に "opengl version: 2.1" と出ていますが、これは「このプロジェクトが」2.1で動かされました、と言う意味で、ハードウェアやライブラリの対応状況を表した物ではありません。
隣には、出力されたtxtが開かれています。これは GL の拡張機能をロードするヘルパライブラリのglew が、「私ここまでなら行けますよ」と言っている物で、このoFに含まれて居るglew的には 4.1 まではいける、ということらしいと分かります。
引用 : http://izmiz.hateblo.jp/entry/2014/10/14/225908
ofのプロジェクトに、以下のコードを足して、GLの対応状況を出力させます。たとえば、main.cpp でOpenGLをセットアップした後に入れると良いと思います。
引用 : http://izmiz.hateblo.jp/entry/2014/10/14/225908
// main.cpp
ofSetupOpenGL(1024,768, OF_WINDOW);
cout << "Vendor :" << glGetString(GL_VENDOR) << '\n';
cout << "GPU : " << glGetString(GL_RENDERER) << '\n';
cout << "OpenGL ver. " << glGetString(GL_VERSION) << '\n';
cout << "GLSL ver. " << glGetString(GL_SHADING_LANGUAGE_VERSION) << '\n
Vendor :Intel Inc.
GPU : Intel HD Graphics 4000 OpenGL Engine
OpenGL ver. 2.1 INTEL-8.28.32
GLSL ver. 1.20
これは、glInfoExample が出力しているのと同じですね。
引用 : http://izmiz.hateblo.jp/entry/2014/10/14/225908
PCごとの最新GLを利用する
マシンが使っているGPUと、oFのバージョンによって、利用できるGLのバージョンが変わります。openFrameworksで最新のGLを使える様にするには、以下のコードを加えます
引用 : http://izmiz.hateblo.jp/entry/2014/10/14/225908
#include "ofGLProgrammableRenderer.h"
int main( ){
ofSetCurrentRenderer(ofGLProgrammableRenderer::TYPE);
ofSetupOpenGL(1024,768, OF_WINDOW);
これで新しいGLに対応したレンダラーを利用するようになります。この書き方については、oF公式のShaderチュートリアルが参考になります
こうした後に、先ほどと同様にGLのバージョンを確認すると、このような出力になります。
引用 : http://izmiz.hateblo.jp/entry/2014/10/14/225908
Vendor :Intel Inc.
GPU : Intel HD Graphics 4000 OpenGL Engine
OpenGL ver. 4.1 INTEL-8.28.32
GLSL ver. 4.10
ここでは、他のもThree.jsとprocessingについても書かれているのでのぞいてみてください。
GLSL / OpenGL違い
OpenGLはライブラリみたいなイメージ。(ライブラリではないはず。)
OpenGLは"単にAPIを規定した"仕様"のことみたいだ。
各OSメーカー・コンピューターメーカーが、(windows / linux / macOS)
OpenGLというAPIを使って、作っていく。様々なバージョンが規定されているので、どれを使うのかは各メーカー・コンピューターによってバラバラみたいだ。
普通のライブラリのように「インターネットからファイルをダウンロードしてくれば最新版が使えるようになる」とかそういったものではないのです。
引用 下記リンク
jsのライブラリやprocessingのライブラリみたいなダウンロードして配置すれば使えるみたいなものではなくて、コンピュータに強く依存するようです。
下記を参照するとわかりやすいのかもしれない。
GLSLはそのOpenGL で使われるプログラミング言語と認識していいのだと思う。
webGL
webGLとはじゃあなんなのか?
このリンクを開いてみてほしい。
なんかすごいのが動かせるだろう
このようにブラウザでグラフィックをGPUで扱えるようにしているものをwebGLと呼ぶみたいだ。
ブラウザで、3次元CGを表示させるための標準仕様のことです。
引用 https://www.marineroad.com/staff-blog/16185.html
そのため、各ブラウザ(Chrome , IE, Firefox, safari)のバージョンによっては、対応しているwebGLのバージョンが異なってくるようだ。
OpenGLでGLSLという言語を使っているように、
webGLを扱うのに、Three.jsというjavascriptのライブラリやGLSLのShaderを使うことで利用できるみたい。
OpenGL ES
OpenGL ES (OpenGL for Embedded Systems) とは、組み込み用途向け OpenGL のサブセット版です。
Khronos Groupが仕様策定を行っています。
OpenGL ES は、OpenGL を携帯電話、PDA(携帯情報端末)、家電などに組み込まれる表示システムでの利用をターゲットに、必要十分な機能に絞り込んでよりコンパクトな規格にまとめたものです。
引用元 :
のように、OpenGLを組み込み用途向けにいい感じにしたものをOpenGL ESと呼ぶみたいだ。
これにも独自のバージョンがあるため気をつけた方がいいらしい。
グラフィックスパイプライン
Graphics pipeline(グラフィックスパイプライン) または rendering pipeline(レンダリングパイプライン)と呼ばれる計算処理方法。
3次元モデル・空間のものから最終的に2次元(ディスプレイ)イメージを作りだす多段階の過程全体を指す、パイプイン処理によって高速化する手法。
一般に「ステージ」と呼ばれる段階で処理が分かれている。
(モデリング)(ステージではなく前提条件、前提作業)
3次元座標を入力して三次元ワールド空間として知られている座標のデータを得る。これには拡大縮小と回転のようなローカルなオブジェクト空間上での基本的な座標変換も含む。
視点変換
物体は3次元のワールド空間座標から3次元の仮想カメラの位置と方向を元にした3次元座標系に変換される。この結果、元の3次元シーンはカメラの視点から見たものになる。この座標系は視空間ないしカメラ空間と定義される。
カリング
3次元モデルのポリゴンメッシュを形成する1つ1つの三角形は、それぞれが3つの頂点から成るが、表面または裏面の向きを持っている。座標変換後にカメラに対して裏面を向けている三角形を描画する必要がない場合、パイプラインから除外される。この工程を裏面カリング(背面カリング)と呼ぶ。どちらが表面でどちらが裏面になるかは、入力頂点の順序および右手座標系/左手座標系のどちらを採用するかによって変化する。
クリッピング
カメラの視界である視錐台 (frustum) の外にはみ出した座標は、この段階で不可視にされ捨てられる。クリッピングは正しい画像イメージを出力するのには必要なものではないが、見えない物体のデータを削れば、この後に続くレンダリング処理が高速化できる。視錐台を横切る「見切れ」状態の座標データは断端となる交点が求められ、両端が視錐台外であっても一部が視錐台内を横切るような線分にも注意が払われる。
ラスタライゼーション
ラスタライゼーションは描画シーンをラスターフォーマットに変換して、2次元画像空間に表現する処理である。これによりピクセル値が決定される。通常、ラスタライズの処理には以下の効果のための処理が含まれる。特に三角形内のピクセルごとの色を決めるピクセルシェーディング処理がパイプラインの主要な処理を占めるため、処理速度の向上のためには可能な範囲での並列・順次処理が図られる。
グラフィックスパイプラインの処理例
1.3Dモデルの構築と取得
2.モデルの配置
3.陰影付加
4.頂点追加
5.画角とクリッピング、陰面処理など
6.ピクセル割り当て
7.テクスチャ貼り付け
8.特殊効果の追加
9.ビデオ映像の読み出し
引用 : wikipedia
つまるところ、ディスプレイに私たちが見えるまでの処理工程のことをグラフィックスパイプラインというイメージで大丈夫。
1) 空間内の物体の座標、頂点決定
2) 物体の頂点の色計算 — [ Vertex shader ]
3) 与えられた頂点から面に分割 (テッセレーション) — [ Geomtery shader ]
4) レンダリングする画面のピクセル情報へと変換 (ラスタライズ)
5) ピクセルの色決定 — [ Fragment shader ]
6) ブレンディング、隠面消去、深度テスト
7) 画面全体を描画情報として保持 (フレームバッファの保持)
引用 : https://ayumu-nagamatsu.com/archives/587/
shaderと呼んでいる、Vertex shader他は、過去にはプログラマブルではない(個人が勝手に、いじれない)、GPUに固定機能として実装された定型の処理しか使えないものだった(固定機能シェーダー)。
GLSLではこれはユーザーは自由にプログラムできる。ブラックボックスだったシェーダー自体がプログラム可能となった。(プログラマブルシェーダー)
下記の床井先生の資料が入門として分かりやすい。特に下のpdfは具体的な仕組みも書いてくれている。
ツールキット
用語として、ツールキットについても書いておく。
OpenGLの補助ライブラリと呼ばれたりもしている。
GLUT(OpenGL Utility Toolkit)は
OpenGLというOS(プラットフォーム)に依存しないグラフィックスAPIをアプリケーションプログラムから使用するために必要なプラットフォームごとに異なる「お膳立て」「呪文」が必要だが、その手順が面倒なので、包み隠して簡単に使えるようにしたツールキットのことだ。
GLUT以外もツールキットがいくつも存在する。
GLUTは、マルチプラットフォームでUnix / Linux, Windows, macOSの間で共通で使用できる。
GLUTは長い間もう、メンテナンスはされておらず、(古いまんま)
代りに、GLUTと互換性のあるfreeglutというツールキットが開発されている。ただし、これはmacOSには対応していないみたい。
またmacOSは以前から標準でGLUTが搭載されていたが、OpenGL2.1にしか対応しておらず、
macOS10.7(Lion)以降で使用可能になった、OpenGL 3.2
macOS10.9(Mavericks)以降で使用可能になった、OpenGL 4.1を
(公式には)使用することができない。
※gl3wというツールを使えば、GLUTでOpenGLバージョン3.2以降の機能を使用できる。
さらには、10.9(Mavericks)ではGLUTの使用自体が非推奨となった。
他のマルチプラットフォームで使えるツールキットとして、FLTK, SDL, Qtとさまざまなものがある。Qt(キュート)は高機能なツールキットで、CG関連のいくつかの主要なプリケーションソフトウェアがこれを使って開発されている。
C++に対応した、openFrameworksやCinder, C#に対応したOpenTKも高機能なツールキット。これらはCreative Codingに向いているものとして利用されている。
GLUTの代わりになる小さなツールキットとして、GLFWというものがある。
こちらもマルチプラットフォーム対応のライブラリだ。OpenGLと組み合わせて使うツールキットの中では、非常にコンパクトであり、OpenGLのウィンドウを管理するための最小限の機能を提供している。GLUTと同様で、Windows / macOS / Linuxでソースプログラムを共通化できる。
macOS(Mac OS X)のバージョン10.7(Lion)以降では、OpenGLのバージョン3.2、10.9(Mavericks)以降ではOpenGLのバージョン4.1を指定することができる。
GLEW(The OpenGL Extension Wrangler Library)というGLFWと名前が紛らわしい、
OpenGLのグラフィックスハードウェアの拡張機能の管理を得意とするライブラリもある。
特に、windowsではもともとサポートしているOpenGLのバージョンが1.1のために、グラフィックスハードウェアがそれ以降のバージョンに対応したものであっても、そのままでは新しい機能を使用することができません。そこでGLEWを使って、グラフィックスハードウェアがもつすべての機能をアプリケーションプログラムから使えるようにします。
詳しくはこちらを参照。
shader 種類
基本3種
頂点シェーダー(Vertex Shader)
入力された頂点を座標変換するための機能
ジオメトリーシェーダー(Geometry Shader)
オブジェクト内の頂点の集合を加工して、新しいプリミティブ図形を生成できる。
フラグメントシェーダー(Fragment Shader)
ピクセルを操作する。フラグメントともいう。画面上の膨大なピクセル情報を高い並列処理機能を持つGPUで実行することができる。
Attribute変数
まず、attribute変数には慣習的に多くの場合頭文字として、
a, a_
をつけておくとわかりやすい。
a_Positon , aTexCoord
p5やOFで扱われたシェイプから受け取ってきたデータで、長方形の頂点座標のポジションやテクスチャなどをはじめに受け取る変数。
rect(o,o,width,height);
のようなコードを書いた部分にshaderの使用がされているときはこれのポジションやTextureが送られてくることになる。
結果として、Attirubte変数はVertex file上でのみ使われることになると思われる。
面で受け取るわけではなくて、vertex、頂点で扱うことに注意
これらを何らかの形で変換して下のVarying変数でフラッグに渡していく
shaderでの書き方
attribute vec3 aPositon
Varying変数
慣習的に、頭文字に、
v, v_
をつけることが多く、その方がわかりやすい
v_Positon, vTexCoord
VertexからFragmentに送りたいデータをこの変数に入れておくと、渡すことができる変数。
Varing変数はAttribute変数と違って、Fragment fileで扱うことが多くなると思われる。
ただし、VertexでFragmentに向けて送るために、書なければいけないので登場しないというわけではない。実際の中身のデータを扱うのはFragment
shaderでの書き方
varying vec3 vPosition
varying vec2 vTexCoord
Uniform変数
Attributeとは違い、頂点に依存しない値に使うべき変数
Uniform変数は定数なのだが、毎フレーム変わる定数みたいなイメージでいたらいいかも。
draw関数が呼ばれるたびにアップデートされていく。
読み込むことはできるが、何か書き込むことはできない。
Uniform変数を使うことで、informationをCPU to GPUのようにできるイメージ。別な言い方をするとp5,OF to Shaderみたいな感じ。
慣習として、よく使われるのは、time , resolution , mouse coordinateに使われる。
u, u_, i
等々が頭文字として採用されることが多い。
iMouse, iTime, uResolution, u_Resolution ...
p5やOF等からはこのような感じで書くことでshaderに送ることができる
theShader.setUniform("u_resolution", [width, height]);
theShader.setUniform("u_time", millis() / 1000.0);
in変数
in 入力変数。VSではOpenGLから渡される頂点情報セットを表す(旧attribute)。GSではVSによって計算された頂点情報セット、FSではVSまたはGSによって計算された頂点情報が補間された値を表す(旧varying)。
GLSL wikiより
最新の方のバージョンの方ではin out 変数が使われるように変更されているみたいだ。
openGL 3.x系から使われるものらしい
ネット上には、2.0系と呼ばれるattirubteやvaryingの表記で書かれている記事が多いため頭の中で変換して考えるといいらしい
vertex shaderでの inは attributeを表すもので、
fragment shaderでのinはvaryingを表すもの
out変数
out 出力変数。 VSではGSまたはFSへ(旧varying)、GSではFSへ渡す頂点情報セットを表す。FSでは最終的にピクセル単位で出力する色情報を表す。
GLSL wikipdiaより
out もinと同じく新し目のバージョンで変更されて適応されている変数
openGL 3.x系から使われるものらしい
ネット上には、2.0系と呼ばれるattirubteやvaryingの表記で書かれている記事が多いため頭の中で変換して考えるといいらしい
vertext shaderでは出力時のVaryingを表し、
Fragment shader では出力用にgl_FragColorの代わりに利用されているものになる。好きな変数名をつけれるのかな?
Texture
テクスチャマッピングとは、
簡単にいえば、ポリゴン(面)に対して、任意の画像を張り付ける行為のことを言う。
単なる面に対して、画像の大きさをや向きを変更せずに張り付けるのではなく、拡大縮小、座標の変換等を行ってから張り付けることを特にいう。
3DCGや画像処理系のことをやっている人ならテクスチャという言葉自体は聞きなれた言葉だと思う。
バインド
バインドする、テクスチャをバインドするという言葉として使われる。
バインドとは、指定したテクスチャを有効にするという作業のことをいう。
今から使うぜ、このテクスチャ!って感じ。
OpenGLにテクスチャをバインド(関連付け)する
まず、glBindTexture関数を使って、
これから指定したテクスチャIDの操作を行うことをOpenGLに伝えます
引用 : http://nn-hokuson.hatenablog.com/entry/2017/02/24/171230
テクスチャの画像のサイズ(width * heigh)は2のn乗が望まれる。
これはデータの扱い的な問題で、効率的に扱うには2のn乗が望ましい。
Textureと座標
テクスチャの座標のことをtexCoord,UV,UVWと書かれることが多い。
ゲーム系業界でのTextureはデータ量をなるべく減らす、メモリの節約、実行速度の維持のために、複数のテクスチャを一枚の画像としてまとめた、テクスチャアトラスというものが使われる。
テクスチャアトラスとは、どんなものかのイメージを見てもらった方が早い。
このいっぱい並んでいる画像から、今使いたい部分だけトリミングして使うようなイメージだ。
テクスチャアトラスからトリミングして使う場合、そうではなくて一枚画像として普通に使うテクスチャ画像どちらにしても、
どこからどこまでという指定が必要だ。
テクスチャの座標として、UV座標系というものが使われる。
左下or左上を原点(0, 0)として、右上or右下を(1, 1)として座標を定義する。
画像の中央を表すuv座標は(0.5, 0.5)となる。
モデルにテクスチャを貼る場合、各頂点にこのuv座標を指定してどのように割り当てるか指示する。
Textureとshader
vertex shader
opngl esの例
attribute vec4 aPosition;
attribute vec2 aTexcoord;
varying vec2 vTexcoord;
void main(){
gl_Position = aPosition;
vTexcoord = aTexcoord;
}
aTexcoordにtextureのuv座標が入っている。
この頂点座標のときのuv座標として、fragmentにvTexcoordとして渡す。
fragment shader
opengl esの例
uniform sampler2D uTexture;
varying vec2 vTexcoord;
void main(){
gl_FragColor = texture2D(uTexture, vTexcoord);
}
uniform変数として、sampler2D型の変数(これには、2次元テクスチャのピクセルのカラーが入っている、テクスチャが入っている)が送られてきている。
texture2D(uTexture, vTexcoord)で、uvに対応するピクセルのカラーを取り出して、表示する。
varying 変数 vary_uv として、頂点シェーダから UV 座標を受け取る。varying の「頂点間で値が補完される」という特性は、UV 座標に関しても同様。なので、ピクセルごとの正確な UV 座標をフラグメントシェーダが把握できるようになる。
ピクセル単位の UV 座標が分かったら、その UV 座標を元にテクスチャからテクセル情報=色を取り出す。そのための GLSL 組み込み関数が texture2D
vec4 texture2D (sampler2D, vec2)
sampler2D : 色を取り出したいテクスチャ
vec2 : テクセルを取り出したい UV 座標
サンプルでは vary_uv の値を元に unif_texture からテクセル色を vec4 型で取り出し、ポリゴンの色として表示している。
gl_FragColor = texture2D(unif_texture, vary_uv);
引用 : https://qiita.com/kazoo/items/7d4550e18e128e1124b3
texelFetch()という関数もある。
texelFetch(texture , index)となっており、
第二引数がuvの座標ではなくて、画像のピクセルのインデックスがはいる
1920 * 1080の画像だとするらば、[0 ~ 1920*1080-1]の範囲のインデックスが入ることになる
TextureとPosition
Vertex,Fragment shaderに現れる、Texture とPostionというベクトル
似て異なる意味のベクトルとして扱っている。
p5やOFやprocessing等から画像を扱って、シェーダに飛ばす際に
Positionは、画像の各ピクセルの位置、ポジションのベクトル
p5やOF上の座標から送られてきた位置的な座標
Textureは、画像の各ピクセルの座標でのカラー情報
テクスチャは、色が入っているベクトルだという感覚で思うのがわかりやすいかもしれない
UVを扱っていることを意識する
vec3 positon = xyz
vec3 texture = rgb
0 ~ 1での考え方
基本的にシェーダーでは0~1の範囲で考えて数値を扱う。
フロートで計算することが通常。少ない数字で効率よく扱うことがデザインされている。
色のアウトプットとかも最終的にはRGBを8bitの0~256で扱うのではなくて、0~1の範囲で扱う
座標の注意
どこを原点として扱っている座標(Coordinate)なのかを意識することが大事。
中心なのか?左上なのか?左下なのか?
OFやp5,processing等では、左上を原点として考えていくが、
Shaderでは最終的には、左下を原点として扱っていくことになる
vertex shaderでは、
スクリーン座標(原点真ん中、端は原点から1の距離にある。-1 ~ 1)
となっているようだ。
これはグラフィックカードにビルドインされている設定
ベクトル変数
vec2 , vec3等のベクトルとして扱える変数があるが、
Resolution.xy
resolution.x
position.y
color.rgb
color.b
とオブジェクト指向のように、ベクトルの中の成分にアクセスすることができる。
二次元ベクトルなら、xy or rgが使える。
color.x == color.r, color.y = color.g , color.z == color.g
のようにそれぞれ同じ意味を表していて、
自分が見やすいように表記していいシステムで作られている。
gl_FragCoord
gl_FragCoordは
デフォルトの出力として vec4 gl_FragColor を使うことができるのと同様に、GLSLにはデフォルトの入力として画面上の「フラグメント」、つまりピクセルの位置を表す vec4 gl_FragCoord が用意されています。vec4 gl_FragCoord を使うとスレッドが描画領域内のどこで作業をしているかを知ることができます。この gl_FragCoordはスレッドごとに異なる値を持っているためuniform変数とは呼ばず、代わりにvarying変数と呼びます。
the book of shaderより
Available only in the fragment language, gl_FragCoord is an input variable that contains the window relative coordinate (x, y, z, 1/w) values for the fragment.
ディスプレイ全体からの座標ではなくて、window,canvasの座標が入ってくる。1920,1080等の正規化されていない数値で入ってくる。
shaderを適用させるているオブジェクトに関係なく、常にwindow, canvasの値が入っている。
補足コラム :
正確には、フラグメントシェーダはポリゴンなどが描かれるすべてのピクセルで実行されます。画面上に描くべきオブジェクトが一切無い場合には、フラグメントシェーダが何かを画面上に描き出すことはありません。
https://qiita.com/doxas/items/f34325520d1aa5af4692より
gl_Postion
glPositonはVertex shaderで最終的に使われる変数
ここには、クリップ空間系と呼ばれる座標に変換した座標を入れることによっておkになる。
座標の考え方・概念・呼び方がいっぱいある。
Object Space
オブジェクト自身が原点になっている座標系。物体ごとに座標系がある
モデリングしてるときの座標系と考えればわかりやすいか。
World Space
ワールド座標系。どこどこになになにがある、といった感じ。
これを仮想空間の座標系と捉えれば良さそう。
Eye Space
視点座標系。たとえばカメラの位置とか。視点の位置が原点になる。
Clip Space
視点座標系から少しズームしたりして、切り取った座標系。クリップ座標系というらしい。
スクリーンみたいな感じだと思う。(それの逆?)
Normalized Device Space
すべてが絶対値1に収まるようにした座標系。
Window Space
ウィンドウの座標系。みんながまさに見ている座標系のこと。
原点が左上だったり左下だったり。。。
引用 https://mactkg.hateblo.jp/entry/2014/02/05/013421
openFrameworksでのshaderを扱う際に、
GL3.2系を選択した場合
vertex shaderで、gl_Positionに
in変数で持ってきた頂点座標 positionに
uniform変数 modelViewProjectionMatrixはワールド座標系からクリップ座標系まで一気に変換してくれる行列(matrix)が合わさった変数のようだ。
今回の話において重要なのは最初の4つ。んで、Object Space -> World Space -> Eye Spaceと変換をしていくのに、ModelViewMatrixが必要。さらに、Eye Space -> Clip Spaceに変換していくのにProjectionMatrixが必要なのだ。modelViewProjectionMatrixは、それを一緒にしてしまったものなのかもしれないと考えてみた。
たぶんin vec4 positionで得られるのはワールド座標系。そこでの情報を取り扱って、クリップ座標系にして返す。これがvertexシェーダのしていることなのだろうかと。
引用 https://mactkg.hateblo.jp/entry/2014/02/05/013421
gl_FragColor
gl_FragCoord とgl_FragCoordは違うものなので見間違いに気をつけよう
gl_FragColorは名前の中に、"Frag"と名前が入っている通り、
Fragment shaderで使える、使うやつだ。
最終的な出力用の変数でここに、最終的なピクセルの色を入れるとおkになる。
GL3系の in out を使うバージョンでは、out 変数が用意されているので、
out vec4 好きな変数名で定義して、
それに、最終的なピクセルの色を入れると大丈夫。
Atomic Counter Buffer
GLSL4.2から追加された機能で、
Compute shader / Fragment shader / Vertex Shaderで扱える
GPUの並列処理の中で一意にカウントしていけるような(インクリメントしていけるような)変数が作れる。
並列処理の中で一意なデータを実現できる。
画素数の数などを数え上げるときに便利。
実態としては一種のバッファにあたるらしい。
//こんな感じで受け取って
layout(binding = 0, offset = 0) uniform atomic_uint counter;
//インクリメントするかつ、returnできる。
int current = int(atomicCounterIncrement(counter));
//ディクリメントとすることもできる。returnも計算がmodifyされたもの
uint atomicCounterDecrement(counter);
ここに関数がのっている。
References
Welcome to p5.js shaders
The Book of Shaders
WebGLでGLSL (Shader) を書く流れを(ざっくり)まとめた
wgld
チュートリアル2:最初の三角形
gl_FragCoord — contains the window-relative coordinates of the current fragment
OpenGL ES について
[連載]やってみれば超簡単! WebGL と GLSL で始める、はじめてのシェーダコーディング(2
GLSL wikipedia
WebGLの仕組みについてまとめ直してみました
未来を感じさせるWeb!?WebGLとは
https://www.marineroad.com/staff-blog/16185.html
OpenGL(GLSL)のvarying,attribute,in,outについて
○○くんのために一所懸命書いたものの結局○○くんの卒業に間に合わなかったGLFW による OpenGL 入門(draft 版).pdf
WebGLの能力を引き出すプログラマブルシェーダー (3/5)
GLSLの組み込み変数
openFrameworksでシェーダを扱う
【OpenGL による 3D 描画の基礎知識】
openFrameworks, Three.js, Processing のGLSL バージョン対応状況調査
GLSLスクール2019 第1回(2019.9.28)
【OpenGLでゲームを作る】テクスチャを表示する
UV座標系 CGWORLD
【連載】Unity時代の3D入門 – 第3回「テクスチャを貼ってみた」
テクスチャのUV座標の設定1
OpenGL ES2.0 入門 基礎編(テクスチャ)
シェーダープログラミングの意義とその実装
グラフィックスパイプライン wikipedia
2009年08月21日 [OpenGL][GLSL][ゼミ] 第1回 レンダリングパイプライン
2009年08月26日 [OpenGL][GLSL][ゼミ] 第2回 準備
Atomic Counter - OpenGL Wiki
Atomic Counter + Indirect Renderingで効率良い可変長インスタンシング - Qiita