Skip to content

Commit 9b72023

Browse files
committed
new light path drawing using antialisased billboarded quads
1 parent bf27aaf commit 9b72023

File tree

12 files changed

+403
-118
lines changed

12 files changed

+403
-118
lines changed

src/appleseed.studio/mainwindow/rendering/lightpathslayer.cpp

Lines changed: 254 additions & 97 deletions
Large diffs are not rendered by default.

src/appleseed.studio/mainwindow/rendering/lightpathslayer.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class LightPathsLayer: public QObject
7777
const size_t width,
7878
const size_t height);
7979

80+
void resize(const size_t width, const size_t height);
8081

8182
void update_render_camera_transform();
8283

@@ -120,15 +121,26 @@ class LightPathsLayer: public QObject
120121

121122
renderer::LightPathArray m_light_paths;
122123
int m_selected_light_path_index; // -1 == display all paths
124+
float m_max_luminance;
125+
float m_max_thickness;
126+
float m_min_thickness;
127+
size_t m_width;
128+
size_t m_height;
123129

124130
QOpenGLFunctions_3_3_Core* m_gl;
125131

126-
GLuint m_light_paths_vbo;
127-
std::vector<GLsizei> m_light_paths_index_offsets;
132+
GLuint m_positions_vbo;
133+
GLuint m_others_vbo;
134+
GLuint m_indices_ebo;
135+
std::vector<GLsizei> m_index_offsets;
128136
GLuint m_light_paths_vao;
129-
GLuint m_light_paths_shader_program;
130-
GLint m_light_paths_view_mat_location;
131-
GLint m_light_paths_proj_mat_location;
137+
GLuint m_shader_program;
138+
GLint m_view_mat_loc;
139+
GLint m_proj_mat_loc;
140+
GLint m_res_loc;
141+
GLint m_max_luminance_loc;
142+
GLint m_min_thickness_loc;
143+
GLint m_max_thickness_loc;
132144
foundation::Matrix4f m_gl_render_view_matrix;
133145
foundation::Matrix4f m_gl_view_matrix;
134146
foundation::Matrix4f m_gl_proj_matrix;

src/appleseed.studio/mainwindow/rendering/viewportwidget.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,18 @@ void ViewportWidget::initializeGL() {
174174
}
175175

176176
void ViewportWidget::resize(
177-
const size_t width,
178-
const size_t height)
177+
const size_t width,
178+
const size_t height)
179179
{
180180
m_render_layer->resize(width, height);
181+
m_light_paths_layer->resize(width, height);
182+
}
183+
184+
void ViewportWidget::resizeGL(
185+
int width,
186+
int height)
187+
{
188+
m_light_paths_layer->resize(width, height);
181189
}
182190

183191
void ViewportWidget::set_draw_light_paths_enabled(const bool enabled)

src/appleseed.studio/mainwindow/rendering/viewportwidget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class ViewportWidget
138138
void create_render_layer(OCIO::ConstConfigRcPtr ocio_config);
139139

140140
void initializeGL() override;
141+
void resizeGL(int width, int height) override;
141142
void paintGL() override;
142143
void dragEnterEvent(QDragEnterEvent* event) override;
143144
void dragMoveEvent(QDragMoveEvent* event) override;

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,20 @@
2828
#version 330
2929
#extension GL_ARB_separate_shader_objects : enable
3030

31-
layout(location = 0) in vec3 v_color;
31+
flat in vec3 f_color;
32+
in float f_aa_norm;
33+
flat in float f_thickness;
34+
flat in float f_total_thickness;
35+
flat in float f_aspect_expansion_len;
36+
37+
uniform vec2 u_res;
3238

3339
out vec4 Target0;
3440

3541
void main()
3642
{
37-
Target0 = vec4(v_color, 1.0);
43+
float dist = abs(f_aa_norm) * f_total_thickness - 0.5 / f_aspect_expansion_len;
44+
float eps = fwidth(dist);
45+
float a = 1.0 - smoothstep(f_thickness - eps, f_thickness + eps, dist);
46+
Target0 = vec4(f_color, a);
3847
}

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

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,84 @@
2626
//
2727

2828
#version 330
29-
#extension GL_ARB_separate_shader_objects : enable
3029

31-
layout(location = 0) in vec3 a_pos;
32-
layout(location = 1) in vec3 a_color;
30+
const float AA_BUFFER_SIZE = 1.0;
31+
32+
layout(location = 0) in vec3 v_previous;
33+
layout(location = 1) in vec3 v_position;
34+
layout(location = 2) in vec3 v_next;
35+
layout(location = 3) in float v_luminance;
36+
layout(location = 4) in int v_direction_start_end;
37+
layout(location = 5) in vec3 v_color;
38+
layout(location = 6) in vec3 v_surface_normal;
3339

