Creating an In-Scene Panel in Three.js Using Plane Geometry and Raycasting

  • Create a text-based article panel using Three.js plane geometries.
  • Use THREE.Raycaster to make it interactive.
  • Style the content visually with colors and layout—all from within Three.js.

🧱 The Concept

We will:

  • Use PlaneGeometry to create a panel.
  • Render multi-line text using CanvasTexture.
  • Apply this as a material to the plane.
  • Detect interaction using Raycaster.

✏️ Step-by-Step Guide

1. Scene Setup

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z = 5;

2. Create a Canvas Texture with Text

function createTextTexture(text, width = 512, height = 512) {
  const canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = height;
  const ctx = canvas.getContext('2d');

  // Background
  ctx.fillStyle = '#ffffff';
  ctx.fillRect(0, 0, width, height);

  // Text styling
  ctx.fillStyle = '#000000';
  ctx.font = '24px sans-serif';
  ctx.textAlign = 'left';
  ctx.textBaseline = 'top';

  const lines = text.split('n');
  lines.forEach((line, i) => {
    ctx.fillText(line, 20, 30 + i * 30);
  });

  return new THREE.CanvasTexture(canvas);
}

3. Apply Texture to Plane

const articleText = `
📘 Article Title

This is an interactive article panel.
Click it to trigger an event or toggle something.
This text is rendered directly in the 3D scene!
`;

const texture = createTextTexture(articleText);
const material = new THREE.MeshBasicMaterial({ map: texture, transparent: true });
const geometry = new THREE.PlaneGeometry(4, 4);
const articlePanel = new THREE.Mesh(geometry, material);
scene.add(articlePanel);

4. Add Raycaster for Interaction

const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

function onClick(event) {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObject(articlePanel);

  if (intersects.length > 0) {
    alert('🖱️ Article panel clicked!');
  }
}

window.addEventListener('click', onClick);

5. Animate the Scene

function animate() {
  requestAnimationFrame(animate);
  articlePanel.rotation.y += 0.005;
  renderer.render(scene, camera);
}
animate();

Result

You now have a 3D article panel:

  • Fully rendered inside a WebGL canvas.
  • Styled and formatted using the CanvasTexture.
  • Fully interactive thanks to Raycaster.

Use Cases

  • VR/AR in-scene documentation
  • In-game help panels
  • Tutorials or UI hints inside 3D scenes

Leave a comment

Your email address will not be published. Required fields are marked *