What's the deal with Object Clipping in Three.JS?

Currently, I am exploring ways to partition my 3D models using three.js in a manner akin to Unity's functionality: https://i.sstatic.net/E30Is.jpg

While experimenting with the camera controls, I have managed to adjust the near/far fields for clipping in line with the camera direction. However, if I wish to solely clip in the X or Y plane, it becomes challenging. One potential solution I pondered was incorporating a sizable transparent block that could slide along that axis and then utilizing binary operations to combine/subtract where it intersects the object. Unfortunately, this method results in creating a new mesh parallel to the new plane instead of completely removing elements along that specific axis.

Should I delve into multiple viewports, or is there a more straightforward approach available?

Answer №1

Applying clipping in the shader can be achieved with relative ease. By performing certain calculations, it is even possible to create a clipping area resembling a sphere, for instance. The simplest way to clip is at a plane perpendicular to the coordinate system. First, compute the world position of the pixel in the vertex shader:

worldPosition = modelMatrix * vec4( position, 1.0 );

In the fragment shader, prevent the rendering of the pixel if it exceeds your defined clipping limit:

if ( worldPosition.x > clippingLimitX ) {
    discard;
}

However, this approach may result in leaving the mesh open along the clipping edge. To address this issue, utilize a stencil buffer. Reduce the stencil using a scene showing the backfaces and then increase it with a scene displaying the clipped front faces. Ensure that the materials used in these scenes are not visible by deactivating their color and depth write capabilities:

new THREE.ShaderMaterial( { colorWrite: false, depthWrite: false, ... } );

Employ the stencil to depict a plane positioned at the clipping planes' location. Subsequently, render the clipped front faces following the disabling of the stencil:

renderer.autoClear = false;
renderer.clear();

var gl = renderer.context;

renderer.state.setStencilTest( true );

renderer.state.setStencilFunc( gl.ALWAYS, 1, 0xff );
renderer.state.setStencilOp( gl.KEEP, gl.KEEP, gl.INCR );
renderer.render( backStencilScene, camera );

renderer.state.setStencilFunc( gl.ALWAYS, 1, 0xff );
renderer.state.setStencilOp( gl.KEEP, gl.KEEP, gl.DECR );
renderer.render( frontStencilScene, camera );

renderer.state.setStencilFunc( gl.EQUAL, 1, 0xff );
renderer.state.setStencilOp( gl.KEEP, gl.KEEP, gl.KEEP );
renderer.render( capsScene, camera );

renderer.state.setStencilTest( false );

renderer.render( scene, camera );

An interactive demo illustrating how to clip at multiple planes simultaneously can be found here:

The built-in three.js clipping planes were not employed in this demo since it necessitates rendering the stencil utilizing a shader to determine if a clipping plane is oriented towards or away from the camera, allowing for clipping only at planes facing the camera.

Answer №2

You can now utilize clipping in your project.

Follow this pattern and adjust it to suit your specific requirements.

var localPlane = new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 1 );

var globalPlane = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 1 );

renderer.clippingPlanes = [ globalPlane ];

renderer.localClippingEnabled = true;

var material = new THREE.MeshPhongMaterial( {
    clippingPlanes: [ localPlane ],
    clipShadows: true
} );

Check out these examples using three.js:

https://threejs.org/examples/webgl_clipping.html https://threejs.org/examples/webgl_clipping_advanced.html

three.js r.85

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Newbie to Next-JS exploring the use of two dynamic APIs, with successful integration of one while encountering difficulties with the other

I recently received help from a friend to transform my inefficient JS web app into a next-app. However, as I attempted to progress further, I encountered various obstacles and found myself feeling lost. Within my project, I have developed two APIs that fe ...

Guide on sending an array containing various arrays through a parameterized URL using JavaScript

As I delve into utilizing javascript, I am faced with the challenge of passing a JSON Serialized array containing multiple arrays as a parameterized URL. While searching on StackOverflow, I came across various articles discussing the passing of singular a ...

What is the process for including "onload" in my Dojo class?

Is there a way for me to incorporate an "onload" function into my personalized Dojo class which can trigger functions that are registered to listen for the event? Perhaps something like myWidget.addOnLoad(...) My class doesn't belong to Dijit, it&apo ...

Encountering issues with Angular 2 router navigation within OnInit of a component

