Strange transparency glitch in Three.js

I've run into a perplexing issue while creating a 3D model for my website. One of the character's arms appears to be transparent, but only partially - you can see inside it. Here's what I'm talking about: Transparent arm. I've tried backtracking my code and re-rendering it in Blender since it's a .obj import, but the problem persists. Does anyone have any insight on how to fix this?

<body>

    <script src="./JS/three.js"></script>

    <script src="./JS/DDSLoader.js"></script>
    <script src="./JS/MTLLoader.js"></script>
    <script src="./JS/OBJLoader.js"></script>
    <script src="./JS/OrbitControls.js"></script>  
    <script src="./JS/Detector.js"></script>
    <script src="./JS/stats.min.js"></script>

    <script>

        var container, stats;

        var camera, scene, renderer;

        var mouseX = 0, mouseY = 0;

        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;


        init();
        animate();


        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );
             renderer = new THREE.WebGLRenderer( { 
              alpha: true,
              antialias: true
              } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( 200,300);
            container.appendChild( renderer.domElement );


            camera = new THREE.PerspectiveCamera( 14, window.innerWidth / window.innerHeight, .3, 1000 );
            camera.position.z = 1;
            camera.position.y = 8;
            //camera.rotation.y = -90*(180/3.14159265)


            var orbit = new THREE.OrbitControls( camera, renderer.domElement );
              orbit.enableZoom = false;
              orbit.enablePan = false;
              orbit.autoRotate = true;
            // scene

            scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight( 0xffffff );
            scene.add( ambient );

             var dirLight = new THREE.DirectionalLight(0xffffff, .41);
            dirLight.position.set(100, 100, 50);
            scene.add(dirLight);


            var light = new THREE.PointLight( 0xf8f8ff, 0.25, 10000 );
            light.position.set( 0, 100,-75);
            scene.add( light );

           
            var onProgress = function ( xhr ) {
                if ( xhr.lengthComputable ) {
                    var percentComplete = xhr.loaded / xhr.total * 100;
                    console.log( Math.round(percentComplete, 2) + '% downloaded' );
                }
            };

            var onError = function ( xhr ) { };

            THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );

            var mtlLoader = new THREE.MTLLoader();
            mtlLoader.setBaseUrl( './Avatar/' );
            mtlLoader.setPath( './Avatar/' );
            mtlLoader.load( 'Avatar.mtl', function( materials ) {

                materials.preload();

                var objLoader = new THREE.OBJLoader();
                objLoader.setMaterials( materials );
                objLoader.setPath( './Avatar/' );
                objLoader.load( 'Avatar.obj', function ( object )
                 {
                    object.alphaTest = 0;
                    object.transparent = false;
                     object.side = THREE.DoubleSide;
                 
                    object.position.y = 0;
                    scene.add( object );

                }, onProgress, onError );

            });

         
            document.addEventListener( 'mousemove', onDocumentMouseMove, false );

            //

            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize() {

            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

           

        }

        function onDocumentMouseMove( event ) {

            mouseX = ( event.clientX - windowHalfX ) / 2;
            mouseY = ( event.clientY - windowHalfY ) / 2;

        }

        

        function animate() {

            requestAnimationFrame( animate );
            render();

        }

        function render() {


            camera.lookAt( scene.position );

            renderer.render( scene, camera );

        }

    </script>

I'm truly stumped at this point and would greatly appreciate any assistance! Thank you in advance. Feel free to reach out if you need more information about my code.

Answer №1

Make sure to check the orientation of face normals on the arm, as they may be flipped towards the backside. It's important to note that if a face normal is pointing backwards, it won't be visible when rendered, and only the back side will show up, even in 3D modeling software like blender.

You can easily verify the direction of normals in three.js by using the FaceNormalsHelper.

For more information about this helper tool, you can visit:

If you find that the normal directions are incorrect, simply flip them in your 3D modeling application.

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

Try fetching new data with React Query by refetching

