// 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 }