GPU raycast

by Paul West

HTML

<script type="importmap">
  {
    "imports": {
      "three": "https://unpkg.com/[email protected]/build/three.module.js",
      "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
    }
  }
</script>

CSS

body{
  overflow: hidden;
  margin: 0;
}

JavaScript

import * as THREE from 'three';
import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
import { ImprovedNoise } from 'three/addons/math/ImprovedNoise.js';
import { GUI } from "three/addons/libs/lil-gui.module.min.js";
import Stats from 'three/addons/libs/stats.module.js';

let perlin = new ImprovedNoise();

let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1001);
camera.position.set(0, 5, 8).setLength(157);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

let controls = new OrbitControls(camera, renderer.domElement);

let light = new THREE.DirectionalLight(0xffffff, Math.PI * 1.25);
light.position.set(1, 1, 0);
scene.add(light, new THREE.AmbientLight(0xffffff, Math.PI * 0.25));

let g = new THREE.PlaneGeometry(200, 200, 1000, 1000);
g.rotateX(Math.PI * -0.5);
let uv = g.attributes.uv;
let pos = g.attributes.position;
let vUv = new THREE.Vector2();
for(let i = 0; i < uv.count; i++){
	vUv.fromBufferAttribute(uv, i);
  vUv.multiplyScalar(10);
  pos.setY(i, perlin.noise(vUv.x, vUv.y, 2.7) * 30);
}
g.computeVertexNormals();

let terrainUniforms = {
	min: {value: new THREE.Vector3()},
  max: {value: new THREE.Vector3()},
  showPositionColors: {value: false},
  lineThickness: {value: 1}
}
let m = new THREE.MeshLambertMaterial({
	color: 0x7D6747,
  wireframe: false,
  side: THREE.DoubleSide,
  onBeforeCompile: shader => {
  	shader.uniforms.boxMin = terrainUniforms.min;
    shader.uniforms.boxMax = terrainUniforms.max;
    shader.uniforms.lineThickness = terrainUniforms.lineThickness;
    shader.uniforms.showPositionColors = terrainUniforms.showPositionColors;
    shader.vertexShader = `
    	varying vec3 vPos;
      ${shader.vertexShader}
    `.replace(
    	`#include <begin_vertex>`,
      `#include <begin_vertex>
      	vPos = transformed;
      `
    );
    //console.log(shader.vertexShader);
   ...