diff --git a/source/light.h b/source/light.h index 5ac4e2f..53d5db3 100644 --- a/source/light.h +++ b/source/light.h @@ -113,10 +113,12 @@ class point_light : public light { wi = normalize(pos - ray_pos); float cos_theta = dot(ray_dir, wi); phase_pdf = henyey_greenstein(cos_theta, phase_g1); - - float falloff = 1 / length(pos*pos - ray_pos * ray_pos); + float sqr_dist = length(pos * pos - ray_pos * ray_pos); + float falloff = 1 / sqr_dist; float3 Li = color * power * tr * phase_pdf * falloff; + + return Li; // Sample point light with equiangular pdf diff --git a/source/main.cpp b/source/main.cpp index eab5bfc..cd51438 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1061,7 +1061,7 @@ static void read_instance_file(std::string file_name) { volume_files.at(i).instances.at(x).position[1], volume_files.at(i).instances.at(x).position[2])); - + new_instance.set_xform(xform); instances.push_back(new_instance); @@ -1197,11 +1197,6 @@ int main(const int argc, const char* argv[]) instances.push_back(GPU_VDB()); instances.at(0).loadVDB(file_path, "density", "heat", "Cd"); - mat4 xform = instances.at(0).get_xform(); - //xform.scale(make_float3(20.0f)); - xform.translate(make_float3(0, 200, 0)); - instances.at(0).set_xform(xform); - } else if (file_extension == ".ins") { read_instance_file(fname); @@ -1280,7 +1275,7 @@ int main(const int argc, const char* argv[]) if(!proc_vol.create_volume(proc_box_min, proc_box_max, 1.0f, 0, 0.1f)) return 0; //instances.clear(); - instances.push_back(proc_vol); + //instances.push_back(proc_vol); // Send volume instances to gpu @@ -1344,15 +1339,20 @@ int main(const int argc, const char* argv[]) std::mt19937 e2(std::random_device{}()); std::uniform_real_distribution<> dist(0, 1); - int num_lights = 0; + int num_lights = 1; light_list l_list(num_lights); l_list.light_ptr = (point_light*)malloc(num_lights * sizeof(point_light)); cudaMallocManaged(&l_list.light_ptr, num_lights * sizeof(point_light)); - for (int i = 0; i < num_lights; ++i) { + l_list.light_ptr[0] = point_light(); + l_list.light_ptr[0].color = make_float3(1.0f, 1.0f, 0.9f); + l_list.light_ptr[0].pos = make_float3(.0f);; + l_list.light_ptr[0].power = 5000.0f; + + for (int i = 1; i < num_lights; ++i) { float3 pos = min + make_float3(dist(e2) * (max.x - min.x), dist(e2) * (max.y - min.y), dist(e2) * (max.z - min.z)); - float3 color = make_float3(dist(e2), dist(e2), dist(e2)); + float3 color = make_float3(1 - (dist(e2)*0.5), dist(e2), 1 - (dist(e2) * 0.5)); l_list.light_ptr[i] = point_light(); l_list.light_ptr[i].color = color; @@ -1530,11 +1530,11 @@ int main(const int argc, const char* argv[]) //*********************************************************************************************************************************** log("Setting up geometry and device pointers...", LOG); - float3 center = make_float3(400, 320, -200); + float3 center = make_float3(0, 1000, 0); float radius = 1; sphere ref_sphere(center, radius); ref_sphere.roughness = 1.0f; - ref_sphere.color = make_float3(1.0f, 0 , 0); + ref_sphere.color = make_float3(10.0f, 0 , 0); CUdeviceptr d_geo_ptr; check_success(cuMemAlloc(&d_geo_ptr, sizeof(sphere) * 1) == cudaSuccess); diff --git a/source/render_kernel.cu b/source/render_kernel.cu index 9c344ab..645a251 100644 --- a/source/render_kernel.cu +++ b/source/render_kernel.cu @@ -1454,18 +1454,19 @@ __device__ inline float3 estimate_point_light( { float3 Ld = make_float3(.0f); - float max_density = gpu_vdb[0].vdb_info.max_density; + + float max_density = root->max_extinction; + int light_budget = 10; - for (int i = 0; i < lights.num_lights; i++) { + while (light_budget >= 0) { - float dist = length(lights.light_ptr[i].pos - ray_pos); - float possible_tr = expf(-gpu_vdb[0].vdb_info.max_density * dist / (sqrtf(lights.light_ptr[i].power) * kernel_params.tr_depth)); + int light_index = int(floor(rand(&randstate) * lights.num_lights)); - if (possible_tr > 0.01f) { - float3 dir = normalize(lights.light_ptr[i].pos - ray_pos); - float3 tr = Tr(randstate, ray_pos, dir, kernel_params, gpu_vdb, ref_sphere, root); - Ld += lights.light_ptr[i].Le(randstate, ray_pos, ray_dir, kernel_params.phase_g1, tr, max_density, kernel_params.density_mult, kernel_params.tr_depth); - } + float3 dir = normalize(lights.light_ptr[light_index].pos - ray_pos); + float3 tr = Tr(randstate, ray_pos, dir, kernel_params, gpu_vdb, ref_sphere, root); + if(light_budget < lights.num_lights) Ld += lights.light_ptr[light_index].Le(randstate, ray_pos, ray_dir, kernel_params.phase_g1, tr, max_density, kernel_params.density_mult, kernel_params.tr_depth); + + light_budget--; } @@ -1763,6 +1764,7 @@ __device__ inline float3 direct_integrator( float& tr, const Kernel_params kernel_params, const GPU_VDB* gpu_vdb, + const light_list lights, const sphere& ref_sphere, OCTNode* root, const AtmosphereParameters atmosphere) @@ -1792,7 +1794,11 @@ __device__ inline float3 direct_integrator( } } - if (mi) L += estimate_sun(kernel_params, rand_state, ray_pos, ray_dir, gpu_vdb, ref_sphere, root, atmosphere) * beta; + if (mi) { + L += estimate_sun(kernel_params, rand_state, ray_pos, ray_dir, gpu_vdb, ref_sphere, root, atmosphere) * beta; + L += estimate_point_light(kernel_params, lights, rand_state, ray_pos, ray_dir, gpu_vdb, ref_sphere, root) * beta; + } + if (kernel_params.emission_scale > 0 && mi) { L += estimate_emission(rand_state, ray_pos, ray_dir, kernel_params, gpu_vdb, root); } @@ -2250,7 +2256,7 @@ extern "C" __global__ void volume_rt_kernel( //value = test_geometry_list(ray_pos, ray_dir, geo_list, rand_state); depth = depth_calculator(rand_state, ray_pos, ray_dir, tr, kernel_params, gpu_vdb, sphere, oct_root); if (kernel_params.integrator) value = vol_integrator(rand_state, lights, ray_pos, ray_dir, tr, kernel_params, gpu_vdb, sphere, oct_root, atmosphere); - else value = direct_integrator(rand_state, ray_pos, ray_dir, tr, kernel_params, gpu_vdb, sphere, oct_root, atmosphere); + else value = direct_integrator(rand_state, ray_pos, ray_dir, tr, kernel_params, gpu_vdb, lights, sphere, oct_root, atmosphere); } // Check if values contains nan or infinite values