Multiple glitches on multiple planes (video/image)
afk-mario opened this issue · 1 comments
afk-mario commented
I'm building the following website
And have some issues:
- Sometimes the canvas won't load until I manually resize the browser window.
- Sometimes the canvas would load but the image is distorted
- The planes seem to be out of sync with he DOM elements position a lot of the time.
- Sometimes the plane just doesn't load the texture.
I was hoping there is something obvious I'm missing and the reason why I'm seeing all this issues, will work between today and tomorrow on building a Sandbox with the issue more complete and isolated, meanwhile here is the basic setup I have.
Here is the code I use for my planes:
import React, { useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Vec2 } from 'curtainsjs';
import { Plane as BasePlane } from 'react-curtains';
import { vertexShader, fragmentShader } from 'shaders/chromatic-aberration';
import style from './style.module.css';
function Plane({ children, className, sensibility, damp, onReady }) {
const ref = useRef();
const isIn = useRef(false);
const mouse = useRef(new Vec2());
const nMouse = useRef(new Vec2());
const uniforms = {
time: {
name: 'u_time',
type: '1f',
value: 0,
},
mouse: {
// our mouse position
name: 'u_mouse',
type: '2f',
value: mouse.current,
},
};
useEffect(() => {
const el = ref.current;
const onMouseMove = (e) => {
mouse.current.set(e.clientX, e.clientY);
isIn.current = true;
};
const onTouchMove = (e) => {
isIn.current = true;
mouse.current.set(e.touches[0].clientX, e.touches[0].clientY);
};
const deactivateMouse = () => {
isIn.current = false;
};
if (el) {
el.addEventListener('mousemove', onMouseMove);
el.addEventListener('touchmove', onTouchMove, { passive: true });
el.addEventListener('mouseout', deactivateMouse);
el.addEventListener('touchend', deactivateMouse);
}
return () => {
if (el) {
el.removeEventListener('mousemove', onMouseMove);
el.removeEventListener('touchmove', onTouchMove, {
passive: true,
});
el.removeEventListener('mouseenter', deactivateMouse);
el.removeEventListener('mouseout', deactivateMouse);
el.removeEventListener('touchend', deactivateMouse);
}
};
});
const onRender = (plane) => {
plane.uniforms.time.value += 1;
const mouseCoords = plane
.mouseToPlaneCoords(mouse.current)
.multiplyScalar(-sensibility);
const oldX = isIn.current ? mouseCoords.x : 0;
const oldY = isIn.current ? mouseCoords.y : 0;
const x = nMouse.current.x + (oldX - nMouse.current.x) * damp;
const y = nMouse.current.y + (oldY - nMouse.current.y) * damp;
nMouse.current.set(x, y);
// update our mouse position uniform
plane.uniforms.mouse.value = nMouse.current;
};
return (
<div
ref={ref}
className={`${className} ${style.wrapper} image-element-wrapper`}
>
<BasePlane
className={`${style.plane} plane`}
vertexShader={vertexShader}
fragmentShader={fragmentShader}
uniforms={uniforms}
onRender={onRender}
onReady={onReady}
>
{children}
</BasePlane>
</div>
);
}
Plane.propTypes = {
className: PropTypes.string,
children: PropTypes.node.isRequired,
sensibility: PropTypes.number,
damp: PropTypes.number,
onReady: PropTypes.func,
};
Plane.defaultProps = {
className: null,
sensibility: 0.2,
damp: 0.2,
onReady: () => {},
};
export default Plane;
Shader
export const vertexShader = `
precision mediump float;
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat4 uTextureMatrix0;
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;
void main() {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
// varyings
vVertexPosition = aVertexPosition;
vTextureCoord = (uTextureMatrix0 * vec4(aTextureCoord, 0.0, 1.0)).xy;
}
`;
export const fragmentShader = `
precision mediump float;
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;
uniform sampler2D uSampler0;
uniform float u_time;
uniform vec2 u_mouse;
vec2 p = u_mouse;
void main() {
float limit = 0.1;
float t = u_time * 0.01;
vec2 textureCoord = vTextureCoord;
vec4 originalR = texture2D(uSampler0, (vTextureCoord) + p * 1.0);
vec4 originalG = texture2D(uSampler0, vTextureCoord + p * 0.6);
vec4 originalB = texture2D(uSampler0, vTextureCoord + p * 0.2);
vec4 red = vec4(originalR.r, 0.0, 0.0, 1.0);
vec4 green = vec4(0.0, originalG.g, 0.0, 1.0);
vec4 blue = vec4(0.0, 0.0, originalB.b, 1.0);
gl_FragColor = texture2D(uSampler0, textureCoord);
gl_FragColor = red + green + blue;
}
`;
martinlaxenaire commented
Hey @afk-mario,
wow, this is a weird one!
I suspect this could be due to a CSS issue (ie the curtains container CSS is loaded after the canvas has been appended - explaining why the issue disappears after a window resize). A codesandbox would be greatly appreciated!
Cheers,