[Solved] How to downsample the screen texture in a filter?

I haven’t been able to find much documentation on filters at all I can’t seem to figure out how this should work.

What I’ve pieced together from the BloomFilter which doesn’t seem to render anything when run:

protected void initFilter(AssetManager assetManager, RenderManager rm, ViewPort vp, final int w, final int h) {
    screenWidth = (int) Math.max(1, (w / downSamplingFactor));
    screenHeight = (int) Math.max(1, (h / downSamplingFactor));
    Material blank = new Material(assetManager, "assets/filters/lensflare/Blank.j3md");
    //I think I may need to make a new pass that renders at a lower res?
    downscalepass = new Pass();
    downscalepass.init(rm.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth);
    //and then render it again?
    material = new Material(assetManager, "assets/filters/lensflare/Blank.j3md");
    Pass main = new Pass(){
	public void beforeRender() {
	    material.setTexture("Texture", downscalepass.getRenderedTexture());
    main.init(rm.getRenderer(), w, h, Format.RGBA8, Format.Depth);

Blank.frag is pretty blank for testing:

#import "Common/ShaderLib/MultiSample.glsllib"

uniform sampler2D m_Texture;

in vec2 texCoord;
out vec4 fragColor;

void main() {
    fragColor = texture2D(m_Texture, texCoord);

The wiki only explains how to add filters to the game and not how they’re actually supposed to be set up when making custom ones so I’m kind of at a loss here.

Any help or tip would be appreciated.

You have to add the pass to a collection called postPasses or something like that (can’t look at the code right now).
Look for a collection like that in Filter.java

You’re right, I somehow missed that (postRenderPasses). Thanks!

It didn’t start to work right away, since I forgot a few other things but starting from the BloomFilter and removing all blur related stuff seems to have solved it.

Also requiresSceneAsTexture looks important.

For future use, a filter that does only downsampling (sorry bout the indentation mess):


public class PixelationFilter extends Filter {
    private float downSamplingFactor = 4;
    private Pass downScalePass;
    private Material extractMat;
    private int screenWidth;
    private int screenHeight;    
    private RenderManager renderManager;
    private ViewPort viewPort;

    private AssetManager assetManager;
    private int initalWidth;
    private int initalHeight;
    public PixelationFilter() {

    protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
        this.renderManager = renderManager;
        this.viewPort = vp;

        this.assetManager = manager;
        screenWidth = (int) Math.max(1, (w / downSamplingFactor));
        screenHeight = (int) Math.max(1, (h / downSamplingFactor));
        postRenderPasses = new ArrayList<Pass>();
        extractMat = new Material(manager, "assets/filters/Blank.j3md");
        downScalePass = new Pass() {
            public boolean requiresSceneAsTexture() {
                return true;

        downScalePass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, extractMat);
        material = new Material(manager, "assets/filters/Blank.j3md");
        material.setTexture("Texture2", downScalePass.getRenderedTexture());

    protected void reInitFilter() {
        initFilter(assetManager, renderManager, viewPort, initalWidth, initalHeight);

    protected void cleanUpFilter(Renderer r) {

    public float getFactor() {
        return downSamplingFactor;

    public void setFactor(float downSamplingFactor) {
        this.downSamplingFactor = downSamplingFactor;
        if (assetManager != null)

	protected Material getMaterial() {
		return material;


uniform sampler2D m_Texture;

#ifdef TEX2
	uniform sampler2D m_Texture2;

varying vec2 texCoord;

void main() {
	#ifdef TEX2
		gl_FragColor = texture2D(m_Texture2, texCoord);
		gl_FragColor = texture2D(m_Texture, texCoord);


MaterialDef Fade {

    MaterialParameters {
        Int NumSamples
        Texture2D Texture
        Texture2D Texture2

    Technique {
        VertexShader GLSL100:   Common/MatDefs/Post/Post.vert
        FragmentShader GLSL100: Common/MatDefs/Pixelate/Pixelate.frag

        WorldParameters {
        Defines {
        	TEX2: Texture2

Probably not the best idea but the default pass always gets the scene as the “Texture” param and overwrites the passed one.