Currently, I am diving into the world of Three.js. My latest project involves adapting a shader that I originally created in Shader Toy to be displayed on my own webpage. The shader itself is a procedural terrain where users can navigate using the WASD keys. Everything seems to be working well except for the movement functionality. In my javascript code, I declare the position as follows:
var pos = new THREE.Vector2(0, 0);
To update the position based on user input, I set up an event listener like this:
window.addEventListener("keydown", function(event){
switch (event.keycode) {
case 65: pos.x -= 0.25;
break;
case 68: pos.x += 0.25;
break;
case 83: pos.y -= 0.25;
break;
case 87: pos.y += 0.25;
break;
default: return;
}
});
The updated position value is then passed to the fragment shader when initializing the shader material:
var shader = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vs').textContent,
fragmentShader: document.getElementById('fs').textContent,
depthWrite: false,
depthTest: false,
uniforms: {
res: {type: "v3", value: resolution},
time: {type: "f", value: 0.0},
deltaTime: {type: "f", value: 0.0},
frame: {type: "i", value: 0},
mouse: {type: "v4", value: mouse},
pos: {type: "v2", value: pos},
}
});
In the render function, the updated position is applied to the shader before rendering the scene:
function render() {
requestAnimationFrame(render);
if (canvas.width !== canvas.clientWidth || canvas.height !== canvas.clientHeight) {
renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
camera.aspect = canvas.clientWidth/canvas.clientHeight;
camera.updateProjectionMatrix();
resolution = new THREE.Vector3(canvas.clientWidth, canvas.clientHeight, 1.0);
}
shader.uniforms['res'].value = resolution;
shader.uniforms['time'].value = clock.getElapsedTime();
shader.uniforms['deltaTime'].value = clock.getDelta();
shader.uniforms['frame'].value = 0;
shader.uniforms['mouse'].value = mouse;
shader.uniforms['pos'].value = pos;
renderer.render(scene, camera);
}
Although everything seems correct, there might be an issue with the event listener since it's the only discrepancy among the other uniform settings. As a beginner in utilizing these libraries, I hope it's not due to a simple mistake.
UPDATE:
In an attempt to resolve the keyboard input issue, I experimented by handling key events similarly to how I manage mouse input:
function readkeys(event){
switch (event.keycode) {
case 65: pos.x -= 0.25;
break;
case 68: pos.x += 0.25;
break;
case 83: pos.y -= 0.25;
break;
case 87: pos.y += 0.25;
break;
default: return;
}
}
Then, calling this function within the HTML canvas element:
<canvas id="canvas" onmousemove="readmouse(event)" keydown="readkeys(event)"/>
Unfortunately, the shader remains unresponsive to keyboard input even after these adjustments.