My code here:
fragment.glsl:
uniform sampler2D uPictureTexture;
uniform sampler2D uGlowTexture;
uniform float uProgress;
uniform sampler2D uSecondPictureTexture;
uniform float uSecondProgress;
varying vec3 vColor;
varying vec2 vUv;
void main() {
vec2 uv = gl_PointCoord;
float distanceToCenter = length(uv - vec2(0.5));
float circleAlpha = smoothstep(0.5, 0.49, distanceToCenter);
vec4 circleColor = vec4(vColor, circleAlpha);
vec4 glowColor = texture2D(uGlowTexture, uv);
vec4 imageColor = texture2D(uPictureTexture, vUv);
vec4 imageColor2 = texture2D(uSecondPictureTexture, vUv);
if (imageColor.r < 0.1) {
discard;
}
vec4 finalColor = mix(circleColor, glowColor, uProgress);
finalColor = mix(finalColor, imageColor2, uSecondProgress);
finalColor.a *= circleAlpha;
gl_FragColor = finalColor;
#include <tonemapping_fragment>
#include <colorspace_fragment>
}
vertex.glsl:
uniform float uProgress;
uniform float uSecondProgress;
uniform sampler2D uPictureTexture;
uniform sampler2D uSecondPictureTexture;
uniform sampler2D uDisplacementTexture;
uniform vec2 uResolution;
attribute float aIntensity;
attribute float aAngle;
attribute vec2 aUv;
varying vec3 vColor;
varying vec2 vUv;
void main() {
float radius = 5.0;
float randomRadius = sqrt(aIntensity) * radius;
vec3 initialPosition = vec3(
randomRadius * cos(aAngle),
randomRadius * sin(aAngle),
0.0
);
vec3 targetPosition = vec3(
(aUv.x - 0.5) * 10.0,
(aUv.y - 0.5) * 10.0,
0.0
);
vec3 targetPosition2 = vec3(
(aUv.x - 0.5) * 10.0 ,
(aUv.y - 0.5) * 10.0,
0.0
);
vec3 finalPosition = mix(initialPosition, targetPosition, uProgress);
if (uProgress >= 0.99) {
finalPosition = mix(finalPosition, targetPosition2, uSecondProgress);
}
float displacementIntensity = texture2D(uDisplacementTexture, aUv).r;
displacementIntensity = smoothstep(0.1, 0.3, displacementIntensity);
finalPosition += vec3(cos(aAngle), sin(aAngle), 0.0) * displacementIntensity * aIntensity * 3.0;
vec4 modelPosition = modelMatrix * vec4(finalPosition, 1.0);
vec4 viewPosition = viewMatrix * modelPosition;
vec4 projectedPosition = projectionMatrix * viewPosition;
gl_Position = projectedPosition;
float pictureIntensity = texture2D(uPictureTexture, aUv).r;
gl_PointSize = 0.15 * pictureIntensity * uResolution.y;
gl_PointSize *= (1.0 / -viewPosition.z);
vColor = vec3(pow(pictureIntensity, 2.0));
vUv = aUv;
}
Js file:
const mypictureTexture = textureLoader.load('./static/02-2.jpg');
const mypictureTexture2 = textureLoader.load('./static/01-2.jpg');
const glowTexture = textureLoader.load('./static/glow.png');
// Material
const particlesMaterial = new THREE.ShaderMaterial({
vertexShader: particlesVertexShader,
fragmentShader: particlesFragmentShader,
uniforms: {
uProgress: { value: 0 },
uSecondProgress: { value: 0 },
uPictureTexture: new THREE.Uniform(mypictureTexture),
uSecondPictureTexture: new THREE.Uniform(mypictureTexture2),
uGlowTexture: new THREE.Uniform(glowTexture),
uDisplacementTexture: new THREE.Uniform(displacement.texture),
uResolution: new THREE.Uniform(new THREE.Vector2(sizes.width * sizes.pixelRatio, sizes.height * sizes.pixelRatio))
},
blending: THREE.AdditiveBlending
});
// Particles
const particles = new THREE.Points(particlesGeometry, particlesMaterial);
scene.add(particles);
let progress = 0;
const animateProgress = () => {
progress += 0.005;
particlesMaterial.uniforms.uProgress.value = progress;
if (progress < 1) {
requestAnimationFrame(animateProgress);
}
else {
setTimeout(animateSecondProgress, 3000);
}
};
setTimeout(animateProgress, 2000);
let secondProgress = 0;
const animateSecondProgress = () => {
secondProgress += 0.005;
particlesMaterial.uniforms.uSecondProgress.value = secondProgress;
if (secondProgress < 1) {
requestAnimationFrame(animateSecondProgress);
}
};