How can we stop self shadowed faces from being illuminated?

Currently, I am working on creating a city scene in Three.js and experimenting with lighting and shadows. Specifically, I am focusing on a single building that was modeled in 3DS Max, then exported to OBJ format, and converted using a Python converter through the command line.

Upon inspecting the model of the building, I noticed that it is a single object with self-shadowing effects. However, I encountered an issue where the lower part of the building, even when within the cast shadow, is still being illuminated by the yellow-white directional light. It seems that the illumination calculation is solely based on how much the surface faces the light source, without considering any obstructions between them.

I have been exploring methods to address this concern and achieve a more realistic outcome where the mesh obstructs the light from reaching objects behind it, including within itself. Should I delve into shaders or normal maps? Or is there another approach that would be more effective?

I came across a related question regarding light penetrating through meshes, but it lacked code snippets or examples for reference: Light penetrating through meshes. Apologies if this overlaps with existing discussions.

For those interested, the JSFiddle link showcasing the relevant code can be found here: http://jsfiddle.net/mrfolkblues/u01jwg53/

The crucial snippet of the code involves:

var T = THREE,
    stats,
    container,
    camera = new T.PerspectiveCamera(40, window.innerWidth/window.innerHeight, 0.1, 200),
    scene = new T.Scene(),
    renderer = new T.WebGLRenderer({
        antialias: true
    }),
    radius = 35, theta = 0, thetaDelta = 0, camtarget,
    boundingbox, cube, plane, poly, polyMesh, sphere, line,
    clock = new T.Clock();

    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFShadowMap;

// initialization
(function(){

    container = document.createElement( 'div' );
    document.body.appendChild( container );

    // setting up the renderer
    renderer.setClearColor( 0xf0f0f0 );
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild(renderer.domElement);

    var light = new T.DirectionalLight( 0xfff3cb, 1.25 );
    light.position.set( 60, 25, 40 );

    var light2 = new T.DirectionalLight( 0x204fae, 1.25 );
    light2.position.set( -30, 40, 0 );

    light.castShadow = true;
    light.shadowDarkness = 0.33;
    light.shadowCameraTop = 20;
    light.shadowCameraRight = 20;
    light.shadowCameraBottom = -20;
    light.shadowCameraLeft = -20;
    light.shadowCameraNear = 0;
    light.shadowCameraFar = 200;
    light.shadowMapWidth = 2048;
    light.shadowMapHeight = 2048;
    light.shadowBias = 0.0002;

    scene.add( light );
    scene.add( light2 );

    var cube = createCube([0.5, 0.5, 0.5], [1.5, 10, 0]);

    // positioning the camera
    camera.position.x = 0;
    camera.position.y = 20;
    camera.position.z = radius;
    camtarget = cube.position;
    camera.lookAt( camtarget );

    createPlane();

    var loader = new T.JSONLoader();
    var parsed = loader.parse(window.buildingModel);

    var material = new T.MeshLambertMaterial( {
        color: 0xffffff
    } );

    var object = new THREE.Mesh( parsed.geometry, material );
    object.castShadow = true;
    object.receiveShadow = true;
    scene.add( object );

    object.position.x = 30;
    object.position.y = 0;
    object.position.z = 15;

    // adding event listeners
    window.addEventListener( 'resize', onWindowResize, false );

    render();
    animate();
})();

Answer №1

The solution you seek is not provided by three.js or any other webgl libraries currently available. Your problem requires the implementation of Global Illumination techniques, which falls beyond the capabilities of three.js.

Answer №2

Shadows in three.js version r.73 are created with a simple approximation method: areas in shadow are darkened by adjusting a factor that you can set yourself:

light.shadowDarkness = 0.33;

If you increase the value of shadowDarkness to 1, the issue will be resolved. However, keep in mind that it may not look as visually appealing.

Check out the updated demo here: http://jsfiddle.net/u01jwg53/1/

Rest assured that future versions of three.js will bring enhancements to the shadow rendering capabilities.

Version r.73 of three.js

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

Deliver JavaScript and HTML through an HTTP response using Node.js

My attempts to send both a JavaScript file and an HTML file as responses seem to be failing, as the client is not receiving either. What could be causing the client to not receive the HTML and JavaScript files? I am using Nodejs along with JavaScript and H ...

Errors related to Typescript are causing issues with the stock installation of Next.js

Whenever I use typescript with create-next-app, my tsx files are filled with numerous "Problems" messages. These errors only appear in Visual Studio Code and do not affect the build process. I have tried uninstalling vscode, removing all extensions, and ...

Exploring the functionality of dimensions in d3 parcoords

