Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl')
-rw-r--r--source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl121
1 files changed, 121 insertions, 0 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl
new file mode 100644
index 00000000000..d0f2a8dcd51
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl
@@ -0,0 +1,121 @@
+
+
+/* This shader essentially operates in Object space, where it aligns given geometry with bone, scales it accordingly
+ * to given radii, and then does usual basic solid operations.
+ * Note that if one of head/tail radius is negative, it assumes it only works on the other end of the bone
+ * (used to draw head/tail spheres). */
+
+
+uniform mat4 ViewMatrix;
+uniform mat4 ViewProjectionMatrix;
+
+
+/* ---- Instanciated Attribs ---- */
+in vec4 pos; /* w encodes head (== 0.0f), tail (== 1.0f) or in-between. */
+
+/* ---- Per instance Attribs ---- */
+in mat4 InstanceModelMatrix;
+in vec4 color;
+
+in float radius_head;
+in float radius_tail;
+
+
+out vec3 normal;
+flat out vec4 finalColor;
+
+
+void main()
+{
+ /* We get head/tail in object space. */
+ vec4 head = InstanceModelMatrix * vec4(0.0f, 0.0f, 0.0f, 1.0f);
+ vec4 tail = InstanceModelMatrix * vec4(0.0f, 1.0f, 0.0f, 1.0f);
+
+ /* We need rotation from bone mat, but not scaling. */
+ mat3 bone_mat = mat3(InstanceModelMatrix);
+ bone_mat[0] = normalize(bone_mat[0]);
+ bone_mat[1] = normalize(bone_mat[1]);
+ bone_mat[2] = normalize(bone_mat[2]);
+
+ mat3 nor_mat = transpose(inverse(mat3(ViewMatrix) * bone_mat));
+
+ /* Where does this comes from???? Don't know why, but is mandatory anyway... :/ */
+ const float size = 2.0f;
+
+ head.xyz *= size;
+ tail.xyz *= size;
+
+ bool head_only = (radius_tail < 0.0f);
+ bool tail_only = (radius_head < 0.0f);
+ /* == 0: head; == 1: tail; in-between: along bone. */
+ float head_fac = head_only ? 0.0f : (tail_only ? 1.0f : pos.w);
+
+ vec4 ob_pos;
+ vec4 ob_bone_origin;
+ float radius;
+
+ /* head */
+ if (head_fac <= 0.0f) {
+ if (!head_only) {
+ /* We are drawing the body itself, need to adjust start/end positions and radius! */
+ vec3 bone_vec = tail.xyz - head.xyz;
+ float len = length(bone_vec);
+
+ if (len > (radius_head + radius_tail)) {
+ float fac = (len - radius_head) / len;
+ radius = fac * radius_head + (1.0f - fac) * radius_tail;
+ bone_vec /= len;
+ ob_bone_origin = vec4(head.xyz + bone_vec * radius_head * size, 1.0f);
+ }
+ else {
+ radius = (radius_head + radius_tail) / 2.0f;
+ ob_bone_origin = (head + tail) / 2.0f;
+ }
+ }
+ else {
+ radius = radius_head;
+ ob_bone_origin = head;
+ }
+ }
+ /* tail */
+ else if (head_fac >= 1.0f) {
+ if (!tail_only) {
+ /* We are drawing the body itself, need to adjust start/end positions and radius! */
+ vec3 bone_vec = tail.xyz - head.xyz;
+ float len = length(bone_vec);
+
+ if (len > (radius_head + radius_tail)) {
+ float fac = (len - radius_tail) / len;
+ radius = fac * radius_tail + (1.0f - fac) * radius_head;
+ bone_vec /= len;
+ ob_bone_origin = vec4(tail.xyz - bone_vec * radius_tail * size, 1.0f);
+ }
+ else {
+ radius = (radius_head + radius_tail) / 2.0f;
+ ob_bone_origin = (head + tail) / 2.0f;
+ }
+ }
+ else {
+ radius = radius_tail;
+ ob_bone_origin = tail;
+ }
+ }
+ /* Body of the bone */
+#if 0 /* Note: not used currently! */
+ else {
+ float tail_fac = 1.0f - head_fac;
+ radius = radius_head * head_fac + radius_tail * tail_fac;
+ ob_bone_origin = head * head_fac + tail * tail_fac;
+ }
+#endif
+
+ /* Yep, since input pos is unit sphere coordinates, it's also our normal. */
+ vec3 nor = pos.xyz;
+ ob_pos = pos * radius * size;
+ ob_pos.xyz = bone_mat * ob_pos.xyz;
+ ob_pos.w = 1.0f;
+
+ gl_Position = ViewProjectionMatrix * (ob_pos + ob_bone_origin);
+ normal = normalize(nor_mat * nor);
+ finalColor = color;
+}