My goal is to exclusively create illustrations of items within a camera's view

Currently, I am using THREEJS to create a dynamically generated 'minecraft' world utilizing a perlin noise generator.

Check out the progress so far: Block World

Everything is going smoothly except that I am facing significant performance issues once the number of 'objects' reaches around 7,000.

My world usually consists of approximately 12-14 thousand objects when the dimensions are set to a maximum of 64*64*6 (the Perlin map only uses a portion of these blocks).

I believe what I need to do is only render the blocks that are visible to the camera and implement "Occlusion Culling," but I have been unable to find any working examples for this in ThreeJS.

One idea I had was to perform Raytracing for each pixel on the screen to check for intersections with the first object:

raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.children );

However, I suspect this approach may be too slow.

Another thought was to merge all meshes together into one, which did improve frame rates significantly. Unfortunately, I lost the ability to manipulate individual blocks and their textures. So, merging may not be the ideal solution.

I am hoping someone can guide me on how to hide meshes that are out of view due to being obstructed by other objects.

Thank you

EDIT: Regarding suggestions to implement frustum culling, I have already tried this

var counter = 0;
//
// Only draw objects that you can see... I think
frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));
for (var i=0; i<world.length; i++) {
    for (var j=0; j<world[i].length; j++) {
        for (var d=0; d<world[i][j].length; d++) {
            if ( world[i][j][d].type !== -1 ) {
                if ( frustum.intersectsObject( world[i][j][d].block ) ) {
                    world[i][j][d].block.visible = true;
                    counter++;
                }
            }
        }
     }
}
console.log(counter);

The counter displayed the number of visible blocks at any given moment, significantly lower than the total number of blocks. However, my framerate decreased drastically with this method, making movement within the scene unbearable.

Answer №1

I came up with a new strategy to combine all the meshes into a single entity, which yielded remarkable results in terms of performance.

If you aim to render numerous cubes at 60 FPS, merging them into one large mesh is essential. However, instead of consolidating all cubes into one massive structure, consider grouping cubes into chunks and utilizing multiple chunks to depict your virtual world.

Although I encountered issues with manipulating individual blocks and preserving their distinct textures after merging, it was evident that finding a method to reference, modify materials for, and delete blocks within the combined geometry was necessary.

Once you have implemented the chunk system, focus on making adjustments at the chunk level rather than individual cube manipulation. Whenever a cube within a chunk is altered, generate updated mesh data for that chunk and transfer it to the GPU.

I am seeking advice on how to conceal invisible meshes located behind other objects. Can anyone provide guidance on this matter?

Unfortunately, concealing non-visible meshes due to being obstructed by other elements is extremely challenging, if not impossible in JavaScript. Conducting chunk-frustum tests to determine if a chunk is within the viewport is recommended, allowing the GPU to handle the rest through depth testing.

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

Updating object values within a while loop using JavaScript

I am facing an issue with managing an array of JavaScript objects that have a property 'table' with values table1, table2, table3, or table4. Each table should only accommodate 6 members. I have implemented a while loop to check if 'table1&a ...

The repeated execution of a Switch Statement

Once again, I find myself facing a puzzling problem... Despite making progress in my game, revisiting one aspect reveals a quirk. There's a check to verify if the player possesses potions, and if so, attempts to use it involves calculating whether the ...

Issue with Angular 2 pipe causing unexpected undefined result

