سؤال

I have a scene containing a map generated from a heightmap. I can move this map around on the X and Y axis, where the map gets moved upwards or downwards such that the map geometry intersects the origin. There is a single light that hovers over the map, always 5 units above the height of the geometry at its x and y coordinate.

When the camera is located close to the origin of the scene, all the lighting behaves fine. The more I move away from it, however, the more triangles jump first quickly to bright white, after which they become black almost instantly. I have not been able to figure out what is causing this.

Here is an overview of the structure of the scene graph:

scene graph overview

  • Container instances do not change the openGL state
  • The shader node activates the shader pair shown below.
    • The problem is also present when using the fixed function pipeline.
  • The scene is translated and rotated prior to rendering the scene graph

I'm fairly certain the problem lies with the construction of the scene, but I'm not entirely certain.

Here are some screenshots of the effects. First one where the light is close to the camera, and where the camera is located some distance away from the scene origin:

up close

Note the light being shown as a sphere, marked by the red circle. Second, one where the light is away from the camera:

far away

I am also drawing the normals for reference. The glow visible in this picture is always present, no matter where the light is located relative to the camera.

Here are my shaders. I'm fairly certain they work as they're supposed to, because they worked properly in ShaderMaker:

Vertex shader:

varying vec3 normal;
varying vec3 position;

void main( void )
{
    gl_Position = ftransform();
    gl_TexCoord[0] = gl_MultiTexCoord0;

    normal = gl_NormalMatrix * gl_Normal;
    position = ( gl_ModelViewMatrix * gl_Vertex ).xyz;
}

Fragment shader:

varying vec3 normal;
varying vec3 position;

vec4 lightSource(vec3 norm, vec3 view, gl_LightSourceParameters light)
{
    vec3 lightVector = normalize(light.position.xyz - view);
    vec3 reflection = normalize(lightVector - view.xyz);

    float diffuseFactor = max(0, dot(norm, lightVector));
    float specularDot = max(0, dot(norm, reflection));

    float specularFactor = pow(specularDot, gl_FrontMaterial.shininess);

    return 
        gl_FrontMaterial.ambient * light.ambient +
        gl_FrontMaterial.diffuse * light.diffuse * diffuseFactor +
        gl_FrontMaterial.specular * light.specular * specularFactor;
}

vec4 lighting()
{
    // normal might be damaged by linear interpolation.
    vec3 norm = normalize(normal);

    return
        gl_FrontMaterial.emission +
        gl_FrontMaterial.ambient * gl_LightModel.ambient +
        lightSource(norm, position, gl_LightSource[0]);
}

void main()
{
    gl_FragColor = lighting();
}
هل كانت مفيدة؟

المحلول

The solution to the problem was that I was applying glFrustrum() on the modelView matrix. When I set the glMatrixMode to the projection matrix before calling glFrustrum instead, the scene rendered correctly.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top