87fa3519da1865a1016931d7bf0ee921ed3e194d
[blender.git] / source / blender / draw / modes / shaders / volume_velocity_vert.glsl
1
2 uniform mat4 ModelMatrix;
3
4 uniform sampler3D velocityX;
5 uniform sampler3D velocityY;
6 uniform sampler3D velocityZ;
7 uniform float displaySize = 1.0;
8 uniform float slicePosition;
9 uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
10
11 flat out vec4 finalColor;
12
13 const vec3 corners[4] = vec3[4](vec3(0.0, 0.2, -0.5),
14                                 vec3(-0.2 * 0.866, -0.2 * 0.5, -0.5),
15                                 vec3(0.2 * 0.866, -0.2 * 0.5, -0.5),
16                                 vec3(0.0, 0.0, 0.5));
17
18 const int indices[12] = int[12](0, 1, 1, 2, 2, 0, 0, 3, 1, 3, 2, 3);
19
20 /* Straight Port from BKE_defvert_weight_to_rgb()
21  * TODO port this to a color ramp. */
22 vec3 weight_to_color(float weight)
23 {
24   vec3 r_rgb = vec3(0.0);
25   float blend = ((weight / 2.0) + 0.5);
26
27   if (weight <= 0.25) { /* blue->cyan */
28     r_rgb.g = blend * weight * 4.0;
29     r_rgb.b = blend;
30   }
31   else if (weight <= 0.50) { /* cyan->green */
32     r_rgb.g = blend;
33     r_rgb.b = blend * (1.0 - ((weight - 0.25) * 4.0));
34   }
35   else if (weight <= 0.75) { /* green->yellow */
36     r_rgb.r = blend * ((weight - 0.50) * 4.0);
37     r_rgb.g = blend;
38   }
39   else if (weight <= 1.0) { /* yellow->red */
40     r_rgb.r = blend;
41     r_rgb.g = blend * (1.0 - ((weight - 0.75) * 4.0));
42   }
43   else {
44     /* exceptional value, unclamped or nan,
45      * avoid uninitialized memory use */
46     r_rgb = vec3(1.0, 0.0, 1.0);
47   }
48
49   return r_rgb;
50 }
51
52 mat3 rotation_from_vector(vec3 v)
53 {
54   /* Add epsilon to avoid NaN. */
55   vec3 N = normalize(v + 1e-8);
56   vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
57   vec3 T = normalize(cross(UpVector, N));
58   vec3 B = cross(N, T);
59   return mat3(T, B, N);
60 }
61
62 void main()
63 {
64 #ifdef USE_NEEDLE
65   int cell = gl_VertexID / 12;
66 #else
67   int cell = gl_VertexID / 2;
68 #endif
69
70   ivec3 volume_size = textureSize(velocityX, 0);
71   float voxel_size = 1.0 / float(max(max(volume_size.x, volume_size.y), volume_size.z));
72
73   ivec3 cell_ofs = ivec3(0);
74   ivec3 cell_div = volume_size;
75   if (sliceAxis == 0) {
76     cell_ofs.x = int(slicePosition * float(volume_size.x));
77     cell_div.x = 1;
78   }
79   else if (sliceAxis == 1) {
80     cell_ofs.y = int(slicePosition * float(volume_size.y));
81     cell_div.y = 1;
82   }
83   else if (sliceAxis == 2) {
84     cell_ofs.z = int(slicePosition * float(volume_size.z));
85     cell_div.z = 1;
86   }
87
88   ivec3 cell_co;
89   cell_co.x = cell % cell_div.x;
90   cell_co.y = (cell / cell_div.x) % cell_div.y;
91   cell_co.z = cell / (cell_div.x * cell_div.y);
92   cell_co += cell_ofs;
93
94   vec3 pos = (vec3(cell_co) + 0.5) / vec3(volume_size);
95   pos = pos * 2.0 - 1.0;
96
97   vec3 velocity;
98   velocity.x = texelFetch(velocityX, cell_co, 0).r;
99   velocity.y = texelFetch(velocityY, cell_co, 0).r;
100   velocity.z = texelFetch(velocityZ, cell_co, 0).r;
101
102   finalColor = vec4(weight_to_color(length(velocity)), 1.0);
103
104 #ifdef USE_NEEDLE
105   mat3 rot_mat = rotation_from_vector(velocity);
106   vec3 rotated_pos = rot_mat * corners[indices[gl_VertexID % 12]];
107   pos += rotated_pos * length(velocity) * displaySize * voxel_size;
108 #else
109   pos += (((gl_VertexID % 2) == 1) ? velocity : vec3(0.0)) * displaySize * voxel_size;
110 #endif
111
112   vec3 world_pos = point_object_to_world(pos);
113   gl_Position = point_world_to_ndc(world_pos);
114 }