Skip to content

Commit 1a71bd3

Browse files
committed
readability
1 parent 0e4f6ee commit 1a71bd3

File tree

2 files changed

+83
-39
lines changed

2 files changed

+83
-39
lines changed

src/appleseed.studio/resources/shaders/lightpaths.frag

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,25 @@
2828
#version 410
2929
#extension GL_ARB_separate_shader_objects : enable
3030

31-
flat in vec4 f_color;
3231
in float f_aa_norm;
32+
flat in vec4 f_color;
3333
flat in float f_thickness;
3434
flat in float f_total_thickness;
3535
flat in float f_aspect_expansion_len;
3636

37-
uniform vec2 u_res;
37+
uniform vec2 u_res; // resolution of the frame.
3838

39+
// Output requires 2 values to be able to overlay correctly paths over a layer.
40+
// The first output is for paths color and the second output is for paths opacity.
3941
layout(location = 0) out vec4 accum_target;
4042
layout(location = 1) out float revealage_target;
4143

42-
void write_pixel(vec4 premultiplied_col, vec3 transmit) {
44+
void write_pixel(vec4 premultiplied_col, vec3 transmit) {
4345
premultiplied_col.a *= 1.0 - clamp((transmit.r + transmit.g + transmit.b) * (1.0 / 3.0), 0, 1);
44-
46+
4547
float a = min(1.0, premultiplied_col.a) * 8.0 + 0.01;
4648
float b = -gl_FragCoord.z * 0.95 + 1.0;
47-
49+
4850
float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2);
4951

5052
accum_target = premultiplied_col * w;

src/appleseed.studio/resources/shaders/lightpaths.vert

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ layout(location = 0) in vec3 v_previous;
3333
layout(location = 1) in vec3 v_position;
3434
layout(location = 2) in vec3 v_next;
3535
layout(location = 3) in float v_luminance;
36-
layout(location = 4) in int v_direction_start_end;
36+
layout(location = 4) in int v_direction_start_end; // flag defining which part of a light path is currently drawn.
3737
layout(location = 5) in vec3 v_color;
3838
layout(location = 6) in vec3 v_surface_normal;
3939

4040
uniform mat4 u_proj;
4141
uniform mat4 u_view;
42-
uniform vec2 u_res;
42+
uniform vec2 u_res; // resolution of the frame.
4343
uniform float u_max_luminance;
4444
uniform float u_max_thickness;
4545
uniform float u_min_thickness;
@@ -53,66 +53,108 @@ flat out float f_thickness;
5353
flat out float f_total_thickness;
5454
flat out float f_aspect_expansion_len;
5555

56-
const float CLIPPING_PREVENTION_FACTOR = 0.01;
56+
const float CLIPPING_PREVENTION_FACTOR = 0.05;
5757

58-
void main() {
59-
float aspect = u_res.x / u_res.y;
60-
vec2 aspect_vec = vec2(aspect, 1.0);
61-
mat4 vp = u_proj * u_view;
62-
vec4 prev_proj = vp * vec4(v_previous, 1.0);
63-
vec4 curr_proj = vp * vec4(v_position + v_surface_normal * CLIPPING_PREVENTION_FACTOR, 1.0);
64-
vec4 next_proj = vp * vec4(v_next, 1.0);
65-
66-
//get 2D screen space with W divide and aspect correction
67-
vec2 curr_screen = curr_proj.xy / curr_proj.w * aspect_vec;
68-
vec2 prev_screen = prev_proj.xy / prev_proj.w * aspect_vec;
69-
vec2 next_screen = next_proj.xy / next_proj.w * aspect_vec;
58+
//
59+
// Reference:
60+
// - https://mattdesl.svbtle.com/drawing-lines-is-hard#screenspace-projected-lines_2
61+
//
7062

71-
float orientation = 1.0;
72-
if ((v_direction_start_end & 1) == 1)
73-
{
74-
orientation = -1.0;
75-
}
63+
#define DRAW_START_PATH 1 // Drawing the start of the light path
64+
#define DRAW_MIDDLE_PATH 2 // Drawing a point in the middle of the light path
65+
#define DRAW_END_PATH 3 // Drawing the end of the light path
7666

77-
vec2 dir = vec2(0.0);
67+
int get_drawing_mode()
68+
{
7869
if ((v_direction_start_end & 2) == 2)
7970
{
8071
//starting point uses (next - current)
81-
dir = normalize(next_screen - curr_screen);
72+
return DRAW_START_PATH;
8273
}
8374
else if ((v_direction_start_end & 4) == 4)
8475
{
8576
//ending point uses (current - previous)
86-
dir = normalize(curr_screen - prev_screen);
87-
} else {
77+
return DRAW_END_PATH;
78+
}
79+
else
80+
{
8881
// middle point uses (next - current)
89-
dir = normalize(next_screen - curr_screen);
82+
return DRAW_MIDDLE_PATH;
9083
}
91-
vec2 perp_dir = vec2(-dir.y, dir.x);
84+
}
85+
86+
// Each point on the light path is duplicated to render a real line.
87+
// The duplicated vertex of each light path point is flagged.
88+
bool is_second_point()
89+
{
90+
return ((v_direction_start_end & 1) == 1);
91+
}
92+
93+
void main() {
94+
// Aspect ratio correction is applied on
95+
// screen points (only on the X axis).
96+
float aspect = u_res.x / u_res.y;
97+
vec2 aspect_correction = vec2(aspect, 1.0);
98+
99+
// Project points.
100+
// The currently drawn point is offset
101+
// from the surface to ensure path
102+
// doesn't go through it.
103+
mat4 vp = u_proj * u_view;
104+
vec4 curr_proj = vp * vec4(v_position + v_surface_normal * CLIPPING_PREVENTION_FACTOR, 1.0);
105+
vec4 prev_proj = vp * vec4(v_previous, 1.0);
106+
vec4 next_proj = vp * vec4(v_next, 1.0);
107+
108+
// Project points in screenspace.
109+
vec2 curr_screen = curr_proj.xy / curr_proj.w;
110+
vec2 prev_screen = prev_proj.xy / prev_proj.w;
111+
vec2 next_screen = next_proj.xy / next_proj.w;
112+
113+
// Apply aspect ratio correction.
114+
curr_screen *= aspect_correction;
115+
prev_screen *= aspect_correction;
116+
next_screen *= aspect_correction;
117+
118+
int drawing_mode = get_drawing_mode();
119+
bool is_second_point = is_second_point();
120+
121+
// Compute current line directionection.
122+
// Depending on which part of the path we
123+
// are drawing (start, middle or end), we
124+
// compute it differently.
125+
vec2 line_direction =
126+
drawing_mode == DRAW_START_PATH ? normalize(next_screen - curr_screen) :
127+
drawing_mode == DRAW_END_PATH ? normalize(curr_screen - prev_screen) :
128+
normalize(next_screen - curr_screen);
129+
130+
// Compute the normal of the line.
131+
vec2 line_normal = vec2(-line_direction.y, line_direction.x);
92132

93133
vec4 normal_clip = vp * vec4(v_surface_normal, 0.0);
94-
normal_clip.xy *= aspect_vec;
134+
normal_clip.xy *= aspect_correction;
95135
normal_clip = normalize(normal_clip);
96136
vec2 tang_clip = vec2(-normal_clip.y, normal_clip.x);
97137

98-
float tdp = dot(tang_clip, perp_dir);
99-
vec2 expansion = perp_dir;
138+
float tdp = dot(tang_clip, line_normal);
139+
vec2 expansion = line_normal;
100140
if (tdp > 0.05)
101141
expansion = tang_clip / tdp;
102142

103143
vec2 norm_exp = normalize(expansion);
104-
vec2 res_exp_dir = vec2(norm_exp.x * u_res.x, norm_exp.y * u_res.y);
105-
f_aspect_expansion_len = length(res_exp_dir);
144+
vec2 res_exp_line_direction = vec2(norm_exp.x * u_res.x, norm_exp.y * u_res.y);
145+
f_aspect_expansion_len = length(res_exp_line_direction);
106146

107147
f_thickness = (max(max(min(v_luminance / u_max_luminance, 1.0), 0.0) * u_max_thickness, u_min_thickness) / 2.0) / f_aspect_expansion_len;
108148

109149
f_total_thickness = f_thickness + AA_BUFFER_SIZE / f_aspect_expansion_len;
110150

111151
expansion *= f_total_thickness;
112-
expansion *= orientation;
113152

114-
gl_Position = vec4((curr_screen + expansion) / aspect_vec, curr_proj.z / curr_proj.w, 1.0);
115-
f_aa_norm = orientation;
153+
// Reverse expansion line_directionection for the duplicated point.
154+
if (is_second_point) expansion *= -1.0;
155+
156+
gl_Position = vec4((curr_screen + expansion) / aspect_correction, curr_proj.z / curr_proj.w, 1.0);
157+
f_aa_norm = is_second_point ? 1.0 : -1.0;
116158

117159
bool is_selected = gl_VertexID >= u_first_selected && gl_VertexID < u_last_selected;
118160
float a = is_selected ? 1.0 : 0.05;

0 commit comments

Comments
 (0)