# Faces of cube map not fitting together

This topic is 1106 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,

I am trying to render a scene to a cube map but the faces are not fitting together. I think there is something wrong with the perspective:

I define a framebuffer and render the scene six times with different viewing directions (one renderpass for each face of the cube map). Then I place the camera at the origin and render a unit cube with the cube map.

The creation of the cube map:

TextureCubeMap::TextureCubeMap(const unsigned int size) : _size(size), _boundSlot(-1){
glGenTextures(1, &_texID);
glBindTexture(GL_TEXTURE_CUBE_MAP, _texID);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

for (int loop = 0; loop < 6; ++loop)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + loop, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
}

glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}

int TextureCubeMap::bind(){
...
glEnable(GL_TEXTURE0 + _boundSlot);
glActiveTexture(GL_TEXTURE0 + _boundSlot);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, _texID);
...
return _boundSlot;
}

void TextureCubeMap::unbind(){
...
glActiveTexture(GL_TEXTURE0 + _boundSlot);
glBindTexture(GL_TEXTURE_2D, 0);
...
}


And this is the part where I render the scene to the cube map sixe times:

void RenderToCubeMap::render(SceneContext& scene_context){
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
const GLenum drawBuffer = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, &drawBuffer);

glViewport(0, 0, (GLsizei)_cubeMap->getSize(), (GLsizei)_cubeMap->getSize());
SceneContext cubeMapContext = scene_context; //Contains all relevant matrices like projection-, view- and modelmatrix
cubeMapContext._P = glm::perspective(90.f, 1.f, 1.f, 1000.f);

_cubeMap->bind();
for (unsigned int iFace = 0; iFace < 6; iFace++){
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + iFace, _cubeMap->getTexID(), 0);
IRenderPass::startRenderPass(); //Enable depth test, backface culling, clear depth & draw buffer

glm::vec3 viewDir, up;
switch (GL_TEXTURE_CUBE_MAP_POSITIVE_X + iFace){
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
viewDir = glm::vec3(1.0f, 0.0f, 0.0f);
up = glm::vec3(0.f, -1.f, 0.f);
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
viewDir = glm::vec3(-1.0f, 0.0f, 0.0f);
up = glm::vec3(0.f, -1.f, 0.f);
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
viewDir = glm::vec3(0.0f, 1.0f, 0.0f);
up = glm::vec3(0.f, 0.f, 1.f);
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
viewDir = glm::vec3(0.0f, -1.0f, 0.0f);
up = glm::vec3(0.f, 0.f, -1.f);
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
viewDir = glm::vec3(0.0f, 0.0f, 1.0f);
up = glm::vec3(0.f, -1.f, 0.f);
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
viewDir = glm::vec3(0.0f, 0.0f, -1.0f);
up = glm::vec3(0.f, -1.f, 0.f);
break;
}

auto viewMatrix = glm::lookAt(glm::vec3(scene_context._camPos), glm::vec3(viewDir + scene_context._camPos), up);
cubeMapContext._V = viewMatrix;
cubeMapContext._MV = viewMatrix * cubeMapContext._M;
cubeMapContext._MVP = cubeMapContext._P * cubeMapContext._MV;
_sceneGraph->renderSubtree(cubeMapContext);
}
_cubeMap->unbind();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
IRenderPass::endRenderPass(); //Disable depth test, backface culling
}


What am I doing wrong? Is there something wrong with the projection matrix? I am really thankful for any input.

Best regards,

Stan

##### Share on other sites

Your result looks like you are rendering the sides with too high a field of view or from a little too far back. But you have 90 for the field of view variable, so that should be fine. This leaves inconsistency of the camera position as the likely culprit.

auto viewMatrix = glm::lookAt(glm::vec3(scene_context._camPos), glm::vec3(viewDir + scene_context._camPos), up);
cubeMapContext._V = viewMatrix;
cubeMapContext._MV = viewMatrix * cubeMapContext._M;
cubeMapContext._MVP = cubeMapContext._P * cubeMapContext._MV;
_sceneGraph->renderSubtree(cubeMapContext);


