2017-06-04 6 views
1

私のOpenGLプログラムでは、フォワードレンダリングアルゴリズムでライトが混在しているところに黒いピクセルが現れることに気付きました。最初は、視覚的に問題が出てきたときにWindow API(SDLからGLFW)に切り替えるまで無視しました。前方にレンダリングライトが点灯しているときにZ戦闘が行われるのはなぜですか?

GL_DEPTH_TESTを無効にすると、黒のアーティファクトが消えますが、物事はその背後にある光に透明になり、解決策にはなりません。 (これは私が潜在的な問題を見つけた方法です)

デプスバッファかもしれませんが、スイッチングウインドウAPIがアーティファクトを助けてくれますか?私はカメラに Rendered scene

を移動すると、パターンがちらつく

私がライトに

// Note: I wrapped OpenGL calls into wrapper functions but the naming convenction is still the same 
gl::Clear(gl::e_ColorBufferBit | gl::e_DepthBufferBit); 

mesh->Render(m_forward_ambient); 
gl::Enable(gl::e_Blend); 
gl::SetBlendFunc(gl::e_One, gl::e_One); // Additive blending 
gl::SetDepthMask(false); // No need to write to depth buffer 
gl::SetDepthFunc(gl::e_Equal); // Only draw fragments of equal depths (ignore fragments behind basically) 
{ 
    for (word i = 0; i < m_lights.Length(); ++i) 
    { 
     m_active_light = m_lights[i]; 
     mesh->Render(m_active_light->shader); // Shaders use active light 
    } 
} 
gl::SetDepthFunc(gl::e_Lequal); // Restore default state 
gl::SetDepthMask(true); 
gl::Disable(gl::e_Blend); 

シェーダコードをブレンドするのはここだ黒色の線/ドットが各三角形

内で分離されているようです(すべてのコードを持つシェーダ、それ以外は実装が少ない)

// Vertex 
void main() 
{ 
    // pv_matrix is projection and camera, ml_matrix is model transform 
    gl_Position = pv_matrix * ml_matrix * vec4(pos, 1); 
    f_pos = (ml_matrix * vec4(pos, 1)).xyz; 
    f_nrm = (ml_matrix * vec4(normalize(nrm), 0)).xyz; 
    f_txc = txc; 
} 
// Fragment 
struct Light 
{ 
    vec3 color; 
    float intensity; 
}; 
struct Attenuation 
{ 
    float constant; 
    float linear; 
    float exponent; 
}; 
struct PointLight 
{ 
    Light light; 
    Attenuation atten; 
    vec3 position; 
    float range; 
}; 
struct SpotLight 
{ 
    PointLight plight; 
    vec3 direction; 
    float cutoff; 
}; 
vec4 CalculateLight(Light light, vec3 direction, vec3 normal) 
{ 
    float diffuse_factor = dot(normal, -direction); 
    vec4 diffuse_color = vec4(0, 0, 0, 0); 
    vec4 specular_color = vec4(0, 0, 0, 0); 

    if (diffuse_factor > 0) 
     diffuse_color = vec4(light.color, 1) * light.intensity * diffuse_factor; 

    vec3 direction_to_eye = normalize(eye_pos - f_pos); // eye_pos is uniform for camera pos, f_pos is (position) attribute sent from vertex shader 
    vec3 reflect_direction = normalize(reflect(direction, normal)); 
    float specular_factor = dot(reflect_direction, direction_to_eye); // specular calculations 
    if (specular_factor > 0) 
    { 
     specular_factor = pow(specular_factor, specular_power); 
     specular_color = vec4(light.color, 1) * specular_intensity * specular_factor; 
    } 

    return diffuse_color + specular_color; 
} 

vec4 CalculatePointLight(PointLight plight, vec3 normal) 
{ 
    vec3 light_direction = f_pos - plight.position; 
    float distance = length(light_direction); 

    if (distance > plight.range) 
     return vec4(0, 0, 0, 0); 

    light_direction = normalize(light_direction); 
    vec4 color = CalculateLight(plight.light, light_direction, normal); 

    float a = plight.atten.constant + (plight.atten.linear * distance) + (plight.atten.exponent * (distance * distance)) + 0.0001; 

    return color/a; 
} 

vec4 CalculateSpotLight(SpotLight slight, vec3 normal) 
{ 
    vec3 light_direction = normalize(f_pos - slight.plight.position); 
    float spot_factor = dot(light_direction, slight.direction); 

    vec4 color = vec4(0, 0, 0, 0); 
    if (spot_factor > slight.cutoff) 
     color = CalculatePointLight(slight.plight, normal) * (1.0 - ((1.0 - spot_factor)/(1.0 - slight.cutoff))); 

    return color; 
} 

uniform SpotLight spot_light; 

void main() 
{ 
    FragColor = CalculateSpotLight(spot_light, f_nrm); // f_nrm is a (normal) attribute sent from vertex shader 
} 
+1

適切な[MCVE](https://stackoverflow.com/help/mcve)を入力してください。私の意見では、この問題の最も可能性が高いと思われる多くのもの、特に頂点変換に関するすべてのパットがまだ不明です。 – derhass

答えて

1

というように、としてgl_Positionの頂点シェーダの出力を宣言していないため、両方のパスで全く同じ入力を使用してもビット単位で同じ入力があっても、 。すべてのパスですべてのシェーダーに適切なinvariance qualifiersを追加する必要があります。

+0

うわー。それかもしれない。私はそれを試してみませんが、私は新しいシェーダ情報を学んだと思います。 – Jarann

+0

うん、それはそれを解決しました。ありがとう! – Jarann

関連する問題