How to make rounded edge in plane geometry?

Hello and good day to the gurus of three.js.
here is the thing, I have add a plane geometry which shows a video in it but I want to have rounded edges for the plane. Any suggestion would be nice. What I found on the internet was bit confusing for me.
Here is what i get

Here is my code (its not great)

import React, { Suspense, useEffect, useState } from "react";
import { Canvas } from "@react-three/fiber";
import {
  OrbitControls,
  Preload,
  useGLTF,
  useVideoTexture,
  useTexture,
  RoundedBox,
  Shape,
} from "@react-three/drei";
import * as THREE from "three";
import CanvasLoader from "./CanvasLoader";

const Mobile = ({ isMobile }) => {
  const mobile = useGLTF("./mobile3D/scenes5.glb");

  return (
    <group>
      <mesh>
        <hemisphereLight intensity={1} />
        <ambientLight intensity={10} />
        <primitive
          object={mobile.scene}
          scale={isMobile ? 0.7 : 50}
          position={isMobile ? [0, 0, 0] : [0, -4, 0]}
          rotation={[0, 4.35, 0]}
        />
        <mesh rotation={[0, 205.41, 0]} position={[-0.19, 0, -0.07]}>
          <planeGeometry args={[1, 1]} />
          <Suspense>
            <LogoMaterial url="mylogo.png" />
          </Suspense>
        </mesh>

        {/* video texture and settings HERE */}
       
        <mesh
          rotation={[0, -199.85, 0]}
          position={[0.19, 0, 0.07]}
        >  
          <planeGeometry args={[3.65, 7.8]} />
          <Suspense fallback={<FallbackMaterial url="play_icon.png" />}
            <VideoMaterial url="10.mp4" />
          </Suspense>
        </mesh>
      </mesh>
    </group>
  );
};

function VideoMaterial({ url }) {
  const texture = useVideoTexture(url);
  return <meshBasicMaterial map={texture} toneMapped={false} />;
}

function FallbackMaterial({ url }) {
  const texture = useTexture(url);
  return <meshBasicMaterial map={texture} toneMapped={false} />;
}

function LogoMaterial({ url }) {
  const texture = useTexture(url);
  return (
    <meshBasicMaterial map={texture} toneMapped={false} transparent={true} />
  );
}

Although I have found few suggestions but they are not very clear… Any suggestion would be really helpful.

Hi!
Don’t hesitate to search the forum: Plane mesh with rounded corners that can have an image texture - #2 by hofk

3 Likes

I have tried with one of the code but there is an error

Error: Objects are not valid as a React child (found: object with keys {isBufferGeometry, uuid, name, type, index, attributes, morphAttributes, morphTargetsRelative, groups, boundingBox, boundingSphere, drawRange, userData}). If you meant to render a collection of children, use an array instead.


I have not made any modifications to the code. I was just trying to see it first and than make the changes.

thank you @prisoner849 your suggestion really helped me. Although I faced other problem but I was able to achieve what i wanted.

Below is the code for RoundedRectangle/ plane with rounded edge

const Mobile = ({ isMobile }) => {
  const mobile = useGLTF("./3D/scenes5.glb");

  const width = 3.6;
  const height = 7.8;
  const radius = 0.5;
  const smoothness = 10;

  const geometry = RectangleRounded(width, height, radius, smoothness);

  return (
    <group>
      <mesh>
        <hemisphereLight intensity={1} />

        <ambientLight intensity={10} />

        <pointLight intensity={0} />
        <primitive
          object={mobile.scene}
          scale={isMobile ? 0.7 : 50}
          position={isMobile ? [0, 0, 0] : [0, -4, 0]}
          rotation={[0, 4.35, 0]}
        />
        <mesh rotation={[0, 205.41, 0]} position={[-0.19, 0, -0.07]}>
          <planeGeometry args={[1, 1]} />
          <Suspense>
            <LogoMaterial url="sm.png" />
          </Suspense>
        </mesh>

        {/* video texture and settings HERE */}

        <mesh
          geometry={geometry}
          rotation={[0, -199.85, 0]}
          position={[0.189, 0.02, 0.07]}
        >
          <Suspense fallback={<FallbackMaterial url="play_icon.png" />}>
            <VideoMaterial url="10.mp4" />
          </Suspense>
        </mesh>
      </mesh>
    </group>
  );
};

function RectangleRounded(w, h, r, s) {
  // This function uses width, height, radiusCorner and smoothness

  const pi2 = Math.PI * 2;
  const n = (s + 1) * 4; // number of segments
  let indices = [];
  let positions = [];
  let uvs = [];
  let qu, sgx, sgy, x, y;

  for (let j = 1; j < n + 1; j++) indices.push(0, j, j + 1); // 0 is center
  indices.push(0, n, 1);
  positions.push(0, 0, 0); // rectangle center
  uvs.push(0.5, 0.5);
  for (let j = 0; j < n; j++) contour(j);

  const geometry = new THREE.BufferGeometry();
  geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(indices), 1));
  geometry.setAttribute(
    "position",
    new THREE.BufferAttribute(new Float32Array(positions), 3)
  );
  geometry.setAttribute(
    "uv",
    new THREE.BufferAttribute(new Float32Array(uvs), 2)
  );

  return geometry;

  function contour(j) {
    qu = Math.trunc((4 * j) / n) + 1; // quadrant  qu: 1..4
    sgx = qu === 1 || qu === 4 ? 1 : -1; // signum left/right
    sgy = qu < 3 ? 1 : -1; // signum  top / bottom
    x = sgx * (w / 2 - r) + r * Math.cos((pi2 * (j - qu + 1)) / (n - 4)); // corner center + circle
    y = sgy * (h / 2 - r) + r * Math.sin((pi2 * (j - qu + 1)) / (n - 4));

    positions.push(x, y, 0);
    uvs.push(0.5 + x / w, 0.5 + y / h);
  }
}
1 Like