# Trying to convert shadertoy 'ping pong feedback' buffer(?) to Processing

**URL:** <https://discourse.processing.org/t/trying-to-convert-shadertoy-ping-pong-feedback-buffer-to-processing/43863>\
**Category:** Coding Questions\
**Created:** [February 8, 2024, 4:57pm UTC](https://discourse.processing.org/t/trying-to-convert-shadertoy-ping-pong-feedback-buffer-to-processing/43863 "2024-02-08T16:57:32Z")\
**Posts on this page:** 1\
**Showing post:** 13

<div class="post-metadata">

**Author:** ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)\
**Post date:** [February 20, 2024, 7:20pm UTC](https://discourse.processing.org/t/trying-to-convert-shadertoy-ping-pong-feedback-buffer-to-processing/43863/13 "2024-02-20T19:20:32Z")

</div>

Hi @scudly ,

Thanks for your helpful reply. I really learn a lot. You mention about the precision difference of the Shadertoy and Processing, which, I think, is critical to the conversion of the Shadertoy shader to Processing. I have experienced similar case and posed in [here](https://discourse.processing.org/t/shadertoy-to-processing-color-channel-storage-issue/43965).

> I assume that shadertoy uses full 32-bit floats for the buffer/channels.

Does this mean the temporary texture map to swap and be written between different passes is a 32-bit-float map, which it is something like this in some game engine such as the Unity (just to get an analogy), the Processing only supports 8-bit-float map as the temporary map to let processing’s shader to write ? but the processing temporary texture map has alpha channel, so this is a different topic?

I am not quite getting this:

> That shadertoy stores a value in the red channel and a velocity in the green.

> Processing always multiplies the rgb by the alpha channel, so to get data out of a shader, you have to always set alpha to 1. This implies that you can get at most 24 bits of data per pixel out of a shader.

I am a bit confused, would you give a bit more information on this or some readings? 🙂

In addition, I got the Processing4 version and run the code. It seems to get a very low frame rate on my poor 5 years old surface laptop. 😂Is this causing by the new string array feature?

This is rendering on1200x900.

 ![p-4_1200x900](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/1/f/1f8ad5e6fd6a76939b602c514e0827f39f625065.jpeg)

This is rendering on 800x600:

 ![p-3_800x600](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/a/6/a63d0444965178e439c4500f423603830afc6bd4.jpeg)

This is rendering on a decent desktop, but the frame rate seems to get limiting on 30 fps:

 ![p-2](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/a/b/abd4fd317dd730677e458e13bc79d38f75aa6976.jpeg)

And the spreading ripples will turn into rectangle shape from its initial circle shape , so is it the processing’s problem on executing the shader?

 ![p-1a](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/3/d/3ddb6f6f2cea6946c11ac810c35bb7523bd56602.jpeg)  
 ![p-1b](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/4/2/42d2abba6b545b93c3abd04f8ae8f39681626c2c.jpeg)

Inspired by your code, I am trying to run my code on the processing 3.5 with a little bit modification ( just trying not to modify much on the original shadertoy code) but it seems to get some channel issues. Is there a way to fix? 🙂

 ![p-6_1200x900](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/b/6/b6f510a771e9203075efc4e9c260b7c57e955672.jpeg)  
 ![p-5_800x600](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/c/d/cd7527f5e195118f2dbc714c3a8b54d59854d5f3.jpeg)  
The frame rate seems to be very good with the shader file loading method.

Here is my code:  
the Processing code:

```auto
PShader BufferAShader;
PShader BufferBShader;
PShader BindShader;
PGraphics buffer1, buffer2, buffer3;
int looping = 0;

void setup()
{
  size(800, 600, P3D);
  
  buffer1 = createGraphics(width, height, P2D);
  buffer1.noSmooth();
  buffer1.beginDraw();
  buffer1.blendMode(REPLACE);
  buffer1.endDraw();
  
  buffer2 = createGraphics(width, height, P2D);
  buffer2.noSmooth();
  buffer2.beginDraw();
  buffer2.blendMode(REPLACE);
  buffer2.endDraw();
  
  buffer3 = createGraphics(width, height, P2D);
  buffer3.noSmooth();
  buffer3.beginDraw();
  buffer3.blendMode(REPLACE);
  buffer3.endDraw();
  
  
  BufferAShader = loadShader("FiniteWater_BufferA.glsl");
  BufferAShader.set("iResolution", float(width), float(height));

  BufferBShader = loadShader("FiniteWater_BufferB.glsl");
  BufferBShader.set("iResolution", float(width), float(height));
  
  BindShader = loadShader("FiniteWater_Binding.glsl");
  BindShader.set("iResolution", float(width), float(height));
}

void draw()
{  
  PGraphics buffTemp = null;
  PGraphics buffLast = null;
  PGraphics buffLast2 = null;
  
  int loopSize = 3;
  
  PGraphics[] buffs = {buffer1, buffer2, buffer3};
  
  buffTemp = buffs[looping%loopSize];
  buffLast = buffs[(looping+1)%loopSize];
  buffLast2 = buffs[(looping+2)%loopSize];
  
  looping++;
  
  //println((looping+1)%loopSize);

  BufferAShader.set("iTime", millis()/1000.);

  if(mousePressed)
  {
    BufferAShader.set("mouseInput", (float)mouseX, (float)height-mouseY);
  }
  else 
  {
    BufferAShader.set("mouseInput", -1, (float)height-mouseY);
  }
  
  BufferAShader.set("iChannel0", buffLast); 
  buffLast.beginDraw();
  buffLast.shader(BufferAShader); 
  buffLast.rect(0, 0, width, height);
  buffLast.endDraw();
  
  
  BufferBShader.set("iChannel0", buffLast);
  buffLast2.beginDraw();
  buffLast2.shader(BufferBShader);
  buffLast2.rect(0, 0, width, height);
  buffLast2.endDraw();

  BindShader.set("iChannel0", buffLast2);
  //BindShader.set("iChannel0", buffLast);
  buffTemp.beginDraw();
  buffTemp.shader(BindShader);
  buffTemp.rect(0, 0, width, height);
  buffTemp.endDraw();
  
  image(buffTemp, 0, 0);

}

```

FiniteWater\_Binding.glsl:

```auto
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

#define PROCESSING_COLOR_SHADER

uniform vec2 iResolution;
uniform sampler2D iChannel0;

void main()
{
  vec2 uv = gl_FragCoord.xy / iResolution.xy;
  //gl_FragColor = vec4(2.0*texture2D(iChannel0, uv).x + 0.5);
  gl_FragColor = vec4(clamp(texture2D(iChannel0, uv).x, 0.0, .998));
}

```

FiniteWater\_BufferA.glsl:

```auto
#ifdef GL_ES
precision highp float;
#endif

#define PROCESSING_COLOR_SHADER

uniform float iTime;
uniform vec2 iResolution;

uniform vec2 mouseInput;
//vec4 iMouse = vec4(mouseInput, 0.0, 0.0);
vec4 iMouse = vec4(mouseInput, mouseInput);
uniform sampler2D iChannel0;

void main()
{
  // Mouse excitation
  vec2 r = gl_FragCoord.xy - iMouse.xy;
  float d = 0.001 * dot(r, r);
  if(iMouse.z > 0.0 && d < 0.05)
  {
    gl_FragColor = vec4(0.0, 0.2, 0.0, 0.0);
    return;
  }
  
  // Periodic excitation
  r = gl_FragCoord.xy - vec2(50, 70);
  d = 0.001 * dot(r, r);
  if(mod(iTime, 0.5) < 0.1 && d < 0.05)
  {
    gl_FragColor = vec4(0.0, 0.1, 0.0, 0.0);
    return;  
  }
  
  // just copy
  vec2 uv = gl_FragCoord.xy / iResolution.xy;
  //gl_FragColor = texture2D(iChannel0, uv);
  gl_FragColor = clamp(texture2D(iChannel0, uv), 0.0, 0.998);

}

```

FiniteWater\_BufferB.glsl:

```auto
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

// Type of shader expected by Processing
#define PROCESSING_COLOR_SHADER

uniform vec2 iResolution;
uniform sampler2D iChannel0;

void main()
{
  float dx = 1.0 / iResolution.x;
  float dy = 1.0 / iResolution.y;
  vec2 uv = gl_FragCoord.xy / iResolution.xy;
  
  vec2 udu = texture2D(iChannel0, uv).xy;
  // old elevation
  float u = udu.x;
  // old velocity
  float du = udu.y;
  
  // Finite differences
  float ux = texture2D(iChannel0, vec2(uv.x + dx, uv.y)).x;
  float umx = texture2D(iChannel0, vec2(uv.x - dx, uv.y)).x;
  float uy = texture2D(iChannel0, vec2(uv.x, uv.y + dy)).x;
  float umy = texture2D(iChannel0, vec2(uv.x, uv.y - dy)).x;
  
  // new elevation
  float nu = u + du + 0.5*(umx+ux+umy+uy-4.0*u);
  nu = 0.99*nu;

  
  nu = clamp(nu, 0.0, 1.0);
  
  // store elevation and velocity
  gl_FragColor = vec4((1.0-nu)*0.998, (1.0-(nu-u))*0.998, 0.0, 1.0);
  //gl_FragColor = vec4((1.0-nu)*0.998, (1.0-(nu-u))*0.998, 0.0, 0.0);
  //gl_FragColor = vec4(nu, nu-u, 0.0, 0.0);

}

```

---

_[View the full topic](https://discourse.processing.org/t/trying-to-convert-shadertoy-ping-pong-feedback-buffer-to-processing/43863)._
