Dear community,
I am setting up a small glsl project using Threejs to make image distortions based on mouse movement. Whenever the mouse moves left or right it is the point to update the uvmap of the image with the corresponding negative or possitive red and green values.
I’m using the setup for feedback from this (p5.js Web Editor) p5.js.
But then instead of video input I’m first rendering a little blurred circle to a canvas with the corresponding red and green values.
The issue I’m facing is that I can not find a way to render negative red and green values in my output buffertexture (used as rendertarget like in the example above).
Which means that my cursos will only displace my final image to the right and up, instead of also having the possibillity to move it down and left.
cheers!!!
Sjoes
Here is some of the code:
setup for the bufershader
bufferTextureSetup(){
this.textureA = new THREE.WebGLRenderTarget(
this.width, this.height,{
minFilter: THREE.LinearFilter,
maxFilter: THREE.LinearFilter,
format: THREE.RGBAFormat
})
this.textureB = new THREE.WebGLRenderTarget(
this.width, this.height,{
minFilter: THREE.LinearFilter,
maxFilter: THREE.LinearFilter,
format: THREE.RGBAFormat
})
this.bufferMaterial = new THREE.ShaderMaterial({
extensions: {
derivatives: "#extension GL_OES_standard_derivatives : enable"
},
side: THREE.DoubleSide,
uniforms: {
ubufferTexture: { value: this.textureA.texture},
ures : { type : 'v2', value: new THREE.Vector2(this.width, this.height)},
videoTexture: { value: new THREE.TextureLoader().load(ocean)},
uTexture2: {value: null},
uValue: {type : 'v2', value : new THREE.Vector2(0,0)},
time: {type: "f", value: Math.random() * Math.PI * 2 + Math.PI },
// refresh: {value: new THREE.Vector2(0.95, 0.99)}
},
vertexShader: vertex,
fragmentShader: frag
});
// var buffer = this.bufferMaterial;
// document.body.onkeyup = function(e, buffer) {
// if (e.key == " " ||
// e.code == "Space" ||
// e.keyCode == 32
// ) {
// buffer.uniforms.refresh.x = 0.9;
// buffer.uniforms.refresh.y = 0.5;
// }
// }
this.bufferPlane = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight);
this.bufferObject = new THREE.Mesh(this.bufferPlane, this.bufferMaterial)
this.bufferScene.add(this.bufferObject);
}
setup for the mousetracking:
trackMousePos(){
if(Math.abs(this.mouse.x - this.prevmouse.x)<1 &&
Math.abs(this.mouse.y - this.prevmouse.y) <1){
this.m.color.r = 0;
this.m.color.g = 0;
} else{
this.circle_color.x = this.mouse.x - this.prevmouse.x;
this.circle_color.y = this.mouse.y - this.prevmouse.y;
// let x = Math.sign(this.mouse.x - this.prevmouse.x);
// let y = Math.sign(this.mouse.y - this.prevmouse.y);
this.bufferMaterial.uniforms.uValue.x = Math.sign(this.mouse.x - this.prevmouse.x);
this.bufferMaterial.uniforms.uValue.y = Math.sign(this.mouse.y - this.prevmouse.y);
// console.log(this.bufferMaterial.uniforms.uValue.x, this.bufferMaterial.uniforms.uValue.y);
// giving the blur circle the red and green colors here.
this.m.color.r = Math.abs(0.1*(this.mouse.x - this.prevmouse.x));//this.circle_color.x;
this.m.color.g = Math.abs(0.1*(this.mouse.y - this.prevmouse.y));//this.circle_color.y;
this.setNewWave(this.mouse.x, this.mouse.y, this.currentWave);
this.currentWave = (this.currentWave +1)%this.max;
// console.log(this.currentWave);
}
this.prevmouse.x = this.mouse.x;
this.prevmouse.y = this.mouse.y;
}
the buffer fragmentshader experiment:
uniform vec2 ures;//The width and height of our screen
uniform sampler2D ubufferTexture;//Our input texture
uniform sampler2D videoTexture;
uniform vec2 uValue;
uniform sampler2D uTexture2;
uniform float time;
// uniform vec2 refresh;
void main() {
vec2 st = gl_FragCoord.xy / ures;
vec2 uv = st - vec2(0.5);
// uv *= 0.995;
uv += vec2(0.5);
// uv *= vec2(0.5);
// uv = uv*2.0 - 1.0;
//vec4 sum = texture2D(ubufferTexture, uv);
vec4 src = texture2D(videoTexture, uv);
src.r = src.r + 0.5*uv.x;
src.g = src.g + 0.5*uv.y;
// uv *= 0.99;
// uv += 0.005;
vec4 sum = texture2D(ubufferTexture, uv);
// sum.rgb = mix(sum.rbg, src.rgb, 0.01);
// sum -= 0.5;
// sum += 0.5;
// src -= 0.5;
// uv.xy = uv.xy + sum.xy;
// uv.x = 2.0*src.r + uv.x;
// uv.y = 2.0*src.g + uv.y;
// sum = 0.5*sum + 0.5;
sum.r = src.r + sum.r;
sum.g = src.g + sum.g;
// sum *= 0.5;
// uv += 4.0*sum.xy;
// uv *= 0.125;
// uv.xy = sum.xy + uv.xy;
// uv *= 0.5;
// sum *= 1.01;
// vec4 color = vec4(uv.xy, 1.0, 1.0);
gl_FragColor = sum;
}
and the final shader.
Here the uniform uDisplacement gets the rendered output of the buffermaterial/bufferscene.
uniform float time;
uniform float progress;
uniform sampler2D uTexture;
uniform sampler2D uPrevTexture;
uniform sampler2D uDisplacement;
uniform vec4 resolution;
varying vec2 vUv;
varying vec3 vPosition;
float PI = 3.141592653589793238;
void main() {
vec2 newUV = (vUv - vec2(0.5))*resolution.zw + vec2(0.5);
vec4 displace = texture2D(uDisplacement, vUv);
displace *= 0.5;
// displace = (displace - 0.5) * 2.0;
vec4 color = texture2D(uTexture, vUv+displace.xy);
// vec2 newUV = (vUv - vec2(0.5))*resolution.zw + vec2(0.5);
gl_FragColor = vec4(displace.xy, 0.0, 1.0);
}