I bolded the line that immediately seemed suspicious to me. Where do you set cubeMapContext._M? It looks like it is supposed to be the identity matrix. Double check that this is really the case or just drop it from the multiplication (which leaves just the assignment). Also make sure you are multiplying the matrices in the correct order, I don't know glm so I don't know which way that is supposed to go.

##### Share on other sites

I have tried out your suggestion but the problem remains. I have even fixed the camera position to the origin:

auto viewMatrix = glm::lookAt(glm::vec3(0), glm::vec3(viewDir + glm::vec3(0)), up);
cubeMapContext._V = cubeMapContext._MV = viewMatrix;
cubeMapContext._MVP = cubeMapContext._P * cubeMapContext._MV;
_sceneGraph->renderSubtree(cubeMapContext);


What I have also tried out is loading a cube map to see if my cube map rendering works correctly. And indeed it is, when loading a cube map everything fits perfectly together. Only when I generate the cube map myself as described above the faces don't fit together. Here is my shader code for the cube map rendering:

#version 430

layout(location=0) in vec3 vertex;

out vec3 ex_uv;

uniform mat4 mvp;

void main(){
ex_uv = vertex;
gl_Position = mvp * vec4(vertex, 1.f);
}

#version 430

in vec3 ex_uv;

out vec4 color;

uniform samplerCube cubeMap;

void main(){
color = texture(cubeMap, ex_uv);
}


And this is the client code initiating the rendering of the cube map:

void render(const SceneContext& context, const glm::mat4x4& tmat){
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
// glUniformMatrix4fv(_uniID, 1, GL_FALSE, valuePtr);
_unitCube->bindVertices(0); // glEnableVertexAttribArray(location); //location = 0
// glBindBuffer(GL_ARRAY_BUFFER, _vBufferID);
// glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, 0, 0);
// glBindBuffer(GL_ARRAY_BUFFER, 0);
_unitCube->render(); // glDrawArrays(GL_TRIANGLES, 0, _vertices.size());
_unitCube->unbind(); // glDisableVertexAttribArray(0);
glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}


Is there maybe conceptually something wrong? I only want to create an environment map/panoramic view of my sponza scene. Isn't it possible to do it the way I do?

Regards,

Stan

##### Share on other sites

But you have 90 for the field of view variable, so that should be fine.

90 radians is 5156.62 degrees! If you assume that it wraps every 360 degrees, then you get a remainder of 116.62 degrees... which is coincidentally, only just a tad higher than 90 degrees, causing only the slight excess in perspective seen in the pictures.

You actually want to be passing Pi/2 radians as the fov argument

Edited by Hodgman

##### Share on other sites

Thanks Hodgman! That was exactly the problem.  After passing the fov in radians everything worked perfectly fine. I somewhere defined the symbol GLM_FORCED_RADIANS and from then on the function took the angle in radians and not in degrees.

##### Share on other sites

But you have 90 for the field of view variable, so that should be fine.

90 radians is 5156.62 degrees! If you assume that it wraps every 360 degrees, then you get a remainder of 116.62 degrees... which is coincidentally, only just a tad higher than 90 degrees, causing only the slight excess in perspective seen in the pictures.

You actually want to be passing Pi/2 radians as the fov argument

Well spotted. I thought I checked that the function took degrees, but apparently I did not...

Thanks Hodgman! That was exactly the problem.  After passing the fov in radians everything worked perfectly fine. I somewhere defined the symbol GLM_FORCED_RADIANS and from then on the function took the angle in radians and not in degrees.

... then again maybe I did. :) May I take a moment to express my hatred towards APIs that change their contract based on a single tidbit anywhere in the code and does not communicate this possibility in the naming of its functions?

1. 1
Rutin
43
2. 2
3. 3
4. 4
5. 5

• 10
• 27
• 20
• 9
• 20
• ### Forum Statistics

• Total Topics
633405
• Total Posts
3011680
• ### Who's Online (See full list)

There are no registered users currently online

×