Hi my friends,
I am trying to convert this shadertoy effect to the porcessing with shaders. In the shadertoy solution, it appears the Buffer A tap loads
a channel with a buffer b and the Buffer C tap loads channel with a buffer a, which they seems to interlinked to each other. I did a bit research with my limited knowledge this seems to be the topics on ping pong feedback, frame buffer object and texture swapping technique etc., which I am not very sure how to implement in my case. Sorry, if I am putting the wrong term here.
My conversion method borrows some steps from RipplesP5, but the result seem quite different.
my conversion on processing:
the shadertoy:
The processing one seems the pixel is not able to recover to its previous state.
Does anyone have some clue on solve this?
Here is my code:
Processing:
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++;
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_BufferA.glsl:
#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);
}
FiniteWater_BufferB.glsl:
#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;
// store elevation and velocity
gl_FragColor = vec4(nu, nu-u, 0.0, 0.0);
}
FiniteWater_Binding.glsl:
#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);
}