bambooflow Note

フラットシェーディング

最終更新:

bambooflow

- view
メンバー限定 登録/ログイン

フラットシェーディング


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

OpenGL 3.x
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の方を指定します。


シェーダコード


  • 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


glsl_flat00.tgz
記事メニュー
目安箱バナー