[SOLVED] Second filter pass not rendered

Hi,

I want to create my own blur filter. For this I need 2 passes (horizontal and vertical). I don’t know what I am doing wrong, but it seams that only the first pass is drawn.

If I comment out this line

postRenderPasses.add(horizontalBlur);

then the second pass will be drawn.

Here is my current code:

public class BlurFilter extends Filter
{
	private final float downSamplingFactor = 1;
	private int screenWidth;
	private int screenHeight;
	private final float blurScale = 1.5f;
	private Material vBlurMat;
	private Material hBlurMat;
	private Pass horizontalBlur = new Pass();
	private Pass verticalalBlur = new Pass();

	@Override
	protected Material getMaterial()
	{
		return material;
	}

	@Override
	protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h)
	{
		screenWidth = (int) Math.max(1, w / downSamplingFactor);
		screenHeight = (int) Math.max(1, h / downSamplingFactor);

		postRenderPasses = new ArrayList<Pass>();

		// configuring horizontal blur pass
		hBlurMat = new Material(manager, "MatDefs/Post/Blur/GaussianBlurH.j3md");
		horizontalBlur = new Pass()
		{
			@Override
			public void beforeRender()
			{
				hBlurMat.setFloat("Size", screenWidth);
				hBlurMat.setFloat("Scale", blurScale);
			}
		};

		horizontalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, hBlurMat);
		postRenderPasses.add(horizontalBlur);

		// configuring vertical blur pass
		vBlurMat = new Material(manager, "MatDefs/Post/Blur/GaussianBlurV.j3md");
		verticalalBlur = new Pass()
		{
			@Override
			public boolean requiresSceneAsTexture()
			{
				return false;
			}

			@Override
			public void beforeRender()
			{
				vBlurMat.setTexture("Texture", horizontalBlur.getRenderedTexture());
				vBlurMat.setFloat("Size", screenHeight);
				vBlurMat.setFloat("Scale", blurScale);
			}
		};

		verticalalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, vBlurMat);
		postRenderPasses.add(verticalalBlur);

		// set the final material
		material = vBlurMat;
	}
}

The bloom filter blurs in separate horizontal and vertical passes. Did you look at that as an example?

yes I did but I don’t get it :confused:

Heheh… me either. But I thought I’d check. :slight_smile:

on the top of my head the forst pass you declare, the horizontal one, need the implement the requiresSceneAsTexture and return true.

this method (requiresSceneAsTexture) already returns true by default so I is not necessary to override it

I think you need to add a new “final material” that you pass the result of the verticalBlur to, I think when the final material is used the vBlurMat.setTexture("Texture", horizontalBlur.getRenderedTexture()); is not the same ‘pass’ so it is not getting that texture.

see the bloomFilter …

//final material
        material = new Material(manager, "Common/MatDefs/Post/BloomFinal.j3md");
        material.setTexture("BloomTex", verticalalBlur.getRenderedTexture());

I tried that way with an pass through shader.I used post.vert form jme and build my own post.frag/post.j3md.

	// final material
	material = new Material(manager, "MatDefs/Post/Post.j3md");
	material.setTexture("FinalTexture", verticalalBlur.getRenderedTexture());

But it is the same result, only the first pass is visible. :confused:

http://www.alrik-online.de/alrik/screens/qb%202016-03-02%2010-00-51-933.png

Or… you misread.

or I am so sorry, you are right! I’ve tried it but the problem still exists.

Now it looks like this

	horizontalBlur = new Pass()
	{
		@Override
		public boolean requiresSceneAsTexture()
		{
			return true;
		}

		@Override
		public void beforeRender()
		{
			// hBlurMat.setTexture("Texture", getRenderedTexture());
			hBlurMat.setFloat("Size", screenWidth);
			hBlurMat.setFloat("Scale", blurScale);
		}
	};

Yeah it may not be your issue though, but you’ll need this at some point.

can you repost your code, including the new final material lines. I’ve done almost exactly the same thing in the past few weeks and ran into very similar problems (which i eventually solved)

edit: … what im thinking is hopefully when you used

// final material
	material = new Material(manager, "MatDefs/Post/Post.j3md");
	material.setTexture("FinalTexture", verticalalBlur.getRenderedTexture());

you didn’t set material to be the final material by mistake, or similar. These are the sorts of silly mistakes I glaze over when debugging quickly.

This is my current code. But I don’t get it what you mean with “you didn’t set material to be the final material”

