OpenGL(GLSL)のvarying,attribute,in,outについて
OpenGLのストレージ修飾子(inとかoutとか)についてです。
これもあんまりまとまった記事がなさそうだったので自分用メモ
前の記事同様OpenGL学び初めたばかりで、しかもネットの情報のみという浅い知識しか持ち合わせていないので、間違いがあったら教えてもらえるとうれしいです。
OpenGL2.x系では、頂点属性の定義はattributeを付けて行っていました。
また、バーテックスシェーダからフラグメントシェーダに内容を渡したいときはvaryingをつけて宣言を行っていました。
↓多分こんな感じ(バーテックスシェーダの例)
attribute vec3 position;
uniform vec4 color;
varying vec4 vColor;
void main() {
vColor = color;
gl_Position = position;
}
しかし、OpenGL3.0以降ではattribute,varyingは使用されなくなりました。
attributeはinに置き換え、varyingはinとoutに置き換えされるようになりました。
以下に例を示します。
OpenGL3.0以降のバーテックスシェーダの例
#version 150 core
in vec3 position;
in vec3 normal;
in vec4 color;
uniform mat4 mvpMatrix;
uniform mat4 mMatrix;
out vec3 vPosition;
out vec3 vNormal;
out vec4 vColor;
void main() {
vPosition = (mMatrix * vec4(position, 1.0)).xyz;
vNormal = normal;
vColor = color;
gl_Position = mvpMatrix * vec4(position, 1.0);
}
OpenGL3.0以降のフラグメントシェーダの例
#version 150 core
precision mediump float;
out vec4 fragment;
uniform mat4 invMatrix;
uniform vec3 lightPosition;
uniform vec4 ambientColor;
uniform vec3 eyeDirection;
in vec3 vPosition;
in vec4 vColor;
in vec3 vNormal;
void main() {
vec3 lightVec = lightPosition - vPosition;
vec3 invLight = normalize(invMatrix * vec4(lightVec, 0.0)).xyz;
vec3 invEye = normalize(invMatrix * vec4(eyeDirection, 0.0)).xyz;
vec3 halfLE = normalize(invLight + invEye);
float diffuse = clamp(dot(vNormal, invLight), 0.0, 1.0) + 0.2;
float specular = pow(clamp(dot(vNormal, halfLE), 0.0, 1.0), 50.0);
fragment = vColor * vec4(vec3(diffuse), 1.0) + vec4(vec3(specular), 1.0) + ambientColor;
}
上記のように、バーテックスシェーダのattributeはinに置き換えられました。
また、varying変数は、バーテックスシェーダ側にout,フラグメントシェーダ側にinと修飾子を付けて、変数名を同名にするようになりました。
OpenGLの記事は古いものも多いので、そういった古い記事のシェーダを読むときに知っているとすんなり理解しやすいのかなと思います。
OpenGL2.x系とOpenGL3.0以降の違いでもう一つ大事そうなのは、テクスチャマッピングをする際のビルトイン関数texture2Dが、textureという名前になっているのとかがあります。
他にもなんかありそうですが、僕は今のところ困っていないのでわからないですw
関係ないですが、色や法線情報のinとoutの前にflatっていう修飾子をつけると、ラスタライザでの線形補間を行わなくなるみたいで、結構面白いです。
↓flatなし
↓flatあり
まだまだわからないことだらけですが、毎日少しずつ理解できているような…気がします。そうだといいな。