@@ -976,46 +976,6 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
976976 // trace the ray against the scene
977977 Intersection hit = scene.intersect (r, inf, prev_id);
978978
979- const HomogeneousVolume* volume = static_cast <const HomogeneousVolume*>(medium_stack.current ());
980- bool in_medium = medium_stack.in_medium ();
981-
982- if (in_medium && volume && !volume->is_vacuum ()) {
983- Medium::Sample medium_sample = volume->sample (r, sampler, hit);
984-
985- path_weight *= medium_sample.transmittance ;
986-
987- if (!(path_weight.x > 0 ) && !(path_weight.y > 0 ) && !(path_weight.z > 0 )) {
988- break ;
989- }
990-
991- r.origin = r.origin + r.direction * medium_sample.t ;
992-
993-
994- if (medium_sample.scatter ) {
995-
996- Vec3 rand_phase = sampler.get ();
997- HenyeyGreenstein phase_func (volume->medium_g );
998- BSDF::Sample phase_sample = phase_func.sample (-r.direction , rand_phase.x , rand_phase.y , rand_phase.z );
999-
1000- if (phase_sample.pdf <= 0 .0f ) {
1001- break ;
1002- }
1003-
1004- Color3 albedo = Color3 (
1005- volume->sigma_s .x / volume->sigma_t .x ,
1006- volume->sigma_s .y / volume->sigma_t .y ,
1007- volume->sigma_s .z / volume->sigma_t .z
1008- );
1009-
1010- path_weight *= albedo * phase_sample.weight ;
1011-
1012- r.direction = phase_sample.wi ;
1013- bsdf_pdf = phase_sample.pdf ;
1014-
1015- continue ;
1016- }
1017- }
1018-
1019979 if (hit.t == inf) {
1020980 // we hit nothing? check background shader
1021981 if (backgroundShaderID >= 0 ) {
@@ -1114,6 +1074,116 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
11141074 float yi = s.y ;
11151075 float zi = s.z ;
11161076
1077+ const HomogeneousVolume* volume = static_cast <const HomogeneousVolume*>(medium_stack.current ());
1078+ bool in_medium = medium_stack.in_medium ();
1079+
1080+ if (in_medium && volume && !volume->is_vacuum ()) {
1081+ Medium::Sample medium_sample = volume->sample (r, sampler, hit);
1082+
1083+ path_weight *= medium_sample.transmittance ;
1084+
1085+ if (!(path_weight.x > 0 || path_weight.y > 0 || path_weight.z > 0 )) {
1086+ break ;
1087+ }
1088+
1089+ if (medium_sample.scatter ) {
1090+ Vec3 scatter_pos = r.point (medium_sample.t );
1091+ r.origin = scatter_pos;
1092+
1093+ HenyeyGreenstein phase_func (volume->medium_g );
1094+
1095+ if (backgroundResolution > 0 ) {
1096+ Dual2<Vec3> bg_dir;
1097+
1098+ float bg_pdf = 0 ;
1099+ Vec3 bg = background.sample (xi, yi, bg_dir, bg_pdf);
1100+
1101+ // evaluate phase function for this direction
1102+ BSDF::Sample phase_sample = phase_func.eval (-r.direction , bg_dir.val ());
1103+
1104+ Color3 contrib = path_weight * phase_sample.pdf / bg_pdf * bg
1105+ * MIS::power_heuristic<MIS::WEIGHT_WEIGHT>(bg_pdf, phase_sample.pdf );
1106+
1107+ if ((contrib.x + contrib.y + contrib.z ) > 0 ) {
1108+ // trace shadow ray from scatter point
1109+ Ray shadow_ray = Ray (scatter_pos, bg_dir.val (), 0 , 0 , 0 , Ray::SHADOW);
1110+ Intersection shadow_hit = scene.intersect (shadow_ray, inf, -1 );
1111+
1112+ if (shadow_hit.t == inf) {
1113+ Color3 tr_to_bg = volume->transmittance (shadow_hit.t );
1114+ path_radiance += contrib * tr_to_bg;
1115+ }
1116+ }
1117+ }
1118+
1119+ if (lightprims_size > 0 ) {
1120+ const float light_pick_pdf = 1 .0f / lightprims_size;
1121+
1122+ float xl = xi * lightprims_size;
1123+ int ls = floorf (xl);
1124+ xl -= ls;
1125+
1126+ uint32_t lid = m_lightprims[ls];
1127+ int shaderID = scene.shaderid (lid);
1128+
1129+ LightSample sample = scene.sample (lid, scatter_pos, xl, yi);
1130+
1131+ // evaluate phase function for direction toward light
1132+ BSDF::Sample phase_sample = phase_func.eval (-r.direction , sample.dir );
1133+
1134+ Color3 contrib = path_weight * phase_sample.pdf
1135+ * MIS::power_heuristic<MIS::EVAL_WEIGHT>(
1136+ light_pick_pdf * sample.pdf , phase_sample.pdf );
1137+
1138+ if ((contrib.x + contrib.y + contrib.z ) > 0 ) {
1139+ ShaderGlobalsType light_sg;
1140+ Ray shadow_ray = Ray (scatter_pos, sample.dir , 0 , 0 , 0 , Ray::SHADOW);
1141+ // trace shadow ray to the light
1142+ Intersection shadow_hit = scene.intersect (shadow_ray, sample.dist , -1 , lid);
1143+
1144+ #ifndef __CUDACC__
1145+ const bool did_hit = shadow_hit.t == sample.dist ;
1146+ #else
1147+ const bool did_hit = fabsf (shadow_hit.t - sample.dist ) < 1e-3f ;
1148+ #endif
1149+
1150+ if (did_hit) {
1151+ globals_from_hit (light_sg, shadow_ray, sample.dist , lid,
1152+ sample.u , sample.v );
1153+ #ifndef __CUDACC__
1154+ shadingsys->execute (*ctx, *m_shaders[shaderID].surf , light_sg);
1155+ #else
1156+ execute_shader (light_sg, shaderID, light_closure_pool);
1157+ #endif
1158+ ShadingResult light_result;
1159+ process_closure (light_sg, 0 , light_result,
1160+ (const ClosureColor*)light_sg.Ci , true );
1161+
1162+ // account for medium attenuation to light
1163+ Color3 tr_to_light = volume->transmittance (sample.dist );
1164+ path_radiance += contrib * light_result.Le * tr_to_light;
1165+ }
1166+ }
1167+ }
1168+
1169+
1170+ Vec3 rand_phase = sampler.get ();
1171+ BSDF::Sample phase_sample = phase_func.sample (-r.direction ,
1172+ rand_phase.x ,
1173+ rand_phase.y ,
1174+ rand_phase.z );
1175+ if (phase_sample.pdf <= 0 .0f ) {
1176+ break ;
1177+ }
1178+
1179+ path_weight *= phase_sample.weight ;
1180+ r.direction = phase_sample.wi ;
1181+ bsdf_pdf = phase_sample.pdf ;
1182+
1183+ continue ;
1184+ }
1185+ }
1186+
11171187 // trace one ray to the background
11181188 if (backgroundResolution > 0 ) {
11191189 Dual2<Vec3> bg_dir;
@@ -1200,10 +1270,11 @@ SimpleRaytracer::subpixel_radiance(float x, float y, Sampler& sampler,
12001270 r.spread = std::max (r.spread , p.roughness );
12011271 r.roughness = p.roughness ;
12021272
1203- if (!result.medium_data .is_vacuum ()) {
1273+ if (!result.medium_data .is_vacuum ()) {// has_params_as(result.medium_data)) {
12041274 bool entering = !sg.backfacing ;
12051275
12061276 if (entering) {
1277+ // std::cout << "asfd" << std::endl;
12071278 medium_stack.push_medium <HomogeneousVolume>(result.medium_data );
12081279 } else {
12091280 medium_stack.pop_medium ();
0 commit comments