0

I’m trying to compute shadows with cubemaps. To generate those, I use layered rendering so that I produce the cubemaps in a single pass. I’d love to attach some code, but it’s full Haskell with my own engine, not sure it’s a good idea. However, this is the GLSL codes:

lightCubeDepthmapVS :: String
lightCubeDepthmapVS = unlines
  [
    "#version 330 core"

  , "layout (location = 0) in vec3 co;"
  , "layout (location = 1) in vec3 no;"

  , "uniform mat4 model;"

  , "void main() {"
  , "  gl_Position = model * vec4(co,1.);"
  , "}"
  ]

-- The geometry shader is used because we’re doing a layered rendering in order
-- to generate the whole cube depthmap in one pass. Each primitive (i.e.
-- triangle) gets duplicate 6 times; one time per cubemap face.
lightCubeDepthmapGS :: String
lightCubeDepthmapGS = unlines
  [
    "#version 330 core"

  , "layout (triangles) in;"
  , "layout (triangle_strip, max_vertices = 18) out;"

  , "out vec3 gco;"

  , "uniform mat4 ligProjViews[6];" -- 6 views

  , "void main() {"
  , "  for (int i = 0; i < 6; ++i) {"
  , "    for (int j = 0; j < 3; ++j) {"
  , "      gl_Layer = i;"
  , "      gco = gl_in[j].gl_Position.xyz;"
  , "      gl_Position = ligProjViews[i] * gl_in[j].gl_Position;"
  , "      EmitVertex();"
  , "    }"
  , "    EndPrimitive();"
  , "  }"
  , "}"
  ]

lightCubeDepthmapFS :: String
lightCubeDepthmapFS = unlines
  [
    "#version 330 core"

  , "in vec3 gco;"
  , "out vec4 frag;"

  , "uniform vec3 ligPos;"
  , "uniform float ligIRad;"

  , "void main() {"
  , "  frag = vec4(length(gco - ligPos) * ligIRad);"
  , "}"
  ]

ligIRad is the inverse of the light radius. So the resulting map (it’s not a standard depthmap) stores the distance light-point at each pixel for 6 faces in [0;1] where 0 = 0 and 1 = radius of the light. This trick enables me to clear the colormap with (1,1,1,1) and then use the cubemap in the lighting phase by simply fetching the texel using the traditional direction and multiplying the fetched .r value by the radius of the light to restore the worldspace distance.

However, I have a black cubemap. I attach the color (R) cubemap and a depth cubemap that I don’t use to the FBO. I figured that attaching a renderbuffer causes the FBO not to be complete (is it because a renderbuffer is not layered-rendering-friendly?).

And final question: I’ve been told there’s a bug around layered rendering into cubemaps. Is it related? Is there a link to such bugs?

phaazon
  • 1,972
  • 15
  • 21
  • Your question discusses incompleteness of using an RBO, which is true (RBOs cannot be attached to layered framebufferers)... but I don't see any actual mention of renderbuffers. The rest of your question talks about two attachments, a color cubemap and a depth cubemap - where does the renderbuffer in your second-to-last paragraph come from? – Andon M. Coleman Jan 09 '15 at 12:02
  • Well, to me, RBO = renderbuffer object – phaazon Jan 09 '15 at 12:19
  • Yes, that is exactly what an RBO is. Cubemaps are not RBOs, they are textures. You can attach two classes of images to Framebuffer Objects: 1. Textures, 2. Renderbuffer Objects. – Andon M. Coleman Jan 09 '15 at 18:18
  • Yes… this is why I attached only textures. When I lookup the cubemap with a constant direction (`vec3(1.,0.,0.)`), I get black color, even with the `glClearColor 1 1 1 1` on the FBO… I don’t get it :( – phaazon Jan 09 '15 at 18:38
  • I was asking why you mentioned an RBO at all in your question. But from your last comment, I have to wonder if you're clearing the depth buffer in all 6 layers (if at all)? – Andon M. Coleman Jan 09 '15 at 18:49
  • I’m cleaning the framebuffer directly. I bind the framebuffer, and call `glClear`. The cubemap is attached with `glFramebufferTexture` and `GL_TEXTURE_CUBE_MAP` in order to perform layered rendering. – phaazon Jan 09 '15 at 23:39

0 Answers0