Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve skinning shader #183

Closed
pjcozzi opened this issue Nov 12, 2013 · 8 comments
Closed

Improve skinning shader #183

pjcozzi opened this issue Nov 12, 2013 · 8 comments
Labels

Comments

@pjcozzi
Copy link
Member

pjcozzi commented Nov 12, 2013

The shader generated for skinning declares uniform mat4 u_jointMat[60];, which is going to hurt performance because many (all?) WebGL implementations will not optimize out the unused array elements. CPU overhead aside, using this much memory/registers will limit the number of shaders that can run in parallel.

We should explicitly declare the upper-bound based on the number of joints used.

Complete shader:

precision highp float;
attribute vec3 a_position;
attribute vec3 a_normal;
varying vec3 v_normal;
attribute vec4 a_joint;
varying vec4 v_joint;
attribute vec4 a_weight;
varying vec4 v_weight;
uniform mat4 u_jointMat[60];
uniform mat3 u_normalMatrix;
uniform mat4 u_modelViewMatrix;
uniform mat4 u_projectionMatrix;
void main(void) {
mat4 skinMat = a_weight.x * u_jointMat[int(a_joint.x)];
skinMat += a_weight.y * u_jointMat[int(a_joint.y)];
skinMat += a_weight.z * u_jointMat[int(a_joint.z)];
skinMat += a_weight.w * u_jointMat[int(a_joint.w)];
vec4 pos = u_modelViewMatrix * skinMat * vec4(a_position,1.0);
v_normal = normalize(u_normalMatrix * mat3(skinMat)* a_normal);
gl_Position = u_projectionMatrix * pos;
}

Use the same model as #182 for testing.

@pjcozzi
Copy link
Member Author

pjcozzi commented Nov 12, 2013

In addition, for this model, the mesh only has two joints, but the vertex shader is created for four. Given our goal of performance, we really need to generate a tighter shader that only weights the joint matrices used.

@fabrobinet
Copy link
Contributor

Yep, I totally agree. I usually make this optimization indeed but as an option because in some cases you want to avoid switching shaders to many times too, so I think there is a whole topic on shader optimizations that I will be happy to tackle once we are feature complete.

@pjcozzi
Copy link
Member Author

pjcozzi commented Nov 12, 2013

This is more than optimization. Depending on how an engine is designed, it may try to set all active uniforms, but in this case, the glTF file doesn't provide 60 matrices.

@pjcozzi
Copy link
Member Author

pjcozzi commented Jan 29, 2014

Also, the skinning shader generates these varyings which are not used in the fragment shader:

varying vec4 v_joint;
varying vec4 v_weight;

@fabrobinet
Copy link
Contributor

Fixed in v0.6-fixes

@fabrobinet
Copy link
Contributor

now shaders just contain the needed number of matrices to match the number of bones. It is still needed to split meshes to comply with a maximum number of uniform.

@fabrobinet
Copy link
Contributor

Following up here #283

@pjcozzi
Copy link
Member Author

pjcozzi commented Jun 7, 2014

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants