简体   繁体   English

OpenGL-使用立方体阴影贴图渲染点光源?

[英]OpenGL - Rendering point light with cube shadow map?

I'm having trouble rendering cube shadow map. 我在渲染立方体阴影贴图时遇到问题。 Negative and positive seem to be reversed and I can't figure out why. 消极和积极的态度似乎是相反的,我不知道为什么。 Tried to reverse targets and directions, but I get event weirder output. 试图颠倒目标和方向,但我得到事件奇怪的输出。

Code: 码:

// init
glGenTextures(1, &mShadowCubeTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, mShadowCubeTex);
for(int i = 0; i < 6; i++)
  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT24, SHADOW_WIDTH, SHADOW_WIDTH, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
/* + filters + wrapping */
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);

glGenFramebuffers(1, &mShadowFbo);
glBindFramebuffer(GL_FRAMEBUFFER, mShadowFbo);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_COMPONENT, mShadowCubeTex, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

// render
static const struct {
  GLenum eTarget;
  vec3   vDirection;
  vec3   vUp;
} oPointLightConfigs[6] = {
  { GL_TEXTURE_CUBE_MAP_POSITIVE_X, vec3( 1.0f, 0.0, 0.0f), vec3(0.0f, 1.0f, 0.0f) },
  { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, vec3(-1.0f, 0.0, 0.0f), vec3(0.0f, 1.0f, 0.0f) },
  { GL_TEXTURE_CUBE_MAP_POSITIVE_Y, vec3( 0.0f, 1.0, 0.0f), vec3(0.0f, 0.0f,-1.0f) },
  { GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, vec3( 0.0f,-1.0, 0.0f), vec3(0.0f, 0.0f, 1.0f) },
  { GL_TEXTURE_CUBE_MAP_POSITIVE_Z, vec3( 0.0f, 0.0, 1.0f), vec3(0.0f, 1.0f, 0.0f) },
  { GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, vec3( 0.0f, 0.0,-1.0f), vec3(0.0f, 1.0f, 0.0f) }
};

// shadow pass
for(int i = 0; i < 6; i++)
{
  glBindFramebuffer(target, mShadowFbo);
  glViewport(0, 0, SHADOW_WIDTH, SHADOW_WIDTH);
  glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, oPointLightConfigs[i].eTarget, mShadowCubeTex, 0);

  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glDrawBuffer(GL_NONE);
  glReadBuffer(GL_NONE);
  glCullFace(GL_FRONT);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  for(CModel* pModel : mModels)
  {
    if(pModel->hasOption(NO_SHADOW_CAST))
    {
      mNullProgram->use(); // no color output

      mat4 M = pModel->getModelMatrix();
      mat4 V = lookAt(pPointLight->getPosition(), oPointLightConfigs[i].vDirection, oPointLightConfigs[i].vUp);
      mat4 P = mCamera->getProjectionMatrix();

      pNullProgram->set("MVP", P * V * M);

      pModel->draw();
    }
  }
}

// color pass
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

pLightProgram->use();

glActiveTexture(GL_TEXTURE6); 
glBindTexture(GL_TEXTURE_2D, mShadowCubeTex);

pLightProgram->set("V", mCamera->getViewMatrix());
pLightProgram->set("P", mCamera->getProjectionMatrix());

/* set program light uniforms */

for(CModel* pModel : mModels)
{
  pLightProgram->set("M", pModel->getModelMatrix());

  pModel->draw()
}


// lighting fragment shader
float computeShadowFactor(in samplerCube sShadowMap, in vec3 vL) {
  /* vL = vLightPosition - vVertexPosition */
  vec3 vLAbs = abs(vL);
  float fNear = 0.1;
  float fFar  = 1000.0;
  float fDepth = max(vLAbs.x, max(vLAbs.y, vLAbs.z));
  fDepth = ((fFar + fNear) / (fFar - fNear)) - ((2.0 * fFar * fNear) / (fFar - fNear)) / fDepth;
  fDepth = (fDepth + 1.0) * 0.5;

  float fShadow = texture(sShadowMap, -vL).r; /* -vL = vVertexPosition - vLightPosition */
  if(fDepth > fShadow) 
    return 0.0;
  return 1.0;
}

Output: 输出:

在此处输入图片说明

在此处输入图片说明

Update: 更新:

I added + oPointLightConfigs[i].vDirection to... 我将+ oPointLightConfigs [i] .vDirection添加到...

V = lookat(pPointLight->mPosition, pPointLight->mPosition + oPointLightConfigs[i].vDirection, oPointLightConfigs[i].vUp);

Output: 输出:

在此处输入图片说明

At least now I get one shadow(instead of 6). 至少现在我得到一个阴影(而不是6个阴影)。 But it's somehow reversed and the Y axis has no shadow. 但是它以某种方式反转了,并且Y轴没有阴影。 When the shadow passes from one cubemap face to another it get interrupted. 当阴影从一个立方体贴图面传递到另一个立方体贴图面时,它会被中断。 Any hints? 有什么提示吗?

These problems were caused by inverted Y's on cubemaps. 这些问题是由立方图上的反向Y引起的。

I used: 我用了:

{ GL_TEXTURE_CUBE_MAP_POSITIVE_Y, math::vec3( 0.0f,-1.0, 0.0f), math::vec3(0.0f, 0.0f, 1.0f) },
{ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, math::vec3( 0.0f, 1.0, 0.0f), math::vec3(0.0f, 0.0f, 1.0f) },

for setting up the shadow cubemap and: 用于设置阴影立方体贴图和:

vL.y *= -1.0;

inside computeShadowFactor() before sampling the shadow cubemap texture. 在对阴影立方体贴图进行采样之前,请在computeShadowFactor()中进行内部设置。

Note: My +Z axis goes into the monitor - left hand coordinate system. 注意:我的+ Z轴进入显示器-左手坐标系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM