MRT and multisampling

Hi,

I have modified the FilterPostProcessor to support Multi Target Rendering (MRT). There are 3 targets: default color target, glow map and a water mask (which only contains the water). The problem is that when I enable multisampling, the other 2 render targets (glow map, water mask) contains garbage only. I hope @nehon can help me because he already knows my situation from this thread: [SOLVED] Prevent rendering scene multiple times using MRT

What I am doing wrong? This is the modified frame buffer part in the FilterPostProcessor:

public void reshape(ViewPort vp, int w, int h)
{
	...

        // antialiasing on filters only supported in opengl 3 due to depth read problem
	if (numSamples > 1 && caps.contains(Caps.FrameBufferMultisample))
	{
		renderFrameBufferMS = new FrameBuffer(width, height, numSamples);
		if (caps.contains(Caps.OpenGL32))
		{
			Texture2D msColor = new Texture2D(width, height, numSamples, fbFormat);
			Texture2D msDepth = new Texture2D(width, height, numSamples, Format.Depth);
			renderFrameBufferMS.setDepthTexture(msDepth);
			renderFrameBufferMS.setColorTexture(msColor);
			filterTexture = msColor;
			depthTexture = msDepth;
		}
		else
		{
			renderFrameBufferMS.setDepthBuffer(Format.Depth);
			renderFrameBufferMS.setColorBuffer(fbFormat);
		}
	}

	if (numSamples <= 1 || !caps.contains(Caps.OpenGL32))
	{
		renderFrameBuffer = new FrameBuffer(width, height, 1);
		renderFrameBuffer.setDepthBuffer(Format.Depth);
		filterTexture = new Texture2D(width, height, fbFormat);
		renderFrameBuffer.setColorTexture(filterTexture);
	}

           // modification below this line

	if (caps.contains(Caps.FrameBufferMRT))
	{
		if (renderFrameBuffer != null)
		{
			renderFrameBuffer.setMultiTarget(true);

			glowMap = new Texture2D(w, h, Format.RGBA8);
			renderFrameBuffer.addColorTexture(glowMap);

			waterMaskMap = new Texture2D(w, h, Format.RGB32F);
			renderFrameBuffer.addColorTexture(waterMaskMap);

			depthMap = new Texture2D(w, h, Format.RGB32F);
			renderFrameBuffer.addColorTexture(depthMap);
		}

		if (renderFrameBufferMS != null && numSamples > 1)
		{
			renderFrameBufferMS.setMultiTarget(true);

			msGlowMap = new Texture2D(w, h, numSamples, Format.RGBA8);
			renderFrameBufferMS.addColorTexture(msGlowMap);

			msWaterMaskMap = new Texture2D(w, h, numSamples, Format.RGB32F);
			renderFrameBufferMS.addColorTexture(msWaterMaskMap);

			msDepthMap = new Texture2D(w, h, numSamples, Format.RGB32F);
			renderFrameBufferMS.addColorTexture(msDepthMap);
		}
	}
	else
	{
		throw new UnsupportedOperationException("Multiple Render Targets (MRT) are not supported by the GPU! Currently there is no fallback supported.");
	}

	...
}
   ....
public Texture2D getGlowMap()
{
	return renderFrameBufferMS != null ? msGlowMap : glowMap;
	// return glowMap;
}

public Texture2D getWaterMaskMap()
{
	return renderFrameBufferMS != null ? msWaterMaskMap : waterMaskMap;
	// return waterMaskMap;
}

public Texture2D getDepthMap()
{
	return renderFrameBufferMS != null ? msDepthMap : depthMap;
	// return depthMap;
}

the garbage looks like the following when I display the target at the screen (simple post filter). I suppose it shows some random textures from the VRAM such as normal maps, diffuse maps and so on:

mhhh When you use multisampling, another framebuffer is created, maybe you didn’t attach your texture to it and you get memory trash.

Relevant code is in the reshape method of the FPP. if opengl3 is supported and multisample is requested (samples > 1) then we create a frameBufferMS. you have to attach your additional render target to this one.

EDIT: ok looked in your code and you did it actually :stuck_out_tongue: let me think that through.

Second try: When you request multisampling, and your opengl version is <3.2, there is a trick. The framebufferMS has to be copied into the single sample framebuffer in order for it to be used properly (I don’t remember exactly why tbh).
Relevant code is in postFrame.
we use renderer.copyFrameBuffer for that and my guess is that it’s doesn’t copy all the color buffer…
It’s a tricky one because behind we use glBlitFramebufferEXT that copies a frame buffer, and I’m not sure how it works with MRT…
Found that, http://www.gamedev.net/topic/634769-blitting-multiple-render-targets/ not really encouraging.

But to be sure… what’s your opengl version?

EDIT: actually the link I posted could work… we could check that the src and dst framebuffer have the same number of attachement and iterate over them and blit them… that’s going to hinder the perfs for sure though… idk how much though.

We need TXAA…

Thanks for your tips I’ll look into that.
I have a AMD R9 290X and it supports OpenGL 4.5.

mhhhhh maybe it’s not that then…try to debug and see in what code block you go through in the FPP.