フラットシェーディング
フラットシェーディングってGLSL使ってどうやるんだろう?って思っていたら以外に簡単でした。
コードとしては、グローシェーディングを少し改良しただけです。
コードとしては、グローシェーディングを少し改良しただけです。
OpenGL 3.x
GLUT (freeglut3.7)
GLM 0.9.0.6
GLUT (freeglut3.7)
GLM 0.9.0.6

フラットシェーディングの方法
varying変数としてバーテックスシェーダからフラグメントシェーダへ渡すcolor情報に""flat"を付けるだけです。
- バーテックスシェーダ側
flat out vec4 v_color;
- フラグメントシェーダ側
flat in vec4 v_color;
- Cソース側
初期化あたりで次を追加します。
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
フラットシェーディングでは、頂点間の補間を行わないようにシェーディングするので、プリミティブ(三角形)のどの頂点を基準にするかという指定をします。
GL_FIRST_VERTEX_CONVENTIONもしくは、GL_LAST_VERTEX_CONVENTIONが設定できます。
ここでは、FIRSTの方を指定します。
GL_FIRST_VERTEX_CONVENTIONもしくは、GL_LAST_VERTEX_CONVENTIONが設定できます。
ここでは、FIRSTの方を指定します。
シェーダコード
- simple.vert
#version 330
struct MaterialParam {
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
};
uniform vec3 u_lightPos;
uniform MaterialParam u_lightMaterial;
uniform MaterialParam u_material;
uniform mat4 u_modelMatrix; // モデル・マトリックス
uniform mat4 u_viewMatrix; // ビュー・マトリックス
uniform mat4 u_projectionMatrix; // 射影・マトリックス
in vec3 a_position;
in vec3 a_normal;
flat out vec4 v_color; // ★outに対してflatを付加★
void main(void)
{
mat4 modelViewMatrix = u_viewMatrix * u_modelMatrix;
vec3 lightPos = vec3(u_viewMatrix * vec4(u_lightPos.xyz,1.0));
mat3 n_mat = mat3( transpose( inverse(modelViewMatrix) ) ); // normal Matrix
vec3 P = vec3(modelViewMatrix * vec4(a_position,1.0));
vec3 N = normalize(n_mat * a_normal);
vec3 L = normalize(lightPos.xyz - P); // light vector
float nDotL = dot(N,L);
float diffuseLight = max(nDotL,0.0);
vec4 ambient = u_lightMaterial.ambient * u_material.ambient;
vec4 diffuse = u_lightMaterial.diffuse * u_material.diffuse * diffuseLight;
vec3 V = normalize(-P);
//vec3 H = normalize(L+V); // ハーフベクトルによるスペキュラー
//float nDotH = pow(max(dot(N,H),0.0), u_material.shininess);
vec3 H = reflect(-L,N); // 反射ベクトルによるスペキュラー
float nDotH = pow(max(dot(V,H),0.0), u_material.shininess);
if (nDotH<0.0) nDotH = 0.0;
vec4 specular = u_lightMaterial.specular * u_material.specular * nDotH;
v_color = ambient + diffuse + specular;
gl_Position = u_projectionMatrix*modelViewMatrix*vec4(a_position.xyz, 1.0);
}
- simple.frag
#version 330
flat in vec4 v_color; // ★inに対してflatを付加★
out vec4 fragColor;
void main(void)
{
fragColor = v_color;
}
Download
