Projective Texture Anomalies (projtex.c)

I am seeing some weird visual anomalies in a projected texture spotlight simulation. At certain orientations, the spotlight projection becomes grossly misshapen with a bulge or a long shaft extruded from it, or disappears altogether (see normal.jpg and anomaly.jpg ). Moving the spotlight just slightly away from these problem positions will return the correct spotlight pattern.

I reproduced this problem by modifying the demo projtex.c to include a “wall” object consisting of a large polygon perpendicular to the line of sight. The problem does not occur in the standard scenarios (cube, dodecahedron, sphere) but is readily seen in the “wall” scenario by carefully moving the spotlight around using the right mouse button. Note that the “wall” is in the same plane as the back wall of the cube scenario. The only obvious difference I can see is that all the standard scenario objects fit inside the viewport, but the “wall” does not.

Can anyone help explain the anomalies? The texture has a black border, so I don’t think that is the issue. Also, experiments show the texgen is behaving OK, so it must be a result of the texture matrix projection. I don’t think it is related to back projection because the problem can be demonstrated with the spotlight close to the line of sight.

Here is a copy of projtex.c modified to demonstrate the effect on startup: projtex.c . I have been running the modified projtex.c on an SGI Onyx2 with IR2 graphics and Irix 6.5.18f. Running on an SGI O2 also produces some weird (although different) effects. I haven’t tried it out on a PC.

It looks to me like it’s projecting onto some hidden geometry, and this is correct behavior.

If you draw the geormtry or make the non illuminated region grey instead of black and add some lighting you should see what’s going on.

Heck just adding lighting modulation will show what’s going on if you have correct normals and the “bulge” should shade differently.

Thanks for your response.

There doesn’t appear to be any hidden geometry - just a single polygon perpendicular to the line of sight.

I enabled lighting as you suggested and there was no relative shading on the bulge. Also, projtex allows you to turn off the projected texture and rotate the geometry in a trackball manner - no extra geometry is apparent when I do this.

The anomaly is triggered at certain very precise orientations of the spotlight and transitions back to normal again with a very small movement of the mouse (which controls the spotlight orientation in projtex) or of the viewpoint. At some problem locations the spotlight disappears altogether; at others it gets really weird (see newAnomaly.jpg ).

Thanks for your response.

There doesn’t appear to be any hidden geometry - just a single polygon perpendicular to the line of sight.

I enabled lighting as you suggested and there was no relative shading on the bulge. Also, projtex allows you to turn off the projected texture and rotate the geometry in a trackball manner - no extra geometry is apparent when I do this.

The anomaly is triggered at certain very precise orientations of the spotlight and transitions back to normal again with a very small movement of the mouse (which controls the spotlight orientation in projtex) or of the viewpoint. At some locations the spotlight disappears altogether; at others it gets really weird (see newAnomaly.jpg ).

It seems strange how the tex coords are changing so dramatically (and reverting back again upon a minute change to the spotlight orientation) just at these precise spots.

can you post the code you set your texture projection matrix with?

The code is the classic openGL sample program projtex.c, augmented to include a different scene, but I haven’t changed the texture projection bits. Here is the full modified program: projtex.c .

The setting of the tex matrix is complicated slightly because the sample program allows the orientation of the view and the projection to be changed using the mouse. The relevant bits are:

static void
loadTextureProjection(GLfloat m[16])
{
GLfloat mInverse[4][4];

/*
** Should use true inverse, but since m consists only
** of rotations, we can just use the transpose.
*/
matrixTranspose((GLfloat *) mInverse, m);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5, 0.5, 0.0);
glScalef(0.5, 0.5, 1.0);
glFrustum(xmin, xmax, ymin, ymax, znear, zfar);
glTranslatef(0.0, 0.0, distance);
glMultMatrixf((GLfloat *) mInverse);
glMatrixMode(GL_MODELVIEW);

}

void
display(void)
{
int s;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if (textureEnabled) {
if (mode == MoveTexture || mode == MoveView) {
    /* Have OpenGL compute the new transformation (simple but slow). */
    glPushMatrix();
    glLoadIdentity();
    glRotatef(angle, axis[0], axis[1], axis[2]);
    glMultMatrixf((GLfloat *) textureXform);
    glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) textureXform);
    glPopMatrix();
}

loadTextureProjection((GLfloat *) textureXform);

glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
}

// continues on to set the modelview matrix etc