After reading through this post, I'm attempting to modify a Voronoi shader from the Book of Shaders based on mouse cursor movements.
However, I seem to be encountering issues with the offsets. Currently, my mouse cursor appears slightly off to the right in relation to my code (see below).
I've tried adjusting the offset using the bounding rectangle of my renderer.domElement
, but setting the top
/left
values to 0 had no effect. When simply trying
e.pageX / window.innerWidth; e.pageY / window.innerHeight;
, the y-position appeared flipped and significantly misaligned.
Additionally, I experimented with the standard mapping to [-1,1] using offsetX
and other methods (commented out) but found them to be even less accurate. I also explored utilizing unproject
from another Stack Overflow post, yet that didn't yield any noticeable changes either.
You can view a jsfiddle demonstrating the same issues here: https://jsfiddle.net/9y8hge3t/1/
Below is the complete code for reference:
<!--
* Based on Book of Shaders 12:
https://thebookofshaders.com/12/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>WebGL Demo - Voronoi (Mouse Move)</title>
<meta charset="utf-8">
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<script src="./libraries/threejs/three.min.js"></script>
<!-- shaders -->
<script type="x-shader/x-vertex" id="vertexShader">
void main() {
//gl_Position = vec4(position, 1.0);
vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * modelViewPosition;
}
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec3 color = vec3(.0);
// Cell positions
vec2 point[5];
point[0] = vec2(0.83,0.75);
point[1] = vec2(0.60,0.07);
point[2] = vec2(0.28,0.64);
point[3] = vec2(0.31,0.26);
point[4] = u_mouse;
float m_dist = 1.; // minimum distance
// Iterate through the points positions
for (int i = 0; i < 5; i++) {
float dist = distance(st, point[i]);
// Keep the closer distance
m_dist = min(m_dist, dist);
}
// Draw the min distance (distance field)
color += m_dist;
// Show isolines
// color -= step(.7,abs(sin(50.0*m_dist)))*.3;
gl_FragColor = vec4(color,1.0);
}
</script>
</head>
<body></body>
<script>
let camera, scene, renderer;
let uniforms, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
// 2D perspective camera -- see linked article on top for full explanation of params
camera = new THREE.Camera();
camera.position.z = 1;
/*
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(0, 0, 1);
*/
camera.lookAt(scene.position);
scene.add(camera);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0x000000, 1);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
uniforms = {
u_resolution: { type: 'vec2', value: new THREE.Vector2() },
u_mouse: { type: 'vec2', value: new THREE.Vector2() },
u_time: { type: 'float', value: 1.0 }
};
let vShader = document.getElementById("vertexShader").textContent;
let fShader = document.getElementById("fragmentShader").textContent;
let geometry = new THREE.PlaneGeometry(2, 2);
// give it a material
let material = new THREE.ShaderMaterial({
uniforms: uniforms,
fragmentShader: fShader,
vertexShader: vShader,
});
// and now create the mesh (geom+mat)
mesh = new THREE.Mesh(geometry, material);
// mesh.position.set(0, 0, 0);//-1.5, 0.0, 4.0);
scene.add(mesh);
onWindowResize();
window.addEventListener('resize', onWindowResize, false);
renderer.domElement.addEventListener('mousemove', onDocumentMouseMove, false);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
uniforms.u_time.value += 0.05;
renderer.render(scene, camera);
}
function onWindowResize(e) {
renderer.setSize(window.innerWidth, window.innerHeight);
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}
function onDocumentMouseMove(e) {
// uniforms.u_mouse.value.x = (e.offsetX / window.innerWidth) * 2 - 1;//e.pageX / window.innerWidth;
// uniforms.u_mouse.valye.y = -(e.offsetY / window.innerHeight) * 2 + 1;//e.pageY / window.innerHeight;
uniforms.u_mouse.value.x = (e.offsetX / window.innerWidth)*2;
uniforms.u_mouse.value.y = -(e.offsetY / window.innerHeight)*2+1;
}
</script>
</html>