ShadowMaps + 2灯(或更多)+ glsl1.2 =麻烦

时间:2014-03-22 22:33:38

标签: opengl glsl

好吧,我已经做了一个测试,看看它是否适用于使用两个光源的阴影贴图。出了点问题,第一个阴影贴图会产生正确的阴影,但第二个阴影贴图没有。这是完整的代码。

功能

void setupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z){
    glLoadIdentity();
    gluLookAt(position_x,position_y,position_z,lookAt_x,lookAt_y,lookAt_z,0,1,0);
}

void setTextureMatrix1(){
    static double modelView[16];
    static double projection[16];

    const GLdouble bias[16] = {0.5, 0.0, 0.0, 0.0,
                               0.0, 0.5, 0.0, 0.0,
                               0.0, 0.0, 0.5, 0.0,
                               0.5, 0.5, 0.5, 1.0};

    glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
    glGetDoublev(GL_PROJECTION_MATRIX, projection);

    glMatrixMode(GL_TEXTURE);
    glActiveTexture(GL_TEXTURE6);

    glLoadIdentity();
    glLoadMatrixd(bias);

    glMultMatrixd (projection);
    glMultMatrixd (modelView);

    glMatrixMode(GL_MODELVIEW);
}

void setTextureMatrix2(){
    static double modelView[16];
    static double projection[16];

    const GLdouble bias[16] = {0.5, 0.0, 0.0, 0.0,
                               0.0, 0.5, 0.0, 0.0,
                               0.0, 0.0, 0.5, 0.0,
                               0.5, 0.5, 0.5, 1.0};

    glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
    glGetDoublev(GL_PROJECTION_MATRIX, projection);

    glMatrixMode(GL_TEXTURE);
    glActiveTexture(GL_TEXTURE7);

    glLoadIdentity();
    glLoadMatrixd(bias);

    glMultMatrixd (projection);
    glMultMatrixd (modelView);

    glMatrixMode(GL_MODELVIEW);
}

void startTranslate1(float x,float y,float z){
    glPushMatrix();
    glTranslatef(x,y,z);
    glMatrixMode(GL_TEXTURE);
    glActiveTextureARB(GL_TEXTURE6);
    glPushMatrix();
    glTranslatef(x,y,z);
}

void startTranslate2(float x,float y,float z){
    glPushMatrix();
    glTranslatef(x,y,z);
    glMatrixMode(GL_TEXTURE);
    glActiveTextureARB(GL_TEXTURE7);
    glPushMatrix();
    glTranslatef(x,y,z);
}

void endTranslate(){
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}

void drawObjects1(){
    glColor4f(0.3f,0.3f,0.3f,1);
    glBegin(GL_QUADS);
    glVertex3f(-35,2,-35);
    glVertex3f(-35,2, 15);
    glVertex3f( 15,2, 15);
    glVertex3f( 15,2,-35);
    glEnd();

    glColor4f(0.9f,0.9f,0.9f,1);
    startTranslate1(0,4,-5);
    glutSolidCube(4);
    endTranslate();
}

void drawObjects2(){
    glColor4f(0.3f,0.3f,0.3f,1);
    glBegin(GL_QUADS);
    glVertex3f(-35,2,-35);
    glVertex3f(-35,2, 15);
    glVertex3f( 15,2, 15);
    glVertex3f( 15,2,-35);
    glEnd();

    glColor4f(0.9f,0.9f,0.9f,1);
    startTranslate2(0,4,-5);
    glutSolidCube(4);
    endTranslate();
}

主要

