Im trying to implement reflections in OpenGL by rendering the scene 6 times from an object. The code to draw the sides to the cubemap is the following:
glm::mat4 currentCubeMapView = glm::mat4(0.0);
GLenum cubemapSides[6] = {
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
};
glm::vec3 targetVectors[6] = {
glm::vec3(1.0f, 0.0f, 0.0f),
glm::vec3(-1.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3(0.0f, -1.0f, 0.0f),
glm::vec3(0.0f, 0.0f, 1.0f),
glm::vec3(0.0f, 0.0f, -1.0f)
};
glm::vec3 upVectors[6] = {
glm::vec3(0.0f, -1.0f, 0.0f),
glm::vec3(0.0f, -1.0f, 0.0f),
glm::vec3(0.0f, 0.0f, 1.0f),
glm::vec3(0.0f, 0.0f, -1.0f),
glm::vec3(0.0f, -1.0f, 0.0f),
glm::vec3(0.0f, -1.0f, 0.0f)
};
projection = glm::perspective(glm::radians(90.0f), 1.0f, near_plane, far_plane);
glm::vec3 cm = mcCubes.getCenterMass();
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
Camera dcCamera = Camera(cm);
dcCamera.Pitch -= 15;
dcCamera.updateCameraVectors();
for (GLuint face = 0; face < 6; ++face)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubemapSides[face], dcmap, 0);
glClear(GL_DEPTH_BUFFER_BIT);
glm::vec3 modelOrigin = glm::vec3(0,0,0);
dcCamera.Position = cm;
dcCamera.Front = targetVectors[face];
dcCamera.Up = upVectors[face];
currentCubeMapView = glm::mat4(1.0);
currentCubeMapView = dcCamera.lookAt(modelOrigin, modelOrigin + targetVectors[face], upVectors[face]);
// Render skybox
glDepthFunc(GL_LEQUAL); // change depth function so depth test passes when values are equal to depth buffer's content
skyboxShader.use();
view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // remove translation from the view matrix
//currentCubeMapView = glm::mat4(glm::mat3(currentCubeMapView));
//currentCubeMapView2 = glm::mat4(glm::mat3(currentCubeMapView2));
skyboxShader.setMat4("view", currentCubeMapView);
skyboxShader.setMat4("projection", projection);
// skybox cube
glBindVertexArray(skyboxVAO);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthFunc(GL_LESS); // set depth function back to default
shader.use();
shader.setInt("diffuseTexture", 0);
shader.setInt("depthMap", 1);
shader.setInt("skybox", 2);
shader.setInt("normalMap", 3);
model_ = glm::mat4(1.0);
//shader.setVec3("viewPos", lightPos);
shader.setVec3("samplePoint", centerBBox);
shader.setVec3("maxBox", bbmax);
shader.setVec3("minBox", bbmin);
shader.setMat4("view", currentCubeMapView);
shader.setMat4("projection", projection);
shader.setMat4("model", model_);
//glCullFace(GL_BACK);
shader.setVec3("samplePoint", modelOrigin );
shader.setBool("depthRendering", true);
renderScene(shader,true);
shader.setBool("depthRendering", false);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
This cubemap is to show the reflections of the result of the marching cubes mesh (skybox and sphere) Similarly, the code for the reflections of a sphere (skybox and cube):
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, cubemapSize, cubemapSize);
glBindFramebuffer(GL_FRAMEBUFFER, noSphereFrameBuffer);
Camera noSphereCamera = Camera(collObjects[0].getPos());
noSphereCamera.updateCameraVectors();
for (GLuint face = 0; face < 6; ++face)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubemapSides[face], noSphereMap, 0);
glClear(GL_DEPTH_BUFFER_BIT);
glm::vec3 modelOrigin = glm::vec3(0, 0, 0);// +collObjects[0].getPos();
currentCubeMapView = glm::mat4(1.0);
noSphereCamera.Position = collObjects[0].getPos();
noSphereCamera.Front = targetVectors[face];
noSphereCamera.Up = upVectors[face];
currentCubeMapView = noSphereCamera.lookAt(modelOrigin, modelOrigin + targetVectors[face], upVectors[face]);
shader.use();
shader.setInt("diffuseTexture", 0);
shader.setInt("depthMap", 1);
shader.setInt("skybox", 2);
shader.setInt("normalMap", 3);
shader.setMat4("view", currentCubeMapView);
shader.setMat4("projection", projection);
shader.setVec3("view_right", noSphereCamera.Right);
shader.setVec3("view_up", noSphereCamera.Up);
shader.setVec3("view_forward", noSphereCamera.Front);
//collObjects[1].pos = Vector3(camera.Position.x, camera.Position.y, camera.Position.z);
renderCollisionObjectAt(shader, 1, noSphereCamera);
// Render skybox
//glCullFace(GL_FRONT);
glDepthFunc(GL_LEQUAL); // change depth function so depth test passes when values are equal to depth buffer's content
skyboxShader.use();
view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // remove translation from the view matrix
skyboxShader.setMat4("view", currentCubeMapView);
skyboxShader.setMat4("projection", projection);
// skybox cube
glBindVertexArray(skyboxVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthFunc(GL_LESS); // set depth function back to default
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Then i use the vertex shader to calculate the reflected vector:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec3 aOffset;
layout (location = 4) in vec3 aTangent;
layout (location = 5) in vec3 aBitangent;
out vec2 TexCoords;
out VS_OUT {
vec3 FragPos;
vec3 Normal;
vec2 TexCoords;
vec3 TangentLightPos;
vec3 TangentViewPos;
vec3 TangentFragPos;
vec3 reflectedVector;
vec3 refractedVector;
} vs_out;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform bool isParticle;
uniform bool reverse_normals;
uniform vec4 plane;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 camPos;
uniform samplerCube depthMap;
uniform vec3 view_right;
uniform vec3 view_up;
uniform vec3 view_forward;
void main()
{
vec4 pos = vec4(aPos,1.0);
if(isParticle)pos = vec4(aPos+aOffset,1.0);
vec4 worldPosition = model*pos;
vs_out.FragPos = vec3(model * pos);
//gl_ClipDistance[0] = dot(worldPosition,plane);
if(reverse_normals) // a slight hack to make sure the outer large cube displays lighting from the 'inside' instead of the default 'outside'.
vs_out.Normal = transpose(inverse(mat3(model))) * (-1.0 * aNormal);
else
vs_out.Normal = transpose(inverse(mat3(model))) * aNormal;
vs_out.TexCoords = aTexCoords;
mat3 normalMatrix = transpose(inverse(mat3(model)));
vec3 T = normalize(normalMatrix * aTangent);
vec3 N = normalize(normalMatrix * aNormal);
T = normalize(T - dot(T, N) * N);
vec3 B = cross(N, T);
mat3 TBN = transpose(mat3(T, B, N));
vs_out.TangentLightPos = TBN * lightPos;
vs_out.TangentViewPos = TBN * viewPos;
vs_out.TangentFragPos = TBN * vs_out.FragPos;
gl_Position = projection * view * model * pos;
//vs_out.FragPos = vec3(gl_Position);
float waterRatio = 1./1.333;
vec3 vNormal = (transpose(inverse(model))*vec4(aNormal, 0.0)).xyz;
vec3 viewVector = normalize(worldPosition.xyz-camPos);
vs_out.reflectedVector = reflect(viewVector,normalize(vNormal));
vs_out.refractedVector = refract(viewVector,normalize(vNormal), waterRatio);
}
Then in the fragment shader i simply do:
vec4 reflectedColour = reflect(textureCube, reflectedVector);
The results i get are not correct as you can see: https://imgur.com/b6Uk784 https://imgur.com/0QfQ45F
I believe it has to do with the way im writing the framebuffer to the cubemap. What is wrong with my code? Any help appreciated!
Aucun commentaire:
Enregistrer un commentaire