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/draw/engines/overlay/shaders/overlay_extra_vert.glsl')
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl226
1 files changed, 226 insertions, 0 deletions
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl
new file mode 100644
index 00000000000..acaf04219c0
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_vert.glsl
@@ -0,0 +1,226 @@
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+#define lamp_area_size inst_data.xy
+#define lamp_clip_sta inst_data.z
+#define lamp_clip_end inst_data.w
+
+#define lamp_spot_cosine inst_data.x
+#define lamp_spot_blend inst_data.y
+
+#define camera_corner inst_data.xy
+#define camera_center inst_data.zw
+#define camera_dist color.a
+#define camera_dist_sta inst_data.z
+#define camera_dist_end inst_data.w
+#define camera_distance_color inst_data.x
+
+#define empty_size inst_data.xyz
+#define empty_scale inst_data.w
+
+/* TODO(fclem): Share with C code. */
+#define VCLASS_LIGHT_AREA_SHAPE (1 << 0)
+#define VCLASS_LIGHT_SPOT_SHAPE (1 << 1)
+#define VCLASS_LIGHT_SPOT_BLEND (1 << 2)
+#define VCLASS_LIGHT_SPOT_CONE (1 << 3)
+#define VCLASS_LIGHT_DIST (1 << 4)
+
+#define VCLASS_CAMERA_FRAME (1 << 5)
+#define VCLASS_CAMERA_DIST (1 << 6)
+#define VCLASS_CAMERA_VOLUME (1 << 7)
+
+#define VCLASS_SCREENSPACE (1 << 8)
+#define VCLASS_SCREENALIGNED (1 << 9)
+
+#define VCLASS_EMPTY_SCALED (1 << 10)
+#define VCLASS_EMPTY_AXES (1 << 11)
+#define VCLASS_EMPTY_AXES_NAME (1 << 12)
+#define VCLASS_EMPTY_AXES_SHADOW (1 << 13)
+#define VCLASS_EMPTY_SIZE (1 << 14)
+
+void main()
+{
+ /* Extract data packed inside the unused mat4 members. */
+ vec4 inst_data = vec4(inst_obmat[0][3], inst_obmat[1][3], inst_obmat[2][3], inst_obmat[3][3]);
+ float inst_color_data = color.a;
+ mat4 obmat = inst_obmat;
+ obmat[0][3] = obmat[1][3] = obmat[2][3] = 0.0;
+ obmat[3][3] = 1.0;
+
+ finalColor = color;
+ if (color.a < 0.0) {
+ finalColor.a = 1.0;
+ }
+
+ float lamp_spot_sine;
+ vec3 vpos = pos;
+ vec3 vofs = vec3(0.0);
+ /* Lights */
+ if ((vclass & VCLASS_LIGHT_AREA_SHAPE) != 0) {
+ /* HACK: use alpha color for spots to pass the area_size. */
+ if (inst_color_data < 0.0) {
+ lamp_area_size.xy = vec2(-inst_color_data);
+ }
+ vpos.xy *= lamp_area_size.xy;
+ }
+ else if ((vclass & VCLASS_LIGHT_SPOT_SHAPE) != 0) {
+ lamp_spot_sine = sqrt(1.0 - lamp_spot_cosine * lamp_spot_cosine);
+ lamp_spot_sine *= ((vclass & VCLASS_LIGHT_SPOT_BLEND) != 0) ? lamp_spot_blend : 1.0;
+ vpos = vec3(pos.xy * lamp_spot_sine, -lamp_spot_cosine);
+ }
+ else if ((vclass & VCLASS_LIGHT_DIST) != 0) {
+ /* Meh nasty mess. Select one of the 6 axes to display on. (see light_distance_z_get()) */
+ int dist_axis = int(pos.z);
+ float dist = pos.z - floor(pos.z) - 0.5;
+ float inv = sign(dist);
+ dist = (abs(dist) > 0.15) ? lamp_clip_end : lamp_clip_sta;
+ vofs[dist_axis] = inv * dist / length(obmat[dist_axis].xyz);
+ vpos.z = 0.0;
+ if (lamp_clip_end < 0.0) {
+ vpos = vofs = vec3(0.0);
+ }
+ }
+ /* Camera */
+ else if ((vclass & VCLASS_CAMERA_FRAME) != 0) {
+ if ((vclass & VCLASS_CAMERA_VOLUME) != 0) {
+ vpos.z = mix(color.b, color.a, pos.z);
+ }
+ else if (camera_dist > 0.0) {
+ vpos.z = -abs(camera_dist);
+ }
+ else {
+ vpos.z *= -abs(camera_dist);
+ }
+ vpos.xy = (camera_center + camera_corner * vpos.xy) * abs(vpos.z);
+ }
+ else if ((vclass & VCLASS_CAMERA_DIST) != 0) {
+ vofs.xy = vec2(0.0);
+ vofs.z = -mix(camera_dist_sta, camera_dist_end, pos.z);
+ vpos.z = 0.0;
+ /* Distance line endpoints color */
+ if (any(notEqual(pos.xy, vec2(0.0)))) {
+ /* Override color. */
+ switch (int(camera_distance_color)) {
+ case 0: /* Mist */
+ finalColor = vec4(0.5, 0.5, 0.5, 1.0);
+ break;
+ case 1: /* Mist Active */
+ finalColor = vec4(1.0, 1.0, 1.0, 1.0);
+ break;
+ case 2: /* Clip */
+ finalColor = vec4(0.5, 0.5, 0.25, 1.0);
+ break;
+ case 3: /* Clip Active */
+ finalColor = vec4(1.0, 1.0, 0.5, 1.0);
+ break;
+ }
+ }
+ /* Focus cross */
+ if (pos.z == 2.0) {
+ vofs.z = 0.0;
+ if (camera_dist < 0.0) {
+ vpos.z = -abs(camera_dist);
+ }
+ else {
+ /* Disabled */
+ vpos = vec3(0.0);
+ }
+ }
+ }
+ /* Empties */
+ else if ((vclass & VCLASS_EMPTY_SCALED) != 0) {
+ /* This is a bit silly but we avoid scaling the object matrix on CPU (saving a mat4 mul) */
+ vpos *= empty_scale;
+ }
+ else if ((vclass & VCLASS_EMPTY_SIZE) != 0) {
+ /* This is a bit silly but we avoid scaling the object matrix on CPU (saving a mat4 mul) */
+ vpos *= empty_size;
+ }
+ else if ((vclass & VCLASS_EMPTY_AXES) != 0) {
+ float axis = vpos.z;
+ vofs[int(axis)] = (1.0 + fract(axis)) * empty_scale;
+ /* Scale uniformly by axis length */
+ vpos *= length(obmat[int(axis)].xyz) * empty_scale;
+
+ vec3 axis_color = vec3(0.0);
+ axis_color[int(axis)] = 1.0;
+ finalColor.rgb = mix(axis_color + fract(axis), color.rgb, color.a);
+ finalColor.a = 1.0;
+ }
+
+ /* Not exclusive with previous flags. */
+ if ((vclass & VCLASS_CAMERA_VOLUME) != 0) {
+ /* Unpack final color. */
+ int color_class = int(floor(color.r));
+ float color_intensity = fract(color.r);
+ switch (color_class) {
+ case 0: /* No eye (convergence plane). */
+ finalColor = vec4(1.0, 1.0, 1.0, 1.0);
+ break;
+ case 1: /* Left eye. */
+ finalColor = vec4(0.0, 1.0, 1.0, 1.0);
+ break;
+ case 2: /* Right eye. */
+ finalColor = vec4(1.0, 0.0, 0.0, 1.0);
+ break;
+ }
+ finalColor *= vec4(vec3(color_intensity), color.g);
+ }
+
+ vec3 world_pos;
+ if ((vclass & VCLASS_SCREENSPACE) != 0) {
+ /* Relative to DPI scaling. Have constant screen size. */
+ vec3 screen_pos = screenVecs[0].xyz * vpos.x + screenVecs[1].xyz * vpos.y;
+ vec3 p = (obmat * vec4(vofs, 1.0)).xyz;
+ float screen_size = mul_project_m4_v3_zfac(p) * sizePixel;
+ world_pos = p + screen_pos * screen_size;
+ }
+ else if ((vclass & VCLASS_SCREENALIGNED) != 0) {
+ /* World sized, camera facing geometry. */
+ vec3 screen_pos = screenVecs[0].xyz * vpos.x + screenVecs[1].xyz * vpos.y;
+ world_pos = (obmat * vec4(vofs, 1.0)).xyz + screen_pos;
+ }
+ else {
+ world_pos = (obmat * vec4(vofs + vpos, 1.0)).xyz;
+ }
+
+ if ((vclass & VCLASS_LIGHT_SPOT_CONE) != 0) {
+ /* Compute point on the cone before and after this one. */
+ vec2 perp = vec2(pos.y, -pos.x);
+ const float incr_angle = 2.0 * 3.1415 / 32.0;
+ const vec2 slope = vec2(cos(incr_angle), sin(incr_angle));
+ vec3 p0 = vec3((pos.xy * slope.x + perp * slope.y) * lamp_spot_sine, -lamp_spot_cosine);
+ vec3 p1 = vec3((pos.xy * slope.x - perp * slope.y) * lamp_spot_sine, -lamp_spot_cosine);
+ p0 = (obmat * vec4(p0, 1.0)).xyz;
+ p1 = (obmat * vec4(p1, 1.0)).xyz;
+ /* Compute normals of each side. */
+ vec3 edge = obmat[3].xyz - world_pos;
+ vec3 n0 = normalize(cross(edge, p0 - world_pos));
+ vec3 n1 = normalize(cross(edge, world_pos - p1));
+ bool persp = (drw_view.winmat[3][3] == 0.0);
+ vec3 V = (persp) ? normalize(drw_view.viewinv[3].xyz - world_pos) : drw_view.viewinv[2].xyz;
+ /* Discard non-silhouette edges. */
+ bool facing0 = dot(n0, V) > 0.0;
+ bool facing1 = dot(n1, V) > 0.0;
+ if (facing0 == facing1) {
+ /* Hide line by making it cover 0 pixels. */
+ world_pos = obmat[3].xyz;
+ }
+ }
+
+ gl_Position = point_world_to_ndc(world_pos);
+
+ /* Convert to screen position [0..sizeVp]. */
+ edgePos = edgeStart = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
+
+#ifdef SELECT_EDGES
+ /* HACK: to avoid losing sub-pixel object in selections, we add a bit of randomness to the
+ * wire to at least create one fragment that will pass the occlusion query. */
+ /* TODO(fclem): Limit this workaround to selection. It's not very noticeable but still... */
+ gl_Position.xy += drw_view.viewport_size_inverse * gl_Position.w *
+ ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
+#endif
+
+ view_clipping_distances(world_pos);
+}