@@ -379,7 +379,7 @@ export material gltf_material(
379
379
// KHR_materials_ior
380
380
uniform float ior = 1.5
381
381
[[
382
- anno::hard_range (1.00 , 5.0),
382
+ anno::soft_range (1.0 , 5.0),
383
383
anno::in_group("Metallic Roughness"),
384
384
anno::display_name("IOR"),
385
385
anno::description("The index of refraction.")
@@ -474,6 +474,50 @@ export material gltf_material(
474
474
anno::enable_if("clearcoat_factor>0.0")
475
475
]],
476
476
477
+ // KHR_materials_iridescence
478
+ uniform float iridescence_factor = 0.0
479
+ [[
480
+ anno::hard_range(0.0, 1.0),
481
+ anno::in_group("Iridescence"),
482
+ anno::display_name("Iridescence Factor"),
483
+ anno::description("Strength of the iridescence. Multiplied to the 'Iridescence Texture' if available.")
484
+ ]],
485
+ gltf_texture_lookup_value iridescence_texture = gltf_texture_lookup()
486
+ [[
487
+ anno::in_group("Iridescence"),
488
+ anno::display_name("Iridescence Texture"),
489
+ anno::description("Strength of the iridescence. Uses only the red channel, assuming linear space. Influenced by the 'Iridescence Factor'."),
490
+ anno::enable_if("iridescence_factor>0")
491
+ ]],
492
+ uniform float iridescence_ior = 1.3
493
+ [[
494
+ anno::soft_range(1.0, 5.0),
495
+ anno::in_group("Iridescence"),
496
+ anno::display_name("Iridescence IOR"),
497
+ anno::description("The index of refraction of the dielectric thin-film layer.")
498
+ ]],
499
+ uniform float iridescence_thickness_minimum = 100
500
+ [[
501
+ anno::soft_range(0.0, 600.0),
502
+ anno::in_group("Iridescence"),
503
+ anno::display_name("Iridescence Thickness Minimum"),
504
+ anno::description("The minimum thickness of the thin-film layer given in nanometers.")
505
+ ]],
506
+ uniform float iridescence_thickness_maximum = 400
507
+ [[
508
+ anno::soft_range(0.0, 1000.0),
509
+ anno::in_group("Iridescence"),
510
+ anno::display_name("Iridescence Thickness Maximum"),
511
+ anno::description("The maximum thickness of the thin-film layer given in nanometers. Used as thickness if no 'Iridescence Thickness Texture' if available.")
512
+ ]],
513
+ gltf_texture_lookup_value iridescence_thickness_texture = gltf_texture_lookup()
514
+ [[
515
+ anno::in_group("Iridescence"),
516
+ anno::display_name("Iridescence Thickness Texture"),
517
+ anno::description("The thickness texture of the thin-film layer. Uses only the red channel, assuming linear space. Used to blend between 'Iridescence Thickness Minimum' and 'Iridescence Thickness Maximum'."),
518
+ anno::enable_if("iridescence_factor>0")
519
+ ]],
520
+
477
521
// emission
478
522
uniform color emissive_factor = color(0.0)
479
523
[[
@@ -568,7 +612,7 @@ export material gltf_material(
568
612
// ------------------------------------------------------------------------
569
613
float4 base_float4 = gltf_prepare_tex_float4(base_color_texture) * scene::data_lookup_float4("COLOR_0", float4(1.0)); // apply vertex color
570
614
color base_color = base_color_factor * color(base_float4.x, base_float4.y, base_float4.z);
571
- float alpha = base_alpha * base_float4.w;
615
+ float alpha = base_alpha * math::pow( base_float4.w, 1.0/2.2) ;
572
616
573
617
float3 metallic_roughness = gltf_prepare_tex_float3(metallic_roughness_texture);
574
618
float metallic = metallic_factor * metallic_roughness.z;
@@ -600,6 +644,11 @@ export material gltf_material(
600
644
float3 clearcoat_normal = gltf_prepare_normal(clearcoat_normal_texture);
601
645
float grazing_refl_coat = math::max((1.0 - clearcoat_roughness), 0.0);
602
646
647
+ // KHR_materials_iridescence
648
+ // ------------------------------------------------------------------------
649
+ float iridescence_strength = gltf_prepare_tex_float3(iridescence_texture).x * iridescence_factor;
650
+ float iridescence_thickness = math::lerp(iridescence_thickness_minimum, iridescence_thickness_maximum, gltf_prepare_tex_float3(iridescence_thickness_texture).x);
651
+
603
652
// metallic roughness model
604
653
// ------------------------------------------------------------------------
605
654
@@ -630,13 +679,41 @@ export material gltf_material(
630
679
normal: normal
631
680
);
632
681
633
- // the metallic component doesn't have a diffuse component,
682
+ // apply iridescence and make the strength adjustable using a weighted layer
683
+ bsdf dielectric_component_with_thin_film = df::weighted_layer(
684
+ weight: iridescence_strength,
685
+ base: dielectric_component,
686
+ layer: df::thin_film(
687
+ thickness: iridescence_thickness,
688
+ ior: color(iridescence_ior),
689
+ base: dielectric_component
690
+ )
691
+ );
692
+
693
+ // the metallic component doesn't have a diffuse component,
634
694
// its only glossy base_color is applied to tint it
635
695
bsdf metallic_component = df::microfacet_ggx_vcavities_bsdf(
636
- tint: base_color * occlusion,
696
+ tint: base_color * occlusion,
637
697
roughness_u: roughness2);
638
698
639
- // apply sheen to the dielectic component
699
+ // apply iridescence and make the strength adjustable using a weighted layer
700
+ // according to KHR_materials_iridescence spec: using dielectric thin film fresnel for metals, too
701
+ color base_color_sqrt = math::min(math::sqrt(math::saturate(base_color * occlusion)), color(0.99f));
702
+ color dielectric_ior = (color(1.0f) + base_color_sqrt) / (color(1.0f) - base_color_sqrt);
703
+ bsdf metallic_component_with_thin_film = df::weighted_layer(
704
+ weight: iridescence_strength,
705
+ base: metallic_component,
706
+ layer: df::thin_film(
707
+ thickness: iridescence_thickness,
708
+ ior: color(iridescence_ior),
709
+ base: df::fresnel_factor(
710
+ ior: dielectric_ior,
711
+ extinction_coefficient: color(0.0f),
712
+ base: df::microfacet_ggx_vcavities_bsdf(roughness_u: roughness2))
713
+ )
714
+ );
715
+
716
+ // apply sheen to the dielectric component
640
717
// add the sheen_color as weight in an outer layer to be able to blend and disable on default
641
718
// otherwise, sheen would be applied and tinted black
642
719
bsdf dielectric_sheen_component = df::color_weighted_layer(
@@ -645,15 +722,15 @@ export material gltf_material(
645
722
roughness: sheen_roughness * sheen_roughness,
646
723
tint: color(1.0),
647
724
multiscatter_tint: color(1.0),
648
- multiscatter: dielectric_component
725
+ multiscatter: dielectric_component // don't apply thin_film
649
726
),
650
- base: dielectric_component );
727
+ base: dielectric_component_with_thin_film );
651
728
652
729
// final BSDF is a linear blend between dielectric and metallic component
653
730
bsdf dielectric_metal_mix = df::weighted_layer(
654
731
weight: metallic,
655
732
base: dielectric_sheen_component,
656
- layer: metallic_component ,
733
+ layer: metallic_component_with_thin_film ,
657
734
normal: normal);
658
735
659
736
bsdf clearcoated = df::custom_curve_layer(
@@ -806,11 +883,11 @@ export material gltf_material_khr_specular_glossiness(
806
883
// ------------------------------------------------------------------------
807
884
float4 diffuse_float4 = gltf_prepare_tex_float4(diffuse_texture) * scene::data_lookup_float4("COLOR_0", float4(1.0)); // apply vertex color
808
885
color diffuse = diffuse_factor * color(diffuse_float4.x, diffuse_float4.y, diffuse_float4.z);
809
- float alpha = base_alpha * diffuse_float4.w;
886
+ float alpha = base_alpha * math::pow( diffuse_float4.w, 1.0/2.2) ;
810
887
811
888
float4 specular_glossiness = gltf_prepare_tex_float4(specular_glossiness_texture);
812
889
color specular = specular_factor * color(specular_glossiness.x, specular_glossiness.y, specular_glossiness.z);
813
- float glossiness = glossiness_factor * specular_glossiness.w;
890
+ float glossiness = glossiness_factor * math::pow( specular_glossiness.w, 1.0/2.2) ;
814
891
815
892
float3 normal = gltf_prepare_normal(normal_texture);
816
893
float occlusion = gltf_prepare_occlusion(occlusion_texture, occlusion_strength);
0 commit comments