gpt4 book ai didi

three.js - 是否可以只使组件的一部分不可见?

转载 作者:行者123 更新时间:2023-12-02 00:58:44 25 4
gpt4 key购买 nike

我有一个想要使用 Aframe 构建的交互概念。
场景由 2 个组件组成。

  • 里面有元素的立方体

  • 立方体内部的元素不可见,因为外壳遮挡了它们。

    现在是棘手的部分:球有一个半径,它将外壳的一部分隐藏在其半径内。

    我认为一张图片会很好地澄清:

    first image: cube with object inside; second image: circle with its radius; third image: case of cube dissapears inside radius of ball
  • 这可以用 Aframe 还是 Three.js 实现?
  • 我该如何处理?

  • 编辑:错字

    最佳答案

    只是解决方案的一个选项,在我的评论中提到:

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.set(-5, 8, -8).setLength(8);
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.target = new THREE.Vector3(0, 2, 0);
    controls.update();

    var light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(-10, 10, 10);
    scene.add(light);
    scene.add(new THREE.AmbientLight(0xffffff, 0.25));

    scene.add(new THREE.GridHelper(4, 4, 0x404040, 0x404040));

    // boxes
    var boxGeom = new THREE.BoxBufferGeometry();
    boxGeom.translate(0, 0.5, 0);
    var boxMaterial = new THREE.MeshLambertMaterial({
    color: "gray"
    });
    for (let x = 0; x <= 1; x++) {
    for (let z = 0; z <= 1; z++) {
    let box = new THREE.Mesh(boxGeom, boxMaterial);
    box.position.set(x - 0.5, 0, z - 0.5).multiplyScalar(1.5);
    box.scale.set(1, Math.abs(x) + Math.abs(z) + 1, 1);
    scene.add(box);
    }
    }

    // wrapping box
    var wrappingBoxGeom = new THREE.BoxBufferGeometry(4, 4, 4);
    wrappingBoxGeom.translate(0, 2, 0);
    var wrappingBoxMaterial = getMaterial({
    diffuse: 0xaaaaaa,
    inside: false
    });
    var wrappingBox = new THREE.Mesh(wrappingBoxGeom, wrappingBoxMaterial);
    scene.add(wrappingBox);

    var clock = new THREE.Clock();
    var time = 0;

    render();

    function render() {
    requestAnimationFrame(render);
    time += clock.getDelta();
    wrappingBoxMaterial.uniforms.clippingSphere.value.x = Math.sin(time) * 2;
    renderer.render(scene, camera);
    }
    body {
    overflow: hidden;
    margin: 0;
    }
    <script src="https://cdn.jsdelivr.net/npm/three@0.96.0/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.96.0/examples/js/controls/OrbitControls.js"></script>
    <script>
    var sphereRadius = {
    value: 2.5
    };

    function getMaterial(params) {

    var diffuse = params.diffuse === undefined ? 0xffffff : params.diffuse;
    var diffuseBack = params.diffuseBack === undefined ? diffuse : params.diffuseBack;

    var inside = params.inside === undefined ? true : params.inside;
    inside = inside ? 1 : -1;

    let lambert = new THREE.ShaderMaterial({
    uniforms: THREE.UniformsUtils.merge([THREE.ShaderLib.lambert.uniforms, {
    clippingSphere: {
    value: new THREE.Vector4()
    },
    diffuseBack: {
    value: new THREE.Color()
    }
    }]),

    vertexShader: THREE.ShaderLib.lambert.vertexShader
    .replace(/varying vec3 vLightFront;/g, 'varying vec3 vLightFront;\nvarying vec4 worldPosition;')
    .replace(/#include <worldpos_vertex>/g, 'worldPosition = modelMatrix * vec4( transformed, 1.0 );'),

    fragmentShader: THREE.ShaderLib.lambert.fragmentShader
    .replace(/uniform float opacity;/g, 'uniform float opacity;\nuniform vec4 clippingSphere;\nuniform vec3 diffuseBack;')
    .replace(/varying vec3 vLightFront;/g, 'varying vec3 vLightFront;\nvarying vec4 worldPosition;')
    .replace(/#include <clipping_planes_fragment>/g, '#include <clipping_planes_fragment>\n if (distance(worldPosition.xyz, clippingSphere.xyz) * sign(clippingSphere.w) > clippingSphere.w) discard;')
    .replace(/#include <dithering_fragment>/g, '#include <dithering_fragment>\n if (!gl_FrontFacing) gl_FragColor.xyz = diffuseBack;'),

    lights: true,

    side: THREE.DoubleSide
    });

    lambert.uniforms.clippingSphere.value.set(0, 3, -1, sphereRadius.value * inside);
    lambert.uniforms.diffuse.value.set(diffuse);
    lambert.uniforms.diffuseBack.value.set(diffuseBack);

    return lambert;
    }
    </script>

    关于three.js - 是否可以只使组件的一部分不可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52172224/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com