34-
uniform mat4 u_view;
3540
uniform mat4 u_proj;
41+
uniform mat4 u_view;
42+
uniform vec2 u_res;
43+
uniform float u_max_luminance;
44+
uniform float u_max_thickness;
45+
uniform float u_min_thickness;
46+
47+
flat out vec3 f_color;
48+
out float f_aa_norm;
49+
flat out float f_thickness;
50+
flat out float f_total_thickness;
51+
flat out float f_aspect_expansion_len;
52+
53+
void main() {
54+
float aspect = u_res.x / u_res.y;
55+
vec2 aspect_vec = vec2(aspect, 1.0);
56+
mat4 vp = u_proj * u_view;
57+
vec4 prev_proj = vp * vec4(v_previous, 1.0);
58+
vec4 curr_proj = vp * vec4(v_position, 1.0);
59+
vec4 next_proj = vp * vec4(v_next, 1.0);
60+
61+
//get 2D screen space with W divide and aspect correction
62+
vec2 curr_screen = curr_proj.xy / curr_proj.w * aspect_vec;
63+
vec2 prev_screen = prev_proj.xy / prev_proj.w * aspect_vec;
64+
vec2 next_screen = next_proj.xy / next_proj.w * aspect_vec;
65+
66+
float orientation = 1.0;
67+
if ((v_direction_start_end & 1) == 1)
68+
{
69+
orientation = -1.0;
70+
}
71+
72+
vec2 dir = vec2(0.0);
73+
if ((v_direction_start_end & 2) == 2)
74+
{
75+
//starting point uses (next - current)
76+
dir = normalize(next_screen - curr_screen);
77+
}
78+
else if ((v_direction_start_end & 4) == 4)
79+
{
80+
//ending point uses (current - v_previous)
81+
dir = normalize(curr_screen - prev_screen);
82+
}
83+
vec2 perp_dir = vec2(-dir.y, dir.x);
84+
85+
vec4 normal_clip = vp * vec4(v_surface_normal, 0.0);
86+
normal_clip.xy *= aspect_vec;
87+
normal_clip = normalize(normal_clip);
88+
vec2 tang_clip = vec2(-normal_clip.y, normal_clip.x);
89+
90+
float tdp = dot(tang_clip, perp_dir);
91+
vec2 expansion = perp_dir;
92+
if (tdp > 0.05)
93+
expansion = tang_clip / tdp;
94+
95+
vec2 norm_exp = normalize(expansion);
96+
vec2 res_exp_dir = vec2(norm_exp.x * u_res.x, norm_exp.y * u_res.y);
97+
f_aspect_expansion_len = length(res_exp_dir);
98+
99+
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;
100+
101+
f_total_thickness = f_thickness + AA_BUFFER_SIZE / f_aspect_expansion_len;
36102

37-
layout(location = 0) out vec3 v_color;
103+
expansion *= f_total_thickness;
104+
expansion *= orientation;
38105

39-
void main()
40-
{
41-
v_color = a_color;
42-
gl_Position = u_proj * u_view * vec4(a_pos, 1.0);
106+
gl_Position = vec4((curr_screen + expansion) / aspect_vec, curr_proj.z / curr_proj.w, 1.0);
107+
f_aa_norm = orientation;
108+
f_color = v_color;
43109
}

src/appleseed/renderer/kernel/lighting/directlightingintegrator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ void DirectLightingIntegrator::add_emitting_shape_sample_contribution(
466466
light_path_stream->sampled_emitting_shape(
467467
*sample.m_shape,
468468
sample.m_point,
469+
sample.m_geometric_normal,
469470
material_value.m_beauty,
470471
edf_value);
471472
}
@@ -541,6 +542,7 @@ void DirectLightingIntegrator::add_non_physical_light_sample_contribution(
541542
light_path_stream->sampled_non_physical_light(
542543
*light,
543544
emission_position,
545+
m_material_sampler.get_shading_point().get_geometric_normal(),
544546
material_value.m_beauty,
545547
light_value);
546548
}

src/appleseed/renderer/kernel/lighting/lightpathrecorder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ void LightPathRecorder::get_light_path_vertex(
276276
result.m_radiance[0] = source_vertex.m_radiance[0];
277277
result.m_radiance[1] = source_vertex.m_radiance[1];
278278
result.m_radiance[2] = source_vertex.m_radiance[2];
279+
280+
result.m_surface_normal[0] = source_vertex.m_surface_normal[0];
281+
result.m_surface_normal[1] = source_vertex.m_surface_normal[1];
282+
result.m_surface_normal[2] = source_vertex.m_surface_normal[2];
279283
}
280284

281285
bool LightPathRecorder::write(const char* filename) const

src/appleseed/renderer/kernel/lighting/lightpathrecorder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct LightPathVertex
6868
const Entity* m_entity;
6969
float m_position[3];
7070
float m_radiance[3];
71+
float m_surface_normal[3];
7172
};
7273

