Recently, I developed a basic fragment shader with THREE.js. The shader essentially takes every pixel's coordinate, modifies the x component by adding a value (looping back to 0 if it exceeds 1), and then retrieves the background image color at this new location. As a result, the background image shifts over and wraps around when it goes off-screen. However, a puzzling issue arises occasionally where a dark line appears along the shifted edge of the image:
Below is the snippet of code I implemented:
var vertexShader = `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
var fragmentShader = `
varying vec2 vUv;
uniform sampler2D background;
void main() {
float x = mod(vUv.x + 0.47, 1.0);
float y = vUv.y;
gl_FragColor = texture(background, vec2(x, y));
}
`;
$(document).ready(function() {
var plotElement = $("#plot");
var scene = new THREE.Scene();
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.OrthographicCamera(-0.5, 0.5, 0.5, -0.5, 0, 1000);
renderer.setSize(500, 500);
plotElement.append(renderer.domElement);
var background = new THREE.TextureLoader().load('https://wearablewearyphase.davidbrock1.repl.co/background.png');
var material = new THREE.ShaderMaterial({
vertexShader: vertexShader,
fragmentShader: fragmentShader,
uniforms: {
background: {
value: background
},
},
});
geom = new THREE.PlaneBufferGeometry(1, 1);
mesh = new THREE.Mesh(geom, material);
scene.add(mesh);
camera.z = 1;
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
});
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r118/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div id="plot"></div>
</body>
</html>
I am certain that this line does not exist in the original image:
The boundary should remain invisible as the colors are consistent on both sides. Moreover, the appearance of the line is specific to certain shift distances (such as 49% and 47%, but not 50% or 48%). I noticed that enlarging the output beyond the background image size eliminates the line, yet I prefer not to resort to this solution.
What exactly causes this line to appear, and how can I prevent it?
Note: The utilization of the "mod" function was merely an example. Initially, another program (another shader) calculated the x and y coordinates for each pixel and stored them in a separate texture as red and green components. Subsequently, the fragment shader sought these coordinates within the image.
My encounter with this issue arose during my attempt to create an animation akin to this. Undesirable lines started cropping up all across the screen, compromising the visual appeal of the project.