diff --git a/include/gproshan/app_viewer.h b/include/gproshan/app_viewer.h index c4555beb..f4adfc9c 100644 --- a/include/gproshan/app_viewer.h +++ b/include/gproshan/app_viewer.h @@ -63,6 +63,7 @@ class app_viewer : public viewer // Scenes static bool process_simulate_scanner(viewer * p_view); + static bool process_scatter(viewer * p_view); // Geometry static bool process_sampling_4points(viewer * p_view); diff --git a/include/gproshan/raytracing/optix_params.h b/include/gproshan/raytracing/optix_params.h index 47369572..41b95310 100644 --- a/include/gproshan/raytracing/optix_params.h +++ b/include/gproshan/raytracing/optix_params.h @@ -17,27 +17,16 @@ namespace gproshan::rt { -struct launch_params +struct launch_params: public base_params { - vec4 * color_buffer = nullptr; - int buffer_size = 0; - int window_width = 0; - int window_height = 0; - int viewport_x = 0; - int viewport_y = 0; - int n_samples = 0; - int n_lights = 0; - light lights[NL]; - light ambient; - vec3 cam_pos; - mat4 inv_proj_view; - bool flat; - OptixTraversableHandle traversable; scene_data sc; + bool flat; void * other = nullptr; + vec4 * color_buffer = nullptr; + unsigned int buffer_size = 0; }; diff --git a/include/gproshan/raytracing/raytracing.h b/include/gproshan/raytracing/raytracing.h index d16a74b7..22df7eef 100644 --- a/include/gproshan/raytracing/raytracing.h +++ b/include/gproshan/raytracing/raytracing.h @@ -14,20 +14,17 @@ namespace gproshan::rt { class raytracing { - protected: - size_t n_samples = 0; - public: raytracing() = default; virtual ~raytracing() = default; virtual void render(vec4 * img, const render_params & params, const bool & flat); - virtual float * raycaster( const ivec2 & windows_size, - const mat4 & inv_proj_view, - const vertex & cam_pos, - const index_t & samples = 4 - ) const; + virtual std::vector raycaster( const uvec2 & windows_size, + const mat4 & inv_proj_view, + const vertex & cam_pos, + const index_t & samples = 4 + ) const; virtual eval_hit intersect( const vertex &, // org const vertex &, //dir diff --git a/include/gproshan/raytracing/render_params.h b/include/gproshan/raytracing/render_params.h index c1e8d218..f823d274 100644 --- a/include/gproshan/raytracing/render_params.h +++ b/include/gproshan/raytracing/render_params.h @@ -12,21 +12,26 @@ namespace gproshan::rt { const size_t NL = 16; // number of lights -struct render_params + +struct base_params { - int window_width = 0; - int window_height = 0; - int viewport_width = 0; - int viewport_height = 0; - int viewport_x = 0; - int viewport_y = 0; - int n_lights = 0; + uvec2 window_size; + uvec2 viewport_pos; + unsigned int depth = 1; + unsigned int n_frames = 0; + unsigned int n_samples = 1; + unsigned int n_lights = 0; light lights[NL]; light ambient = {0, 1, 0.1}; - vertex cam_pos; mat4 inv_proj_view; - bool restart = false; + vertex cam_pos; +}; + +struct render_params: public base_params +{ + uvec2 viewport_size; bool viewport_is_window = true; + bool restart = false; bool add_light(const light & l) { @@ -39,12 +44,9 @@ struct render_params void log() { - gproshan_log_var(window_width); - gproshan_log_var(window_height); - gproshan_log_var(viewport_width); - gproshan_log_var(viewport_height); - gproshan_log_var(viewport_x); - gproshan_log_var(viewport_y); + gproshan_log_var(window_size); + gproshan_log_var(viewport_size); + gproshan_log_var(viewport_pos); gproshan_log_var(n_lights); gproshan_log_var(cam_pos); gproshan_log_var(restart); diff --git a/include/gproshan/raytracing/utils.h b/include/gproshan/raytracing/utils.h index 93514412..11e062d0 100644 --- a/include/gproshan/raytracing/utils.h +++ b/include/gproshan/raytracing/utils.h @@ -13,16 +13,19 @@ namespace gproshan::rt { -template +template struct random { - uint32_t previous; + unsigned int previous; __host_device__ - random(uint32_t v0, uint32_t v1) + random(unsigned int p): previous(p) {} + + __host_device__ + random(unsigned int v0, unsigned int v1) { - uint32_t s = 0; - for(uint32_t i = 0; i < N; ++i) + unsigned int s = 0; + for(unsigned int i = 0; i < N; ++i) { s += 0x9e3779b9; v0 += ((v1 << 4) + 0xa341316c) ^ (v1 + s) ^ ((v1 >> 5) + 0xc8013ea4); @@ -37,6 +40,12 @@ struct random previous = previous * 1664525 + 1013904223; return T(previous & 0x00FFFFFF) / T(0x01000000); } + + __host_device__ + operator unsigned int & () + { + return previous; + } }; template @@ -65,6 +74,7 @@ template struct t_eval_hit { index_t primID = NIL; + int illum = 1; T dist = 0; T u = 0, v = 0; vec position; @@ -73,6 +83,7 @@ struct t_eval_hit vec Kd = 0.5; vec Ks = 0.2; T Ns = 10; + T Ni = 0; T d = 1; __host_device__ @@ -117,21 +128,80 @@ struct t_eval_hit Ka = mat.Ka; if(mat.map_Ka != -1) - Ka *= texture(sc.textures[mat.map_Ka], texcoord); + Ka = texture(sc.textures[mat.map_Ka], texcoord); Kd = mat.Kd; if(mat.map_Kd != -1) - Kd *= texture(sc.textures[mat.map_Kd], texcoord); + Kd = texture(sc.textures[mat.map_Kd], texcoord); Ks = mat.Ks; if(mat.map_Ks != -1) - Ks *= texture(sc.textures[mat.map_Ks], texcoord); + Ks = texture(sc.textures[mat.map_Ks], texcoord); Ns = mat.Ns; + Ni = mat.Ni; d = mat.d; // if(mat.map_d != -1) // d = texture(sc.textures[mat.map_d], texcoord); + + illum = mat.illum; + } + + // PTX symbols of certain types (e.g. pointers to functions) cannot be used to initialize array + __host_device__ + bool scatter_mat(const vec & v, vec & scattered, random & rnd) + { + switch(illum) + { + case 1: + case 2: + return scatter_diffuse(v, scattered, rnd); + case 3: + case 5: + case 6: + case 7: + return scatter_reflect(v, scattered, rnd); + } + + return false; + } + + __host_device__ + bool scatter_reflect(const vec & v, vec & scattered, random & ) + { + scattered = normalize(v - 2 * dot(v, normal) * normal); + return dot(scattered, normal) > 0; + } + + __host_device__ + bool scatter_refract(const vec & v, vec & scattered, random & ) + { + const float dvn = dot(v, normal); + const float d = 1 - Ni * Ni * (1 - dvn * dvn); + + if(d <= 0) return false; + + scattered = Ni * (v - dvn * normal) - normal * sqrtf(d); + return true; + } + + __host_device__ + bool scatter_diffuse(const vec & , vec & scattered, random & rnd) + { + // random unit sphere + const T & theta = rnd() * 2 * M_PI; + const T & phi = acosf(2 * rnd() - 1); + const T & r = cbrtf(rnd()); + + const vec p = { r * sinf(phi) * cosf(theta) + , r * sinf(phi) * sinf(theta) + , r * cosf(phi) + }; + + scattered = normalize(normal + p); + + return true; } }; @@ -139,7 +209,7 @@ template __host_device__ vec eval_li(const t_eval_hit & hit, const light & ambient, const light * lights, const int & n_lights, const vec & eye, Occluded occluded) { - const vec v = normalize(eye - hit.position); + const vec & v = normalize(eye - hit.position); const vec & n = hit.normal; T lambertian; @@ -179,10 +249,15 @@ using eval_hit = t_eval_hit; template __host_device__ -vec ray_view_dir(const ivec2 & pos, const ivec2 & windows_size, const mat & inv_proj_view, const vec & cam_pos) +vec ray_view_dir( const uvec2 & pos, + const uvec2 & windows_size, + const mat & inv_proj_view, + const vec & cam_pos, + random & rnd + ) { - vec2 screen = { (float(pos.x()) + 0.5f) / windows_size.x(), - (float(pos.y()) + 0.5f) / windows_size.y() + vec2 screen = { (float(pos.x()) + rnd()) / windows_size.x(), + (float(pos.y()) + rnd()) / windows_size.y() }; vec view = {screen.x() * 2 - 1, screen.y() * 2 - 1, 1, 1}; vec q = inv_proj_view * view; diff --git a/include/gproshan/viewer/che_viewer.h b/include/gproshan/viewer/che_viewer.h index 3911ffa2..0be733ad 100644 --- a/include/gproshan/viewer/che_viewer.h +++ b/include/gproshan/viewer/che_viewer.h @@ -84,7 +84,7 @@ class che_viewer virtual void draw_pointcloud(shader & program); void draw_selected_vertices(che_viewer & sphere, shader & program); - void select(const ivec2 & pos, const ivec2 & windows_size, const mat4 & inv_proj_view_mat, const vertex & cam_pos); + void select(const uvec2 & pos, const uvec2 & windows_size, const mat4 & inv_proj_view_mat, const vertex & cam_pos); void log_info(); }; diff --git a/include/gproshan/viewer/viewer.h b/include/gproshan/viewer/viewer.h index 130eb926..2e6a9e36 100644 --- a/include/gproshan/viewer/viewer.h +++ b/include/gproshan/viewer/viewer.h @@ -60,10 +60,10 @@ class viewer GLFWwindow * window = nullptr; rt::render_params render_params; - int & window_width = render_params.window_width; - int & window_height = render_params.window_height; - int & viewport_width = render_params.viewport_width; - int & viewport_height = render_params.viewport_height; + unsigned int & window_width = render_params.window_size.x(); + unsigned int & window_height = render_params.window_size.y(); + unsigned int & viewport_width = render_params.viewport_size.x(); + unsigned int & viewport_height = render_params.viewport_size.y(); mat4 proj_mat; mat4 proj_view_mat; @@ -176,7 +176,7 @@ class viewer static bool m_raycasting(viewer * view); - void pick_vertex(const int & x, const int & y); + void pick_vertex(const uvec2 & pos); void check_apply_all_meshes(const std::function & fun); }; diff --git a/shaders/shading.glsl b/shaders/shading.glsl index e271a344..dab32d5a 100644 --- a/shaders/shading.glsl +++ b/shaders/shading.glsl @@ -49,15 +49,15 @@ vec3 shading(vec3 color, vec3 n, vec3 pos, vec2 texcoord) { Ka = mat.Ka; if(mat.map_Ka != -1) - Ka *= texture(tex_Ka, texcoord).rgb; + Ka = texture(tex_Ka, texcoord).rgb; Kd = mat.Kd; if(mat.map_Kd != -1) - Kd *= texture(tex_Kd, texcoord).rgb; + Kd = texture(tex_Kd, texcoord).rgb; Ks = mat.Ks; if(mat.map_Ks != -1) - Ks *= texture(tex_Ks, texcoord).rgb; + Ks = vec3(texture(tex_Ks, texcoord).r); Ns = mat.Ns; } diff --git a/src/gproshan/app_viewer.cpp b/src/gproshan/app_viewer.cpp index c884e6b2..107fcc13 100644 --- a/src/gproshan/app_viewer.cpp +++ b/src/gproshan/app_viewer.cpp @@ -52,7 +52,8 @@ void app_viewer::init() add_menu("Scenes", { - add_process("Scan Scene", process_simulate_scanner) + add_process("Scan Scene", process_simulate_scanner), + add_process("RT Scatter Points", process_scatter) }); add_menu("Geometry", @@ -219,6 +220,22 @@ bool app_viewer::process_simulate_scanner(viewer * p_view) return true; } +bool app_viewer::process_scatter(viewer * p_view) +{ + app_viewer * view = (app_viewer *) p_view; + + rt::eval_hit h; + std::vector scatter(100); + + rt::random rnd(0xABCDEF); + for(vertex & v: scatter) + h.scatter_diffuse({}, v, rnd); + + view->add_mesh(new che(scatter.data(), scatter.size(), nullptr, 0)); + + return false; +} + // Geometry bool app_viewer::process_sampling_4points(viewer * p_view) diff --git a/src/gproshan/raytracing/embree.cpp b/src/gproshan/raytracing/embree.cpp index d55fbf22..8ac41daa 100644 --- a/src/gproshan/raytracing/embree.cpp +++ b/src/gproshan/raytracing/embree.cpp @@ -132,11 +132,12 @@ void embree::build_bvh(const std::vector & meshes, const std::vectorn_trigs || pointcloud) g_meshes[i]->n_trigs = 0; + [[maybe_unused]] const index_t & geomID = g_meshes[i]->n_trigs || meshes[i]->is_scene() ? add_mesh(meshes[i], model_mats[i]) : add_pointcloud(meshes[i], model_mats[i]); - gproshan_error_var(i == geomID); + gproshan_debug_var(i == geomID); } rtcCommitScene(rtc_scene); diff --git a/src/gproshan/raytracing/optix.cpp b/src/gproshan/raytracing/optix.cpp index d185463b..7cdcc073 100644 --- a/src/gproshan/raytracing/optix.cpp +++ b/src/gproshan/raytracing/optix.cpp @@ -61,8 +61,8 @@ optix::optix(const std::string & ptx) optix_pipeline_compile_opt = {}; optix_pipeline_compile_opt.traversableGraphFlags = OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS; optix_pipeline_compile_opt.usesMotionBlur = false; - optix_pipeline_compile_opt.numPayloadValues = 2; - optix_pipeline_compile_opt.numAttributeValues = 2; + optix_pipeline_compile_opt.numPayloadValues = 3; + optix_pipeline_compile_opt.numAttributeValues = 3; optix_pipeline_compile_opt.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE; optix_pipeline_compile_opt.pipelineLaunchParamsVariableName = "optix_params"; @@ -125,21 +125,16 @@ optix::~optix() void optix::render(vec4 * img, const render_params & params, const bool & flat) { - if(params.restart) n_samples = 0; - - optix_params.n_samples = n_samples; + optix_params.depth = params.depth; + optix_params.n_frames = params.n_frames; + optix_params.n_samples = params.n_samples; optix_params.color_buffer = img; - optix_params.window_width = params.window_width; - optix_params.window_height = params.window_height; + optix_params.window_size = params.window_size; if(params.viewport_is_window) - { - optix_params.window_width = params.viewport_width; - optix_params.window_height = params.viewport_height; - } + optix_params.window_size = params.viewport_size; - optix_params.viewport_x = params.viewport_x; - optix_params.viewport_y = params.viewport_y; + optix_params.viewport_pos = params.viewport_pos; optix_params.flat = flat; optix_params.cam_pos = params.cam_pos; @@ -155,14 +150,12 @@ void optix::render(vec4 * img, const render_params & params, const bool & flat) (CUdeviceptr) optix_params_buffer, sizeof(launch_params), &sbt, - params.viewport_width, - params.viewport_height, + params.viewport_size.x(), + params.viewport_size.y(), 1 ); cudaDeviceSynchronize(); - - ++n_samples; } void optix::create_raygen_programs() diff --git a/src/gproshan/raytracing/optix.cu b/src/gproshan/raytracing/optix.cu index de3c95e4..a6a15fe8 100644 --- a/src/gproshan/raytracing/optix.cu +++ b/src/gproshan/raytracing/optix.cu @@ -58,17 +58,23 @@ extern "C" __global__ void __closesthit__radiance() hit.normal = optix_params.flat ? normalize(cross(B - A, C - A)) : hit.normal; hit.position = (1.f - hit.u - hit.v) * A + hit.u * B + hit.v * C; - vec3 li = eval_li(hit, optix_params.ambient, optix_params.lights, optix_params.n_lights, optix_params.cam_pos, - [&](const vec3 & position, const vec3 & wi, const float & light_dist) -> bool - { - uint32_t occluded = 1; - optixTrace( optix_params.traversable, - * (float3 *) &position, - * (float3 *) &wi, - 1e-3f, // tmin - light_dist - 1e-3f, // tmax - 0.0f, // rayTime - OptixVisibilityMask(255), + vec3 * trace = ray_data(); + vec3 & color = trace[0]; + vec3 & position = trace[1]; + vec3 & scattered = trace[2]; // in ray_dir / out scattered + vec3 & attenuation = trace[3]; + + color = eval_li(hit, optix_params.ambient, optix_params.lights, optix_params.n_lights, optix_params.cam_pos, + [&](const vec3 & position, const vec3 & wi, const float & light_dist) -> bool + { + uint32_t occluded = 1; + optixTrace( optix_params.traversable, + * (float3 *) &position, + * (float3 *) &wi, + 1e-3f, // tmin + light_dist - 1e-3f, // tmax + 0.0f, // rayTime + OptixVisibilityMask(255), OPTIX_RAY_FLAG_DISABLE_ANYHIT | OPTIX_RAY_FLAG_DISABLE_CLOSESTHIT | OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT, @@ -80,8 +86,15 @@ extern "C" __global__ void __closesthit__radiance() return occluded != 0; }); - vec4 & pixel_color = *ray_data(); - pixel_color = (pixel_color * optix_params.n_samples + (li, 1)) / (optix_params.n_samples + 1); + random rnd = optixGetPayload_2(); + color *= attenuation; + position = hit.position; + + if(!hit.scatter_mat(scattered, scattered, rnd)) + attenuation = 0; + + attenuation /= 2; + optixSetPayload_2(rnd); } @@ -92,8 +105,7 @@ extern "C" __global__ void __anyhit__shadow() {} extern "C" __global__ void __miss__radiance() { - vec4 & pixel_color = *ray_data(); - pixel_color = {0, 0, 0, 0}; + optixSetPayload_0(0); } extern "C" __global__ void __miss__shadow() @@ -104,32 +116,59 @@ extern "C" __global__ void __miss__shadow() extern "C" __global__ void __raygen__render_frame() { - const int ix = optixGetLaunchIndex().x; - const int iy = optixGetLaunchIndex().y; + const uvec2 & id = {optixGetLaunchIndex().x, + optixGetLaunchIndex().y + }; + + const uvec2 & pos = id + optix_params.viewport_pos; - const vec3 ray_dir = ray_view_dir( {ix + optix_params.viewport_x, iy + optix_params.viewport_y}, - {optix_params.window_width, optix_params.window_height}, - optix_params.inv_proj_view, - optix_params.cam_pos - ); + random rnd(pos.x() + optix_params.window_size.x() * pos.y(), optix_params.n_frames); - vec4 & pixel_color = optix_params.color_buffer[ix + iy * optixGetLaunchDimensions().x]; + vec3 color_acc = 0; uint32_t u0, u1; - pack_pointer(&pixel_color, u0, u1); - - optixTrace( optix_params.traversable, - * (float3 *) &optix_params.cam_pos, - * (float3 *) &ray_dir, - 1e-5f, // tmin - 1e20f, // tmax - 0.0f, // rayTime - OptixVisibilityMask(255), - OPTIX_RAY_FLAG_DISABLE_ANYHIT, //OPTIX_RAY_FLAG_NONE, - 0, // SBT offset - 2, // SBT stride - 0, // missSBTIndex - u0, u1); + int depth; + + int samples = optix_params.n_samples; + do + { + vec3 trace[4]; + vec3 & color = trace[0]; + vec3 & position = trace[1] = optix_params.cam_pos; + vec3 & ray_dir = trace[2]; + vec3 & attenuation = trace[3] = 1; + + ray_dir = ray_view_dir(pos, optix_params.window_size, optix_params.inv_proj_view, optix_params.cam_pos, rnd); + + pack_pointer(trace, u0, u1); + + depth = optix_params.depth; + do + { + optixTrace( optix_params.traversable, + * (float3 *) &position, + * (float3 *) &ray_dir, + 1e-5f, // tmin + 1e20f, // tmax + 0.0f, // rayTime + OptixVisibilityMask(255), + OPTIX_RAY_FLAG_DISABLE_ANYHIT, //OPTIX_RAY_FLAG_NONE, + 0, // SBT offset + 2, // SBT stride + 0, // missSBTIndex + u0, u1, (unsigned int &) rnd); + + if(!u0) break; // miss + color_acc += color; + } + while(--depth); + } + while(--samples); + + color_acc /= optix_params.n_samples; + + vec4 & pixel_color = optix_params.color_buffer[id.x() + id.y() * optixGetLaunchDimensions().x]; + pixel_color = (pixel_color * optix_params.n_frames + (color_acc, 1)) / (optix_params.n_frames + 1); } diff --git a/src/gproshan/raytracing/raytracing.cpp b/src/gproshan/raytracing/raytracing.cpp index 3e3ea393..903c2437 100644 --- a/src/gproshan/raytracing/raytracing.cpp +++ b/src/gproshan/raytracing/raytracing.cpp @@ -9,52 +9,45 @@ namespace gproshan::rt { void raytracing::render(vec4 * img, const render_params & params, const bool & flat) { - if(params.restart) n_samples = 0; - - int window_width = params.window_width; - int window_height = params.window_height; + uvec2 window_size = params.window_size; if(params.viewport_is_window) + window_size = params.viewport_size; + + #pragma omp parallel for + for(unsigned int i = 0; i < params.viewport_size.x(); ++i) + for(unsigned int j = 0; j < params.viewport_size.y(); ++j) { - window_width = params.viewport_width; - window_height = params.viewport_height; - } + const uvec2 & pos = params.viewport_size + uvec2{i, j}; - vec4 li; + random rnd(pos.x() + window_size.x() * pos.y(), params.n_frames); - #pragma omp parallel for private(li) - for(int i = 0; i < params.viewport_width; ++i) - for(int j = 0; j < params.viewport_height; ++j) - { //row major - vec4 & color = img[j * params.viewport_width + i]; - const vertex & dir = ray_view_dir( {i + params.viewport_x, j + params.viewport_y}, - {window_width, window_height}, - params.inv_proj_view, - params.cam_pos - ); + vec4 & color = img[j * params.viewport_size.x() + i]; + const vertex & dir = ray_view_dir(pos, window_size, params.inv_proj_view, params.cam_pos, rnd); - vec3 li = closesthit_radiance(params.cam_pos, dir, params.ambient, params.lights, params.n_lights, params.cam_pos, flat); + const vec3 & li = closesthit_radiance(params.cam_pos, dir, params.ambient, params.lights, params.n_lights, params.cam_pos, flat); - color = (color * n_samples + (li, 1)) / (n_samples + 1); + color = (color * params.n_frames + (li, 1)) / (params.n_frames + 1); } - - ++n_samples; } -float * raytracing::raycaster( const ivec2 & windows_size, - const mat4 & inv_proj_view, - const vertex & cam_pos, - const index_t & samples ) const +std::vector raytracing::raycaster( const uvec2 & windows_size, + const mat4 & inv_proj_view, + const vertex & cam_pos, + const index_t & samples + ) const { - float * frame = new float[windows_size.x() * windows_size.y()]; + std::vector frame(windows_size.x() * windows_size.y()); #pragma omp parallel for - for(int i = 0; i < windows_size.x(); ++i) - for(int j = 0; j < windows_size.y(); ++j) + for(unsigned int i = 0; i < windows_size.x(); ++i) + for(unsigned int j = 0; j < windows_size.y(); ++j) { + random rnd(i, j); + //row major float & color = frame[(windows_size.y() - j - 1) * windows_size.x() + i] = 0; - vertex dir = ray_view_dir({i, j}, windows_size, inv_proj_view, cam_pos); + vertex dir = ray_view_dir({i, j}, windows_size, inv_proj_view, cam_pos, rnd); for(index_t s = 0; s < samples; ++s) color += intersect_depth(cam_pos, dir); diff --git a/src/gproshan/viewer/che_viewer.cpp b/src/gproshan/viewer/che_viewer.cpp index 702e945f..8c2965f0 100644 --- a/src/gproshan/viewer/che_viewer.cpp +++ b/src/gproshan/viewer/che_viewer.cpp @@ -234,9 +234,10 @@ void che_viewer::draw_selected_vertices(che_viewer & sphere, shader & program) } } -void che_viewer::select(const ivec2 & pos, const ivec2 & windows_size, const mat4 & inv_proj_view_mat, const vertex & cam_pos) +void che_viewer::select(const uvec2 & pos, const uvec2 & windows_size, const mat4 & inv_proj_view_mat, const vertex & cam_pos) { - const vertex & dir = rt::ray_view_dir({pos.x(), windows_size.y() - pos.y()}, windows_size, inv_proj_view_mat, cam_pos); + rt::random rnd(pos.x(), pos.y()); + const vertex & dir = rt::ray_view_dir({pos.x(), windows_size.y() - pos.y()}, windows_size, inv_proj_view_mat, cam_pos, rnd); const index_t & v = rt_embree->closest_vertex(cam_pos, dir); if(v != NIL) selected.push_back(v); diff --git a/src/gproshan/viewer/viewer.cpp b/src/gproshan/viewer/viewer.cpp index 4a5951ad..7c6e8d7d 100644 --- a/src/gproshan/viewer/viewer.cpp +++ b/src/gproshan/viewer/viewer.cpp @@ -280,7 +280,7 @@ void viewer::imgui() ImGui::Separator(); - for(int i = 0; i < render_params.n_lights; ++i) + for(unsigned int i = 0; i < render_params.n_lights; ++i) { light & l = render_params.lights[i]; @@ -310,7 +310,7 @@ void viewer::imgui() if(ImGui::Button("show lights")) { sphere_points.clear(); - for(int i = 0; i < render_params.n_lights; ++i) + for(unsigned int i = 0; i < render_params.n_lights; ++i) sphere_points.push_back(render_params.lights[i].pos); } @@ -609,7 +609,7 @@ void viewer::update_viewport_meshes() meshes[m]->vy = rows - (m / cols) - 1; } - glfwGetFramebufferSize(window, &viewport_width, &viewport_height); + glfwGetFramebufferSize(window, (int *) &viewport_width, (int *) &viewport_height); viewport_width /= cols; viewport_height /= rows; cam.aspect = real_t(viewport_width) / viewport_height; @@ -704,7 +704,7 @@ void viewer::mouse_callback(GLFWwindow * window, int button, int action, int mod view->idx_selected_mesh = idx_mesh; if(mods == GLFW_MOD_SHIFT && button == GLFW_MOUSE_BUTTON_LEFT) - view->pick_vertex(ix % view->viewport_width, iy % view->viewport_height); + view->pick_vertex({ix % view->viewport_width, iy % view->viewport_height}); } if(button == GLFW_MOUSE_BUTTON_LEFT) @@ -979,6 +979,8 @@ bool viewer::m_setup_raytracing(viewer * view) static double time = 0; ImGui::Combo("rt", &rt, "Select\0Embree\0OptiX\0\0"); + ImGui::SliderInt("depth", (int *) &view->render_params.depth, 1, 1 << 5); + ImGui::SliderInt("n_samples", (int *) &view->render_params.n_samples, 1, 1 << 5); if(ImGui::Button("Build")) { @@ -1163,18 +1165,13 @@ bool viewer::m_raycasting(viewer * view) rt::embree rc({mesh}, {mesh.model_mat}); - float * frame = rc.raycaster( {view->viewport_width, view->viewport_height}, - inverse(view->proj_view_mat), - view->cam.eye - ); + auto frame = rc.raycaster(view->render_params.viewport_size, inverse(view->proj_view_mat), view->cam.eye); std::thread([](const CImg & img) { img.display(); }, - CImg(frame, view->viewport_width, view->viewport_height)).detach(); - - delete [] frame; + CImg(frame.data(), view->viewport_width, view->viewport_height)).detach(); return false; } @@ -1257,6 +1254,9 @@ void viewer::render_rt(che_viewer & mesh, frame & rt_frame) render_params.restart = rt_frame.resize(viewport_width, viewport_height) || render_params.restart; + if(render_params.restart) + render_params.n_frames = 0; + //render_params.viewport_x = mesh.vx * viewport_width; //render_params.viewport_y = mesh.vy * viewport_height; //render_params.viewport_is_window = false; @@ -1267,13 +1267,15 @@ void viewer::render_rt(che_viewer & mesh, frame & rt_frame) rt_frame.unmap_pbo(mesh.render_opt == R_OPTIX); rt_frame.display(); + + ++render_params.n_frames; } -void viewer::pick_vertex(const int & x, const int & y) +void viewer::pick_vertex(const uvec2 & pos) { che_viewer & mesh = selected_mesh(); - mesh.select({x, y}, {viewport_width, viewport_height}, inverse(proj_view_mat), cam.eye); + mesh.select(pos, render_params.viewport_size, inverse(proj_view_mat), cam.eye); } void viewer::check_apply_all_meshes(const std::function & fun)