three.js基础之clipping

clipping

<canvas id="mainCanvas"></canvas>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/addons/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";
  import Stats from "three/addons/libs/stats.module.js";
  import { GUI } from "three/addons/libs/lil-gui.module.min.js";
  import { TrackballControls } from "three/addons/controls/TrackballControls.js";
  import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight } from "./init.js";

  function init() {
    const renderer = initRenderer("mainCanvas");

    const scene = new THREE.Scene();

    const camera = initPerspectiveCamera();
    camera.position.set(-10, 10, 10);
    scene.add(camera);

    const ambientLight = initAmbientLight();
    scene.add(ambientLight);

    const spotLight = initSpotLight();
    scene.add(spotLight);

    const trackballControls = new TrackballControls(camera, renderer.domElement);
    const clock = new THREE.Clock();

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

    const stats = new Stats();
    document.body.appendChild(stats.dom);

    const localPlane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.8);
    const globalPlane = new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0.1);

    const globalPlanes = [globalPlane],
      Empty = Object.freeze([]);
    renderer.clippingPlanes = Empty;
    renderer.localClippingEnabled = true;

    const ground = new THREE.Mesh(new THREE.PlaneGeometry(9, 9), new THREE.MeshPhongMaterial({ color: 0xa0adaf, shininess: 150 }));
    ground.rotation.x = -Math.PI / 2;
    ground.receiveShadow = true;
    scene.add(ground);

    const material = new THREE.MeshPhongMaterial({
      color: 0x80ee10,
      shininess: 100,
      side: THREE.DoubleSide,

      clippingPlanes: [localPlane],
      clipShadows: true,
      alphaToCoverage: true,
    });
    const geometry = new THREE.TorusKnotGeometry(0.4, 0.08, 95, 20);
    const object = new THREE.Mesh(geometry, material);
    object.castShadow = true;
    scene.add(object);

    const gui = new GUI(),
      props = {
        alphaToCoverage: true,
      },
      folderLocal = gui.addFolder("Local Clipping"),
      propsLocal = {
        get Enabled() {
          return renderer.localClippingEnabled;
        },
        set Enabled(v) {
          renderer.localClippingEnabled = v;
        },
        get Shadows() {
          return material.clipShadows;
        },
        set Shadows(v) {
          material.clipShadows = v;
        },
        get Plane() {
          return localPlane.constant;
        },
        set Plane(v) {
          localPlane.constant = v;
        },
      },
      folderGlobal = gui.addFolder("Global Clipping"),
      propsGlobal = {
        get Enabled() {
          return renderer.clippingPlanes !== Empty;
        },
        set Enabled(v) {
          renderer.clippingPlanes = v ? globalPlanes : Empty;
        },
        get Plane() {
          return globalPlane.constant;
        },
        set Plane(v) {
          globalPlane.constant = v;
        },
      };

    gui.add(props, "alphaToCoverage").onChange(function (value) {
      ground.material.alphaToCoverage = value;
      ground.material.needsUpdate = true;

      material.alphaToCoverage = value;
      material.needsUpdate = true;
    });
    folderLocal.add(propsLocal, "Enabled");
    folderLocal.add(propsLocal, "Shadows");
    folderLocal.add(propsLocal, "Plane", 0.3, 1.25);

    folderGlobal.add(propsGlobal, "Enabled");
    folderGlobal.add(propsGlobal, "Plane", -0.4, 3);

    const startTime = Date.now();

    render();

    function render() {
      trackballControls.update(clock.getDelta());

      const currentTime = Date.now();
      const time = (currentTime - startTime) / 1000;

      object.position.y = 0.8;
      object.rotation.x = time * 0.5;
      object.rotation.y = time * 0.2;
      object.scale.setScalar(Math.cos(time) * 0.125 + 0.875);

      requestAnimationFrame(render);
      stats.begin();
      renderer.render(scene, camera);
      stats.end();
    }
  }

  init();
</script>

 

 

 

posted @ 2024-07-15 10:18  carol2014  阅读(4)  评论(0编辑  收藏  举报