An optimal method for illuminating and creating shadows on a voxel landscape

I'm currently working on generating a Minecraft-like chunk using BufferGeometry and predefined data. My main issue lies in efficiently lighting up this object.

My current setup involves using a MeshLambertMaterial along with a DirectionalLight to cast shadows on voxels not directly in the light's view. However, due to the large terrain size, I am encountering problems with the shadow map being too large and causing glitchy artifacts in the shadows.

Below is the code snippet I am using to add indices and vertices to the BufferGeometry:

// Add indices to BufferGeometry
for ( var i = 0; i < section.indices.length; i ++ ) {
    var j = i * 3;
    var q = section.indices[i];

    indices[ j ]     = q[0] % chunkSize;
    indices[ j + 1 ] = q[1] % chunkSize;
    indices[ j + 2 ] = q[2] % chunkSize;
}

// Add vertices to BufferGeometry
for ( var i = 0; i < section.vertices.length; i ++ ) {
    var q = section.vertices[i];

    // There's 1 color for every 4 vertices (square)
    var hexColor = section.colors[i / 4];

    addVertex( i, q[0], q[1], q[2], hexColor );
}

Here's an example of my 'chunk': http://jsfiddle.net/9sSyz/4/

Take a look at this screenshot:

If I were to remove the shadows from my example, all voxels on the correct side would be lit up even if another voxel obstructed the light. I am looking for a more scalable solution to create the illusion of a shadow. One idea could be to adjust vertex colors based on their visibility to the light source. It doesn't have to be as precise as the current shadow implementation, so changing the vertex colors to simulate blocky shadows might suffice.

Any advice or help in this matter would be greatly appreciated. Thank you.

Answer №1

When dealing with large terrains, one effective approach is to divide the scene into multiple cascades, each having its own shadow map. This technique, known as CSM (cascaded shadow maps), is commonly used in dynamic scenes. However, finding a webGL example that demonstrates this method can be challenging.

Another possibility is incorporating ambient occlusion, which adds depth and realism to the environment but does not directly create shadows like CSMs do.

If your scene remains mostly static, another viable option is using baked shadows - preprocessed textures applied directly to objects such as terrain. For dynamic elements, rendering their own shadow maps and applying them to geometry can simulate shadows realistically.

Combining these techniques can result in even more effective shading and lighting effects for your projects.

P.S. If possible, could you please share a screenshot? Unfortunately, the fiddles seem to be failing to load at the moment.

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

Node.js allows for keeping pipe and sockets open even after streaming an HTTP response

My current challenge involves streaming data from an HTTP response to a cloud storage provider within an internal service. const response = await request<Readable>({ headers: httpOpts?.headers, data: httpOpts?.data, url, method, responseTyp ...

Guide to implementing the patchValues() method in conjunction with the <mat-form-field> within the (keyup.enter) event binding

I am currently working on a feature that populates the city based on a zip code input. I have successfully achieved this functionality using normal HTML tags with the (keyup) event binding. However, when trying to implement it using CSS, I had to use (keyu ...

Leveraging Amplify for offline storage while transitioning between HTTP and HTTPS protocols

Recently, I encountered an issue with Amplify 1.0a1 on my website. It seems that when storing the value of prod_id in localStorage on a page using HTTP, and then navigating to a page using HTTPS (such as the 'list' page), I am unable to access th ...

Maintaining form field stability while utilizing jQuery for form creation

Using JSON to populate options in a select tag, I want the system to dynamically fill the city dropdown when a country is selected. <label class="AddressLable">Country</label> <select name="country" id="countryCB"> ...

Performing JavaScript functions after fetching an XSLT page via AJAX

Is there a way to trigger JavaScript at a particular time without relying on setInterval() or onClick()? The issue I'm facing is that when I click to load an XSLT page using Ajax, the JavaScript within it does not execute even though it's writt ...

Critical bug discovered in fundamental Vue.js component by Internet Explorer

My Vue.js-powered application is performing flawlessly in all web browsers, except for one... Upon attempting to launch it on Internet Explorer, a frustrating error appears: An anticipated identifier in vue.min.js, line 6 character 4872 Locating the spe ...

Tips for successfully transferring values from an onclick event in JavaScript to a jQuery function

I am encountering a challenge with an image that has an onclick function associated with it. <img id='1213' src='img/heart.png' onclick='heart(this.id)'> This particular function needs to be triggered : function heart ...

Having trouble launching the react app with npm start command

Attempting to launch a react app created by someone else. The instructions provided stated that in order to start it, I need to follow these steps To initiate the webpack dev script, execute npm start [appname]. The term [appname] corresponds to an appli ...

Filter out the selection choice that begins with 'aa' in the drop-down menu

Here is a select field with various options: <select id="sel"> <option value="1">aadkdo</option> <option value="2">sdsdf</option> <option value="3">aasdfsddkdo</option> <option value="4"> ...

Identifying the moment when attention shifts away from an element

Is it possible to detect when focus occurs outside an element without relying on global selectors like $(document), $(body), or $(window) for performance reasons? If achieving this without global selectors is not feasible, provide a provable reason expla ...

Updating a database seamlessly via a dropdown menu without having to refresh the entire webpage

Before we proceed, please take a look at the following code: $(document).ready(function() { $("#alternatecolor [type=button]").each(function() { $(this).on('click', function() { btnObj = $(this); rowId = $(this).attr("rowId") ...

Invoking a parent controller method from a directive in AngularJS

I have utilized a tree grid plugin from the following link: https://github.com/khan4019/tree-grid-directive and I made some customizations to its template: .directive('treeGrid', [ '$timeout', function($timeout) { return { ...

Guide to creating draggable text on a video with HTML

I have a challenge where I need to overlay text on a video and make it draggable across the entire video. Currently, I am able to display the text over the video successfully, but when I try to drag it and then drop it, the text appears below the video and ...

Tips for verifying the compatibility of elements as parent or child components

Is it possible in JavaScript to verify if an HTML element can be a child of another element? For instance: Can an unordered list (<ul>) contain a list item (<li>) as a valid child element? - Yes Can an unordered list (<ul>) contain ano ...

Loading a page with a subtle fade-in effect using jQuery

Looking to add some jQuery functionality to my navigation menu in order to have the page wrapper fade in and out when a main nav link is clicked. While the code itself is functioning properly, I am encountering a couple of issues: There is a brief flash ...

Using Three JS: Import an OBJ file, move it to the center of the scene, and rotate around it

I am trying to figure out how to load an OBJ file and translate its coordinates to the world origin (0,0,0) in order to make orbit controls function smoothly without using Pivot points. My goal is to automatically translate random OBJ objects with differe ...

Changes to the parent state will not be reflected in the child props

When the child component PlaylistSpotify updates the state localPlaylist of its parent, I encounter an issue where the props in PlaylistSpotify do not update with the new results. I've been struggling to figure out what I'm missing or doing wrong ...

Incorporating the fadeout technique in conjunction with the append() function

Here is some code that I am working with: $('body').on('click' , function(){ $('body').append('<div class="ajax-success"><p>Its Done !!!</p></div>').fadeOut(2000); }); The goal was to a ...

Creating a real-time email validation system that incorporates both syntax and domain checking

I recently came across a helpful example on that guided me in implementing basic validation for emails and usernames. This led me to another demonstration where ajax was used to call a live email checker PHP script. However, I've hit a roadblock whe ...

Analyzing the markup within the React-Mentions package

I am currently utilizing the 'react-mentions' library to mention names from a database. However, the data format that is being returned is quite peculiar. I am now looking to transform this data into a JSON format. Here is the code I have: <M ...