Here is a JSON format that I am working with: [{ "id": 9156, "slug": "chicken-seekh-wrap", "type": "dish", "title": "Chicken Seekh Wrap", "cuisine_type": [2140] }, { "id": 9150, "slug": "green-salad", "type": "dish", "title": "Green Sala ...

Utilizing optional parameters with React Router

Imagine I have a page at http://www.example.com/page/#/search set up with the following routing: <Router history={hashHistory}> <Route path='/search/' component={SearchPage} /> </Router> When a user performs a search using t ...

The FontLoader feature seems to be causing issues when integrated with Vuejs

While working on a Vue project with threejs, I encountered an error similar to the one described here. The issue arose when attempting to generate a text geometry despite confirming that the path to the typeface font is accurate and in json format. ...

What is the best way to showcase a singular item from response.data?

Below is the controller I have set up to display details of a single book from my collection of json records .controller('BookDetailsController', ['$scope','$http','$stateParams',function($scope,$http,$stateParams){ ...

Insert a THREE.Points element into the scene: Error in THREE.Object3D.add: The object being added is not a valid instance of THREE.Object3D (

Trying to incorporate a system of particles, a THREE.Points element into the scene has resulted in the following error: "THREE.Object3D.add: object not an instance of THREE.Object3D. undefined" The code used for this is as follows: var backCount = 1800; ...

Trouble arises when trying to open a new window using the Angular 8 CDK

I am attempting to open my component in a new window, similar to this example: https://stackblitz.com/edit/angular-open-window However, when the window opens, my component is not displayed and I receive the following error in the console: Error: Must pro ...

Discover the secret to instantly displaying comments after submission without refreshing the page in VueJS

Is there a way to display the comment instantly after clicking on the submit button, without having to refresh the page? Currently, the comment is saved to the database but only appears after refreshing. I'm looking for a solution or syntax that can h ...

What is the best way to customize the functionality of the Done (node-dialog-ok) button in node-red when it is

I have created a custom node and I want to trigger some specific actions when the 'Done' button (with id: node-dialog-ok) in the editor-tray-toolbar is clicked, instead of its default functionality. Is it possible to override the onclick event o ...

On iOS devices, background images may not appear in the Home Screen after being added

My CSS code looks like this: #thumbnail { background-image: url(bla.jpg), background-size: cover, background-repeat: no-repeat; background-position: 50% 50%; } While it displays fine on iOS Safari and other platforms, the image does not s ...

Issue in VueJs where mutations do not properly save new objects to the state

I am facing an issue with updating my vuex store after modifying my user credentials in a component. Below is the code snippet for reference: mutations: { updateUserState: function(state, user) { state.user = user; }, } actions: { updat ...

Utilizing jQuery BBQ for Seamless Transitions – From Fading to Sliding and More

This is my first time posting a question here, even though I am an active user of stackoverflow. I have developed a website using jQuery BBQ to load pages through AJAX while still maintaining the ability to track history with the back button and other fun ...

"Implement highcharts redraw() method to update the chart, along with a callback function that interacts

I am working with a chart that utilizes the events.load function to draw lines based on the properties of the chart. The load function is functioning as expected, but I want to erase and redraw the lines each time the chart is redrawn, such as when hiding ...

Is there a way to retrieve the JSON url from the input box

My goal is to retrieve a JSON file from a URL entered in a text box. I have identified the text box as txtr and used jQuery to get the value like this: var txtbval = $("#txtr").val();. I then included this value in the JSON parsing script as follows: url: ...

Developing a side panel for navigation

My goal is to create a sidebar that shifts to the right from the left side and makes space on the page when the hamburger menu is pressed. I have made progress in achieving this, but I am encountering difficulties with the animation. const btnToggleSide ...

What could be the reason for Spawn() not being invoked?

After working with node.js and express for some time, I have encountered a persistent bug in my code. In my service file, there is a resolved Promise where I call spawn(), but for some reason, the spawn code never gets executed (or if it does, ls.on(' ...

Display exclusively the chosen option from the dropdown menu

I am facing an issue with the select input on my webpage. Whenever I try to print the page, it prints all the options of the select instead of just the one that is selected. Can someone please guide me on how to modify it so that only the selected option ...

Bizarre symbols observed while extracting data from HTML tables produced by Javascript

I am in the process of extracting data from Specifically, my focus is on the "tournament-page-data-results" div within the source code. Upon inspecting the HTML source code, the data does show up, but it appears with a mix of real information and random c ...

Blend express router by chaining the (.route) method with other HTTP methods like (.get, .post, etc) to create

Here is my code structure: let router = require( 'express' ).Router(); Later on, I define my routes like this: router .route( '/' ) .get( listMiddleware ); router .route( '/:id' ) .get( getOneByIdMiddleware ...