I am diving into the world of d3 and experimenting with Behold, a simplistic example directly from the website. <script src="http://d3js.org/d3.v3.min.js"></script> <script src="d3.parcoords.js"></script> <link rel="stylesheet" ...

What is the significance of the ngf prefix within the context of AngularJS and ng-file-upload?

I recently discovered the ngf-select directive within ng-file-upload for AngularJS. Here's how it's used: <button type="file" ngf-select="uploadFiles($file, $invalidFiles)" accept="image/*" ngf-max-height="1000" ngf-max-size="1MB"> ...

Obtain the value from the controller of the amazing-rating component

Currently utilizing the amazing Rating AngularJS library available at https://github.com/bandraszyk/awesome-rating I am interested in understanding how to retrieve the selected value and store it in my controller. The $scope.rating is returning undefined ...

Is there a way to modify the window's location without having to reload it and without resorting to any sne

Initially, I believed that the hash hack was a necessity, but after observing the recent updates from Facebook, my perspective has shifted. The original hash hack (not certain if this is the correct term) involved changing location.hash to save a state in ...

Fetching Unicode block specials using axios in getStaticProps with Next.js

Click here to view the code and data results My attempt using the fetch method was successful, but I encountered issues when trying to use 'axios' ...

Execute Python code alongside JavaScript functions using ExecJS - an efficient JavaScript engine for seamless integration with

Currently, I am exploring the integration of JavaScript engine with Python. I am interested in working with Python classes in JavaScript and vice versa, as well as using JavaScript code within Python. How can I achieve this? In a Java project, I have suc ...

Attitude: Defiant and Ignoring Authority

So far, no suggestions have been made, indicating that maybe I haven't properly summarized the issue; The problem arises when I absolutely position the section with the class="container" using an additional class or id specific to that <div>. I ...

What is the best method for extracting information from different websites? I typically utilize the $.post function for this task

Currently conducting a test on a javascript code located on localhost. The script is dependent on receiving data in JSON format from a remote server. Strangely, when I manually access the JSON url, the data loads without issue. However, when using JavaScri ...

Ionic: How come my image is not loading with HTTP.GET?

I have been attempting to populate a gallery in my Ionic application by fetching images from a JSON file, but I am encountering issues. While following a guide on creating a grid-like image gallery using the Ionic framework (https://blog.nraboy.com/2015/03 ...

Trouble with jQuery click event on dynamically generated elements

I have a jQuery function that iterates through each element inside a specified div (#container) and triggers a JavaScript alert whenever a span is clicked. Everything functions correctly when the spans are static. However, when I include code like this: ...

Locating a specific item using its individual ID within Firebase

One thing that's often overlooked in Firebase tutorials is how to retrieve objects based on their unique IDs. The push() method generates these unique IDs automatically, but the question remains: how do we access the specific object associated with an ...

Is it possible to return an array of middleware from one middleware to another in Express JS?

Looking to display shop information through a route. The route setup is as follows: router.param('userId',getUserById) router.get("/store/:storeName/:userId?",isAuthenticated,getStoreDetail) My goal is to send different responses based ...

When you log a JavaScript array after making a call using $.ajax, it may return an index

I am experiencing an issue with my array of 10 elements. When I log their key, value pairs in a loop, they are correctly ordered. $.each( sArray, function(i, k) { log(i, k); // log(i, k) returns correctly // [0] ELEMENT ONE // [1] ELEMENT TW ...

Creating a dynamic table in AngularJS with rotating values for rows and columns

I am seeking assistance in creating a table with a custom number of rows and columns. The table should have two input fields for specifying the number of rows and columns, and upon submission, the table should dynamically adjust to display the specified nu ...

Implementing Text Box Control Validation within a Gridview using UpdatePanel in c# ASP.Net

In my gridview, one of the columns contains a Text Box Control. I am looking to validate the text entered by users as alphanumeric characters and spaces only. Allowed characters are: a-z, A-Z, 0-9, and space. I want to perform this validation using Java ...

Is the create attachment function of the Microsoft Graph API not functioning properly?

I've been trying to create an attachment for my messages by following the documentation provided, but unfortunately, the API seems to be giving me some trouble. I referred to the document at for guidance. Below is the JavaScript code that I have bee ...

Removing background color and opacity with JavaScript

Is there a way to eliminate the background-color and opacity attributes using JavaScript exclusively (without relying on jQuery)? I attempted the following: document.getElementById('darkOverlay').style.removeProperty("background-color"); docume ...

invoke a function through a form in Angular

I am encountering an issue with invoking a function from Angular. This particular function has a dual purpose - it uploads an image to S3 and saves the form data along with the URL of the image in the MongoDB database. Below is the HTML snippet where I cal ...