If you want to provide additional information like the offset amount, it would be a common practice.
uniform float offset1;
uniform float offset2;
uniform sampler2D texture;
varying vec2 vUv; // vertex uv
void main() {
vec2 uv = vUv;
float red = texture2D(texture, vec2(uv.x, uv.y + offset1)).r;
float green = texture2D(texture, uv).g;
float blue = texture2D(texture, vec2(uv.x, uv.y + offset2)).b;
float alpha = texture2D(texture, uv).a;
gl_FragColor = vec4(vec3(red, green, blue), alpha);
}
To adjust this in JavaScript, you can do something like:
const uniforms = {
offset1: { value: 0 },
offset2: { value: 0 },
...
};
...
uniforms.offset1.value = 2 / textureHeight;
uniforms.offset2.value = -2 / textureHeight;
A slight modification could look like this:
uniform vec2 channelOffsets[4];
uniform vec4 channelMult[4];
uniform sampler2D texture;
varying vec2 vUv; // vertex uv
void main() {
vec2 uv = vUv;
vec4 channel0 = texture2D(texture, uv + channelOffset[0]);
vec4 channel1 = texture2D(texture, uv + channelOffset[1]);
vec4 channel2 = texture2D(texture, uv + channelOffset[2]);
vec4 channel3 = texture2D(texture, uv + channelOffset[3]);
gl_FragColor =
channelMult[0] * channel0 +
channelMult[1] * channel1 +
channelMult[2] * channel2 +
channelMult[3] * channel3 ;
}
To set them:
const uniforms = {
channelOffsets: { value: [
new THREE.Vector2(),
new THREE.Vector2(),
new THREE.Vector2(),
new THREE.Vector2(),
]},
channelMults: { value: [
new THREE.Vector4(1, 0, 0, 0),
new THREE.Vector4(0, 1, 0, 0),
new THREE.Vector4(0, 0, 1, 0),
new THREE.Vector4(0, 0, 0, 1),
]},
....
}
...
uniforms.channelOffsets.value[0].y = -2 / textureHeight;
uniforms.channelOffsets.value[2].y = 2 / textureHeight;
For a more flexible approach, using texture matrices instead of offsets and combining matrix transformations for more advanced effects is recommended.