鏡面反射

「鏡面反射」の編集履歴(バックアップ)一覧はこちら

鏡面反射」(2014/05/01 (木) 17:54:26) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

<p><strong>プラスチックや金属など、よく磨きこまれた反射率の高い物体に光が当たると<br /> 表面が光り輝いているように見えます。<br /> そのハイライトを表現するのが鏡面反射です。</strong></p> <p> <img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=48&amp;file=specular.png" /></p> <p>vertex.shader</p> <table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td> <p><font size="2">//フラグメントシェーダーに渡す変数<br /> varying vec3 P;//位置ベクトル<br /> varying vec3 N;//法線ベクトル</font></p> <p><font size="2">void main(void)<br /> {<br />   P = vec3(gl_ModelViewMatrix * gl_Vertex);<br />   N = normalize(gl_NormalMatrix * gl_Normal);<br />   gl_Position = ftransform();<br /> }</font></p> </td> </tr></tbody></table><p>flagment.shader</p> <table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td> <p><font size="2">//頂点シェーダーから受け取る変数<br /> varying vec3 P;//位置ベクトル<br /> varying vec3 N;//法線ベクトル</font></p> <p><font size="2">void main(void)<br /> {<br />   vec3 L = normalize(gl_LightSource[0].position.xyz - P);<br />   N = normalize(N);<br />  <br />   vec4 ambient = gl_FrontLightProduct[0].ambient;<br />   float dotNL = dot(N, L);<br />   vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL);<br />   vec3 V = normalize(-P);<br />  vec3 H = normalize(L + V);<br />  float powNH = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);<br />  if(dotNL &lt;= 0.0) powNH = 0.0;<br />  vec4 specular = gl_FrontLightProduct[0].specular * powNH;<br />  //統合<br />  gl_FragColor = ambient + diffuse + specular;<br /> }</font></p> </td> </tr></tbody></table><p>GLSL.h</p> <table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td> <p><font size="2">GLuint vertexShader, fragmentShader;<br /> //shader fileを読み込みコンパイルする<br /> void readShaderCompile(GLuint shader, const char *file)<br /> {<br />   FILE *fp;<br />   char *buf;<br />   GLsizei size, len;<br />   GLint compiled;<br />  <br />   // ファイルを開く<br />   fopen_s(&amp;fp,file, "rb");<br />   if(!fp) printf("ファイルを開くことができません %s\n", file);<br />  <br />   //ファイルの末尾に移動し現在位置を得る<br />   fseek(fp, 0, SEEK_END);<br />   size = ftell(fp);//ファイルサイズを取得<br />  <br />   // ファイルサイズのメモリを確保<br />   buf = (GLchar *)malloc(size);<br />   if (buf == NULL) {<br />     printf("メモリが確保できませんでした \n");<br />   }<br />  <br />   // ファイルを先頭から読み込む<br />   fseek(fp, 0, SEEK_SET);<br />   fread(buf, 1, size, fp);<br />   //シェーダオブジェクトにプログラムをセット<br />   glShaderSource(shader, 1, (const GLchar **)&amp;buf, &amp;size);<br />   //シェーダ読み込み領域の解放<br />   free(buf);<br />   fclose(fp);</font></p> <p><font size="2">  // シェーダのコンパイル<br />   glCompileShader(shader);<br />   glGetShaderiv( shader, GL_COMPILE_STATUS, &amp;compiled );</font></p> <p><font size="2">  if ( compiled == GL_FALSE )<br />   {<br />    printf( "コンパイルできませんでした!!: %s \n ", file);<br />    glGetProgramiv( shader, GL_INFO_LOG_LENGTH, &amp;size );<br />    if ( size &gt; 0 )<br />    {<br />     buf = (char *)malloc(size);<br />     glGetShaderInfoLog( shader, size, &amp;len, buf);<br />     printf(buf);<br />     free(buf);<br />    }<br />   }<br /> }</font></p> <p><font size="2">//リンクする<br /> void link( GLuint prog )<br /> {<br />   GLsizei size, len;<br />   GLint linked;<br />   char *infoLog ;</font></p> <p><font size="2">  glLinkProgram( prog );</font></p> <p><font size="2">  glGetProgramiv( prog, GL_LINK_STATUS, &amp;linked );</font></p> <p><font size="2">  if ( linked == GL_FALSE )<br />   {<br />   printf("リンクできませんでした!! \n");<br />     <br />   glGetProgramiv( prog, GL_INFO_LOG_LENGTH, &amp;size );<br />   if ( size &gt; 0 )<br />   {<br />    infoLog = (char *)malloc(size);<br />    glGetProgramInfoLog( prog, size, &amp;len, infoLog );<br />    printf(infoLog);<br />    free(infoLog);<br />   }<br />   }<br /> }<br /> //GLSLの初期化<br /> void initGlsl(GLuint *program, const char *vertexFile)<br /> {<br />   //glewの初期化<br />   GLenum err = glewInit();<br />   if (err != GLEW_OK)<br />   {<br />    printf("Error: %s\n", glewGetErrorString(err));<br />   }<br />   // GPU,OpenGL情報<br />   printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />   printf("GPU= %s \n", glGetString(GL_RENDERER));<br />   printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />   printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />   //シェーダーオブジェクトの作成<br />   vertexShader = glCreateShader(GL_VERTEX_SHADER);<br />   //シェーダーの読み込みとコンパイル<br />   readShaderCompile(vertexShader, vertexFile);</font></p> <p><font size="2">  // シェーダプログラムの作成<br />   *program = glCreateProgram();</font></p> <p><font size="2">  // シェーダオブジェクトをシェーダプログラムに関連付ける<br />   glAttachShader(*program, vertexShader);</font></p> <p><font size="2">  // シェーダオブジェクトの削除<br />   glDeleteShader(vertexShader);</font></p> <p><font size="2">  // シェーダプログラムのリンク<br />   link(*program);<br /> }</font></p> <p><br /><font size="2">void initGlsl(GLuint *program, const char *vertexFile, const char *fragmentFile)<br /> {<br />   //glewの初期化<br />   GLenum err = glewInit();<br />   if (err != GLEW_OK)<br />   {<br />    printf("Error: %s\n", glewGetErrorString(err));<br />   }<br />   // GPU,OpenGL情報<br />   printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />   printf("GPU= %s \n", glGetString(GL_RENDERER));<br />   printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />   printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />   //シェーダーオブジェクトの作成<br />   vertexShader = glCreateShader(GL_VERTEX_SHADER);<br />   fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);<br />   //シェーダーの読み込みとコンパイル<br />   readShaderCompile(vertexShader, vertexFile);<br />   readShaderCompile(fragmentShader, fragmentFile);</font></p> <p><font size="2">  // プログラムオブジェクトの作成<br />   *program = glCreateProgram();</font></p> <p><font size="2">  // シェーダオブジェクトをシェーダプログラムに関連付ける<br />   glAttachShader(*program, vertexShader);<br />   glAttachShader(*program, fragmentShader);</font></p> <p><font size="2">  // シェーダオブジェクトの削除<br />   glDeleteShader(vertexShader);<br />   glDeleteShader(fragmentShader);<br />   // シェーダプログラムのリンク<br />   link(*program);<br /> }<br /></font></p> </td> </tr></tbody></table><p>main.cpp</p> <table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td> <p><font size="2">#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br /> #pragma comment(lib, "glew32.lib")</font></p> <p><font size="2">#include &lt;stdio.h&gt;<br /> #include &lt;GL/glew.h&gt;<br /> #include &lt;GL/freeglut/freeglut.h&gt;<br /> #include "GLSL.h"</font></p> <p><font size="2">#define WIDTH 320<br /> #define HEIGHT 240</font></p> <p><font size="2">GLuint shaderProg;<br /> //回転用<br /> float anglex = 0.0f;<br /> //ライトの位置<br /> GLfloat lightpos[] = { 20.0, 80.0, -50.0, 1.0 };</font></p> <p><font size="2">float Ambient[] = {0.8f, 0.0f, 0.2f, 1.0f};<br /> float Diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};<br /> float specular[]= { 0.4, 0.4, 0.4, 1.0};//鏡面反射<br /> float AmbientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f};<br /> float DiffuseLight[] = { 0.2f, 0.7f, 0.7f, 1.0f};<br /> float SpecularLight[] = {1.0, 1.0, 1.0, 1.0};//鏡面光</font></p> <p><br /><font size="2">void setLight()<br /> {<br />  glMaterialfv(GL_FRONT,GL_AMBIENT,Ambient);<br />  glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse);<br />  glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />  glMaterialf(GL_FRONT,GL_SHININESS,8);<br />  glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);<br />  glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);<br />  glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight);<br />  glLightfv(GL_LIGHT0, GL_POSITION, lightpos);<br /> }<br /> void display(void)<br /> {</font></p> <p><font size="2"> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />  glViewport(0, 0, WIDTH, HEIGHT);<br />  glMatrixMode(GL_PROJECTION);<br />  glLoadIdentity();<br />  //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)<br />  gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);<br />  glMatrixMode(GL_MODELVIEW);<br />     glLoadIdentity();<br />  //視点の設定<br />  gluLookAt(150.0,100.0,-200.0, //カメラの座標<br />       0.0,0.0,0.0, // 注視点の座標<br />      0.0,1.0,0.0); // 画面の上方向を指すベクトル<br />  //ライトの設定<br />  setLight();</font></p> <p><font size="2"> //回転<br />  glRotatef(anglex,1.0f,0.0f,0.0f);//X軸を回転<br />  glUseProgram(shaderProg);//シェーダー描画に切り替え<br />  glutSolidSphere(40.0,16,16);<br />  glUseProgram(0);//シェーダー解除</font></p> <p><font size="2"> glutSwapBuffers();<br /> }<br /> void idle(void)<br /> {<br />  anglex+=0.02f;</font></p> <p><font size="2"> glutPostRedisplay();<br /> }<br /> void Init(){<br />  initGlsl(&amp;shaderProg, "vertex.shader","flagment.shader");<br />  glClearColor(0.3f, 0.3f, 0.3f, 1.0f);<br />  glEnable(GL_DEPTH_TEST);<br />  glEnable(GL_LIGHTING);<br />  glEnable(GL_LIGHT0);</font></p> <p><font size="2">}<br /> int main(int argc, char *argv[])<br /> {<br />  glutInitWindowPosition(100, 100);<br />  glutInitWindowSize(WIDTH, HEIGHT);<br />  glutInit(&amp;argc, argv);<br />  glutCreateWindow("スペキュラー");<br />  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />  glutDisplayFunc(display);<br />  glutIdleFunc(idle);<br />  Init();<br />  glutMainLoop();<br />  glDeleteProgram(shaderProg);<br />  return 0;<br /> }<br /></font></p> </td> </tr></tbody></table><p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p>
<p><strong>プラスチックや金属など、よく磨きこまれた反射率の高い物体に光が当たると<br /> 表面が光り輝いているように見えます。<br /> そのハイライトを表現するのが鏡面反射です。</strong></p> <p> <img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&amp;act=open&amp;pageid=48&amp;file=specular.png" /></p> <p>vertex.shader</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td> <p><font size="2">//フラグメントシェーダーに渡す変数<br /> varying vec3 P;//位置ベクトル<br /> varying vec3 N;//法線ベクトル</font></p> <p><font size="2">void main(void)<br /> {<br />   P = vec3(gl_ModelViewMatrix * gl_Vertex);<br />   N = normalize(gl_NormalMatrix * gl_Normal);<br />   gl_Position = ftransform();<br /> }</font></p> </td> </tr></tbody></table><p>flagment.shader</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td> <p><font size="2">//頂点シェーダーから受け取る変数<br /> varying vec3 P;//位置ベクトル<br /> varying vec3 N;//法線ベクトル</font></p> <p><font size="2">void main(void)<br /> {<br />   vec3 L = normalize(gl_LightSource[0].position.xyz - P);<br />   N = normalize(N);<br />  <br />   vec4 ambient = gl_FrontLightProduct[0].ambient;<br />   float dotNL = dot(N, L);<br />   vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL);<br />   vec3 V = normalize(-P);<br />  vec3 H = normalize(L + V);<br />  float powNH = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);<br />  if(dotNL &lt;= 0.0) powNH = 0.0;<br />  vec4 specular = gl_FrontLightProduct[0].specular * powNH;<br />  //統合<br />  gl_FragColor = ambient + diffuse + specular;<br /> }</font></p> </td> </tr></tbody></table><p>GLSL.h</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td> <p>#pragma once<br />  #include &lt;stdio.h&gt;<br />  <br /> //GLSLクラス<br />  class GLSL{<br />  public:<br />   GLuint ShaderProg;<br />   GLuint VertexShader, FragmentShader;<br />   void ReadShaderCompile(GLuint Shader, const char *File);//shader fileを読み込みコンパイルする<br />   void Link( GLuint Prog );//リンクする<br />   void InitGLSL(const char *VertexFile);//GLSLの初期化<br />   void InitGLSL(const char *VertexFile, const char *FragmentFile);//GLSLの初期化<br />   void ON();//シェーダー描画に切り替え<br />   void OFF();//シェーダー解除<br />   ~GLSL();<br />  };<br />  <br />  void GLSL::ReadShaderCompile(GLuint Shader, const char *File){<br />     FILE *fp;<br />     char *buf;<br />     GLsizei size, len;<br />     GLint compiled;<br />  <br />     fopen_s(&amp;fp,File, "rb");<br />     if(!fp) printf("ファイルを開くことができません %s\n", File);<br />  <br />     fseek(fp, 0, SEEK_END);<br />     size = ftell(fp);<br />  <br />    buf = (GLchar *)malloc(size);<br />     if (buf == NULL) {<br />       printf("メモリが確保できませんでした \n");<br />     }<br />  <br />     fseek(fp, 0, SEEK_SET);<br />     fread(buf, 1, size, fp);<br />     glShaderSource(Shader, 1, (const GLchar **)&amp;buf, &amp;size);<br />     free(buf);<br />     fclose(fp);<br />  <br />     glCompileShader(Shader);<br />     glGetShaderiv( Shader, GL_COMPILE_STATUS, &amp;compiled );<br />  <br />    if ( compiled == GL_FALSE )<br />     {<br />      printf( "コンパイルできませんでした!!: %s \n ", File);<br />      glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, &amp;size );<br />      if ( size &gt; 0 )<br />      {<br />       buf = (char *)malloc(size);<br />       glGetShaderInfoLog( Shader, size, &amp;len, buf);<br />       printf(buf);<br />       free(buf);<br />      }<br />     }<br />   }<br />  <br />  void GLSL::Link( GLuint Prog ){<br />     GLsizei size, len;<br />     GLint linked;<br />     char *infoLog ;<br />  <br />    glLinkProgram( Prog );<br />  <br />    glGetProgramiv( Prog, GL_LINK_STATUS, &amp;linked );<br />  <br />    if ( linked == GL_FALSE ){<br />     printf("リンクできませんでした!! \n");<br />     <br />     glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, &amp;size );<br />     if ( size &gt; 0 ){<br />      infoLog = (char *)malloc(size);<br />      glGetProgramInfoLog( Prog, size, &amp;len, infoLog );<br />      printf(infoLog);<br />      free(infoLog);<br />     }<br />    }<br />  }<br />  <br /> void GLSL::InitGLSL(const char *VertexFile){<br />     GLenum err = glewInit();<br />     if (err != GLEW_OK)<br />     {<br />      printf("Error: %s\n", glewGetErrorString(err));<br />     }<br />     printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />     printf("GPU= %s \n", glGetString(GL_RENDERER));<br />     printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />     printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />     VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />     ReadShaderCompile(VertexShader, VertexFile);<br />     ShaderProg = glCreateProgram();<br />     glAttachShader(ShaderProg, VertexShader);<br />     glDeleteShader(VertexShader);<br />     Link(ShaderProg);<br />   }<br />  <br />  <br /> void GLSL::InitGLSL(const char *VertexFile, const char *FragmentFile){<br />     GLenum err = glewInit();<br />     if (err != GLEW_OK)<br />     {<br />      printf("Error: %s\n", glewGetErrorString(err));<br />     }<br />     printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />     printf("GPU= %s \n", glGetString(GL_RENDERER));<br />     printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />     printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />  <br />    VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />     FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);<br />  <br />    ReadShaderCompile(VertexShader, VertexFile);<br />     ReadShaderCompile(FragmentShader, FragmentFile);<br />  <br />    ShaderProg = glCreateProgram();<br />  <br />     glAttachShader(ShaderProg, VertexShader);<br />     glAttachShader(ShaderProg, FragmentShader);<br />  <br />     glDeleteShader(VertexShader);<br />     glDeleteShader(FragmentShader);<br />     Link(ShaderProg);<br />   }<br />  <br /> void GLSL::ON(){<br />   glUseProgram(ShaderProg);<br />  }<br />  <br /> void GLSL::OFF(){<br />   glUseProgram(0);<br />  }<br />  <br /> GLSL::~GLSL(){<br />   glDeleteProgram(ShaderProg);<br />  }<br />  </p> <p> </p> </td> </tr></tbody></table><p>main.cpp</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td> <p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br /> #pragma comment(lib, "glew32.lib")</p> <p>#include &lt;stdio.h&gt;<br /> #include &lt;GL/glew.h&gt;<br /> #include &lt;GL/freeglut/freeglut.h&gt;<br /> #include "GLSL.h"</p> <p>#define WIDTH 320<br /> #define HEIGHT 240</p> <p>GLSL glsl;<br /> //回転用<br /> float anglex = 0.0f;<br /> //ライトの位置<br /> GLfloat lightpos[] = { 20.0, 80.0, -50.0, 1.0 };</p> <p>float Ambient[] = {0.8f, 0.0f, 0.2f, 1.0f};<br /> float Diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};<br /> float specular[]= { 0.4, 0.4, 0.4, 1.0};//鏡面反射<br /> float AmbientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f};<br /> float DiffuseLight[] = { 0.2f, 0.7f, 0.7f, 1.0f};<br /> float SpecularLight[] = {1.0, 1.0, 1.0, 1.0};//鏡面光</p> <p>void setLight(){<br />  glMaterialfv(GL_FRONT,GL_AMBIENT,Ambient);<br />  glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse);<br />  glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />  glMaterialf(GL_FRONT,GL_SHININESS,8);<br />  glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);<br />  glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);<br />  glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight);<br />  glLightfv(GL_LIGHT0, GL_POSITION, lightpos);<br /> }<br /> void display(void){<br />  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />  glViewport(0, 0, WIDTH, HEIGHT);<br />  glMatrixMode(GL_PROJECTION);<br />  glLoadIdentity();<br />  //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)<br />  gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);<br />  glMatrixMode(GL_MODELVIEW);<br />     glLoadIdentity();<br />  //視点の設定<br />  gluLookAt(150.0,100.0,-200.0, //カメラの座標<br />       0.0,0.0,0.0, // 注視点の座標<br />      0.0,1.0,0.0); // 画面の上方向を指すベクトル<br />  //ライトの設定<br />  setLight();<br />  //回転<br />  glRotatef(anglex,1.0f,0.0f,0.0f);//X軸を回転<br />  glsl.ON();//シェーダー描画に切り替え<br />  glutSolidSphere(40.0,16,16);<br />  glsl.OFF();//シェーダー解除<br />  glutSwapBuffers();<br /> }<br /> void idle(void){<br />  anglex+=2.0f;<br />  Sleep(1);<br />  glutPostRedisplay();<br /> }<br /> void Init(){<br />  glsl.InitGLSL("vertex.shader","flagment.shader");<br />  glClearColor(0.3f, 0.3f, 0.3f, 1.0f);<br />  glEnable(GL_DEPTH_TEST);<br />  glEnable(GL_LIGHTING);<br />  glEnable(GL_LIGHT0);<br /> }<br /> void main(int argc, char *argv[]){<br />  glutInitWindowPosition(100, 100);<br />  glutInitWindowSize(WIDTH, HEIGHT);<br />  glutInit(&amp;argc, argv);<br />  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />  glutCreateWindow("スペキュラー");<br />  glutDisplayFunc(display);<br />  glutIdleFunc(idle);<br />  Init();<br />  glutMainLoop();<br />  return;<br /> }</p> </td> </tr></tbody></table><p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p>

表示オプション

横に並べて表示:
変化行の前後のみ表示: