The animation in Three.js may come to a halt when the "skinning = true" setting is employed alongside THREE.ShaderMaterial

Currently, I am developing a game using WebGL and three.js, and I am in need of a skin shader for my character models. However, I have encountered a problem where if I use THREE.ShaderMaterial, the animation stops. Can anyone provide assistance or guidance on this issue?

SkinShaderSimple = function (mapColor, mapHeight, mapSpecular, composer)
{
if (mapColor === undefined)    return new THREE.MeshPhongMaterial();
if (mapHeight === undefined)   return new THREE.MeshPhongMaterial();
if (mapSpecular === undefined) return new THREE.MeshPhongMaterial();
if (composer === undefined)    return new THREE.MeshPhongMaterial();

var shader = THREE.ShaderSkin[ "skinSimple" ];
var fragmentShader = shader.fragmentShader;
var vertexShader = shader.vertexShader;

var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

uniforms[ "enableBump" ].value = true;
uniforms[ "enableSpecular" ].value = true;
uniforms[ "tBeckmann" ].value = composer.renderTarget1;
uniforms[ "tDiffuse" ].value = mapColor;

uniforms[ "bumpMap" ].value = mapHeight;
uniforms[ "specularMap" ].value = mapSpecular;

uniforms[ "diffuse" ].value.setHex( 0xa0a0a0 );
uniforms[ "specular" ].value.setHex( 0xa0a0a0 );

uniforms[ "uRoughness" ].value = 0.145;
uniforms[ "uSpecularBrightness" ].value = 0.75;

uniforms[ "bumpScale" ].value = 16;

uniforms[ "offsetRepeat" ].value.set( 0.001, 0.001, 0.998, 0.998 );


 var mat = new THREE.ShaderMaterial( { fragmentShader: fragmentShader,vertexShader: vertexShader, uniforms: uniforms, lights: true, skinning : true} );

 return mat;
};`

After creating the material, I will then proceed to load the character model and apply the material to it

     loadMainChar = function()
     {
         //tmp loader
          var loader = new THREE.JSONLoader();     

          //loader with callback function
          loader.load( "content/models/character/Goblin.13.js", 
          function ( geometry, materials ) 
          {                  

               // Tell the material that it has bone weights
               var mtl = MaterialsLibrary.CharacterSkinShaderSimple; 
               mtl.skinning = true;


               // Create a new SkinnedMesh (important! Not a animatedMesh!)
              mainCharacter = new THREE.SkinnedMesh( geometry, mtl );
              mainCharacter.position.set(0,0,0); 
              mainCharacter.scale.set(1,1,1);

               // Instantiate the animation

               mainCharAnimation=new THREE.Animation(mainCharacter, geometry.animation);
               mainCharacter.castShadow    = true;
               mainCharacter.receiveShadow = true;

               // Start playing the animation
               mainCharAnimation.play();

               //add char to scene
               scene.add(mainCharacter);
          }          
         ); 

       loader.onLoadComplete = function () {CheckLoadingMeshes();};
   }; 

Answer №1

If you're looking to dive into THREE.WebGLRenderer 82, this block of code will help you get started.

<script type="x-shader/x-vertex" class="vs">

    varying vec2 vUv;
    uniform mat4 bindMatrix;
    uniform mat4 bindMatrixInverse;
    uniform mat4 boneMatrices[ MAX_BONES ];

    mat4 getBoneMatrix( const in float i ) {
        mat4 bone = boneMatrices[ int(i) ];
        return bone;
    }

    void main() {
        vUv = uv;
        mat4 boneMatX = getBoneMatrix( skinIndex.x );
        mat4 boneMatY = getBoneMatrix( skinIndex.y );
        mat4 boneMatZ = getBoneMatrix( skinIndex.z );
        mat4 boneMatW = getBoneMatrix( skinIndex.w );
        mat4 skinMatrix = mat4( 0.0 );
        skinMatrix += skinWeight.x * boneMatX;
        skinMatrix += skinWeight.y * boneMatY;
        skinMatrix += skinWeight.z * boneMatZ;
        skinMatrix += skinWeight.w * boneMatW;
        skinMatrix  = bindMatrixInverse * skinMatrix * bindMatrix;
        vec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );
        vec3 objectNormal = skinnedNormal.xyz;
        vec3 transformedNormal = normalMatrix * objectNormal;
        vec4 skinVertex = bindMatrix * vec4( position, 1.0 );
        vec4 skinned = vec4( 0.0 );
        skinned += boneMatX * skinVertex * skinWeight.x;
        skinned += boneMatY * skinVertex * skinWeight.y;
        skinned += boneMatZ * skinVertex * skinWeight.z;
        skinned += boneMatW * skinVertex * skinWeight.w;
        skinned  = bindMatrixInverse * skinned;
        vec4 mvPosition = modelViewMatrix * skinned;
        gl_Position = projectionMatrix * mvPosition;
    }

</script>
<script type="x-shader/x-fragment" class="fs">

    varying vec2 vUv;

    void main() {
        gl_FragColor = vec4(1, vUv.x, 0, 1.0);
    }

</script>
<script>
    material = new THREE.ShaderMaterial( {
        vertexShader: document.querySelector( '.vs' ).textContent,
        fragmentShader: document.querySelector( '.fs' ).textContent,
        skinning:true
    });
</script>

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

Expanding a React component passed through the Redux connect() function

Is there a method to extend a component connected by the Redux connect() function? For instance, if I am working within the form-container.js and using const FormContainer = connect( mapStateToProps, mapDispatchToProps )(Form) Can I override meth ...

What could be causing my onscroll function to cut off before reaching the end of the element?

Struggling with a function I created to slide a div horizontally into view in the center of a vertically scrolling page. It seems to work well under normal conditions, but when the page is scrolled quickly, it sometimes fails to complete the horizontal mov ...

Exploring AngularJS: Leveraging ng-model within a custom directive featuring iterations and dynamically generated HTML elements

Trying to implement a directive for a grid, I encountered an issue where passing in a column definition that includes an HTML control with ng-model and ng-click directives resulted in an error: "Error: [$rootScope:infdig] 10 $digest() iterations reached. ...

How to create expandable nodes with lazy-loaded children in Dynatree?

I have successfully implemented a tree navigation menu using Dynatree (). The tree consists of four levels: company, group, user, and computer. Each object within the tree is selectable, opening a page displaying the properties of that specific object. How ...

Using jquery and Ajax to extract data from nested JSON structures

Need help with modifying a code snippet for parsing nested JSON format [ { "name":"Barot Bellingham", "shortname":"Barot_Bellingham", "reknown":"Royal Academy of Painting and Sculpture", "bio":"Barot has just finished his final year at T ...

Fill the drop-down menu with the present day's date, month, and year

I'm new to this, so please bear with me. I have some html and jQuery code: $(document).ready(function() { var d = new Date(); var month = d.getMonth() + 1; var year = d.getFullYear(); $("#month").val(month); $("#year").val(year) ...

What is the preferred approach in JavaScript: having a single large file or multiple smaller files?

Having a multitude of JavaScript files loaded on a single page can result in decreased performance. My inquiry is this: Is it preferable to have individual files or combine them into one JavaScript file? If consolidating all scripts into one file is the ...

Is there a way to assign a dynamic value to an input just once, and then retain the updated value without it changing again

During a for loop, I have an input element (type number) that needs its value modified by decrease and increase buttons: <div class="s-featured-list__item s-featured-list__item--expandable" v-for="(item, itemIndex) in category.items" ...

The system encountered an error stating that the required component "Footer" in the main directory was not located in the specified node_modules

Issue I'm Facing: Error found in components/main/Footer within the file path: ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue Components Tree as shown in the screenshot below: https ...

Tips for connecting to multiple items in an md-select element from within a directive

Looking to develop a straightforward directive that displays either a textbox or dropdown based on whether an array is provided for the model property on the scope. Any value other than explicitly setting false in the directive markup such as multiple="fa ...

What is the hierarchy for displaying elements depending on the props?

I have developed a search input component that includes an icon which I want to reposition (either on the left or right side) depending on different scenarios. This input is part of a bootstrap input-group, so modifying the order of elements within my di ...

The div element is finally loading properly after multiple clicks

I need some assistance with loading dynamic divs in Angular. I have created a button that adds new divs each time it is clicked in a specific area. However, once these new divs are added, they appear incorrectly: https://i.sstatic.net/sAE6q.png After add ...

Angular 2 keypress validation: Ensuring data integrity through real-time input verification

I am currently facing an issue with implementing number validation in my Angular2 project. I am struggling to replicate the JavaScript code provided below. Here is the HTML: <input type="text" class="textfield" value="" id="extra7" name="extra7" onkeyp ...

Is there a way to automatically trigger a function once another function has completed its execution?

I am diving into the world of JavaScript as a beginner. All I want to do is trigger the function called seconOne() right after the execution of firstOne(). Specifically, I need the function two to be invoked when the value of p1 reaches 4. While I can us ...

Leverage the `dispatch` hook within a useEffect function

When it comes to triggering an action upon the React component unmounting, I faced a challenge due to hooks not allowing the use of componentWillUnmount. In order to address this, I turned to the useEffect hook: const dispatch = useDispatch(); useEffect(( ...

Running a series of functions consecutively with JQUERY

Currently, I am facing an issue with using an ajax method .load to replace the content of a div. The library I am working with does not allow me to replace the content of a div as some functions continue to run in the background. To overcome this challeng ...

Retrieving, storing, and implementing the classes of child elements directly from an array using jQuery

With the help of jQuery, you can retrieve child elements of the #parent element that have the class .west. In this case, we are not interested in fetching the content of these child elements but instead their class names. For example: <div id="parent" ...

Updating the title of a page on CoreUI's CBreadcrumbRouter dynamically

I'm currently developing a project with VueJS and the CoreUI admin template. Is there a way I can change the title of the current page as shown on the CBreadcrumbRouter? The GitHub documentation mentions that the script typically displays meta.label ...

When testing my jQuery locally, it runs smoothly. However, upon uploading it to my website, I encounter some issues where it

After successfully running my webpage on localhost, I encountered an issue when uploading it to my website. Only a portion of the code seems to be executing properly. I have included the following jquery function in my script and there are no reported err ...

Utilizing Anglar 16's MatTable trackBy feature on FormGroup for identifying unaltered fields

In my application, I am working with a MatTable that has a datasource consisting of AbstractControls (FormGroups) to create an editable table. At the end of each row, there are action buttons for saving or deleting the elements. My goal is to implement tr ...