Writing to a 16 bit image buffer from a shader?

Continuing my Shadertoy importing, I now need to know how to get a shader to render to a 16 bit image texture (rather than directly to the screen). This texture then needs to be ‘fed’ back into the shader as a texture source.

The texture is acting a ‘height’ buffer - the same way Shadertoy has this implemented, for example, ‘bufA’ in this,

This would be the first pass. The next pass would be calculating final color and rendering to the screen.

Any help appreciated :slight_smile:


you should look into Filters and FilterPostProcessor.
look into the BloomFilter.

will do thanks…

Hi nehon,
I hacked the BloomFilter and got the basic pipeline working - but the results look wrong. Here’s a comparison of results,

Here’s the original shader,

Like I said this is the basic process,

  1. Pass One - generate data from a shader and store to a 16 bit texture buffer (buffer A).
  2. Make sure this texture is accessible from same shader.
  3. Final render pass - simply display results with any color changes.

I’m suspecting that my buffer isn’t in the right format - or isn’t being properly read / written. As far as I know shadertoy uses 16 bit signed buffers. I used RGBA16F for mine. I’m hoping that is correct.

Below is my code for the Filter I’m using.

public class PurpleFilter extends Filter {

private float downSamplingFactor = 1;
private Pass bufApass = new Pass();
private Pass finalPass = new Pass();
private Material bufAmat;
private Material finalMat;
private int screenWidth;
private int screenHeight;    
private RenderManager renderManager;
private ViewPort viewPort;
private AssetManager assetManager;
private int initalWidth;
private int initalHeight;

float mytime =0;
public PurpleFilter() {
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
    this.renderManager = renderManager;
    this.viewPort = vp;
    this.assetManager = manager;
    this.initalWidth = w;
    this.initalHeight = h;
    screenWidth = (int) Math.max(1, (w / downSamplingFactor));
    screenHeight = (int) Math.max(1, (h / downSamplingFactor));
    //    System.out.println(screenWidth + " " + screenHeight);
    postRenderPasses = new ArrayList<Pass>();
    //buffer A pass
    bufAmat = new Material(manager, "MatDefs/PurpleBufA.j3md");
    bufApass = new Pass() {
        public void beforeRender() {
            bufAmat.setFloat("t", mytime);
            bufAmat.setTexture("Texture", bufApass.getRenderedTexture());
    bufApass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA16F, Format.Depth, 1, bufAmat);
    //final pass
    finalMat = new Material(manager, "MatDefs/PurpleFinal.j3md");
    finalPass = new Pass() {
        public void beforeRender() {

    finalPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA16F, Format.Depth, 1, finalMat);
    //final material
    material = new Material(manager, "MatDefs/PurpleFinal.j3md");
    material.setTexture("finalRender", finalPass.getRenderedTexture());
protected Material getMaterial() {
    return material;