Whenever a button is clicked, I attempt to fetch new data by calling Refetch. const {refetch,data,isLoading} = useQuery( "getkurs",() =>fetch( `https://free.currconv.com/api/v7/convert? q=${selected.country.currencyId}_IDR&compa ...

Updating the input value in a React application

With a list and an edit button, upon clicking the edit button, a new modal opens. How can I auto-populate the selected username email? The server-side response is {this.test.name}, where I provide him with the input value to auto-populate. However, when ...

No data, response or issue received from the Internet API

In my web api project, I have created the following controller: public IEnumerable<Speciality> GetAllSpecialities() { List<Speciality> specialities = null; try { specialities = (new Datatable(Proper ...

Having trouble locating the module '.outputserver ode_modulespiniadistpinia' in Nuxt3 and Pinia?

I recently integrated Pinia into my Nuxt3 project, and while everything works fine in development mode, I encountered an error when trying to access the application in production mode resulting in the website freezing. [h3] [unhandled] H3Error: Cannot find ...

What is the best way to identify duplicate data being returned from a server within a for loop?

When receiving sorted data from the server through an infinite scroll, my goal is to filter out duplicate entries and add new unique data to a client-side array. If duplicates are found, I want to stop the infinite scrolling process. $scope.collections = ...

Encountered an issue retrieving audio during recording with Recorder.js

I've come across a scenario where I'm utilizing the Recorder.js Demo for recording audio. Interestingly, it works perfectly on Linux but encounters an issue when used on Windows. A pop-up alert stating "Error getting audio" shows up. Here's ...

The hyperlink tag within the overlay div is unresponsive

I'm facing an issue with my overlay div (rb-overlay) that pops up when users click on a page option. The overlay takes up the entire page and includes a close button in the top right corner. However, I've noticed that the link at the end of the t ...

Is there a way to customize the selected option in the autocomplete feature of Material UI components?

Is it possible to customize the CSS of selected options in Material UI autocomplete? Can this be achieved by utilizing the theme? ...

Unable to verify the provided resource: Mailchimp

Welcome everyone to my first question posted on StackOverflow. I have tried my best to provide all the necessary details regarding the issue in order to seek assistance. If you require additional information, feel free to ask. To give a brief overview, I ...

Trouble with displaying a cube from Blender to Three.js

Hey everyone, I'm having some trouble exporting a cube from Blender to three.js. I've exported the JSON file, but when I try to display the cube in my code, it's not showing up - instead, all I see is the setColor screen and I can't fig ...

The basic Kendo UI remote DataSource fails to fetch any data

I'm working on a basic exercise where my DataSource object is not returning any data. Here's a snippet of the code: var data = new kendo.data.DataSource({ transport: { read: { url: "data.json", ...

Conditional jQuery actions based on the selected radio button - utilizing if/else statements

This task seemed simple at first, but I quickly realized it's more challenging than expected. Apologies in advance, as Javascript is not my strong suit. My goal is to have the main button (Get Your New Rate) perform different actions based on whether ...

Disabling the scrollTop() effect following a click event with onClick()

Utilizing the scrollTop() event to toggle the visibility of a div at a specific position and also using the onClick() event to permanently hide the div. While the events are functioning properly, an issue arises when scrolling the page causing the div to r ...

Tips for achieving a blurred background image effect when hovering, while keeping the text unaffected

Hey there, I've recently started my journey into web development and have encountered a roadblock. I'm trying to blur the background image of a div on hover without affecting the text inside. I have an id called c1 where I used a javascript func ...

Bootbox Dialog Form

Looking to implement a functionality where a Bootbox dialog pops up with an "OK" button. Upon clicking the "OK" button, it should initiate a POST request, sending back the ID of the message to acknowledge that the user has read it. The Bootbox dialog fun ...

Error: Although precheck is successful, the Chrome API Runtime has exceeded the QUOTA_BYTES_PER_ITEM quota

I keep receiving a QUOTA_BYTES_PER_ITEM error when attempting to store an object, even though my size precheck shows that it should be under the quota. I must be missing something simple here (is this method correct for checking object size?). I've al ...

"Use jQuery to target the first child element within a parent element that has a specific class

Is there a way to choose only the first child of a specific parent class with a certain class for the purpose of clone()? <div class="sector_order"> <div class="line_item_wrapper"> SELECT THIS DIV </div> <div class=" ...

Display a list of items in Angular using ng-repeat, and allow the full description to appear in full width

<div ng-controller = "MyController"> <ul class="items" > <div ng-repeat="item in colors" ng-class="{active:isActive(item)}" ng-click="select(item); whattoshow=!whattoshow"> <li class="col-md-3 col-sm-3 col-lg-3 co ...

Set the local storage value to the $scope variable

I am attempting to set a local storage value to a $scope variable and utilize that $scope variable in ng-model to populate dropdowns. However, the code I have tried is not functioning as expected. You can view the Plunker example here: https://plnkr.co/ed ...

What is the method to restrict the selection of only one option for specific values in a multiple-selection dropdown menu?

Is there a way to create a dropdown menu with the following functionalities: I want to allow multiple selections for options A, B, and C, but disable multiple selection if option D is selected. Any tips on how to achieve this? Thank you. <label>Ch ...