public class BlurFilter extends Filter
{
	private final float downSamplingFactor = 1;
	private int screenWidth;
	private int screenHeight;
	private final float blurScale = 1.5f;
	private Material vBlurMat;
	private Material hBlurMat;
	private Pass horizontalBlur = new Pass();
	private Pass verticalalBlur = new Pass();

	@Override
	protected Material getMaterial()
	{
		return material;
	}

	@Override
	protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h)
	{
		screenWidth = (int) Math.max(1, w / downSamplingFactor);
		screenHeight = (int) Math.max(1, h / downSamplingFactor);

		postRenderPasses = new ArrayList<Pass>();

		// configuring horizontal blur pass
		hBlurMat = new Material(manager, "MatDefs/Post/Blur/GaussianBlurH.j3md");
		horizontalBlur = new Pass()
		{
			@Override
			public boolean requiresSceneAsTexture()
			{
				return true;
			}

			@Override
			public void beforeRender()
			{
				hBlurMat.setFloat("Size", screenWidth);
				hBlurMat.setFloat("Scale", blurScale);
			}
		};

		horizontalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, hBlurMat);
		postRenderPasses.add(horizontalBlur);

		// configuring vertical blur pass
		vBlurMat = new Material(manager, "MatDefs/Post/Blur/GaussianBlurV.j3md");
		verticalalBlur = new Pass()
		{
			@Override
			public void beforeRender()
			{
				vBlurMat.setTexture("Texture", horizontalBlur.getRenderedTexture());
				vBlurMat.setFloat("Size", screenHeight);
				vBlurMat.setFloat("Scale", blurScale);
			}
		};

		verticalalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, vBlurMat);
		postRenderPasses.add(verticalalBlur);

		// final material
		material = new Material(manager, "MatDefs/Post/Post.j3md");
		material.setTexture("FinalTexture", verticalalBlur.getRenderedTexture());
	}
}

OK this is working :


public class BlurFilter extends Filter {

    private final float downSamplingFactor = 1;
    private int screenWidth;
    private int screenHeight;
    private final float blurScale = 1.5f;    
    private Material hBlurMat;
    private Pass horizontalBlur = new Pass();
    
    @Override
    protected Material getMaterial() {
        return material;
    }

    @Override
    protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
        screenWidth = (int) Math.max(1, w / downSamplingFactor);
        screenHeight = (int) Math.max(1, h / downSamplingFactor);

        postRenderPasses = new ArrayList<Pass>();

        // configuring horizontal blur pass
        hBlurMat = new Material(manager, "Common/MatDefs/Blur/HGaussianBlur.j3md");
        horizontalBlur = new Pass() {

            @Override
            public boolean requiresSceneAsTexture() {
                return true;
            }

            @Override
            public void beforeRender() {
                hBlurMat.setFloat("Size", screenWidth);
                hBlurMat.setFloat("Scale", blurScale);
            }
        };

        horizontalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, hBlurMat);
        postRenderPasses.add(horizontalBlur);

        // configuring vertical blur pass
        material = new Material(manager, "Common/MatDefs/Blur/VGaussianBlur.j3md");

        material.setTexture("Texture", horizontalBlur.getRenderedTexture());
        material.setFloat("Size", screenHeight);
        material.setFloat("Scale", blurScale);

    }

    @Override
    protected boolean isRequiresSceneTexture() {
        return false;
    }

}

replace the mats with your own mats (I replaced them with stock blur shaders to test.
I don’t have a lot of time right now, but I’ll come back later to explain why and how it works

1 Like

I was wrong, what you had was fine, I just didnt read it carefully enough, sorry dude

np :smile:

I’ve tackled this problem 3 or 4 times now, always starting with Bloom and never getting it working till my last attempt, it is frustrating as hell, so I was just throwing everything I could think of at it… damn post pass filter bs texture sceneTextures false true final material blahaeoahdohqwohgohwohg

Btw. WTH is going on if I enable multisampling?!

filterPostProcessor.setNumSamples(6);

Its the same problem that still exists in one of my previous posts!

=> Possible bug: DoF (GLSL 1.5) + MSAA - #23 by alrik

Could you wrap up a test case?

Here is the test case. Its a modified copy of the cross hatch filter test.
It works without MSAA. If MSAA enabled it won’t work and I also got a NPE when toggling the filter via space key.

GPU: AMD Radeon R9 290X @ driver ver: 15.20.1062

http://alrik-online.de/alrik/java/postFilterMSAATestCase.zip

1 Like