PDA

View Full Version : Issues Rendering to Cubemapped FBO



sgsrules
07-09-2010, 10:41 AM
I've been using cubemaps as environment maps successfully but i'm having trouble setting up a dynamic one. I've been able to setup the fbo correctly along with it's multiple attachments and i can see the reflections on the surface of the object but it looks like I've got the faces in the wrong order. I'm pretty sure that the culprit is in my viewmatrix setup for each face. If i'm not mistaken the order should be: +x,-x,+y-,y,+z,-z from 0-5. I don't want to use the geometry shader approach because some of my objects use geometry shaders and incorporating the two would be a pain. Been staring at this for hours any help would be much appreciated. coded in c#, all the fbo stuff seems to work.


using System;
using OpenTK;
using OpenTK.Graphics.OpenGL;

namespace ML3D
{
public class CubeFBO
{
public int[] FBO;
public int[] ColorTexture;
public int[] DepthTexture;
public int DepthMap;
private string fboMsg;
private Camera camera;
public CubeFBO()
{
FBO = new int[1];
ColorTexture = new int[1];
GL.GenTextures(1, ColorTexture);
GL.BindTexture(TextureTarget.TextureCubeMap, ColorTexture[0]);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter,
(int)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter,
(int)TextureMinFilter.Nearest);
for (int i = 0; i < 6; i++)
{
GL.TexImage2D(TextureTarget.TextureCubeMapPositive X + i, 0, PixelInternalFormat.Rgba16f, 512, 512, 0, PixelFormat.Bgra, PixelType.HalfFloat, IntPtr.Zero);
}
GL.BindTexture(TextureTarget.TextureCubeMap, 0);

DepthTexture = new int[1];

GL.GenTextures(1, DepthTexture);
GL.BindTexture(TextureTarget.TextureCubeMap, DepthTexture[0]);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS,
(int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT,
(int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter,
(int)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter,
(int)TextureMinFilter.Nearest);
GL.TexImage2D(TextureTarget.TextureCubeMap, 0, PixelInternalFormat.DepthComponent24, 512, 512, 0,
PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero);
GL.BindTexture(TextureTarget.TextureCubeMap, 0);

GL.GenFramebuffers(1, FBO);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO[0]);
for (int i = 0; i < 6; i++)
{
GL.FramebufferTexture2D(FramebufferTarget.Framebuf fer, FramebufferAttachment.ColorAttachment0 + i, TextureTarget.TextureCubeMapPositiveX + i, ColorTexture[0], 0);

}
GL.FramebufferTexture2D(FramebufferTarget.Framebuf fer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, DepthTexture[0], 0);

GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
fboMsg = GL.CheckFramebufferStatus(FramebufferTarget.Frameb uffer).ToString();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
camera = new Camera();
camera.Fov = 90;
}

public Vector3 pos;
private Matrix4 tempMatrix;
public void Render()
{
GL.Enable(EnableCap.TextureCubeMapSeamless);
Camera.SetFov(90); // changes perspective matrix and is later sent to the shader during RenderScene();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO[0]);
for (int i = 0; i < 6; i++)
{
GL.DrawBuffer(DrawBufferMode.ColorAttachment0 + i);
Background.Render(); // this clears the buffers
GL.FramebufferTexture2D(FramebufferTarget.Framebuf fer, FramebufferAttachment.ColorAttachment0 + i, TextureTarget.TextureCubeMapPositiveX + i, ColorTexture[0], 0);

switch (i)
{
case 0: Camera.ViewMatrix = Matrix4.LookAt(pos, pos + Vector3.UnitX, Vector3.UnitY); //pos is the center of the cubemap in world coordinates
break;
case 1: Camera.ViewMatrix = Matrix4.LookAt(pos, pos - Vector3.UnitX, Vector3.UnitY); // camera view matrix is later sent to the shader during RenderScene();
break;
case 2: Camera.ViewMatrix = Matrix4.LookAt(pos, pos + Vector3.UnitY, Vector3.UnitZ);
break;
case 3: Camera.ViewMatrix = Matrix4.LookAt(pos, pos - Vector3.UnitY, -Vector3.UnitZ);
break;
case 4: Camera.ViewMatrix = Matrix4.LookAt(pos, pos + Vector3.UnitZ, Vector3.UnitY);
break;
case 5: Camera.ViewMatrix = Matrix4.LookAt(pos, pos - Vector3.UnitZ, Vector3.UnitY);
break;
}
RenderScene();
}
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}

public void Destroy()
{
GL.DeleteTextures(1, ColorTexture);
GL.DeleteTextures(1, DepthTexture);
GL.DeleteBuffers(1, FBO);
}

public void BindTexture(int texUnit)
{
Renderer.ActiveTexture(texUnit);
GL.BindTexture(TextureTarget.TextureCubeMap, ColorTexture[0]);
}

}
}


and the relevant part of the shader that applies the cubemap:


vec3 R = reflect(In,normal); //In is incident vector
fragColor= texture(reflectCubeSampler,R);