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;
}
}
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.
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.
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
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
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.