@@ -669,14 +669,39 @@ export material mx_displacement_vector3(
669669);
670670
671671
672+ // helper function to mix two scattering volumes:
673+ // - combined scattering coefficient is just the sum of the two
674+ // - VDF mixer weight is the relative probability of encountering the corresponding
675+ // particle type
676+ // NOTE: mixer weight should be a color, but due to a bug in current MDL compilers
677+ // the color mixers don't accept non-uniform weights yet
678+ struct volume_mix_return {
679+ color scattering_coefficient;
680+ float mix_weight1; // mix_weight2 = 1.0 - mix_weight1, can use any mixer
681+ };
682+ volume_mix_return volume_mix(
683+ color scattering_coefficient1,
684+ float weight1,
685+ color scattering_coefficient2,
686+ float weight2)
687+ {
688+ color s1 = weight1 * scattering_coefficient1;
689+ color s = s1 + weight2 * scattering_coefficient2;
690+ return volume_mix_return(scattering_coefficient: s, mix_weight1: math::average(s1 / s));
691+ }
692+
672693export material mx_mix_bsdf(
673694 material mxp_fg = material() [[ anno::usage( "materialx:bsdf") ]],
674695 material mxp_bg = material() [[ anno::usage( "materialx:bsdf") ]],
675696 float mxp_mix = 0.0
676697) [[
677698 anno::usage( "materialx:bsdf")
678699]]
679- = material(
700+ = let {
701+ volume_mix_return v = volume_mix(
702+ mxp_fg.volume.scattering_coefficient, mxp_mix,
703+ mxp_bg.volume.scattering_coefficient, (1.0f - mxp_mix));
704+ } in material(
680705 surface: material_surface(
681706 scattering: df::weighted_layer(
682707 weight: mxp_mix,
@@ -687,15 +712,14 @@ export material mx_mix_bsdf(
687712 // we need to carry volume properties along for SSS
688713 ior: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here
689714 volume: material_volume(
690- scattering: df::clamped_mix (
715+ scattering: df::unbounded_mix (
691716 df::vdf_component[](
692- df::vdf_component( mxp_mix , mxp_fg.volume.scattering),
693- df::vdf_component( 1.0 - mxp_mix , mxp_bg.volume.scattering))
717+ df::vdf_component(v.mix_weight1 , mxp_fg.volume.scattering),
718+ df::vdf_component(1.0 - v.mix_weight1 , mxp_bg.volume.scattering))
694719 ),
695720 absorption_coefficient: mxp_mix * mxp_fg.volume.absorption_coefficient +
696721 (1.0 - mxp_mix) * mxp_bg.volume.absorption_coefficient,
697- scattering_coefficient: mxp_mix * mxp_fg.volume.scattering_coefficient +
698- (1.0 - mxp_mix) * mxp_bg.volume.scattering_coefficient
722+ scattering_coefficient: v.scattering_coefficient
699723 )
700724);
701725
@@ -709,7 +733,7 @@ export material mx_mix_edf(
709733= material(
710734 surface: material_surface(
711735 emission: material_emission(
712- emission: df::clamped_mix(
736+ emission: df::unbounded_mix( // unbounded_mix is cheaper
713737 df::edf_component[](
714738 df::edf_component( mxp_mix, mxp_fg.surface.emission.emission),
715739 df::edf_component( 1.0 - mxp_mix, mxp_bg.surface.emission.emission))
@@ -727,18 +751,21 @@ export material mx_mix_vdf(
727751) [[
728752 anno::usage( "materialx:vdf")
729753]]
730- = material(
754+ = let {
755+ volume_mix_return v = volume_mix(
756+ mxp_fg.volume.scattering_coefficient, mxp_mix,
757+ mxp_bg.volume.scattering_coefficient, (1.0f - mxp_mix));
758+ } in material(
731759 ior: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here
732760 volume: material_volume(
733- scattering: df::clamped_mix (
761+ scattering: df::unbounded_mix (
734762 df::vdf_component[](
735- df::vdf_component( mxp_mix , mxp_fg.volume.scattering),
736- df::vdf_component( 1.0 - mxp_mix , mxp_bg.volume.scattering))
763+ df::vdf_component( v.mix_weight1 , mxp_fg.volume.scattering),
764+ df::vdf_component( 1.0 - v.mix_weight1 , mxp_bg.volume.scattering))
737765 ),
738766 absorption_coefficient: mxp_mix * mxp_fg.volume.absorption_coefficient +
739767 (1.0 - mxp_mix) * mxp_bg.volume.absorption_coefficient,
740- scattering_coefficient: mxp_mix * mxp_fg.volume.scattering_coefficient +
741- (1.0 - mxp_mix) * mxp_bg.volume.scattering_coefficient
768+ scattering_coefficient: v.scattering_coefficient
742769 )
743770);
744771
@@ -751,7 +778,11 @@ export material mx_add_bsdf(
751778) [[
752779 anno::usage( "materialx:bsdf")
753780]]
754- = material(
781+ = let {
782+ volume_mix_return v = volume_mix(
783+ mxp_in1.volume.scattering_coefficient, 1.0f,
784+ mxp_in2.volume.scattering_coefficient, 1.0f);
785+ } in material(
755786 surface: material_surface(
756787 scattering: df::unbounded_mix(
757788 df::bsdf_component[](
@@ -764,13 +795,12 @@ export material mx_add_bsdf(
764795 volume: material_volume(
765796 scattering: df::unbounded_mix(
766797 df::vdf_component[](
767- df::vdf_component( 1.0 , mxp_in1.volume.scattering),
768- df::vdf_component( 1.0, mxp_in2.volume.scattering))
798+ df::vdf_component( v.mix_weight1 , mxp_in1.volume.scattering),
799+ df::vdf_component( 1.0 - v.mix_weight1 , mxp_in2.volume.scattering))
769800 ),
770801 absorption_coefficient: mxp_in1.volume.absorption_coefficient +
771802 mxp_in2.volume.absorption_coefficient,
772- scattering_coefficient: mxp_in1.volume.scattering_coefficient +
773- mxp_in2.volume.scattering_coefficient
803+ scattering_coefficient: v.scattering_coefficient
774804 )
775805);
776806
@@ -806,19 +836,22 @@ export material mx_add_vdf(
806836) [[
807837 anno::usage( "materialx:vdf")
808838]]
809- = material(
839+ = let {
840+ volume_mix_return v = volume_mix(
841+ mxp_in1.volume.scattering_coefficient, 1.0f,
842+ mxp_in2.volume.scattering_coefficient, 1.0f);
843+ } in material(
810844 // assuming mixing the IOR is the best we can do here
811845 ior: 0.5 * mxp_in1.ior + 0.5 * mxp_in2.ior,
812846 volume: material_volume(
813847 scattering: df::unbounded_mix(
814848 df::vdf_component[](
815- df::vdf_component( 1.0 , mxp_in1.volume.scattering),
816- df::vdf_component( 1.0, mxp_in2.volume.scattering))
849+ df::vdf_component( v.mix_weight1 , mxp_in1.volume.scattering),
850+ df::vdf_component( 1.0 - v.mix_weight1 , mxp_in2.volume.scattering))
817851 ),
818852 absorption_coefficient: mxp_in1.volume.absorption_coefficient +
819853 mxp_in2.volume.absorption_coefficient,
820- scattering_coefficient: mxp_in1.volume.scattering_coefficient +
821- mxp_in2.volume.scattering_coefficient
854+ scattering_coefficient: v.scattering_coefficient
822855 )
823856);
824857
0 commit comments