7374

src/appleseed/renderer/kernel/lighting/lightpathstream.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ void LightPathStream::clear()
7777
void LightPathStream::begin_path(
7878
const PixelContext& pixel_context,
7979
const Camera* camera,
80-
const Vector3d& camera_vertex_position)
80+
const Vector3d& camera_vertex_position,
81+
const Vector3d& camera_vertex_normal)
8182
{
8283
assert(m_events.empty());
8384
assert(m_hit_reflector_data.empty());
@@ -90,6 +91,7 @@ void LightPathStream::begin_path(
9091

9192
m_camera = camera;
9293
m_camera_vertex_position = Vector3f(camera_vertex_position);
94+
m_camera_vertex_normal = Vector3f(camera_vertex_normal);
9395
m_pixel_coords = pixel_context.get_pixel_coords();
9496
m_sample_position = Vector2f(pixel_context.get_sample_position());
9597
}
@@ -107,6 +109,7 @@ void LightPathStream::hit_reflector(const PathVertex& vertex)
107109
HitReflectorData data;
108110
data.m_object_instance = &vertex.m_shading_point->get_object_instance();
109111
data.m_vertex_position = Vector3f(vertex.get_point());
112+
data.m_surface_normal = Vector3f(vertex.get_geometric_normal());
110113
data.m_path_throughput = vertex.m_throughput.to_rgb(g_std_lighting_conditions);
111114
m_hit_reflector_data.push_back(data);
112115
}
@@ -126,6 +129,7 @@ void LightPathStream::hit_emitter(
126129
HitEmitterData data;
127130
data.m_object_instance = &vertex.m_shading_point->get_object_instance();
128131
data.m_vertex_position = Vector3f(vertex.get_point());
132+
data.m_surface_normal = Vector3f(vertex.get_geometric_normal());
129133
data.m_path_throughput = vertex.m_throughput.to_rgb(g_std_lighting_conditions);
130134
data.m_emitted_radiance = emitted_radiance.to_rgb(g_std_lighting_conditions);
131135
m_hit_emitter_data.push_back(data);
@@ -134,6 +138,7 @@ void LightPathStream::hit_emitter(
134138
void LightPathStream::sampled_emitting_shape(
135139
const EmittingShape& shape,
136140
const Vector3d& emission_position,
141+
const Vector3d& emission_normal,
137142
const Spectrum& material_value,
138143
const Spectrum& emitted_radiance)
139144
{
@@ -147,6 +152,7 @@ void LightPathStream::sampled_emitting_shape(
147152
shape.get_assembly_instance()->get_assembly().object_instances().get_by_index(
148153
shape.get_object_instance_index());
149154
data.m_vertex_position = Vector3f(emission_position);
155+
data.m_surface_normal = Vector3f(emission_normal);
150156
data.m_material_value = material_value.to_rgb(g_std_lighting_conditions);
151157
data.m_emitted_radiance = emitted_radiance.to_rgb(g_std_lighting_conditions);
152158
m_sampled_emitter_data.push_back(data);
@@ -155,6 +161,7 @@ void LightPathStream::sampled_emitting_shape(
155161
void LightPathStream::sampled_non_physical_light(
156162
const Light& light,
157163
const Vector3d& emission_position,
164+
const Vector3d& emission_normal,
158165
const Spectrum& material_value,
159166
const Spectrum& emitted_radiance)
160167
{
@@ -166,6 +173,7 @@ void LightPathStream::sampled_non_physical_light(
166173
SampledEmitterData data;
167174
data.m_entity = &light;
168175
data.m_vertex_position = Vector3f(emission_position);
176+
data.m_surface_normal = Vector3f(emission_normal);
169177
data.m_material_value = material_value.to_rgb(g_std_lighting_conditions);
170178
data.m_emitted_radiance = emitted_radiance.to_rgb(g_std_lighting_conditions);
171179
m_sampled_emitter_data.push_back(data);
@@ -244,6 +252,7 @@ void LightPathStream::create_path_from_hit_emitter(const size_t emitter_event_in
244252
StoredPathVertex emitter_vertex;
245253
emitter_vertex.m_entity = hit_emitter_data.m_object_instance;
246254
emitter_vertex.m_position = hit_emitter_data.m_vertex_position;
255+
emitter_vertex.m_surface_normal = hit_emitter_data.m_surface_normal;
247256
emitter_vertex.m_radiance = hit_emitter_data.m_emitted_radiance;
248257
m_vertices.push_back(emitter_vertex);
249258

@@ -264,6 +273,7 @@ void LightPathStream::create_path_from_hit_emitter(const size_t emitter_event_in
264273
StoredPathVertex reflector_vertex;
265274
reflector_vertex.m_entity = event_data.m_object_instance;
266275
reflector_vertex.m_position = event_data.m_vertex_position;
276+
reflector_vertex.m_surface_normal = event_data.m_surface_normal;
267277
reflector_vertex.m_radiance = current_radiance;
268278
m_vertices.push_back(reflector_vertex);
269279

@@ -288,6 +298,7 @@ void LightPathStream::create_path_from_hit_emitter(const size_t emitter_event_in
288298
StoredPathVertex camera_vertex;
289299
camera_vertex.m_entity = m_camera;
290300
camera_vertex.m_position = m_camera_vertex_position;
301+
camera_vertex.m_surface_normal = m_camera_vertex_normal;
291302
camera_vertex.m_radiance = current_radiance;
292303
m_vertices.push_back(camera_vertex);
293304

@@ -319,6 +330,7 @@ void LightPathStream::create_path_from_sampled_emitter(const size_t emitter_even
319330
StoredPathVertex emitter_vertex;
320331
emitter_vertex.m_entity = sampled_emitter_data.m_entity;
321332
emitter_vertex.m_position = sampled_emitter_data.m_vertex_position;
333+
emitter_vertex.m_surface_normal = sampled_emitter_data.m_surface_normal;
322334
emitter_vertex.m_radiance = sampled_emitter_data.m_emitted_radiance;
323335
m_vertices.push_back(emitter_vertex);
324336

@@ -339,6 +351,7 @@ void LightPathStream::create_path_from_sampled_emitter(const size_t emitter_even
339351
StoredPathVertex reflector_vertex;
340352
reflector_vertex.m_entity = event_data.m_object_instance;
341353
reflector_vertex.m_position = event_data.m_vertex_position;
354+
reflector_vertex.m_surface_normal = event_data.m_surface_normal;
342355
reflector_vertex.m_radiance = current_radiance;
343356
m_vertices.push_back(reflector_vertex);
344357

@@ -363,6 +376,7 @@ void LightPathStream::create_path_from_sampled_emitter(const size_t emitter_even
363376
StoredPathVertex camera_vertex;
364377
camera_vertex.m_entity = m_camera;
365378
camera_vertex.m_position = m_camera_vertex_position;
379+
camera_vertex.m_surface_normal = m_camera_vertex_normal;
366380
camera_vertex.m_radiance = current_radiance;
367381
m_vertices.push_back(camera_vertex);
368382

@@ -394,6 +408,7 @@ void LightPathStream::create_path_from_sampled_environment(const size_t env_even
394408
StoredPathVertex emitter_vertex;
395409
emitter_vertex.m_entity = sampled_env_data.m_environment_edf;
396410
emitter_vertex.m_position = last_reflector_data.m_vertex_position + m_scene_diameter * sampled_env_data.m_emission_direction;
411+
emitter_vertex.m_surface_normal = -sampled_env_data.m_emission_direction;
397412
emitter_vertex.m_radiance = sampled_env_data.m_emitted_radiance;
398413
m_vertices.push_back(emitter_vertex);
399414

@@ -414,6 +429,7 @@ void LightPathStream::create_path_from_sampled_environment(const size_t env_even
414429
StoredPathVertex reflector_vertex;
415430
reflector_vertex.m_entity = event_data.m_object_instance;
416431
reflector_vertex.m_position = event_data.m_vertex_position;
432+
reflector_vertex.m_surface_normal = event_data.m_surface_normal;
417433
reflector_vertex.m_radiance = current_radiance;
418434
m_vertices.push_back(reflector_vertex);
419435

@@ -438,6 +454,7 @@ void LightPathStream::create_path_from_sampled_environment(const size_t env_even
438454
StoredPathVertex camera_vertex;
439455
camera_vertex.m_entity = m_camera;
440456
camera_vertex.m_position = m_camera_vertex_position;
457+
camera_vertex.m_surface_normal = m_camera_vertex_normal;
441458
camera_vertex.m_radiance = current_radiance;
442459
m_vertices.push_back(camera_vertex);
443460

0 commit comments

Comments
 (0)