I am trying to render a scene to a cubemap, so I can later use it as environment map for another object. The object I want to use the environment map with is a surface, I am trying to render water. But I have an issue, when the refraction index is set to 1.0 (air), the skybox is shown correctly, however the other object is not.
The circled area is where the cube made out of air is, in these images:
But when I position my camera so it includes a part of the stone platform, the stone platform appears much more larger than it should be:
I render to cubemap as follows:
glm::mat4 translateInfoMat = x.model - glm::mat4(glm::mat3(x.model));
glm::vec3 position = glm::vec3(translateInfoMat[3][0], translateInfoMat[3][1], translateInfoMat[3][2]);//gets the view position of the cubemap from the object's model matrix.
glm::mat4 _projection = glm::perspective(glm::radians(90.0f), 1.f, 0.1f, 2000.0f);
for(int j = 0; j < 6; j++)// for each face it renders the scene
{
envMap.bindRenderToFace(j); //sets the current face to draw to.
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 _view = glm::lookAt(position, position + targets[j], ups[j]);
//renders skybox
glDepthMask(GL_FALSE);
if(skybox != NULL)
{
skybox->setVP(_projection * glm::mat4(glm::mat3(_view)));
skybox->draw(&skyboxShader);
}
glDepthMask(GL_TRUE);
for(int i = 0; i < renderQueue.size(); i++)//renders the objects that doesn't need environment map (the stone platform)
{
RenderableElement object = renderQueue[i];
if(!y.renderInfo.m_needsEnvironmentMap)
{
lighting.SetMVP(_projection * _view * y.model);
lighting.SetModel( object.model);
lighting.SetViewPos(viewPos);
lighting.Use();
object.mesh->Draw(lighting.GetShader());
}
}
}
And the shader that does the refraction is:
#version 330 core
in vec3 FragPos; //the position of the current fragment in world space
in vec3 Normal; //normal in world space
out vec4 FragColor;
uniform vec3 viewPos;
uniform samplerCube skybox;
vec3 refraction(vec3 normal, vec3 viewPos, vec3 fragPos, float n1, float n2)
{
vec3 i = normalize(fragPos - viewPos);
vec3 r = refract(i, normalize(normal), n1 / n2);
return texture(skybox, normalize(r)).rgb;
}
void main()
{
vec3 normal;
normal = normalize(Normal);
vec4 refr = vec4(refraction(normal, viewPos, FragPos, 1.0, 1.0), 1.0);
FragColor = refr;
}
I have verified my code with multiple sources, and they are doing approximately the same way as I have done. The data fed to the shader is correct (normals, vertex position, model matrix, view position, etc.).