In the process of creating a testing platform for students to take tests, I encounter an issue with navigation in my TestComponent. Upon initialization, I retrieve the complete test from a service and then attempt to route to either the questions or instru ...

React-Native 0.1.17 Navigator Bar: Enhancing User Navigation Experience

An issue arose after upgrading my react-native 0.1.15 app to version 0.1.17 - I'm now encountering an 'Unable to download JS bundle error'. Upon investigation, I found the error in my code: var SportsSocial = React.createClass({ component ...

How do I make pagination re-render in React based on the number of objects displayed per view selected by the user?

My pagination system, which utilizes <ToggleButtons>, allows users to choose how many items they want displayed per page. However, there is an issue where the pagination display shows more page numbers than needed when a user selects a different amou ...

Navigating to a specific element following an AJAX request

Can't seem to get the page to scroll to a specific element after an ajax call. What could be causing this issue? index.php <style> #sectionOne { border: 1px solid red; height: 100%; width: 100%; } #sectionTwo { border: 1px solid blue; heigh ...

Having trouble launching the Socket.io Chat Demo? Encounter an issue with the error message at ..//

Hello, I am a novice in the world of programming and recently attempted to run the socket.io chat demo. Unfortunately, I encountered an error message at line 5 stating that it cannot find ('../..'). Can someone please shed some light on why this ...

Starting a web application offline using npm: A beginner's guide

Asking about starting offline development for a web-oriented application may seem odd in today's constantly connected world, but I am truly fed up with this situation. Every time I initiate a project using modern web technologies and tools like webpa ...

Storing a collection of strings in a MongoDB database: A step-by-step guide

I have come across a few similar questions on stack overflow like this one: How to store an array of Strings in Node MongoDB Mongoose - Save array of strings However, I am unable to understand why my method is not working. I am attempting to save the str ...

Exploring ways to retrieve query parameters and search params within a loader function in React Router version 6

I set up a route configuration like this: const router = createBrowserRouter([ { path: "/", element: <Layout />, children: [ { index: true, element: <Home /> }, { path: "contacts", element: <Cont ...

Struggling with the Communication of Data between React Native and a React Application Rendered in WebView

I am currently working on a project that involves sending gyroscope data from a React Native app to a React app embedded within a WebView. Unfortunately, I have been encountering challenges in transmitting this data successfully. To simplify things, I woul ...

Creating a seamless and interactive online platform

I am in the process of designing a website that has a sleek and dynamic layout, rather than just a static homepage. Let me explain further: Here is my current setup so you can understand what I am trying to achieve. By dynamic, I mean that when the page ...

Emulate a Click Using Pure JavaScript

I am looking to add a click event to my custom dropdown, which replaces a SELECT element. The purpose of this click event is to trigger the corresponding OPTION item when an LI element is clicked. It seems like Woocommerce uses some JavaScript or PHP func ...

Converting JSON arrays with nested "nth level" objects into a multidimensional array

Looking for guidance on converting a nested object into a multidimensional array. [{ "name": "level1", "subCategory": [{ "name": "level2", "subCategory": [{ "name": "level3", "val": 1, "subCategory": null }] }] }, { " ...

Unable to adjust the width of the content and sidebar

I've been attempting to adjust the width of content and sidebar on my website , but I'm not having much luck. It may seem like a simple question, but even after tweaking the CSS, I am still not seeing the desired outcome. Any assistance would be ...

The component in React does not refresh after updating the state

I have a React page where I am displaying a list of quizzes fetched from an external API. There's also a "New Quiz" button that opens a dialog with a form for users to create a new quiz. My issue is with making the table re-render once the POST reque ...

Error Event Triggered by AJAX with No Response Data

I am currently facing an issue with an API call I am making. Everything seems to be working fine as I receive the token and a status code of 200 is returned (confirmed in Fiddler). However, the problem arises when the AjaxError event fires and the respon ...

HTML anchor tag failing to redirect to specified link

I need to populate the URI property from an API result into an HTML format. I attempted to achieve this by calling a function and running a loop 3 times in order to display 3 links with the URI property of each object. However, the code is not functioning ...

Creating a dynamic start page for Progressive Web Apps (PWA) involves determining the

Recently, I developed a project called "Progressive Web App" using JavaScript and Visual Studio 2017. One key element of the project is the file "package.appxmanifest", which defines the StartPage. I am curious to know if there is a way to dynamically se ...