How to achieve similar 2D "overflow-hidden" effect in 3D react-three-fiber?

203 views Asked by At

I am trying to similar 2D effect of overflow-hidden but in 3D model with reference to this amazing kprverse website. I tried using clipping plane but it does not produce the same effect.

Below is original 3D model before clipping

original model

After Clipping

clipped model

Ideally, the result should show model between the red lines and overflow should be hidden. But, I could not achieve it with clipping planes.

ideally clipped model

is there any better way to achieve the similar 2D "overflow-hidden" effect?

CodeSandbox: https://codesandbox.io/s/delicate-cache-8j9iji?file=/src/App.js:0-2081

Following is my codes.

 import * as THREE from "three";
import { useGLTF, OrbitControls, ScrollControls } from "@react-three/drei";

import React, { useRef } from "react";
import { Canvas } from "@react-three/fiber";

export const FLOOR_HEIGHT = 2.3;
export const NB_FLOORS = 3;

export default function TestingClipping(props) {
  const { nodes, materials } = useGLTF("./models/WawaOffice.glb");
  const planes = useRef([
    new THREE.Plane(new THREE.Vector3(-0.5, 0, 0), 1),
    new THREE.Plane(new THREE.Vector3(0.5, 0, 0), 1)
  ]);
  return (
    <Canvas
      style={{ height: "100vh", width: "100vw" }}
      gl={{ localClippingEnabled: true }}
    >
      <ambientLight intensity={1} />
      <OrbitControls enableZoom={false} enableDamping={false} />
      <ScrollControls pages={3} damping={0.25}>
        <group scale={[1, 1, 1]}>
          <group
            {...props}
            dispose={null}
            position={[0.5, -1, -1]}
            rotation={[0, -Math.PI / 3, 0]}
            style={{ transform: "scale(0.1)" }}
          >
            <mesh geometry={nodes["01_office"].geometry}>
              <meshStandardMaterial
                {...materials["01"]}
                clippingPlanes={planes.current}
              />
            </mesh>
            <group position={[0, 2.11, -2.23]}>
              <group>
                <mesh geometry={nodes["02_library"].geometry}>
                  <meshStandardMaterial
                    {...materials["02"]}
                    clippingPlanes={planes.current}
                  />
                </mesh>
              </group>
            </group>
            <group position={[-1.97, 4.23, -2.2]}>
              <group>
                <mesh geometry={nodes["03_attic"].geometry}>
                  <meshStandardMaterial
                    {...materials["03"]}
                    clippingPlanes={planes.current}
                  />
                </mesh>
              </group>
            </group>
          </group>
        </group>
      </ScrollControls>
    </Canvas>
  );
}

// useGLTF.preload("./models/WawaOffice.glb");
1

There are 1 answers

1
LY Hooi On

Huge thanks to Remi, I found the solution with drei-mask.

https://github.com/pmndrs/drei#mask