@@ -14,6 +14,7 @@ uniform vec3 camera_position;
1414uniform mat4 env_map_model;
1515// Direction from the light toward the scene.
1616uniform vec3 light_dir;
17+ uniform int light_type;
1718uniform vec3 light_color;
1819uniform sampler2D opaque_albedo_texture;
1920uniform sampler2D opaque_normal_texture;
@@ -86,6 +87,11 @@ layout(std430, binding = 3) buffer BvhBufferOpaque
8687
8788const int kMaterialTransmissive = 0 ;
8889const int kMaterialOpaque = 1 ;
90+ const int kLightTypePoint = 2 ;
91+ const float kPointLightLinearAttenuation = 0.45 ;
92+ const float kPointLightQuadraticAttenuation = 0.35 ;
93+ const float kPointLightFadeStart = 3.5 ;
94+ const float kPointLightFadeEnd = 11.0 ;
8995
9096int TriangleCountTransmissive()
9197{
@@ -285,6 +291,17 @@ vec3 ComputeAbsorption(const HitInfo hit, float travel)
285291 return exp (- attenuation_coeff * max (travel, 0.0 ));
286292}
287293
294+ float ComputePointLightVisibility(const float distance_to_light)
295+ {
296+ float attenuation =
297+ 1.0 /
298+ (1.0 + kPointLightLinearAttenuation * distance_to_light +
299+ kPointLightQuadraticAttenuation * distance_to_light * distance_to_light);
300+ float fade =
301+ 1.0 - smoothstep (kPointLightFadeStart, kPointLightFadeEnd, distance_to_light);
302+ return attenuation * fade;
303+ }
304+
288305bool rayTriangleIntersect(
289306 const vec3 ray_origin,
290307 const vec3 ray_direction,
@@ -335,6 +352,7 @@ bool rayAabbIntersect(
335352bool traverseTransmissiveBVH(
336353 const vec3 ray_origin,
337354 const vec3 ray_dir,
355+ const float max_t,
338356 out float out_t,
339357 out vec2 out_bary,
340358 out int out_tri)
@@ -371,7 +389,8 @@ bool traverseTransmissiveBVH(
371389 transmissive_triangles[tri_index],
372390 t,
373391 bary) &&
374- t < out_t)
392+ t < out_t &&
393+ t < max_t)
375394 {
376395 out_t = t;
377396 out_bary = bary;
@@ -398,6 +417,7 @@ bool traverseTransmissiveBVH(
398417bool traverseOpaqueBVH(
399418 const vec3 ray_origin,
400419 const vec3 ray_dir,
420+ const float max_t,
401421 out float out_t,
402422 out vec2 out_bary,
403423 out int out_tri)
@@ -434,7 +454,8 @@ bool traverseOpaqueBVH(
434454 opaque_triangles[tri_index],
435455 t,
436456 bary) &&
437- t < out_t)
457+ t < out_t &&
458+ t < max_t)
438459 {
439460 out_t = t;
440461 out_bary = bary;
@@ -458,14 +479,14 @@ bool traverseOpaqueBVH(
458479 return hit;
459480}
460481
461- bool anyHitTriangles(const vec3 ray_origin, const vec3 ray_dir)
482+ bool anyHitTriangles(const vec3 ray_origin, const vec3 ray_dir, const float max_t )
462483{
463484 if (transmissive_nodes.length () > 0 )
464485 {
465486 float t = 0.0 ;
466487 vec2 bary = vec2 (0.0 );
467488 int tri_index = - 1 ;
468- if (traverseTransmissiveBVH(ray_origin, ray_dir, t, bary, tri_index))
489+ if (traverseTransmissiveBVH(ray_origin, ray_dir, max_t, t, bary, tri_index))
469490 {
470491 return true;
471492 }
@@ -482,7 +503,8 @@ bool anyHitTriangles(const vec3 ray_origin, const vec3 ray_dir)
482503 ray_dir,
483504 transmissive_triangles[i],
484505 t,
485- bary))
506+ bary) &&
507+ t < max_t)
486508 {
487509 return true;
488510 }
@@ -493,7 +515,7 @@ bool anyHitTriangles(const vec3 ray_origin, const vec3 ray_dir)
493515 float t = 0.0 ;
494516 vec2 bary = vec2 (0.0 );
495517 int tri_index = - 1 ;
496- if (traverseOpaqueBVH(ray_origin, ray_dir, t, bary, tri_index))
518+ if (traverseOpaqueBVH(ray_origin, ray_dir, max_t, t, bary, tri_index))
497519 {
498520 return true;
499521 }
@@ -510,7 +532,8 @@ bool anyHitTriangles(const vec3 ray_origin, const vec3 ray_dir)
510532 ray_dir,
511533 opaque_triangles[i],
512534 t,
513- bary))
535+ bary) &&
536+ t < max_t)
514537 {
515538 return true;
516539 }
@@ -519,6 +542,11 @@ bool anyHitTriangles(const vec3 ray_origin, const vec3 ray_dir)
519542 return false;
520543}
521544
545+ bool anyHitTriangles(const vec3 ray_origin, const vec3 ray_dir)
546+ {
547+ return anyHitTriangles(ray_origin, ray_dir, 1e20 );
548+ }
549+
522550HitInfo TraceScene(const vec3 ray_origin, const vec3 ray_dir)
523551{
524552 HitInfo info;
@@ -546,6 +574,7 @@ HitInfo TraceScene(const vec3 ray_origin, const vec3 ray_dir)
546574 if (traverseTransmissiveBVH(
547575 ray_origin,
548576 ray_dir,
577+ 1e20 ,
549578 t,
550579 bary,
551580 tri_index) &&
@@ -587,6 +616,7 @@ HitInfo TraceScene(const vec3 ray_origin, const vec3 ray_dir)
587616 if (traverseOpaqueBVH(
588617 ray_origin,
589618 ray_dir,
619+ 1e20 ,
590620 t,
591621 bary,
592622 tri_index) &&
@@ -739,6 +769,7 @@ vec3 ShadeOpaque(
739769 vec3 ray_dir_world,
740770 mat3 model_inv3,
741771 mat3 normal_matrix,
772+ int scene_light_type,
742773 vec3 light_dir_world,
743774 vec3 light_color_world,
744775 mat3 env_rot_inv,
@@ -761,14 +792,43 @@ vec3 ShadeOpaque(
761792 hit_normal = N;
762793 }
763794
764- vec3 dir = length (light_dir_world) > 0.0 ? light_dir_world
765- : vec3 (1.0 , - 1.0 , 1.0 );
766795 vec3 col = length (light_color_world) > 0.0 ? light_color_world
767796 : vec3 (1.0 );
797+ vec3 hit_pos_world = (model * vec4 (hit.pos_model, 1.0 )).xyz;
798+ vec3 L = vec3 (0.0 , 1.0 , 0.0 );
799+ vec3 shadow_dir = vec3 (0.0 , 1.0 , 0.0 );
800+ float shadow_tmax = 1e20 ;
801+ float light_visibility = 1.0 ;
802+
803+ if (scene_light_type == kLightTypePoint)
804+ {
805+ vec3 to_light = light_dir_world - hit_pos_world;
806+ float light_distance = length (to_light);
807+ if (light_distance > 0.001 )
808+ {
809+ L = to_light / light_distance;
810+ shadow_dir = normalize (model_inv3 * L);
811+ shadow_tmax = max (light_distance - 0.02 , 0.0 );
812+ light_visibility = ComputePointLightVisibility(light_distance);
813+ }
814+ }
815+ else
816+ {
817+ vec3 dir = length (light_dir_world) > 0.0 ? light_dir_world
818+ : vec3 (1.0 , - 1.0 , 1.0 );
819+ L = normalize (- dir);
820+ shadow_dir = normalize (model_inv3 * - dir);
821+ }
768822
769- vec3 shadow_dir = normalize (model_inv3 * - dir);
770823 vec3 shadow_origin = hit.pos_model + hit.normal_model * 0.0015 ;
771- bool in_shadow = anyHitTriangles(shadow_origin, shadow_dir);
824+ bool in_shadow = false;
825+ if (light_visibility > 0.0 )
826+ {
827+ in_shadow = scene_light_type == kLightTypePoint
828+ ? (shadow_tmax > 0.001 &&
829+ anyHitTriangles(shadow_origin, shadow_dir, shadow_tmax))
830+ : anyHitTriangles(shadow_origin, shadow_dir);
831+ }
772832 float shadow_factor = in_shadow ? 0.3 : 1.0 ;
773833
774834 vec3 albedo = SampleAlbedo(hit);
@@ -779,7 +839,6 @@ vec3 ShadeOpaque(
779839 vec3 specular_color = SampleSpecularColor(hit);
780840
781841 vec3 V = normalize (- ray_dir_world);
782- vec3 L = normalize (- dir);
783842 vec3 H = normalize (V + L);
784843 vec3 dielectric_f0 = vec3 (0.04 ) * specular_factor * specular_color;
785844 vec3 F0 = mix (dielectric_f0, albedo, metallic);
@@ -830,14 +889,20 @@ vec3 ShadeOpaque(
830889 vec3 Lo = diffuse * col * NdotL * shadow_factor +
831890 specular * col * NdotL * (in_shadow ? 0.0 : 1.0 ) +
832891 env_specular;
833- return ambient + Lo;
892+ vec3 shaded = ambient + Lo;
893+ if (scene_light_type == kLightTypePoint)
894+ {
895+ shaded *= light_visibility;
896+ }
897+ return shaded;
834898}
835899
836900vec3 ShadeGlass(
837901 const HitInfo hit,
838902 vec3 ray_dir_world,
839903 mat3 model_inv3,
840904 mat3 normal_matrix,
905+ int scene_light_type,
841906 vec3 light_dir_world,
842907 vec3 light_color_world,
843908 mat3 env_rot_inv,
@@ -893,6 +958,7 @@ vec3 ShadeGlass(
893958 dir_world,
894959 model_inv3,
895960 normal_matrix,
961+ scene_light_type,
896962 light_dir_world,
897963 light_color_world,
898964 env_rot_inv,
@@ -1007,6 +1073,7 @@ void main()
10071073 ray_dir_world,
10081074 model_inv3,
10091075 normal_matrix,
1076+ light_type,
10101077 light_dir,
10111078 light_color,
10121079 env_rot_inv,
@@ -1020,6 +1087,7 @@ void main()
10201087 ray_dir_world,
10211088 model_inv3,
10221089 normal_matrix,
1090+ light_type,
10231091 light_dir,
10241092 light_color,
10251093 env_rot_inv,
0 commit comments