I urgently need help!

Hello, I need help with the following: I need to make the RGB effect work on all images; that is, it should process each one and apply the same effect to all. I’ve tried several approaches, but I can’t get it to work, or for some reason, everything gets “messed up” and goes from bad to worse. I would greatly appreciate your help! :slight_smile:

Here is the code:

import * as THREE from "three"

import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass.js";

const $img = document.getElementById("texture")
const $image = document.createElement("img")

let camera, scene, renderer, composer, renderPass, customPass
let geometry, material, mesh, texture, uMouse = new THREE.Vector2(0, 0)

const uploadImage = ($image.onload = () => {
	$img.style.opacity = 0

	texture = new THREE.Texture($image)
	texture.needsUpdate = true
  
	toggleAnimations();
	animation();
})

const toggleAnimations = () => {
	 camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10)

	camera.position.z = 1
    
	scene = new THREE.Scene()
  
	geometry = new THREE.PlaneGeometry(0.80, 0.5)
	
	material = new THREE.MeshBasicMaterial({
	  map: texture 
	})
	
	mesh = new THREE.Mesh(geometry, material)
	scene.add(mesh); 
  
	renderer = new THREE.WebGLRenderer({ antialias: true })

	renderer.setSize(window.innerWidth, window.innerHeight)

	renderer.outputEncoding = THREE.sRGBEncoding

	document.body.appendChild(renderer.domElement)
  
	composer = new EffectComposer(renderer)

	renderPass = new RenderPass(scene, camera)

	composer.addPass(renderPass)
  
	const shaderEffect = {
	  uniforms: {
		tDiffuse: { value: null }, 
		resolution: { 
		  value: new THREE.Vector2(1, window.innerHeight / window.innerWidth),
		},
		uMouse: { value: new THREE.Vector2(-10, -10) },

	  },

	  vertexShader: 
	  `varying vec2 vUv;void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0 );}`,

	  fragmentShader: 
	  `uniform float time;
		  uniform sampler2D tDiffuse;
		  uniform vec2 resolution;
		  varying vec2 vUv;
		  uniform vec2 uMouse;
	
		  float circle(vec2 uv, vec2 disc_center, float disc_radius, float border_size) {
			uv -= disc_center;
			uv*=resolution;
			float dist = sqrt(dot(uv, uv));
			return smoothstep(disc_radius+border_size, disc_radius-border_size, dist);
		  }

		  void main()  {
			  vec2 newUV = vUv;
			  float c = circle(vUv, uMouse, 0.0, 0.2);
			  float r = texture2D(tDiffuse, newUV.xy += c * (0.1 * .5)).x;
			  float g = texture2D(tDiffuse, newUV.xy += c * (0.1 * .525)).y;
			  float b = texture2D(tDiffuse, newUV.xy += c * (0.1 * .55)).z;
			  vec4 color = vec4(r, g, b, 1.);
  
			  gl_FragColor = color;
		  }`,

	};
  
	customPass = new ShaderPass(shaderEffect);

	customPass.renderToScreen = true;
	composer.addPass(customPass);
}

const animation = () => {
	customPass.uniforms.uMouse.value = uMouse; 
	requestAnimationFrame(animation); 
	composer.render(); 
}

$image.src = $img.src

const handleCursorAnimation = () => {
	document.addEventListener("mousemove", (e) => {
		uMouse.x = e.clientX / window.innerWidth;
		uMouse.y = 1 - e.clientY / window.innerHeight;
	  });
	  uploadImage()
}


handleCursorAnimation();

Sorry, I’m a bit new to this, and it’s been quite challenging to try to make it work!

What gets messed up? I think the += in the texture lookup is invalid syntax.

The problem is that the effect doesn’t apply to more than one image. I tried instantiating the effect on several images, but it doesn’t work.

Here is something that works, somewhat simplified to 3 images in an array.
It is also in the form of a standalone HTML file.

It looks like you would need to load everything prior to rendering.

Just pay attention to the code since I did make a lot of changes.

Effect.zip (2.7 KB)

Thank you so much! I’ll review it right away and let you know how it goes :slight_smile:

It works, but the problem is that I think the changes are so significant that they affected the entire scene. Do you think I could send you my files in a zip and get your help? If you can’t, that’s no problem. Thank you so much for responding.

You will have to figure this out on your own.

It is all about making sure that all images are loaded prior to rendering.

Here is another example that loads 3 different images from three.js repository by using the THREE.TextureLoader and $image was replaced with url.

Effect2.zip (2.2 KB)

1 Like

Yeah, I already found the solution. It took time but it was achieved. Anyway, thank you!