# How to make plane geometry vertices position equals to material`s displacement map?

Hi there!

In my application I want to change plane geometry vertices position by moving mouse over it but still be capable of raycasting on it and get the point on the changed plane.

For now it was done by changing the displacement map texture, which is canvas where user drawing when moving mouse over the plane. But when i`m raycasting on the newly created “mountains” I receive to intersections. After reading other question from forum I understand i need to change vertices positions too. Unfortunately answer from questions is depricated, since geometry.vertices is no longer in use.

here is a demo of my current version

And here is the code how i change displacement map based on canvas element for those how can`t access the demo sandbox.

``````function height2normal(context, contextN) {
const width = 128;
const height = 128;

const src = context.getImageData(0, 0, width, height);
const dst = contextN.createImageData(width, height);

for (let i = 0, l = width * height * 4; i < l; i += 4) {
let x1, x2, y1, y2;

if (i % (width * 4) === 0) {
// left edge
x1 = src.data[i];
x2 = src.data[i + 4];
} else if (i % (width * 4) === (width - 1) * 4) {
// right edge
x1 = src.data[i - 4];
x2 = src.data[i];
} else {
x1 = src.data[i - 4];
x2 = src.data[i + 4];
}

if (i < width * 4) {
// top edge
y1 = src.data[i];
y2 = src.data[i + width * 4];
} else if (i > width * (height - 1) * 4) {
// bottom edge
y1 = src.data[i - width * 4];
y2 = src.data[i];
} else {
y1 = src.data[i - width * 4];
y2 = src.data[i + width * 4];
}

dst.data[i] = x1 - x2 + 127;
dst.data[i + 1] = y1 - y2 + 127;
dst.data[i + 2] = 255;
dst.data[i + 3] = 255;
}

contextN.putImageData(dst, 0, 0);
}

// uv - intersection uv, point of intersection on the plane texture
function draw(uv) {
const { scene } = three();
const canvasD = document.getElementById('canvasD');
const contextD = canvasD.getContext('2d');
const canvasN = document.getElementById('canvasN');
const contextN = canvasN.getContext('2d');
const plane = scene.getObjectByName('terrain');
const material = plane.material;

contextD.fillStyle = '#FFFFFF';
contextD.fillRect(uv.x * 128, 128 - uv.y * 128, 2, 2);
material.needsUpdate = true;
material.displacementMap.needsUpdate = true;
height2normal(contextD, contextN);
material.normalMap.needsUpdate = true;
}
``````

Hi!

The respective JSFiddle, in the mentioned post, was updated, and uses BufferGeometry (the code snippet in the post wasn’t updated though)

1 Like

Thanks for updating the jsFiddle in the prev post, I tried to apply your changes to my sandbox, but now after clicking on the plane, it squeezes it into some strange shape, instead of changing the Y coordinate of vertices. I thought that it a problem of using displacement map and changing positions at the same time, but after removing displacementMap prop from material it didn`t fix the problem.

I updated my sandbox to demonstrate it. Can you please check it?

I would go with this setup:

``````const geometry = new THREE.PlaneGeometry(1, 1, 128, 128).rotateX(-Math.PI * 0.5);
...
//plane.rotation.x = -Math.PI / 2;
``````

Rotate the geometry itself, not the mesh.

@prisoner849 I have also tested the image from the respective JSFiddle, in the mentioned post, on other sandbox, feels like smth is squeezing my plane mesh after aplying transforming position code

The “mountains” here is like rotated and imprinted into the plane

The same issue: you rotate the mesh, whereas you need to rotate the geometry of the plane.

Thanks! That was the problem, u helped a lot, thank you!

Can u please share piece of advice what is difference and use-cases of rotating geometry or mesh?