Description
In current implementation processing and rendering of skinned and not skinned meshes implemented in different ways. This approach has drawbacks:
- 2 materials should be created for skinned and not skinned meshes
- 2 shader pairs should be created for skinned and not skinned meshes
- whenever a mesh is modified it should be analyzed for whether it is weighted or not to set correct value to the "skeleton" property.
That means that in the c++ code there should be a loop through all the vertices which is ran whenever the mesh changes. - semi-skinned meshes are not supported. If summary weight of a vertex is less than 1.0, the vertex position is incorrect.
I suggest that the approach for rendering skinned and not skinned meshes should be unified.
To do that this vertex shader can be used:
vec4 pos = vec4(VERTEX, 1.0); float totalWeight = 0.0; vec4 weightedPos = vec4(0.0, 0.0, 0.0, 0.0); for(int i = 0; i != 4; ++i) { weightedPos += BONE_TRANSFORMS[JOINTS[i]] * WEIGHTS[i] * pos; totalWeight += WEIGHTS[i]; } if(totalWeight < 1.0) { weightedPos += MODEL_MATRIX * (1.0 - totalWeight) * pos; } POSITION = PROJECTION_MATRIX * (VIEW_MATRIX * weightedPos);
With this shader code:
- when total weigh is 1.0 the vertex position completely depends on the joint matrices.
- If it is between 0.0 and 1.0, depending on the total weight value vertex position is partially weighted to MODEL_MATRIX.
- If totalWeight is 0 i.e. the mesh is not skinned, it is fully weighted to the node global transform - MODEL_MATRIX.
Benefits of this approach:
- only one material is required for skinned/semi-skinned and not skinned meshes.
- only one pair of shaders is required for skinned/semi-skinned and not skinned meshes.
- skeleton property can always be set to the model, no need to loop through all the vertices to check whether the mesh is weighted or not.
- correct rendering of semi-weighted meshes.
In order to implement this approach further changes should be made:
- MODEL_MATRIX should not be set to identity when the skeleton property is not null. To not break current implementation, MODEL_MATRIX_SKINNED with correct values could be added and used instead.
- the shader should compile if there are no Joint nodes in the scene (https://bugreports.qt.io/browse/QTBUG-101076).