bool builder::resample_surfels(boost::filesystem::path const& input_file) const { std::cout << std::endl; std::cout << "--------------------------------" << std::endl; std::cout << "resample" << std::endl; std::cout << "--------------------------------" << std::endl; LOGGER_TRACE("resample stage"); lamure::pre::bvh bvh(memory_limit_, desc_.buffer_size, desc_.rep_radius_algo); if (!bvh.load_tree(input_file.string())) { return false; } if (bvh.state() != bvh::state_type::after_downsweep) { LOGGER_ERROR("Wrong processing state!"); return false; } CPU_TIMER; // perform resample bvh.resample(); //write resampled leaf level out format_xyz format_out; std::unique_ptr<format_xyz> dummy_format_in{new format_xyz()}; auto xyz_res_file = add_to_path(base_path_, "_res.xyz"); converter conv(*dummy_format_in, format_out, desc_.buffer_size); surfel_vector resampled_ll = bvh.get_resampled_leaf_lv_surfels(); conv.write_in_core_surfels_out(resampled_ll, xyz_res_file.string()); std::remove(input_file.string().c_str()); // LOGGER_DEBUG("Used memory: " << GetProcessUsedMemory() / 1024 / 1024 << " MiB"); return true; }
void BvhTriangleMesh::formTriangleAabbs() { void * cvs = verticesOnDevice(); void * tri = triangleIndicesOnDevice(); void * dst = bvh()->leafAabbs(); bvhCalculateLeafAabbsTriangle((Aabb *)dst, (float3 *)cvs, (uint3 *)tri, numTriangles()); }
bool builder::reserialize(boost::filesystem::path const& input_file, uint16_t start_stage) const { std::cout << std::endl; std::cout << "--------------------------------" << std::endl; std::cout << "serialize to file" << std::endl; std::cout << "--------------------------------" << std::endl; lamure::pre::bvh bvh(memory_limit_, desc_.buffer_size, desc_.rep_radius_algo); if (!bvh.load_tree(input_file.string())) { return false; } if (bvh.state() != bvh::state_type::after_upsweep) { LOGGER_ERROR("Wrong processing state!"); return false; } CPU_TIMER; auto lod_file = add_to_path(base_path_, ".lod"); auto kdn_file = add_to_path(base_path_, ".bvh"); std::cout << "serialize surfels to file" << std::endl; bvh.serialize_surfels_to_file(lod_file.string(), desc_.buffer_size); std::cout << "serialize bvh to file" << std::endl << std::endl; bvh.serialize_tree_to_file(kdn_file.string(), false); if ((!desc_.keep_intermediate_files) && (start_stage < 3)) { std::remove(input_file.string().c_str()); bvh.reset_nodes(); } // LOGGER_DEBUG("Used memory: " << GetProcessUsedMemory() / 1024 / 1024 << " MiB"); return true; }
void BvhTriangleMesh::initOnDevice() { m_verticesOnDevice = new CUDABuffer; m_verticesOnDevice->create(m_vertices->bufferSize()); m_triangleIndicesOnDevice = new CUDABuffer; m_triangleIndicesOnDevice->create(m_triangleIndices->bufferSize()); m_triangleIndicesOnDevice->hostToDevice(m_triangleIndices->data(), m_triangleIndices->bufferSize()); bvh()->setNumLeafNodes(numTriangles()); CollisionObject::initOnDevice(); }
boost::filesystem::path builder::upsweep(boost::filesystem::path input_file, uint16_t start_stage, reduction_strategy const* reduction_strategy, normal_computation_strategy const* normal_comp_strategy, radius_computation_strategy const* radius_comp_strategy) const { std::cout << std::endl; std::cout << "--------------------------------" << std::endl; std::cout << "upsweep" << std::endl; std::cout << "--------------------------------" << std::endl; LOGGER_TRACE("upsweep stage"); lamure::pre::bvh bvh(memory_limit_, desc_.buffer_size, desc_.rep_radius_algo); if (!bvh.load_tree(input_file.string())) { return boost::filesystem::path{}; } if (bvh.state() != bvh::state_type::after_downsweep) { LOGGER_ERROR("Wrong processing state!"); return boost::filesystem::path{}; } CPU_TIMER; // perform upsweep bvh.upsweep(*reduction_strategy, *normal_comp_strategy, *radius_comp_strategy, desc_.compute_normals_and_radii, desc_.resample); auto bvhu_file = add_to_path(base_path_, ".bvhu"); bvh.serialize_tree_to_file(bvhu_file.string(), true); if ((!desc_.keep_intermediate_files) && (start_stage < 2)) { std::remove(input_file.string().c_str()); } input_file = bvhu_file; // LOGGER_DEBUG("Used memory: " << GetProcessUsedMemory() / 1024 / 1024 << " MiB"); return input_file; }
void ZFighter::process(Mesh& mesh) const { Bvh bvh(&mesh); std::default_random_engine generator; std::uniform_real_distribution<double> distribution(0.00009,0.00012); // if any two triangles overlap, displace one of them for (int i = 0; i < (int)mesh.faces.size(); i++) { Eigen::Vector3d normal = mesh.faces[i].normal(mesh); if (bvh.doesOverlap(i, normal) != -1) { double r = distribution(generator); if (rand() / (double)RAND_MAX > 0.5) r = -r; for (int k = 0; k < 3; k++) { mesh.vertices[mesh.faces[i].indices[k]].position += r * normal; } } } }
boost::filesystem::path builder::downsweep(boost::filesystem::path input_file, uint16_t start_stage) const{ bool performed_outlier_removal = false; do { std::string status_suffix = ""; if ( true == performed_outlier_removal ) { status_suffix = " (after outlier removal)"; } std::cout << std::endl; std::cout << "--------------------------------" << std::endl; std::cout << "bvh properties" << status_suffix << std::endl; std::cout << "--------------------------------" << std::endl; lamure::pre::bvh bvh(memory_limit_, desc_.buffer_size, desc_.rep_radius_algo); bvh.init_tree(input_file.string(), desc_.max_fan_factor, desc_.surfels_per_node, base_path_); bvh.print_tree_properties(); std::cout << std::endl; std::cout << "--------------------------------" << std::endl; std::cout << "downsweep" << status_suffix << std::endl; std::cout << "--------------------------------" << std::endl; LOGGER_TRACE("downsweep stage"); CPU_TIMER; bvh.downsweep(desc_.translate_to_origin, input_file.string()); auto bvhd_file = add_to_path(base_path_, ".bvhd"); bvh.serialize_tree_to_file(bvhd_file.string(), true); if ((!desc_.keep_intermediate_files) && (start_stage < 1)) { // do not remove input file std::remove(input_file.string().c_str()); } input_file = bvhd_file; // LOGGER_DEBUG("Used memory: " << GetProcessUsedMemory() / 1024 / 1024 << " MiB"); if ( 3 <= start_stage ) { break; } if ( performed_outlier_removal ) { break; } if(start_stage <= 2 ) { if(desc_.outlier_ratio != 0.0) { size_t num_outliers = desc_.outlier_ratio * (bvh.nodes().size() - bvh.first_leaf()) * bvh.max_surfels_per_node(); size_t ten_percent_of_surfels = std::max( size_t(0.1 * (bvh.nodes().size() - bvh.first_leaf()) * bvh.max_surfels_per_node()), size_t(1) ); num_outliers = std::min(std::max(num_outliers, size_t(1) ), ten_percent_of_surfels); // remove at least 1 surfel, for any given ratio != 0.0 std::cout << std::endl; std::cout << "--------------------------------" << std::endl; std::cout << "outlier removal ( " << int(desc_.outlier_ratio * 100) << " percent = " << num_outliers << " surfels)" << std::endl; std::cout << "--------------------------------" << std::endl; LOGGER_TRACE("outlier removal stage"); surfel_vector kept_surfels = bvh.remove_outliers_statistically(num_outliers, desc_.number_of_outlier_neighbours); format_bin format_out; std::unique_ptr<format_abstract> dummy_format_in{new format_xyz()}; converter conv(*dummy_format_in, format_out, desc_.buffer_size); conv.set_surfel_callback([](surfel &s, bool& keep) { if (s.pos() == vec3r(0.0,0.0,0.0)) keep = false; }); auto binary_outlier_removed_file = add_to_path(base_path_, ".bin_wo_outlier"); conv.write_in_core_surfels_out(kept_surfels, binary_outlier_removed_file.string()); bvh.reset_nodes(); input_file = fs::canonical(binary_outlier_removed_file); performed_outlier_removal = true; } else { break; } } } while( true ); return input_file; }
Renderer::Renderer(CCamera* m_camera, COGLContext* glContext, CConfigManager* confManager) : m_camera(m_camera), m_glContext(glContext), m_confManager(confManager) { { std::vector<float3> positions; positions.push_back(make_float3(536.419, 548.9, 431.274)); positions.push_back(make_float3(540.488, 548.9, 465.94)); positions.push_back(make_float3(419.977, 469.29, 559.3)); positions.push_back(make_float3(555.476, 471.466, 510.595)); positions.push_back(make_float3(438.946, 548.9, 506.097)); positions.push_back(make_float3(434.071, 501.603, 559.3)); positions.push_back(make_float3(452.146, 548.9, 529.52)); positions.push_back(make_float3(504.6, 509.978, 559.3)); std::vector<float3> normals; for (int i = 0; i < positions.size(); ++i) { normals.push_back(make_float3(0.f, 1.f, 0.f)); } SimpleBvh bvh(positions, normals, false); } m_cudaContext .reset(new cuda::CudaContext()); m_textureViewer .reset(new TextureViewer()); m_postProcess .reset(new Postprocess(m_confManager)); m_fullScreenQuad .reset(new FullScreenQuad()); m_shadowMap .reset(new CShadowMap(512)); m_experimentData .reset(new CExperimentData()); m_export .reset(new CExport()); m_depthBuffer.reset(new COGLTexture2D(m_camera->GetWidth(), m_camera->GetHeight(), GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, 1, false, "Renderer.m_pDepthBuffer")); m_testTexture.reset(new COGLTexture2D(m_camera->GetWidth(), m_camera->GetHeight(), GL_RGBA32F, GL_RGBA, GL_FLOAT, 1, false, "Renderer.m_pTestTexture")); m_gbuffer.reset(new CGBuffer(m_camera->GetWidth(), m_camera->GetHeight(), m_depthBuffer.get())); m_ubTransform.reset(new COGLUniformBuffer(sizeof(TRANSFORM), 0, GL_DYNAMIC_DRAW , "UBTransform" )); m_ubMaterial .reset(new COGLUniformBuffer(sizeof(MATERIAL), 0, GL_DYNAMIC_DRAW , "UBMaterial" )); m_ubLight .reset(new COGLUniformBuffer(sizeof(AVPL_STRUCT), 0, GL_DYNAMIC_DRAW , "UBLight" )); m_ubConfig .reset(new COGLUniformBuffer(sizeof(CONFIG), 0, GL_DYNAMIC_DRAW , "UBConfig" )); m_ubCamera .reset(new COGLUniformBuffer(sizeof(CAMERA), 0, GL_DYNAMIC_DRAW , "UBCamera" )); m_ubInfo .reset(new COGLUniformBuffer(sizeof(INFO), 0, GL_DYNAMIC_DRAW , "UBInfo" )); m_linearSampler .reset(new COGLSampler(GL_LINEAR, GL_LINEAR, GL_CLAMP, GL_CLAMP, "LinearSampler")); m_pointSampler .reset(new COGLSampler(GL_NEAREST, GL_NEAREST, GL_REPEAT, GL_REPEAT, "PointSampler")); m_shadowMapSampler .reset(new COGLSampler(GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, "ShadowMapSampler")); m_postProcessRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 1, 0)); m_errorRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 1, 0)); m_gatherShadowmapRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 4, 0)); m_gatherAntiradianceRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 4, 0)); m_normalizeShadowmapRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 3, m_depthBuffer.get())); m_normalizeAntiradianceRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 3, m_depthBuffer.get())); m_resultRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 1, m_depthBuffer.get())); m_lightDebugRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 1, m_depthBuffer.get())); m_cudaRenderTarget .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 4, 0)); m_cudaRenderTargetSum .reset(new CRenderTarget(m_camera->GetWidth(), m_camera->GetHeight(), 4, 0)); m_gatherProgram .reset(new CProgram("Shaders/Gather.vert" , "Shaders/Gather.frag" , "GatherProgram" )); m_normalizeProgram .reset(new CProgram("Shaders/Gather.vert" , "Shaders/Normalize.frag" , "NormalizeProgram" )); m_errorProgram .reset(new CProgram("Shaders/Gather.vert" , "Shaders/Error.frag" , "ErrorProgram" )); m_addProgram .reset(new CProgram("Shaders/Gather.vert" , "Shaders/Add.frag" , "AddProgram" )); m_createGBufferProgram .reset(new CProgram("Shaders/CreateGBuffer.vert" , "Shaders/CreateGBuffer.frag" , "CreateGBufferProgram" )); m_createSMProgram .reset(new CProgram("Shaders/CreateSM.vert" , "Shaders/CreateSM.frag" , "CreateSMProgram" )); m_gatherRadianceWithSMProgram .reset(new CProgram("Shaders/Gather.vert" , "Shaders/GatherRadianceWithSM.frag" , "GatherRadianceWithSMProgram" )); m_areaLightProgram .reset(new CProgram("Shaders/DrawAreaLight.vert" , "Shaders/DrawAreaLight.frag" , "AreaLightProgram" )); m_drawSphere .reset(new CProgram("Shaders/DrawSphere.vert" , "Shaders/DrawSphere.frag" , "DrawSphere" )); m_debugProgram .reset(new CProgram("Shaders/Debug.vert" , "Shaders/Debug.frag" , "Debug" )); m_scene.reset(new Scene(m_camera, m_confManager)); m_scene->LoadCornellBox(); m_avplShooter.reset(new AvplShooter(m_scene.get(), m_confManager)); m_imagePlane .reset(new CImagePlane(m_scene->GetCamera())); m_pathTracingIntegrator .reset(new CPathTracingIntegrator(m_scene.get(), m_imagePlane.get())); m_cpuTimer .reset(new CTimer(CTimer::CPU)); m_glTimer .reset(new CTimer(CTimer::OGL)); m_globalTimer .reset(new CTimer(CTimer::CPU)); m_resultTimer .reset(new CTimer(CTimer::CPU)); m_cpuFrameProfiler .reset(new CTimer(CTimer::CPU)); m_gpuFrameProfiler .reset(new CTimer(CTimer::OGL)); m_Finished = false; m_FinishedDirectLighting = false; m_FinishedIndirectLighting = false; m_FinishedDebug = false; m_ProfileFrame = false; m_NumAVPLsForNextDataExport = 1000; m_NumAVPLsForNextImageExport = 10000; m_NumAVPLs = 0; m_NumPathsDebug = 0; m_ClearLighting = false; m_ClearAccumulationBuffer = false; BindSamplers(); UpdateUniformBuffers(); time(&m_StartTime); InitDebugLights(); ClearAccumulationBuffer(); m_globalTimer->Start(); m_cudaTargetTexture.reset(new COGLTexture2D(m_camera->GetWidth(), m_camera->GetWidth(), GL_RGBA32F, GL_RGBA, GL_FLOAT, 1, false, "m_cudaTarget")); m_cudaGather.reset(new CudaGather(m_camera, m_gbuffer->GetPositionTextureWS()->GetResourceIdentifier(), m_gbuffer->GetNormalTexture()->GetResourceIdentifier(), m_cudaRenderTarget->GetTarget(0)->GetResourceIdentifier(), m_cudaRenderTarget->GetTarget(1)->GetResourceIdentifier(), m_cudaRenderTarget->GetTarget(2)->GetResourceIdentifier(), m_scene->GetMaterialBuffer()->getMaterials(), m_ubTransform.get(), m_confManager)); }
int main() { //Checks for memory leaks in debug mode _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(width, height, "Hikari", nullptr, nullptr); glfwMakeContextCurrent(window); //Set callbacks for keyboard and mouse glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glewExperimental = GL_TRUE; glewInit(); glGetError(); //Define the viewport dimensions glViewport(0, 0, width, height); //Initialize cuda->opengl context cudaCheck(cudaGLSetGLDevice(0)); cudaGraphicsResource *resource; //Create a texture to store ray tracing result GLuint tex; glActiveTexture(GL_TEXTURE0); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL); cudaCheck(cudaGraphicsGLRegisterImage(&resource, tex, GL_TEXTURE_2D, cudaGraphicsMapFlagsWriteDiscard)); glBindTexture(GL_TEXTURE_2D, 0); Shader final = Shader("fsQuad.vert", "fsQuad.frag"); FullscreenQuad fsQuad = FullscreenQuad(); float4* buffer; cudaCheck(cudaMalloc((void**)&buffer, width * height * sizeof(float4))); cudaCheck(cudaMemset(buffer, 0, width * height * sizeof(float4))); //Mesh float3 offset = make_float3(0); float3 scale = make_float3(15); Mesh cBox("objs/Avent", 0, scale, offset); offset = make_float3(0, 55, 0); scale = make_float3(100); Mesh light("objs/plane", (int)cBox.triangles.size(), scale, offset); cBox.triangles.insert(cBox.triangles.end(), light.triangles.begin(), light.triangles.end()); cBox.aabbs.insert(cBox.aabbs.end(), light.aabbs.begin(), light.aabbs.end()); std::cout << "Num triangles: " << cBox.triangles.size() << std::endl; cBox.root = AABB(fminf(cBox.root.minBounds, light.root.minBounds), fmaxf(cBox.root.maxBounds, light.root.maxBounds)); BVH bvh(cBox.aabbs, cBox.triangles, cBox.root); Camera cam(make_float3(14, 15, 80), make_int2(width, height), 45.0f, 0.04f, 80.0f); Camera* dCam; cudaCheck(cudaMalloc((void**)&dCam, sizeof(Camera))); cudaCheck(cudaMemcpy(dCam, &cam, sizeof(Camera), cudaMemcpyHostToDevice)); cudaCheck(cudaGraphicsMapResources(1, &resource, 0)); cudaArray* pixels; cudaCheck(cudaGraphicsSubResourceGetMappedArray(&pixels, resource, 0, 0)); cudaResourceDesc viewCudaArrayResourceDesc; viewCudaArrayResourceDesc.resType = cudaResourceTypeArray; viewCudaArrayResourceDesc.res.array.array = pixels; cudaSurfaceObject_t viewCudaSurfaceObject; cudaCheck(cudaCreateSurfaceObject(&viewCudaSurfaceObject, &viewCudaArrayResourceDesc)); cudaCheck(cudaGraphicsUnmapResources(1, &resource, 0)); while (!glfwWindowShouldClose(window)) { float currentFrame = float(glfwGetTime()); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; //Check and call events glfwPollEvents(); handleInput(window, cam); if (cam.moved) { frameNumber = 0; cudaCheck(cudaMemset(buffer, 0, width * height * sizeof(float4))); } cam.rebuildCamera(); cudaCheck(cudaMemcpy(dCam, &cam, sizeof(Camera), cudaMemcpyHostToDevice)); frameNumber++; if (frameNumber < 20000) { cudaCheck(cudaGraphicsMapResources(1, &resource, 0)); std::chrono::time_point<std::chrono::system_clock> start, end; start = std::chrono::system_clock::now(); render(cam, dCam, viewCudaSurfaceObject, buffer, bvh.dTriangles, bvh.dNodes, frameNumber, cam.moved); end = std::chrono::system_clock::now(); std::chrono::duration<double> elapsed = end - start; std::cout << "Frame: " << frameNumber << " --- Elapsed time: " << elapsed.count() << "s\n"; cudaCheck(cudaGraphicsUnmapResources(1, &resource, 0)); } cam.moved = false; glUseProgram(final.program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glClear(GL_COLOR_BUFFER_BIT); final.setUniformi("tRender", 0); fsQuad.render(); //std::cout << glGetError() << std::endl; //Swap the buffers glfwSwapBuffers(window); glfwSetCursorPos(window, lastX, lastY); }