英文:
Box Overflow Clipping Three JS
问题
使用three.js有没有办法裁剪或隐藏对象超出其父级的部分?例如,我有一个盒子和一个球体,就像这张图片上的样子:球体在盒子内。
我想裁剪或隐藏球体超出盒子外部的部分。简单来说,我需要类似于CSS中overflow:hidden
的逻辑。
我在three.js方面非常新手,请不要因为我问了一些愚蠢的问题而批评我。无论如何,我的代码在这里:
// 简单的例子
import * as THREE from "https://cdn.skypack.dev/three@0.136.0";
import { OrbitControls } from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls";
let renderer, scene, camera, controls;
init();
animate();
function init() {
// 渲染器
renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
console.log(renderer);
// 场景
scene = new THREE.Scene();
// 相机
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 40);
// 控制器
controls = new OrbitControls(camera, renderer.domElement);
const materialA = new THREE.MeshStandardMaterial({
roughness: 0,
metalness: 0,
color: 0xffffff,
});
const materialB = new THREE.MeshPhysicalMaterial({
roughness: 0,
transmission: 1,
thickness: 0.5,
});
const sphere = new THREE.Mesh(new THREE.SphereGeometry(5, 30, 30), materialA);
sphere.position.set(5, 0, 0);
const box = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 12), materialB);
scene.add(box);
const light = new THREE.DirectionalLight('white', 1);
light.position.set(10, 10, 0);
const light2 = new THREE.DirectionalLight('white', 1);
light2.position.set(-10, -10, -10);
scene.add(sphere, box, light, light2);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
英文:
Using three js is there any way to clip or hide object out of its parent? For example i have a box and a sphere inside of this box like on image: sphere inside box
I want to clip or hide the part of sphere that is outside of the box. To put it simply, i need similar logic like css overflow:hidden works;
I am very new working with three.js, don't judge me if i'm asking something dumb. Anyways,my code is here:
// Simple example
import * as THREE from "https://cdn.skypack.dev/three@0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls";
let renderer, scene, camera, controls;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer({alpha:true, antialias:true});
renderer.autoClear = false;
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
console.log(renderer)
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set(0, 0, 40);
// controls
controls = new OrbitControls( camera, renderer.domElement );
const materialA = new THREE.MeshStandardMaterial({
roughness: 0,
metalness: 0,
color: 0xffffff,
})
const materialB = new THREE.MeshPhysicalMaterial({
roughness: 0,
transmission: 1,
thickness: 0.5
});
const sphere = new THREE.Mesh(new THREE.SphereGeometry(-5,30,30),materialA);
sphere.position.set(5, 0, 0)
const box = new THREE.Mesh(new THREE.BoxGeometry(12,12,12),materialB);
scene.add(box);
const light = new THREE.DirectionalLight('white', 1);
light.position.set(10, 10, 0);
const light2 = new THREE.DirectionalLight('white', 1);
light2.position.set(-10, -10, -10);
scene.add(sphere, box,light,light2);
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
答案1
得分: 0
以下是已翻译的内容:
-
One solution is to using clipping as you suggest.
一种解决方法是使用剪裁,正如您所建议的那样。 -
You have some example here: https://threejs.org/examples/?q=clip
您可以在这里找到一些示例:https://threejs.org/examples/?q=clip -
First you have to enable local clipping on the renderer (see WebGLRenderer.localClippingEnabled).
首先,您需要在渲染器上启用局部剪裁(参见 WebGLRenderer.localClippingEnabled)。 -
Then you can add some clipping planes to specify the area you want to clip. For this, you can use the Math class.
然后,您可以添加一些剪裁平面来指定要剪裁的区域。为此,您可以使用Math类。 -
Enable local clipping:
启用局部剪裁:renderer.localClippingEnabled = true;
-
Create a plane:
创建一个平面:const clipPlane1 = new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0); clipPlane1.translate(new THREE.Vector3(6, 0, 0));
-
And finally, specify the plane in the material:
最后,在材质中指定平面:clippingPlanes: [clipPlane1], clipIntersection: true
-
Here is your entire code:
这是您的完整代码:
// 简单示例
import * as THREE from 'three';
import { OrbitControls } from 'https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls';
let renderer, scene, camera, controls;
init();
animate();
function init() {
// 渲染器
renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.localClippingEnabled = true;
document.body.appendChild(renderer.domElement);
console.log(renderer);
// 场景
scene = new THREE.Scene();
// 相机
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 40);
// 平面
const clipPlane1 = new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0);
clipPlane1.translate(new THREE.Vector3(6, 0, 0));
// 控制器
controls = new OrbitControls(camera, renderer.domElement);
const materialA = new THREE.MeshStandardMaterial({
roughness: 0,
metalness: 0,
color: 0xffffff,
clippingPlanes: [clipPlane1],
clipIntersection: true,
});
const materialB = new THREE.MeshPhysicalMaterial({
roughness: 0,
transmission: 1,
thickness: 0.5,
});
const sphere = new THREE.Mesh(new THREE.SphereGeometry(-5, 30, 30), materialA);
sphere.position.set(5, 0, 0);
const box = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 12), materialB);
scene.add(box);
const light = new THREE.DirectionalLight('white', 1);
light.position.set(10, 10, 0);
const light2 = new THREE.DirectionalLight('white', 1);
light2.position set(-10, -10, -10);
scene.add(sphere, box, light, light2);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
<details>
<summary>英文:</summary>
One solution is to using clipping as you suggest.
You have some example here: https://threejs.org/examples/?q=clip
First you have to enable local clipping on the renderer
(see [WebGLRenderer.localClippingEnabled][1]). Then you can add some clipping planes to specify the area you want to clip. For this, you can use the [Math class][2].
So in your example, you have to:
Enable local clipping:
renderer.localClippingEnabled = true;
Create a plane:
const clipPlane1 = new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0);
clipPlane1.translate(new THREE.Vector3(6, 0, 0));
And finally, specify the plane in the material:
clippingPlanes: [clipPlane1],
clipIntersection: true
---
Here is your entire code:
// Simple example
import * as THREE from 'three';
import { OrbitControls } from 'https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls';
let renderer, scene, camera, controls;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.localClippingEnabled = true;
document.body.appendChild(renderer.domElement);
console.log(renderer);
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 40);
// planes
const clipPlane1 = new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0);
clipPlane1.translate(new THREE.Vector3(6, 0, 0));
// controls
controls = new OrbitControls(camera, renderer.domElement);
const materialA = new THREE.MeshStandardMaterial({
roughness: 0,
metalness: 0,
color: 0xffffff,
clippingPlanes: [clipPlane1],
clipIntersection: true,
});
const materialB = new THREE.MeshPhysicalMaterial({
roughness: 0,
transmission: 1,
thickness: 0.5,
});
const sphere = new THREE.Mesh(new THREE.SphereGeometry(-5, 30, 30), materialA);
sphere.position.set(5, 0, 0);
const box = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 12), materialB);
scene.add(box);
const light = new THREE.DirectionalLight('white', 1);
light.position.set(10, 10, 0);
const light2 = new THREE.DirectionalLight('white', 1);
light2.position.set(-10, -10, -10);
scene.add(sphere, box, light, light2);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
[1]: https://threejs.org/docs/index.html?q=renderer#api/en/renderers/WebGLRenderer.localClippingEnabled
[2]: https://threejs.org/docs/index.html?q=plane#api/en/math/Plane
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论