2016-09-05 10 views
0

テクスチャにいくつかのライティングを適用しようとしています。 テクスチャキューブを作成して、その中にカメラを配置しました。 今、私はその内面を照らしたいと思います。私はシェーダを使用する必要があると言われてきたので、私は多くのチュートリアルを読んで、私が作成した:シェーダ付きOpenGLで照明する

頂点シェーダ:I後

const GLchar* vertexSkySource = 
#if defined(__APPLE_CC__) 
"#version 150 core\n" 
#else 
"#version 130\n" 
#endif 
"uniform mat3 view_rot;" 
"in vec3 position;" 
"out vec3 Coord;" 
"void main() {" 
" Coord = view_rot * position;" 
" gl_Position = vec4(position, 1.0);" 
"}"; 

フラグメントシェーダ

const GLchar* fragmentSkySource = 
#if defined(__APPLE_CC__) 
"#version 150 core\n" 
#else 
"#version 130\n" 
#endif 
"in vec3 Coord;" 
"out vec4 outColor;" 
"uniform samplerCube textureSampler;" 
"void main() {" 
" outColor = texture(textureSampler, Coord);" 
"}"; 

それらを初期化する

void initialize_shader() 
{ 
    // shader per la skybox 
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShader, 1, &vertexSkySource, NULL); 
    glCompileShader(vertexShader); 
    { 
     GLchar log[512]; 
     GLsizei slen = 0; 
     glGetShaderInfoLog(vertexShader, 512, &slen, log); 
     if (slen) 
      std::cerr << log << std::endl; 
    } 

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragmentShader, 1, &fragmentSkySource, NULL); 
    glCompileShader(fragmentShader); 
    { 
     GLchar log[512]; 
     GLsizei slen = 0; 
     glGetShaderInfoLog(fragmentShader, 512, &slen, log); 
     if (slen) 
      std::cerr << log << std::endl; 
    } 

    skyProgram = glCreateProgram(); 
    glAttachShader(skyProgram, vertexShader); 
    glAttachShader(skyProgram, fragmentShader); 
    glBindFragDataLocation(skyProgram, 0, "outColor"); 
    glLinkProgram(skyProgram); 
    GLint status = 0; 
    glGetProgramiv(skyProgram, GL_LINK_STATUS, &status); 
    if (!status) 
    { 
     std::cout << "failed to link" << std::endl; 
     GLchar log[256]; 
     GLsizei slen = 0; 
     glGetProgramInfoLog(skyProgram, 256, &slen, log); 
     std::cout << log << std::endl; 
    } 
    glDeleteShader(vertexShader); 
    glDeleteShader(fragmentShader); 
} 
glm::vec3 light_direction = glm::normalize(glm::vec3(1.f, 1.f, 3.f)); 
glm::vec3 light_position = glm::vec3(1.0f, 1.0f, 0.0f); 
glm::vec3 light_intensity = glm::vec3(1.f, 1.f, 1.f); 

glDepthMask(GL_FALSE); 
glUseProgram(skyProgram); 
glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube); 
glUniform1i(glGetUniformLocation(skyProgram, "textureSampler"), 3); 
glUniform3fv(glGetUniformLocation(skyProgram, "light_direction"), 1, &light_direction[0]); 
glUniform3fv(glGetUniformLocation(skyProgram, "light_intensity"), 1, &light_intensity[0]); 
glUniform3fv(glGetUniformLocation(skyProgram, "view_position"), 1, &camera_position[0]); 
glUniform1f(glGetUniformLocation(skyProgram, "shininess"), 60); // shininess = 60, range is [0.0 - 128.0] 
glUniformMatrix3fv(glGetUniformLocation(skyProgram, "view_rot"), 1, GL_FALSE, &(glm::mat3(glm::inverse(view)))[0][0]); 

私は私が私のシェーダに何を追加する必要があり、キューブの顔にライトを見ることができません。mainメソッド内部で呼び出されます私のdrawメソッドで次に私はこれを行いますか?

+1

私が見るところでは、シェーダのどのライティングも計算していません。また、シェーダに存在しない制服を設定しようとしているので、OpenGLエラーが発生しています。 – BDL

+1

@BDL:実際には、位置-1の制服を設定すると明示的にGLにエラーが発生しません。 – derhass

答えて

2

あなたはシェーダに光のパラメータ(light_directionlight_intensityview_positionshininess)を送信されますが、それらを受け取ったりして何もしていません。あなたのフラグメントシェーダは、テクスチャのみを読み込み、それに任意の照明が適用されません。シェーディングへ

outColor = texture(textureSampler, Coord); 

完全なソースは大きく、より多くのコードを見ることなくなり与えることは困難であるので、私はいくつかのポインタをあげる:

  • 最初に、glGetError()をC++コードのさまざまな部分に追加して、OpenGL APIが間違っているかどうかを知ることができます。
  • 位置に加えて、頂点法線をシェーダに送る必要があります
  • シェーディングアルゴリズムを選択する必要があります。Blinn-Phongはシンプルで広く使用されています。

    outColor = texture(textureSampler, Coord) * shading; 
    
  • あなたは、通常と光の方向があなたのoutColorニーズ算出されたシェーディングと乗算されるが、最終的には、

だから、同じ座標空間にあることを確認する必要があります

しかし、ライトの方向と頂点ノーマルに基づいて頂点シェーダとフラグメントシェーダを計算するには、頂点シェーダとフラグメントシェーダを変更する必要があります。 GitHub projectに基づい

編集

私がコンパイルし、プロジェクトを実行し、いくつかの問題を解決しなければならなかった:

  • を含めるとライブラリパスがプロジェクトに対するお使​​いのコンピュータ用に設定していませんでしたディレクトリ。

  • フラグメントシェーダでは、「シェーディング」を「アウト」と宣言しています。その行を削除し、shading += vec4...

  • vec4(light_intensity)が間違っていると私のNVIDIA Windowsドライバ上でコンパイルできないvec4 shading = vec4(0.0, 0.0, 0.0, 1.0);前に追加し、私は私が変更しても画面上に何かを得ることができませんでしたvec4(light_intensity,1.0)

と交換常に赤を出力するシェーダ。

+0

提案していただきありがとうございます。私はコードを修正しましたが、私は実際にシェーディングの動作を理解する/しようとしています。 https://github.com/luca92c/openGLに私のコード全体をアップロードしました。私は単純なフォンシェーディング効果を得るまでにどれくらいの時間がかかっているのか分かりませんが、これは私の最初のOpenGLプロジェクトです。 – splunk

+0

@splunkすぐに私の答えを更新します – SurvivalMachine

+0

ありがとう、もう一度。今私は光の効果を見ることができます。しかし、あなたはvec4(0.0、0.0、0.0、1.0)の4つのパラメータを何か説明できますか?平均? – splunk

関連する問題