@@ -348,14 +348,13 @@ fn derive_lighting_input(N: vec3<f32>, V: vec3<f32>, L: vec3<f32>) -> DerivedLig
348348 return input ;
349349}
350350
351- // Returns L in the `xyz` components and the modified roughness in the `w` component.
351+ // Returns L in the `xyz` components and the specular intensity in the `w` component.
352352fn compute_specular_layer_values_for_point_light (
353353 input : ptr <function , LightingInput >,
354354 layer : u32 ,
355355 V : vec3 <f32 >,
356356 light_to_frag : vec3 <f32 >,
357357 light_position_radius : f32 ,
358- distance : f32 ,
359358) -> vec4 <f32 > {
360359 // Unpack.
361360 let R = (*input ). layers [layer ]. R ;
@@ -383,24 +382,22 @@ fn compute_specular_layer_values_for_point_light(
383382 let closestPoint = light_to_frag + centerToRay * saturate (
384383 light_position_radius * inverseSqrt (dot (centerToRay , centerToRay )));
385384 let LspecLengthInverse = inverseSqrt (dot (closestPoint , closestPoint ));
386-
387- // a' = saturate( a + sourceRadius / (2 * distance) )
388- // see Karis 2013
389- let a_prime = saturate (a + light_position_radius / (2 .0 * distance ));
385+ let normalizationFactor = a / saturate (a + (light_position_radius * 0 .5 * LspecLengthInverse ));
386+ let intensity = normalizationFactor * normalizationFactor ;
390387
391388 let L : vec3 <f32 > = closestPoint * LspecLengthInverse ; // normalize() equivalent?
392- return vec4 (L , a_prime );
389+ return vec4 (L , intensity );
393390}
394391
395392// Cook-Torrance approximation of the microfacet model integration using Fresnel law F to model f_m
396393// f_r(v,l) = { D(h,α) G(v,l,α) F(v,h,f0) } / { 4 (n⋅v) (n⋅l) }
397394fn specular (
398395 input : ptr <function , LightingInput >,
399396 derived_input : ptr <function , DerivedLightingInput >,
400- roughness : f32 ,
401397 specular_intensity : f32 ,
402398) -> vec3 <f32 > {
403399 // Unpack.
400+ let roughness = (*input ). layers [LAYER_BASE ]. roughness ;
404401 let NdotV = (*input ). layers [LAYER_BASE ]. NdotV ;
405402 let F0 = (*input ). F0_ ;
406403 let NdotL = (*derived_input ). NdotL ;
@@ -428,10 +425,10 @@ fn specular_clearcoat(
428425 input : ptr <function , LightingInput >,
429426 derived_input : ptr <function , DerivedLightingInput >,
430427 clearcoat_strength : f32 ,
431- roughness : f32 ,
432428 specular_intensity : f32 ,
433429) -> vec2 <f32 > {
434430 // Unpack.
431+ let roughness = (*input ). layers [LAYER_CLEARCOAT ]. roughness ;
435432 let NdotH = (*derived_input ). NdotH ;
436433 let LdotH = (*derived_input ). LdotH ;
437434
@@ -452,10 +449,10 @@ fn specular_anisotropy(
452449 input : ptr <function , LightingInput >,
453450 derived_input : ptr <function , DerivedLightingInput >,
454451 L : vec3 <f32 >,
455- roughness : f32 ,
456452 specular_intensity : f32 ,
457453) -> vec3 <f32 > {
458454 // Unpack.
455+ let roughness = (*input ). layers [LAYER_BASE ]. roughness ;
459456 let NdotV = (*input ). layers [LAYER_BASE ]. NdotV ;
460457 let V = (*input ). V ;
461458 let F0 = (*input ). F0_ ;
@@ -623,31 +620,25 @@ fn point_light(
623620 let light_to_frag = (*light ). position_radius . xyz - P ;
624621 let L = normalize (light_to_frag );
625622 let distance_square = dot (light_to_frag , light_to_frag );
626- let distance = sqrt (distance_square );
627623 let rangeAttenuation = getDistanceAttenuation (distance_square , (*light ). color_inverse_square_range . w );
628624
629625 // Base layer
630626
631- let a = (*input ). layers [LAYER_BASE ]. roughness ;
632- let specular_L_a_prime = compute_specular_layer_values_for_point_light (
627+ let specular_L_intensity = compute_specular_layer_values_for_point_light (
633628 input ,
634629 LAYER_BASE ,
635630 V ,
636631 light_to_frag ,
637632 (*light ). position_radius . w ,
638- distance ,
639633 );
640- let L_spec = specular_L_a_prime . xyz ;
641- let a_prime = specular_L_a_prime . w ;
642- var specular_derived_input = derive_lighting_input (N , V , L_spec );
634+ var specular_derived_input = derive_lighting_input (N , V , specular_L_intensity . xyz );
643635
644- let normalizationFactor = a / a_prime ;
645- let specular_intensity = normalizationFactor * normalizationFactor ;
636+ let specular_intensity = specular_L_intensity . w ;
646637
647638#ifdef STANDARD_MATERIAL_ANISOTROPY
648- let specular_light = specular_anisotropy (input , & specular_derived_input , L , a_prime , specular_intensity );
639+ let specular_light = specular_anisotropy (input , & specular_derived_input , L , specular_intensity );
649640#else // STANDARD_MATERIAL_ANISOTROPY
650- let specular_light = specular (input , & specular_derived_input , a_prime , specular_intensity );
641+ let specular_light = specular (input , & specular_derived_input , specular_intensity );
651642#endif // STANDARD_MATERIAL_ANISOTROPY
652643
653644 // Clearcoat
@@ -656,32 +647,26 @@ fn point_light(
656647 // Unpack.
657648 let clearcoat_N = (*input ). layers [LAYER_CLEARCOAT ]. N ;
658649 let clearcoat_strength = (*input ). clearcoat_strength ;
659- let clearcoat_a = (*input ). layers [LAYER_CLEARCOAT ]. roughness ;
660650
661651 // Perform specular input calculations again for the clearcoat layer. We
662652 // can't reuse the above because the clearcoat normal might be different
663653 // from the main layer normal.
664- let clearcoat_specular_L_a_prime = compute_specular_layer_values_for_point_light (
654+ let clearcoat_specular_L_intensity = compute_specular_layer_values_for_point_light (
665655 input ,
666656 LAYER_CLEARCOAT ,
667657 V ,
668658 light_to_frag ,
669659 (*light ). position_radius . w ,
670- distance ,
671660 );
672- let L_clearcoat_spec = clearcoat_specular_L_a_prime . xyz ;
673- let clearcoat_a_prime = clearcoat_specular_L_a_prime . w ;
674661 var clearcoat_specular_derived_input =
675- derive_lighting_input (clearcoat_N , V , L_clearcoat_spec );
662+ derive_lighting_input (clearcoat_N , V , clearcoat_specular_L_intensity . xyz );
676663
677664 // Calculate the specular light.
678- let clearcoat_normalizationFactor = clearcoat_a / clearcoat_a_prime ;
679- let clearcoat_specular_intensity = clearcoat_normalizationFactor * clearcoat_normalizationFactor ;
665+ let clearcoat_specular_intensity = clearcoat_specular_L_intensity . w ;
680666 let Fc_Frc = specular_clearcoat (
681667 input ,
682668 & clearcoat_specular_derived_input ,
683669 clearcoat_strength ,
684- clearcoat_a_prime ,
685670 clearcoat_specular_intensity
686671 );
687672 let inv_Fc = 1 .0 - Fc_Frc . r ; // Inverse Fresnel term.
@@ -709,14 +694,14 @@ fn point_light(
709694
710695 // NOTE: (*light).color.rgb is premultiplied with (*light).intensity / 4 π (which would be the luminous intensity) on the CPU
711696
712- var color_times_NdotL : vec3 <f32 >;
697+ var color : vec3 <f32 >;
713698#ifdef STANDARD_MATERIAL_CLEARCOAT
714699 // Account for the Fresnel term from the clearcoat darkening the main layer.
715700 //
716701 // <https://google.github.io/filament/Filament.html#materialsystem/clearcoatmodel/integrationinthesurfaceresponse>
717- color_times_NdotL = (diffuse * derived_input . NdotL + specular_light * specular_derived_input . NdotL * inv_Fc ) * inv_Fc + Frc * clearcoat_specular_derived_input . NdotL ;
702+ color = (diffuse + specular_light * inv_Fc ) * inv_Fc + Frc ;
718703#else // STANDARD_MATERIAL_CLEARCOAT
719- color_times_NdotL = diffuse * derived_input . NdotL + specular_light * specular_derived_input . NdotL ;
704+ color = diffuse + specular_light ;
720705#endif // STANDARD_MATERIAL_CLEARCOAT
721706
722707 var texture_sample = 1f ;
@@ -737,8 +722,8 @@ fn point_light(
737722 }
738723#endif
739724
740- return color_times_NdotL * (*light ). color_inverse_square_range . rgb *
741- rangeAttenuation * texture_sample ;
725+ return color * (*light ). color_inverse_square_range . rgb *
726+ ( rangeAttenuation * derived_input . NdotL ) * texture_sample ;
742727}
743728
744729fn spot_light (
@@ -812,23 +797,22 @@ fn directional_light(
812797 }
813798
814799#ifdef STANDARD_MATERIAL_ANISOTROPY
815- let specular_light = specular_anisotropy (input , & derived_input , L , roughness , 1 .0 );
800+ let specular_light = specular_anisotropy (input , & derived_input , L , 1 .0 );
816801#else // STANDARD_MATERIAL_ANISOTROPY
817- let specular_light = specular (input , & derived_input , roughness , 1 .0 );
802+ let specular_light = specular (input , & derived_input , 1 .0 );
818803#endif // STANDARD_MATERIAL_ANISOTROPY
819804
820805#ifdef STANDARD_MATERIAL_CLEARCOAT
821806 let clearcoat_N = (*input ). layers [LAYER_CLEARCOAT ]. N ;
822807 let clearcoat_strength = (*input ). clearcoat_strength ;
823- let clearcoat_roughness = (*input ). layers [LAYER_CLEARCOAT ]. roughness ;
824808
825809 // Perform specular input calculations again for the clearcoat layer. We
826810 // can't reuse the above because the clearcoat normal might be different
827811 // from the main layer normal.
828812 var derived_clearcoat_input = derive_lighting_input (clearcoat_N , V , L );
829813
830814 let Fc_Frc =
831- specular_clearcoat (input , & derived_clearcoat_input , clearcoat_strength , clearcoat_roughness , 1 .0 );
815+ specular_clearcoat (input , & derived_clearcoat_input , clearcoat_strength , 1 .0 );
832816 let inv_Fc = 1 .0 - Fc_Frc . r ;
833817 let Frc = Fc_Frc . g ;
834818#endif // STANDARD_MATERIAL_CLEARCOAT
0 commit comments