@@ -160,24 +160,24 @@ KERNEL void GenerateLightVertices(
160
160
n ,
161
161
n ,
162
162
0.f ,
163
+ selection_pdf * light_pdf ,
163
164
1.f ,
164
- 1.f ,
165
- ke / (selection_pdf * light_pdf ),
165
+ 100.f ,//ke * fabs(dot(n, my_ray->d.xyz)) / selection_pdf * light_pdf,
166
166
kLight ,
167
167
-1 );
168
168
169
169
* my_count = 1 ;
170
170
* my_vertex = v ;
171
171
172
172
// Initlize path data
173
- my_path -> throughput = make_float3 ( 1.f , 1.f , 1.f ) ;
173
+ my_path -> throughput = ke * fabs ( dot ( n , my_ray -> d . xyz )) / selection_pdf * light_pdf ;
174
174
my_path -> volume = -1 ;
175
175
my_path -> flags = 0 ;
176
176
my_path -> active = 0xFF ;
177
177
}
178
178
}
179
179
180
- KERNEL void SampleSurface (
180
+ KERNEL void SampleSurface (
181
181
// Ray batch
182
182
GLOBAL ray const * rays ,
183
183
// Intersection data
@@ -361,7 +361,7 @@ KERNEL void SampleSurface(
361
361
diffgeo .uv ,
362
362
pdf_fwd ,
363
363
0.f ,
364
- throughput * t / bxdfpdf ,
364
+ my_prev_vertex -> flow * t / bxdfpdf ,
365
365
kSurface ,
366
366
diffgeo .material_index );
367
367
@@ -508,8 +508,8 @@ KERNEL void SampleSurface(
508
508
509
509
bool singular_light = Light_IsSingular (& scene .lights [light_idx ]);
510
510
bool singular_bxdf = Bxdf_IsSingular (& diffgeo );
511
- lightweight = singular_light ? 1.f : BalanceHeuristic (1 , lightpdf , 1 , lightbxdfpdf );
512
- bxdfweight = singular_bxdf ? 1.f : BalanceHeuristic (1 , bxdfpdf , 1 , bxdflightpdf );
511
+ lightweight = singular_light ? 1.f : BalanceHeuristic (1 , lightpdf * selection_pdf , 1 , lightbxdfpdf );
512
+ bxdfweight = singular_bxdf ? 1.f : BalanceHeuristic (1 , bxdfpdf , 1 , bxdflightpdf * selection_pdf );
513
513
514
514
float3 radiance = 0.f ;
515
515
float3 wo ;
@@ -518,7 +518,7 @@ KERNEL void SampleSurface(
518
518
{
519
519
// Otherwise save some intersector cycles
520
520
Ray_SetInactive (shadowrays + global_id );
521
- lightsamples [global_id ] = 0 ;
521
+ lightsamples [global_id ] = 0 ;
522
522
return ;
523
523
}
524
524
@@ -527,15 +527,15 @@ KERNEL void SampleSurface(
527
527
if (((singular_bxdf && !singular_light ) || split < 0.5f ) && bxdfpdf > 0.f )
528
528
{
529
529
wo = CRAZY_HIGH_DISTANCE * bxdfwo ;
530
- le = Light_GetLe (light_idx , & scene , & diffgeo , & wo , TEXTURE_ARGS );
531
530
float ndotwo = fabs (dot (diffgeo .n , normalize (wo )));
532
- radiance = 2.f * le * bxdfweight * throughput * bxdf * ndotwo / bxdfpdf ;
531
+ le = Light_GetLe (light_idx , & scene , & diffgeo , & wo , TEXTURE_ARGS );
532
+ radiance = 2.f * bxdfweight * le * throughput * bxdf * ndotwo / bxdfpdf ;
533
533
}
534
534
535
535
if (((!singular_bxdf && singular_light ) || split >= 0.5f ) && lightpdf > 0.f )
536
536
{
537
537
wo = lightwo ;
538
- float ndotwo = fabs (dot (diffgeo .n , normalize (wo )));
538
+ float ndotwo = fabs (dot (diffgeo .n , normalize (wo )));
539
539
radiance = 2.f * lightweight * le * Bxdf_Evaluate (& diffgeo , wi , normalize (wo ), TEXTURE_ARGS ) * throughput * ndotwo / lightpdf / selection_pdf ;
540
540
}
541
541
@@ -546,7 +546,7 @@ KERNEL void SampleSurface(
546
546
float3 shadow_ray_o = diffgeo .p + CRAZY_LOW_DISTANCE * diffgeo .n ;
547
547
float3 temp = diffgeo .p + wo - shadow_ray_o ;
548
548
float3 shadow_ray_dir = normalize (temp );
549
- float shadow_ray_length = length (temp );
549
+ float shadow_ray_length = 0.999f * length (temp );
550
550
int shadow_ray_mask = 0xFFFFFFFF ;
551
551
552
552
Ray_Init (shadowrays + global_id , shadow_ray_o , shadow_ray_dir , shadow_ray_length , 0.f , shadow_ray_mask );
@@ -722,7 +722,7 @@ KERNEL void SampleSurface(
722
722
723
723
float3 connect_ray_o = eye_dg .p + CRAZY_LOW_DISTANCE * eye_dg .n ;
724
724
float3 temp = light_dg .p - connect_ray_o ;
725
- float connect_ray_length = length (temp );
725
+ float connect_ray_length = 0.999f * length (temp );
726
726
float3 connect_ray_dir = eye_wo ;
727
727
728
728
Ray_Init (& connection_rays [global_id ], connect_ray_o , connect_ray_dir , connect_ray_length , 0.f , 0xFFFFFFFF );
@@ -863,6 +863,36 @@ KERNEL void GatherContributions(
863
863
}
864
864
}
865
865
866
+ KERNEL void GatherCausticContributions (
867
+ int num_items ,
868
+ int width ,
869
+ int height ,
870
+ GLOBAL int const * restrict shadow_hits ,
871
+ GLOBAL float3 const * restrict contributions ,
872
+ GLOBAL float2 const * restrict image_plane_positions ,
873
+ GLOBAL float4 * restrict output
874
+ )
875
+ {
876
+ int global_id = get_global_id (0 );
877
+
878
+ if (global_id < num_items )
879
+ {
880
+ // Start collecting samples
881
+ {
882
+ // If shadow ray didn't hit anything and reached skydome
883
+ if (shadow_hits [global_id ] == -1 )
884
+ {
885
+ // Add its contribution to radiance accumulator
886
+ float3 radiance = contributions [global_id ];
887
+ float2 uv = image_plane_positions [global_id ];
888
+ int x = clamp ((int )(uv .x * width ), 0 , width - 1 );
889
+ int y = clamp ((int )(uv .y * height ), 0 , height - 1 );
890
+ output [y * width + x ].xyz += radiance ;
891
+ }
892
+ }
893
+ }
894
+ }
895
+
866
896
// Restore pixel indices after compaction
867
897
KERNEL void RestorePixelIndices (
868
898
// Compacted indices
@@ -907,3 +937,127 @@ KERNEL void ApplyGammaAndCopyData(
907
937
}
908
938
909
939
940
+ INLINE void atomic_add_float (volatile __global float * addr , float val )
941
+ {
942
+ union {
943
+ unsigned int u32 ;
944
+ float f32 ;
945
+ } next , expected , current ;
946
+ current .f32 = * addr ;
947
+ do {
948
+ expected .f32 = current .f32 ;
949
+ next .f32 = expected .f32 + val ;
950
+ current .u32 = atomic_cmpxchg ((volatile __global unsigned int * )addr ,
951
+ expected .u32 , next .u32 );
952
+ } while (current .u32 != expected .u32 );
953
+ }
954
+
955
+ KERNEL void ConnectCaustics (
956
+ int num_items ,
957
+ int eye_vertex_index ,
958
+ GLOBAL PathVertex const * restrict light_subpath ,
959
+ GLOBAL int const * restrict light_subpath_length ,
960
+ GLOBAL Camera const * restrict camera ,
961
+ GLOBAL Material const * restrict materials ,
962
+ TEXTURE_ARG_LIST ,
963
+ GLOBAL ray * restrict connection_rays ,
964
+ GLOBAL float4 * restrict contributions ,
965
+ GLOBAL float2 * restrict image_plane_positions
966
+ )
967
+ {
968
+ int global_id = get_global_id (0 );
969
+
970
+ if (global_id >= num_items )
971
+ return ;
972
+
973
+ if (eye_vertex_index >= light_subpath_length [global_id ])
974
+ {
975
+ contributions [global_id ].xyz = 0.f ;
976
+ Ray_SetInactive (connection_rays + global_id );
977
+ return ;
978
+ }
979
+
980
+ GLOBAL PathVertex const * my_light_vertex = light_subpath + BDPT_MAX_SUBPATH_LEN * global_id + eye_vertex_index ;
981
+ GLOBAL PathVertex const * my_prev_light_vertex = light_subpath + BDPT_MAX_SUBPATH_LEN * global_id + eye_vertex_index - 1 ;
982
+
983
+ DifferentialGeometry eye_dg ;
984
+ eye_dg .p = camera -> p ;
985
+ eye_dg .n = camera -> forward ;
986
+ eye_dg .ng = camera -> forward ;
987
+ eye_dg .uv = 0.f ;
988
+ eye_dg .dpdu = GetOrthoVector (eye_dg .n );
989
+ eye_dg .dpdv = cross (eye_dg .n , eye_dg .dpdu );
990
+ DifferentialGeometry_CalculateTangentTransforms (& eye_dg );
991
+
992
+ DifferentialGeometry light_dg ;
993
+ light_dg .p = my_light_vertex -> position ;
994
+ light_dg .n = my_light_vertex -> shading_normal ;
995
+ light_dg .ng = my_light_vertex -> geometric_normal ;
996
+ light_dg .uv = my_light_vertex -> uv ;
997
+ light_dg .dpdu = GetOrthoVector (light_dg .n );
998
+ light_dg .dpdv = cross (light_dg .dpdu , light_dg .n );
999
+ light_dg .mat = materials [my_light_vertex -> material_index ];
1000
+ light_dg .mat .fresnel = 1.f ;
1001
+ DifferentialGeometry_CalculateTangentTransforms (& light_dg );
1002
+
1003
+ float3 eye_wo = normalize (light_dg .p - eye_dg .p );
1004
+ float3 light_wi = normalize (my_prev_light_vertex -> position - light_dg .p );
1005
+ float3 light_wo = - eye_wo ;
1006
+
1007
+ float3 light_bxdf = Bxdf_Evaluate (& light_dg , light_wi , light_wo , TEXTURE_ARGS );
1008
+ float light_pdf = Bxdf_GetPdf (& light_dg , light_wi , light_wo , TEXTURE_ARGS );
1009
+ float light_dotnl = max (dot (light_dg .n , light_wo ), 0.f );
1010
+
1011
+ float3 light_contribution = my_prev_light_vertex -> flow * (light_bxdf ) / my_light_vertex -> pdf_forward ;
1012
+
1013
+ //float w0 = camera_pdf / (camera_pdf + light_pdf);
1014
+ //float w1 = light_pdf / (camera_pdf + light_pdf);
1015
+
1016
+ float dist = length (light_dg .p - eye_dg .p );
1017
+ float3 val = (light_contribution ) / (dist * dist );
1018
+ contributions [global_id ].xyz = REASONABLE_RADIANCE (val );
1019
+
1020
+ float connect_ray_length = 0.99f * length (light_dg .p - eye_dg .p );
1021
+ float3 connect_ray_dir = eye_wo ;
1022
+ float3 connect_ray_o = eye_dg .p ;
1023
+
1024
+ Ray_Init (connection_rays + global_id , connect_ray_o , connect_ray_dir , connect_ray_length , 0.f , 0xFFFFFFFF );
1025
+
1026
+ ray r ;
1027
+ r .o .xyz = eye_dg .p ;
1028
+ r .o .w = CRAZY_HIGH_DISTANCE ;
1029
+ r .d .xyz = eye_wo ;
1030
+
1031
+ float3 v0 , v1 , v2 , v3 ;
1032
+ float2 ext = 0.5f * camera -> dim ;
1033
+ v0 = camera -> p + camera -> focal_length * camera -> forward - ext .x * camera -> right - ext .y * camera -> up ;
1034
+ v1 = camera -> p + camera -> focal_length * camera -> forward + ext .x * camera -> right - ext .y * camera -> up ;
1035
+ v2 = camera -> p + camera -> focal_length * camera -> forward + ext .x * camera -> right + ext .y * camera -> up ;
1036
+ v3 = camera -> p + camera -> focal_length * camera -> forward - ext .x * camera -> right + ext .y * camera -> up ;
1037
+
1038
+ float a , b ;
1039
+ float3 p ;
1040
+ if (IntersectTriangle (& r , v0 , v1 , v2 , & a , & b ))
1041
+ {
1042
+ p = (1.f - a - b ) * v0 + a * v1 + b * v2 ;
1043
+ }
1044
+ else if (IntersectTriangle (& r , v0 , v2 , v3 , & a , & b ))
1045
+ {
1046
+ p = (1.f - a - b ) * v0 + a * v2 + b * v3 ;
1047
+ }
1048
+ else
1049
+ {
1050
+ contributions [global_id ].xyz = 0.f ;
1051
+ Ray_SetInactive (connection_rays + global_id );
1052
+ return ;
1053
+ }
1054
+
1055
+ float3 imgp = p - v0 ;
1056
+ float2 impuv ;
1057
+ impuv .x = clamp (dot (imgp , v1 - v0 ) / dot (v1 - v0 , v1 - v0 ), 0.f , 1.f );
1058
+ impuv .y = clamp (dot (imgp , v3 - v0 ) / dot (v3 - v0 , v3 - v0 ), 0.f , 1.f );
1059
+ image_plane_positions [global_id ] = impuv ;
1060
+ }
1061
+
1062
+
1063
+
0 commit comments