How To Create A Cannon-es Body For Ground Made With Displacement Map

I’m trying to create a ground body for ground (three.js mesh) made by displacement map , in cannon but I can’t.

here is my code :



import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';
import * as CANNON from 'cannon-es';
import CannonDebugger from 'cannon-es-debugger';




const scene = new THREE.Scene();
const world = new CANNON.World({
  gravity : new CANNON.Vec3(0 , -9.8 , 0)
});


const hdrLoader = new RGBELoader();
const sky = hdrLoader.load('Textures/evening_road_01_puresky_4k.hdr', (texture) => {
  texture.mapping = THREE.EquirectangularReflectionMapping;
  scene.background = texture;
});

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 3000);
camera.position.set(0, 1, 3);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const orbitControls = new OrbitControls(camera, renderer.domElement);

const textureLoader = new THREE.TextureLoader();

const ambientLight = new THREE.AmbientLight();
scene.add(ambientLight);

const groundGeo = new THREE.PlaneGeometry(1000, 1000, 50, 50);
const HM = textureLoader.load('/HM/Rolling Hills Height Map.png');

const groundMat = new THREE.MeshStandardMaterial({
  displacementMap: HM,
  displacementScale: 400,
  map: textureLoader.load('Textures/leafy_grass_diff_2k.jpg'),
  side: THREE.DoubleSide,
});

groundMat.map.wrapS = groundMat.map.wrapT = THREE.RepeatWrapping;
groundMat.map.repeat.set(5, 5);

const ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotateX = -Math.PI / 2;
ground.position.y = -0.01;
ground.rotation.x = -Math.PI / 2;
ground.position.y = -30;
scene.add(ground);
console.log(groundGeo);

const groundBody = new CANNON.Body({
  type : CANNON.Body.STATIC,
shape : new CANNON.Heightfield(groundGeo.attributes.position.array)
});

 console.log(groundGeo.attributes.position.array);

const playerGeo = new THREE.CapsuleGeometry();
const playerMat = new THREE.MeshBasicMaterial();
const player = new THREE.Mesh(playerGeo , playerMat);
scene.add(player);

const playerBody = new CANNON.Body({
  mass : 1 ,
  shape : new  CANNON.Cylinder()
});
playerBody.position.set(0 , 10 , 0)
world.addBody(playerBody);



const groundHelper = new THREE.GridHelper(50, 20, new THREE.Color(0xff0000), new THREE.Color(0x00ff00));
//scene.add(groundHelper);

const axesHelper = new THREE.AxesHelper(5);
// scene.add(axesHelper);



const cannonDebugger = new CannonDebugger(scene , world);

function animate() {
  requestAnimationFrame(animate);
  world.fixedStep();

console.log(playerBody.position.y);


  applyPhysics()
  renderer.render(scene, camera);
}

animate();


function applyPhysics() {

  player.position.copy(playerBody.position);
  player.quaternion.copy(playerBody.quaternion);



}




Please someone provide solution thnx

The displacement only happens in the Shader (GPU side) and is not really displacing the geometry of the plane directly (CPU side).

Cannon only sees the original flat plane, so you need to somehow directly apply the displacement to the geometry with a js script, or import it from blender or similar software.

Any way to do it directly without using any 3d software

I don’t have a pc I use mobile for development

PC or laptop would be more convenient to create threejs apps or any web applications.