Strange Behavior When Encapsulating Image in Fragment Shader

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.

Answer №1

The reason for this phenomenon is due to how the fragment shader blends values across pixels. As one pixel column reaches a value of 1.0, the following column compresses the entirety of your texture between 1.0 - 0.0, and the subsequent column resets back to 0.0.

To avoid this issue, a simple solution is to adjust the wrapping mode of your texture to THREE.RepeatWrapping and remove the need for using mod(). This way, when your texture exceeds a value of 1.0, it will seamlessly repeat from the initial position on the left.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am attempting to retrieve the aria-expanded value using JavaScript, however, I keep receiving an "undefined" response

I'm attempting to dynamically change the class of a <span> element based on the value of the attribute aria-expanded. However, I am encountering an issue where it returns "undefined" instead of the expected value of true or false. Below is the ...

Enhance your app with the seamless navigation experience using Ionic 2

As a beginner in Angular2, Ionic2, NodeJS ... I am experimenting with writing some code to learn. In my journey, I attempted to create a screen with 3 tabs and a menuToggle. When the application is launched, clicking the menuToggle button on the first tab ...

Having trouble with installing node-steam on your node.js server?

I recently attempted to install node-steam and encountered a significant error. Can anyone provide guidance on how to resolve this issue? Is the mistake on my end? ... gyp ERR! configure error gyp ERR! stack Error: Can't find Python ex ...

Click on ng-click to sort through the blog entries

Currently, I am in the process of developing a blog utilizing AngularJS and JSON. Nearly everything is functioning as expected except for one particular filter item. As I am relatively new to Angular, it presents a bit of a challenge for me. The issue ari ...

The hyperlink element has been added but is not clickable

I'm attempting to incorporate a download feature into my webpage using Greasemonkey. Despite successfully adding the new div element to the page, I am encountering an issue where the download window does not open as expected. var iDiv = document.crea ...

A guide to setting a custom icon for the DatePicker component in Material-UI 5

Seeking to incorporate custom Icons from react-feathers, I have implemented a CustomIcon component which returns the desired icon based on the name prop. Below is the code for this component. import React from 'react'; import * as Icon from &apo ...

Ways to extract information from a JavaScript popup window before it closes

I am currently facing the challenge of detecting the existence of a form field in a closed popup window. Unfortunately, I do not have control over the child window, but it is within the same domain as the parent window. I have explored the possibility of ...

The absence of shadows in ThreeJS has been noted

I've been struggling to figure out what's going on with my scene. The shadows aren't being cast correctly and everything appears too bright. I followed the documentation step by step, but I just can't seem to pinpoint the issue. 'u ...

Align the inline text at the center as if it were an inline-block element

Currently working on a design that appears deceptively simple, yet I'm encountering challenges in centering it while keeping the text aligned to the left. https://i.sstatic.net/qhf6p.png In an attempt to have the background span only the actual text ...

Having trouble fixing the '@material-ui/lab' error while working with the newest React update?

My goal is to set up a global alert by following this method: Check out the Sandbox Demo Yet, I encounter an issue with the following error message: ERROR in ./src/components/snackbar/Alert.js 5:0-82 Module not found: Error: Can't resolve '@m ...

The jQuery panel slider magically appears when you click the button, but refuses to disappear

One issue I am facing on my webpage involves a button that triggers a right panel to open using the jquery and modernizr frameworks. The button is positioned at the far right of the screen. When clicked, it slides to the left along with the panel it reveal ...

Looking to display or conceal several divs according to the option selected from a dropdown menu?

I've been searching for a solution to my simple dropdown issue, but haven't had any luck in the forums. This is the code for the dropdown: <select id ="category_faq"> <option value="1">item1</option> <option value= ...

Display a specific tab section upon clicking using jQuery or JavaScript

Hello everyone! I am completely new to JavaScript. I have added a tab slider to my HTML with 3 categories in the tab menu: All, Creative, and Branding. How can I show a div after clicking on one of the list items? I have assigned classes to the list items ...

Issue with Bootstrap Table Style When Using window.print();

The color of my Bootstrap table style is not displaying correctly in the print preview using window.print(). Here is a screenshot showing that the table style is not working properly: https://i.stack.imgur.com/eyxjl.jpg Below is the code I am using: < ...

Attempting to access an HTTP Node server from within an HTTPS environment resulted in an SSL error

I am faced with the challenge of connecting to a socket.io from a React client within a Node server. Both the React client and the location of the Node server (a microservice housed in a separate Docker container alongside a Java container) are operating o ...

Encountering the error message "[TypeError]: Unable to access properties of undefined (reading 'prototype')" when utilizing axios post function in next.js

I am encountering an issue while utilizing the next.js app directory and attempting to make a POST request using axios. const submitHandler = async (e) => { e.preventDefault(); try { const {data} = await axios.post('/api/register&ap ...

Derive the property type based on the type of another property in TypeScript

interface customFeatureType<Properties=any, State=any> { defaultState: State; properties: Properties; analyzeState: (properties: Properties, state: State) => any; } const customFeatureComponent: customFeatureType = { defaultState: { lastN ...

The forkJoin method fails to execute the log lines

I've come up with a solution. private retrieveData() { console.log('Start'); const sub1 = this.http['url1'].get(); const sub2 = this.http['url2'].get(); const sub3 = this.http['url3'].get(); ...

Unable to Get Basic jQuery .load Example to Function

Seeking assistance with a jQuery issue regarding loading HTML snippets into a page. When the snippet contains just HTML, it loads fine. However, when it includes a script, there seems to be an issue. Simplified code provided below for better understandin ...

Error in Express.js application: form fields lose their values

I am currently developing a blogging application using Express, EJS and MongoDB. One of the main features is an "Add New Post" form with an addPost() method in the controller; exports.addPost = (req, res, next) => { const errors = validationResult ...