// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. uniform FrameInfo { mat4 mvp; float enable_skinning; float joint_texture_size; } frame_info; uniform sampler2D joints_texture; // This attribute layout is expected to be identical to `SkinnedVertex` within // `impeller/scene/importer/scene.fbs`. in vec3 position; in vec3 normal; in vec4 tangent; in vec2 texture_coords; in vec4 color; in vec4 joints; in vec4 weights; out vec3 v_position; out mat3 v_tangent_space; out vec2 v_texture_coords; out vec4 v_color; const int kMatrixTexelStride = 4; mat4 GetJoint(float joint_index) { // The size of one texel in UV space. The joint texture should always be // square, so the answer is the same in both dimensions. float texel_size_uv = 1 / frame_info.joint_texture_size; // Each joint matrix takes up 4 pixels (16 floats), so we jump 4 pixels per // joint matrix. float matrix_start = joint_index * kMatrixTexelStride; // The texture space coordinates at the start of the matrix. float x = mod(matrix_start, frame_info.joint_texture_size); float y = floor(matrix_start / frame_info.joint_texture_size); // Nearest sample the middle of each the texel by adding `0.5 * texel_size_uv` // to both dimensions. y = (y + 0.5) * texel_size_uv; mat4 joint = mat4(texture(joints_texture, vec2((x + 0.5) * texel_size_uv, y)), texture(joints_texture, vec2((x + 1.5) * texel_size_uv, y)), texture(joints_texture, vec2((x + 2.5) * texel_size_uv, y)), texture(joints_texture, vec2((x + 3.5) * texel_size_uv, y))); return joint; } void main() { mat4 skin_matrix; if (frame_info.enable_skinning == 1) { skin_matrix = GetJoint(joints.x) * weights.x + GetJoint(joints.y) * weights.y + GetJoint(joints.z) * weights.z + GetJoint(joints.w) * weights.w; } else { skin_matrix = mat4(1); // Identity matrix. } gl_Position = frame_info.mvp * skin_matrix * vec4(position, 1.0); v_position = gl_Position.xyz; vec3 lh_tangent = (skin_matrix * vec4(tangent.xyz * tangent.w, 0.0)).xyz; vec3 out_normal = (skin_matrix * vec4(normal, 0.0)).xyz; v_tangent_space = mat3(frame_info.mvp) * mat3(lh_tangent, cross(out_normal, lh_tangent), out_normal); v_texture_coords = texture_coords; v_color = color; }