2022-06-25 11:52:00 +08:00

128 lines
3.3 KiB
C++

// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
#if CC_USE_SKINNING
in vec4 a_weights;
in vec4 a_joints;
#if CC_USE_JOINTS_TEXTRUE
uniform SKINNING {
vec2 jointsTextureSize;
};
#pragma builtin(local)
uniform sampler2D jointsTexture;
#if CC_JOINTS_TEXTURE_FLOAT32
mat4 getBoneMatrix(const in float i) {
float width = jointsTextureSize.x;
float height = jointsTextureSize.y;
float j = i * 4.0;
float x = mod(j, width);
float y = floor(j / width);
float dx = 1.0 / width;
float dy = 1.0 / height;
y = dy * (y + 0.5);
vec4 v1 = texture(jointsTexture, vec2(dx * (x + 0.5), y));
vec4 v2 = texture(jointsTexture, vec2(dx * (x + 1.5), y));
vec4 v3 = texture(jointsTexture, vec2(dx * (x + 2.5), y));
vec4 v4 = texture(jointsTexture, vec2(dx * (x + 3.5), y));
return mat4(v1, v2, v3, v4);
}
#else
float decode32(vec4 rgba) {
float Sign = 1.0 - step(128.0, rgba[0]) * 2.0;
float Exponent = 2.0 * mod(rgba[0], 128.0) + step(128.0, rgba[1]) - 127.0;
float Mantissa = mod(rgba[1], 128.0) * 65536.0 + rgba[2] * 256.0 + rgba[3] + 8388608.0;
return Sign * exp2(Exponent - 23.0) * Mantissa;
}
vec4 decodevec4 (vec4 x, vec4 y, vec4 z, vec4 w) {
// TODO: check this on big endian devices
return vec4(
decode32(x.wzyx * 255.0),
decode32(y.wzyx * 255.0),
decode32(z.wzyx * 255.0),
decode32(w.wzyx * 255.0)
);
}
vec4 decodevec4 (float dx, float x, float y) {
return decodevec4(
texture(jointsTexture, vec2(dx * (x + 0.5), y)),
texture(jointsTexture, vec2(dx * (x + 1.5), y)),
texture(jointsTexture, vec2(dx * (x + 2.5), y)),
texture(jointsTexture, vec2(dx * (x + 3.5), y))
);
}
mat4 getBoneMatrix(const in float i) {
float width = jointsTextureSize.x;
float height = jointsTextureSize.y;
float j = i * 16.0;
float x = mod(j, width);
float y = floor(j / width);
float dx = 1.0 / width;
float dy = 1.0 / height;
y = dy * (y + 0.5);
vec4 v1 = decodevec4(dx, x, y);
vec4 v2 = decodevec4(dx, x+4.0, y);
vec4 v3 = decodevec4(dx, x+8.0, y);
vec4 v4 = decodevec4(dx, x+12.0, y);
return mat4(v1, v2, v3, v4);
}
#endif
#else
#define CC_JOINT_MATRICES_SIZE 50
#pragma builtin(local)
uniform JOINT_MATRIX {
mat4 jointMatrices[CC_JOINT_MATRICES_SIZE];
};
mat4 getBoneMatrix(const in float i) {
return jointMatrices[int(i)];
}
#endif
mat4 skinMatrix() {
return
getBoneMatrix(a_joints.x) * a_weights.x +
getBoneMatrix(a_joints.y) * a_weights.y +
getBoneMatrix(a_joints.z) * a_weights.z +
getBoneMatrix(a_joints.w) * a_weights.w
;
}
#endif
void SKIN_VERTEX(inout vec4 a1) {
#if CC_USE_SKINNING
mat4 m = skinMatrix();
a1 = m * a1;
#endif
}
void SKIN_VERTEX(inout vec4 a1, inout vec4 a2) {
#if CC_USE_SKINNING
mat4 m = skinMatrix();
a1 = m * a1;
a2 = m * a2;
#endif
}
void SKIN_VERTEX(inout vec4 a1, inout vec4 a2, inout vec4 a3) {
#if CC_USE_SKINNING
mat4 m = skinMatrix();
a1 = m * a1;
a2 = m * a2;
a3 = m * a3;
#endif
}