int main(){

  GLuint depthTextureId;
  glGenTextures(1, &depthTextureId);
  glBindTexture(GL_TEXTURE_2D, depthTextureId);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
  glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
  glBindTexture(GL_TEXTURE_2D, 0);

  GLuint fboId;
  GLenum FBOstatus;
  glGenFramebuffersEXT(1, &fboId);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
  glDrawBuffer(GL_NONE);
  glReadBuffer(GL_NONE);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId, 0);

  FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)return 1;
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

  /////////////////////////////////////////////////////////////////////

  GLuint depthTextureId2;
  glGenTextures(1, &depthTextureId2);
  glBindTexture(GL_TEXTURE_2D, depthTextureId2);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
  glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
  glBindTexture(GL_TEXTURE_2D, 0);

  GLuint fboId2;
  GLenum FBOstatus2;
  glGenFramebuffersEXT(1, &fboId2);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId2);
  glDrawBuffer(GL_NONE);
  glReadBuffer(GL_NONE);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId2, 0);

  FBOstatus2 = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  if(FBOstatus2 != GL_FRAMEBUFFER_COMPLETE_EXT)return 1;
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

  GLfloat angulo = 0.0;
  GLfloat posZ = 0.0;

  glEnable(GL_CULL_FACE);
  glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);

MAIN LOOP

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId);
glViewport(0,0,640,480);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
setupMatrices(5.0,15.0,0.0,-5.0,0.0,-5.0);
glCullFace(GL_FRONT);
drawObjects1();
setTextureMatrix1();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId2);
glViewport(0,0,640,480);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
setupMatrices(p_light[0],p_light[1],p_light[2],l_light[0],l_light[1],l_light[2]);
glCullFace(GL_FRONT);
drawObjects2();
setTextureMatrix2();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);

glViewport(0,0,640,480);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

glUseProgram(p);
  glUniform1i(shadowMapUniform,6);
  glActiveTexture(GL_TEXTURE6);
  glBindTexture(GL_TEXTURE_2D,depthTextureId);

  glUniform1i(shadowMapUniform2,7);
  glActiveTexture(GL_TEXTURE7);
  glBindTexture(GL_TEXTURE_2D,depthTextureId2);

  glCullFace(GL_BACK);
  setupMatrices(p_camera[0],p_camera[1],p_camera[2],l_camera[0],l_camera[1],l_camera[2]);
  drawObjects1();
  glBindTexture(GL_TEXTURE_2D,0);
glUseProgram(0);

VERTEX SHADER

varying vec4 ShadowCoord1;
varying vec4 ShadowCoord2;

void main(){

  ShadowCoord1 = gl_TextureMatrix[6] * gl_Vertex;
  ShadowCoord2 = gl_TextureMatrix[7] * gl_Vertex;

  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

  gl_FrontColor = gl_Color;
}

FRAGMENT SHADER

uniform sampler2D ShadowMap;
uniform sampler2D ShadowMap2;
varying vec4 ShadowCoord1;
varying vec4 ShadowCoord2;
varying vec3 pvertice;

void main(){    
    vec4 shadowCoordinateWdivide1 = ShadowCoord1 / ShadowCoord1.w ;
    vec4 shadowCoordinateWdivide2 = ShadowCoord2 / ShadowCoord2.w ;

    shadowCoordinateWdivide1.z += 0.0001;
    shadowCoordinateWdivide2.z += 0.0001;   

    float distanceFromLight1 = texture2D(ShadowMap,shadowCoordinateWdivide1.st).z;
    float distanceFromLight2 = texture2D(ShadowMap2,shadowCoordinateWdivide2.st).z; 

    float shadow1 = 1.0;
    if (ShadowCoord1.w > 0.0){
      shadow1 = distanceFromLight1 < shadowCoordinateWdivide1.z ? 0.5 : 1.0 ;
    }

    float shadow2 = 1.0;
    if (ShadowCoord2.w > 0.0){
      shadow2 = distanceFromLight2 < shadowCoordinateWdivide2.z ? 0.5 : 1.0 ;
    }

    gl_FragColor = mix(shadow1,shadow2,0.5) * gl_Color;
}

有什么问题?这看起来像......

enter image description here

如果我试图移动物体,它看起来很糟糕。

虽然在同一位置使用一盏灯,但看起来像这样。

enter image description here

如果我试图移动物体,这看起来不错。

感谢。

1 个答案:

答案 0 :(得分:0)

这些偏见影响自我遮蔽,尝试将它们设置得更高。

shadowCoordinateWdivide1.z += 0.0001;
shadowCoordinateWdivide2.z += 0.0001;