diff --git a/examples_tests b/examples_tests index 7f581463bf..99206836d6 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 7f581463bfaf2d4cb67919b9cd5eae3475de5f83 +Subproject commit 99206836d6afd6fe55735b88f4a576a0b52e10a2 diff --git a/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl b/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl index 8284f46e6e..7fde50ab95 100644 --- a/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl @@ -10,6 +10,7 @@ #include "nbl/builtin/hlsl/numbers.hlsl" #include "nbl/builtin/hlsl/complex.hlsl" #include "nbl/builtin/hlsl/tgmath.hlsl" +#include "nbl/builtin/hlsl/colorspace.hlsl" #include "nbl/builtin/hlsl/vector_utils/vector_traits.hlsl" namespace nbl @@ -366,22 +367,43 @@ struct Conductor return retval; } + // TODO: will probably merge with __call at some point + static void __polarized(const T orientedEta, const T orientedEtak, const T cosTheta, NBL_REF_ARG(T) Rp, NBL_REF_ARG(T) Rs) + { + T cosTheta_2 = cosTheta * cosTheta; + T sinTheta2 = hlsl::promote(1.0) - cosTheta_2; + const T eta = orientedEta; + const T eta2 = eta*eta; + const T etak = orientedEtak; + const T etak2 = etak*etak; + + const T etaLen2 = eta2 + etak2; + assert(hlsl::all(etaLen2 > hlsl::promote(hlsl::exp2(-numeric_limits::digits)))); + T t1 = etaLen2 * cosTheta_2; + const T etaCosTwice = eta * cosTheta * scalar_type(2.0); + + const T rs_common = etaLen2 + cosTheta_2; + Rs = (rs_common - etaCosTwice) / (rs_common + etaCosTwice); + const T rp_common = t1 + hlsl::promote(1.0); + Rp = (rp_common - etaCosTwice) / (rp_common + etaCosTwice); + } + T operator()() { - const scalar_type cosTheta2 = clampedCosTheta * clampedCosTheta; - //const float sinTheta2 = 1.0 - cosTheta2; + const scalar_type cosTheta_2 = clampedCosTheta * clampedCosTheta; + //const float sinTheta2 = 1.0 - cosTheta_2; const T etaLen2 = eta * eta + etak2; assert(hlsl::all(etaLen2 > hlsl::promote(hlsl::exp2(-numeric_limits::digits)))); - const T etaCosTwice = eta * clampedCosTheta * 2.0f; + const T etaCosTwice = eta * clampedCosTheta * hlsl::promote(2.0); - const T rs_common = etaLen2 + (T)(cosTheta2); + const T rs_common = etaLen2 + hlsl::promote(cosTheta_2); const T rs2 = (rs_common - etaCosTwice) / (rs_common + etaCosTwice); - const T rp_common = etaLen2 * cosTheta2 + (T)(1.0); + const T rp_common = etaLen2 * cosTheta_2 + hlsl::promote(1.0); const T rp2 = (rp_common - etaCosTwice) / (rp_common + etaCosTwice); - return (rs2 + rp2) * 0.5f; + return (rs2 + rp2) * hlsl::promote(0.5); } T eta; @@ -405,18 +427,35 @@ struct Dielectric return retval; } - static T __call(NBL_CONST_REF_ARG(T) orientedEta2, scalar_type absCosTheta) + // TODO: will probably merge with __call at some point + static void __polarized(const T orientedEta, const T cosTheta, NBL_REF_ARG(T) Rp, NBL_REF_ARG(T) Rs) { - const scalar_type sinTheta2 = 1.0 - absCosTheta * absCosTheta; + T sinTheta2 = hlsl::promote(1.0) - cosTheta * cosTheta; + const T eta = orientedEta; + const T eta2 = eta * eta; + + T t0 = hlsl::sqrt(eta2 - sinTheta2); + T t2 = eta2 * cosTheta; + + T rp = (t0 - t2) / (t0 + t2); + Rp = rp * rp; + T rs = (cosTheta - t0) / (cosTheta + t0); + Rs = rs * rs; + } + + static T __call(const T orientedEta2, scalar_type absCosTheta) + { + const scalar_type sinTheta2 = scalar_type(1.0) - absCosTheta * absCosTheta; // the max() clamping can handle TIR when orientedEta2<1.0 const T t0 = hlsl::sqrt(hlsl::max(orientedEta2 - sinTheta2, hlsl::promote(0.0))); const T rs = (hlsl::promote(absCosTheta) - t0) / (hlsl::promote(absCosTheta) + t0); + // one additional orientedEta multiplied to remove the 1/orientedEta and make it the same as t0 for rs const T t2 = orientedEta2 * absCosTheta; const T rp = (t0 - t2) / (t0 + t2); - return (rs * rs + rp * rp) * 0.5f; + return (rs * rs + rp * rp) * scalar_type(0.5); } T operator()() @@ -451,6 +490,140 @@ struct DielectricFrontFaceOnly scalar_type absCosTheta; }; +// adapted from https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html +template) +struct Iridescent +{ + using scalar_type = typename vector_traits::scalar_type; + using monochrome_type = vector; + using vector_type = T; // assert dim==3? + + // returns reflectance R = (rp, rs), phi is the phase shift for each plane of polarization (p,s) + static void phase_shift(const vector_type orientedEta, const vector_type orientedEtak, const vector_type cosTheta, NBL_REF_ARG(vector_type) phiS, NBL_REF_ARG(vector_type) phiP) + { + vector_type cosTheta_2 = cosTheta * cosTheta; + vector_type sinTheta2 = hlsl::promote(1.0) - cosTheta_2; + const vector_type eta2 = orientedEta*orientedEta; + const vector_type etak2 = orientedEtak*orientedEtak; + + vector_type z = eta2 - etak2 - sinTheta2; + vector_type w = hlsl::sqrt(z * z + scalar_type(4.0) * eta2 * eta2 * etak2); + vector_type a2 = (z + w) * hlsl::promote(0.5); + vector_type b2 = (w - z) * hlsl::promote(0.5); + vector_type b = hlsl::sqrt(b2); + + const vector_type t0 = eta2 + etak2; + const vector_type t1 = t0 * cosTheta_2; + + phiS = hlsl::atan2(hlsl::promote(2.0) * b * cosTheta, a2 + b2 - cosTheta_2); + phiP = hlsl::atan2(hlsl::promote(2.0) * eta2 * cosTheta * (hlsl::promote(2.0) * orientedEtak * hlsl::sqrt(a2) - etak2 * b), t1 - a2 + b2); + } + + // Evaluation XYZ sensitivity curves in Fourier space + static vector_type evalSensitivity(vector_type opd, vector_type shift) + { + // Use Gaussian fits, given by 3 parameters: val, pos and var + vector_type phase = scalar_type(2.0) * numbers::pi * opd * scalar_type(1.0e-9); + vector_type phase2 = phase * phase; + vector_type val = vector_type(5.4856e-13, 4.4201e-13, 5.2481e-13); + vector_type pos = vector_type(1.6810e+06, 1.7953e+06, 2.2084e+06); + vector_type var = vector_type(4.3278e+09, 9.3046e+09, 6.6121e+09); + vector_type xyz = val * hlsl::sqrt(scalar_type(2.0) * numbers::pi * var) * hlsl::cos(pos * phase + shift) * hlsl::exp(-var * phase2); + xyz.x = xyz.x + scalar_type(9.7470e-14) * hlsl::sqrt(scalar_type(2.0) * numbers::pi * scalar_type(4.5282e+09)) * hlsl::cos(scalar_type(2.2399e+06) * phase[0] + shift[0]) * hlsl::exp(scalar_type(-4.5282e+09) * phase2[0]); + return xyz / scalar_type(1.0685e-7); + } + + T operator()() + { + const vector_type wavelengths = vector_type(colorspace::scRGB::wavelength_R, colorspace::scRGB::wavelength_G, colorspace::scRGB::wavelength_B); + + vector_type eta12 = ior2/ior1; + vector_type eta23 = ior3/ior2; + vector_type etak23 = iork3/ior2; + scalar_type cosTheta_1 = absCosTheta; + vector_type cosTheta_2; + + vector_type R12p, R23p, R12s, R23s; + const vector_type scale = ior1/ior2; + const vector_type cosTheta2_2 = hlsl::promote(1.0) - hlsl::promote(1-cosTheta_1*cosTheta_1) * scale * scale; + + cosTheta_2 = hlsl::sqrt(cosTheta2_2); + Dielectric::__polarized(eta12, hlsl::promote(cosTheta_1), R12p, R12s); + + // Reflected part by the base + // if kappa==0, base material is dielectric + if (hlsl::all::Dimension> >(iork3 < hlsl::promote(hlsl::numeric_limits::min))) + Dielectric::__polarized(eta23, cosTheta_2, R23p, R23s); + else + Conductor::__polarized(eta23, etak23, cosTheta_2, R23p, R23s); + + // Check for total internal reflection + R12s = hlsl::mix(R12s, hlsl::promote(1.0), cosTheta2_2 <= hlsl::promote(0.0)); + R12p = hlsl::mix(R12p, hlsl::promote(1.0), cosTheta2_2 <= hlsl::promote(0.0)); + + // Compute the transmission coefficients + vector_type T121p = hlsl::promote(1.0) - R12p; + vector_type T121s = hlsl::promote(1.0) - R12s; + + // Optical Path Difference + const vector_type D = hlsl::promote(2.0 * Dinc) * ior2 * cosTheta_2; + const vector_type Dphi = hlsl::promote(2.0 * numbers::pi) * D / wavelengths; + + vector_type phi21p, phi21s, phi23p, phi23s, r123s, r123p, Rs; + vector_type I = hlsl::promote(0.0); + + // Evaluate the phase shift + phase_shift(eta12, hlsl::promote(0.0), hlsl::promote(cosTheta_1), phi21p, phi21s); + phase_shift(eta23, etak23, cosTheta_2, phi23p, phi23s); + phi21p = hlsl::promote(numbers::pi) - phi21p; + phi21s = hlsl::promote(numbers::pi) - phi21s; + + r123p = hlsl::sqrt(R12p*R23p); + r123s = hlsl::sqrt(R12s*R23s); + + vector_type C0, Cm, Sm; + const vector_type S0 = hlsl::promote(1.0); + + // Iridescence term using spectral antialiasing + // Reflectance term for m=0 (DC term amplitude) + Rs = (T121p*T121p*R23p) / (hlsl::promote(1.0) - R12p*R23p); + C0 = R12p + Rs; + I += C0 * S0; + + // Reflectance term for m>0 (pairs of diracs) + Cm = Rs - T121p; + NBL_UNROLL for (int m=1; m<=2; ++m) + { + Cm *= r123p; + Sm = hlsl::promote(2.0) * evalSensitivity(hlsl::promote(m)*D, hlsl::promote(m)*(phi23p+phi21p)); + I += Cm*Sm; + } + + // Reflectance term for m=0 (DC term amplitude) + Rs = (T121s*T121s*R23s) / (hlsl::promote(1.0) - R12s*R23s); + C0 = R12s + Rs; + I += C0 * S0; + + // Reflectance term for m>0 (pairs of diracs) + Cm = Rs - T121s; + NBL_UNROLL for (int m=1; m<=2; ++m) + { + Cm *= r123s; + Sm = hlsl::promote(2.0) * evalSensitivity(hlsl::promote(m)*D, hlsl::promote(m) *(phi23s+phi21s)); + I += Cm*Sm; + } + + return hlsl::max(colorspace::scRGB::FromXYZ(I), hlsl::promote(0.0)) * hlsl::promote(0.5); + } + + scalar_type absCosTheta;// LdotH + scalar_type Dinc; // thickness of thin film in nanometers, rec. 100-25000nm + vector_type ior1; // usually air (1.0) + vector_type ior2; // thin-film index + vector_type ior3; // complex conductor index, k==0 makes dielectric + vector_type iork3; +}; + // gets the sum of all R, T R T, T R^3 T, T R^5 T, ... paths template || concepts::FloatingPointLikeVectorial) diff --git a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl index ed049d3d1a..774f011021 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl @@ -8,6 +8,7 @@ #include "nbl/builtin/hlsl/bxdf/reflection/oren_nayar.hlsl" #include "nbl/builtin/hlsl/bxdf/reflection/beckmann.hlsl" #include "nbl/builtin/hlsl/bxdf/reflection/ggx.hlsl" +#include "nbl/builtin/hlsl/bxdf/reflection/iridescent.hlsl" namespace nbl { diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/iridescent.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/iridescent.hlsl new file mode 100644 index 0000000000..c8f0631a03 --- /dev/null +++ b/include/nbl/builtin/hlsl/bxdf/reflection/iridescent.hlsl @@ -0,0 +1,211 @@ +// Copyright (C) 2018-2025 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h +#ifndef _NBL_BUILTIN_HLSL_BXDF_REFLECTION_IRIDESCENT_INCLUDED_ +#define _NBL_BUILTIN_HLSL_BXDF_REFLECTION_IRIDESCENT_INCLUDED_ + +#include "nbl/builtin/hlsl/bxdf/reflection/ggx.hlsl" + +namespace nbl +{ +namespace hlsl +{ +namespace bxdf +{ +namespace reflection +{ + +template) +struct SIridescent +{ + using this_t = SIridescent; + NBL_BXDF_CONFIG_ALIAS(scalar_type, Config); + NBL_BXDF_CONFIG_ALIAS(vector2_type, Config); + NBL_BXDF_CONFIG_ALIAS(vector3_type, Config); + NBL_BXDF_CONFIG_ALIAS(ray_dir_info_type, Config); + + NBL_BXDF_CONFIG_ALIAS(isotropic_interaction_type, Config); + NBL_BXDF_CONFIG_ALIAS(anisotropic_interaction_type, Config); + NBL_BXDF_CONFIG_ALIAS(sample_type, Config); + NBL_BXDF_CONFIG_ALIAS(spectral_type, Config); + NBL_BXDF_CONFIG_ALIAS(quotient_pdf_type, Config); + NBL_BXDF_CONFIG_ALIAS(isocache_type, Config); + NBL_BXDF_CONFIG_ALIAS(anisocache_type, Config); + + using ndf_type = ndf::GGX; + using fresnel_type = fresnel::Iridescent; + using measure_transform_type = ndf::SDualMeasureQuant; + + NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; + + struct SCreationParams + { + scalar_type A; + scalar_type thickness; // thin-film thickness in nm + spectral_type ior0; + spectral_type ior1; + spectral_type ior2; + spectral_type iork2; + }; + using creation_type = SCreationParams; + + struct SIridQuery + { + using scalar_type = scalar_type; + + scalar_type getDevshV() NBL_CONST_MEMBER_FUNC { return devsh_v; } + scalar_type getDevshL() NBL_CONST_MEMBER_FUNC { return devsh_l; } + + scalar_type devsh_v; + scalar_type devsh_l; + }; + using query_type = SIridQuery; + + static this_t create(scalar_type A, scalar_type thickness, NBL_CONST_REF_ARG(spectral_type) ior0, NBL_CONST_REF_ARG(spectral_type) ior1, NBL_CONST_REF_ARG(spectral_type) ior2, NBL_CONST_REF_ARG(spectral_type) iork2) + { + this_t retval; + retval.__base.ndf.A = vector2_type(A, A); + retval.__base.ndf.a2 = A*A; + retval.__base.ndf.one_minus_a2 = scalar_type(1.0) - A*A; + retval.__base.fresnel.Dinc = thickness; + retval.__base.fresnel.ior1 = ior0; + retval.__base.fresnel.ior2 = ior1; + retval.__base.fresnel.ior3 = ior2; + retval.__base.fresnel.iork3 = iork2; + return retval; + } + static this_t create(NBL_CONST_REF_ARG(creation_type) params) + { + return create(params.A, params.thickness, params.ior0, params.ior1, params.ior2, params.iork2); + } + + query_type createQuery(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + { + query_type query; + ndf_type ggx_ndf = __base.getNDF(); + query.devsh_v = ggx_ndf.devsh_part(interaction.getNdotV2()); + query.devsh_l = ggx_ndf.devsh_part(_sample.getNdotL2()); + return query; + } + + spectral_type eval(NBL_CONST_REF_ARG(query_type) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) cache) + { + if (_sample.getNdotL() > numeric_limits::min && interaction.getNdotV() > numeric_limits::min) + { + struct SGGXG2XQuery + { + using scalar_type = scalar_type; + + scalar_type getDevshV() NBL_CONST_MEMBER_FUNC { return devsh_v; } + scalar_type getDevshL() NBL_CONST_MEMBER_FUNC { return devsh_l; } + BxDFClampMode getClampMode() NBL_CONST_MEMBER_FUNC { return _clamp; } + + scalar_type devsh_v; + scalar_type devsh_l; + BxDFClampMode _clamp; + }; + + SGGXG2XQuery g2_query; + g2_query.devsh_v = query.getDevshV(); + g2_query.devsh_l = query.getDevshL(); + g2_query._clamp = _clamp; + + measure_transform_type dualMeasure = __base.template __DG(g2_query, _sample, interaction, cache); + dualMeasure.maxNdotL = _sample.getNdotL(_clamp); + scalar_type DG = dualMeasure.getProjectedLightMeasure(); + fresnel_type f = __base.getFresnel(); + f.absCosTheta = cache.getLdotH(); + return f() * DG; + } + else + return hlsl::promote(0.0); + } + + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u, NBL_REF_ARG(isocache_type) cache) + { + SGGXAnisotropic ggx_aniso = SGGXAnisotropic::create(__base.ndf.A.x, __base.ndf.A.y, __base.fresnel.ior3/__base.fresnel.ior2, __base.fresnel.iork3/__base.fresnel.ior2); + anisocache_type anisocache; + sample_type s = ggx_aniso.generate(anisotropic_interaction_type::create(interaction), u, anisocache); + cache = anisocache.iso_cache; + return s; + } + + scalar_type pdf(NBL_CONST_REF_ARG(query_type) query, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) cache) + { + struct SGGXDG1Query + { + using scalar_type = scalar_type; + + scalar_type getNdf() NBL_CONST_MEMBER_FUNC { return ndf; } + scalar_type getG1over2NdotV() NBL_CONST_MEMBER_FUNC { return G1_over_2NdotV; } + + scalar_type ndf; + scalar_type G1_over_2NdotV; + }; + + SGGXDG1Query dg1_query; + ndf_type ggx_ndf = __base.getNDF(); + dg1_query.ndf = __base.__D(cache); + + const scalar_type devsh_v = query.getDevshV(); + dg1_query.G1_over_2NdotV = ggx_ndf.G1_wo_numerator_devsh_part(interaction.getNdotV(_clamp), devsh_v); + + measure_transform_type dualMeasure = __base.template __DG1(dg1_query); + return dualMeasure.getMicrofacetMeasure(); + } + + quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(query_type) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) cache) + { + scalar_type _pdf = pdf(query, interaction, cache); + + spectral_type quo = hlsl::promote(0.0); + if (_sample.getNdotL() > numeric_limits::min && interaction.getNdotV() > numeric_limits::min) + { + struct SGGXG2XQuery + { + using scalar_type = scalar_type; + + scalar_type getDevshV() NBL_CONST_MEMBER_FUNC { return devsh_v; } + scalar_type getDevshL() NBL_CONST_MEMBER_FUNC { return devsh_l; } + BxDFClampMode getClampMode() NBL_CONST_MEMBER_FUNC { return _clamp; } + + scalar_type devsh_v; + scalar_type devsh_l; + BxDFClampMode _clamp; + }; + + ndf_type ggx_ndf = __base.getNDF(); + + SGGXG2XQuery g2_query; + g2_query.devsh_v = query.getDevshV(); + g2_query.devsh_l = query.getDevshL(); + g2_query._clamp = _clamp; + const scalar_type G2_over_G1 = ggx_ndf.template G2_over_G1(g2_query, _sample, interaction, cache); + + fresnel_type f = __base.getFresnel(); + f.absCosTheta = cache.getLdotH(); + const spectral_type reflectance = f(); + quo = reflectance * G2_over_G1; + } + + return quotient_pdf_type::create(quo, _pdf); + } + + SCookTorrance __base; +}; + +} + +template +struct traits > +{ + NBL_CONSTEXPR_STATIC_INLINE BxDFType type = BT_BRDF; + NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = true; + NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; +}; + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl index 81f531e1a6..8fe66cefa1 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl @@ -8,6 +8,7 @@ #include "nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl" #include "nbl/builtin/hlsl/bxdf/transmission/beckmann.hlsl" #include "nbl/builtin/hlsl/bxdf/transmission/ggx.hlsl" +#include "nbl/builtin/hlsl/bxdf/transmission/iridescent.hlsl" namespace nbl { diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/iridescent.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/iridescent.hlsl new file mode 100644 index 0000000000..aa2fde373e --- /dev/null +++ b/include/nbl/builtin/hlsl/bxdf/transmission/iridescent.hlsl @@ -0,0 +1,212 @@ +// Copyright (C) 2018-2025 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h +#ifndef _NBL_BUILTIN_HLSL_BXDF_TRANSMISSION_IRIDESCENT_INCLUDED_ +#define _NBL_BUILTIN_HLSL_BXDF_TRANSMISSION_IRIDESCENT_INCLUDED_ + +#include "nbl/builtin/hlsl/bxdf/transmission/ggx.hlsl" + +namespace nbl +{ +namespace hlsl +{ +namespace bxdf +{ +namespace transmission +{ + +template) +struct SIridescent +{ + using this_t = SIridescent; + NBL_BXDF_CONFIG_ALIAS(scalar_type, Config); + NBL_BXDF_CONFIG_ALIAS(vector2_type, Config); + NBL_BXDF_CONFIG_ALIAS(vector3_type, Config); + NBL_BXDF_CONFIG_ALIAS(matrix3x3_type, Config); + NBL_BXDF_CONFIG_ALIAS(monochrome_type, Config); + NBL_BXDF_CONFIG_ALIAS(ray_dir_info_type, Config); + + NBL_BXDF_CONFIG_ALIAS(isotropic_interaction_type, Config); + NBL_BXDF_CONFIG_ALIAS(anisotropic_interaction_type, Config); + NBL_BXDF_CONFIG_ALIAS(sample_type, Config); + NBL_BXDF_CONFIG_ALIAS(spectral_type, Config); + NBL_BXDF_CONFIG_ALIAS(quotient_pdf_type, Config); + NBL_BXDF_CONFIG_ALIAS(isocache_type, Config); + NBL_BXDF_CONFIG_ALIAS(anisocache_type, Config); + using brdf_type = reflection::SGGXIsotropic; + + using ndf_type = ndf::GGX; + using fresnel_type = fresnel::Iridescent; + using measure_transform_type = ndf::SDualMeasureQuant; + + NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; + + struct SCreationParams + { + scalar_type A; + scalar_type thickness; // thin-film thickness in nm + spectral_type ior0; + spectral_type ior1; + spectral_type ior2; + }; + using creation_type = SCreationParams; + + struct SIridQuery + { + using scalar_type = scalar_type; + + scalar_type getDevshV() NBL_CONST_MEMBER_FUNC { return devsh_v; } + scalar_type getDevshL() NBL_CONST_MEMBER_FUNC { return devsh_l; } + + scalar_type devsh_v; + scalar_type devsh_l; + }; + using query_type = SIridQuery; + + static this_t create(scalar_type A, scalar_type thickness, NBL_CONST_REF_ARG(spectral_type) ior0, NBL_CONST_REF_ARG(spectral_type) ior1, NBL_CONST_REF_ARG(spectral_type) ior2) + { + this_t retval; + retval.__base.ndf.A = vector2_type(A, A); + retval.__base.ndf.a2 = A*A; + retval.__base.ndf.one_minus_a2 = scalar_type(1.0) - A*A; + retval.__base.fresnel.Dinc = thickness; + retval.__base.fresnel.ior1 = ior0; + retval.__base.fresnel.ior2 = ior1; + retval.__base.fresnel.ior3 = ior2; + retval.__base.fresnel.iork3 = hlsl::promote(0.0); // always 0.0 for dielectric base layer + return retval; + } + static this_t create(NBL_CONST_REF_ARG(creation_type) params) + { + return create(params.A, params.thickness, params.ior0, params.ior1, params.ior2); + } + + query_type createQuery(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + { + query_type query; + ndf_type ggx_ndf = __base.getNDF(); + query.devsh_v = ggx_ndf.devsh_part(interaction.getNdotV2()); + query.devsh_l = ggx_ndf.devsh_part(_sample.getNdotL2()); + return query; + } + + spectral_type eval(NBL_CONST_REF_ARG(query_type) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) cache) + { + struct SGGXG2XQuery + { + using scalar_type = scalar_type; + + scalar_type getDevshV() NBL_CONST_MEMBER_FUNC { return devsh_v; } + scalar_type getDevshL() NBL_CONST_MEMBER_FUNC { return devsh_l; } + BxDFClampMode getClampMode() NBL_CONST_MEMBER_FUNC { return _clamp; } + + scalar_type devsh_v; + scalar_type devsh_l; + BxDFClampMode _clamp; + }; + + SGGXG2XQuery g2_query; + g2_query.devsh_v = query.getDevshV(); + g2_query.devsh_l = query.getDevshL(); + g2_query._clamp = _clamp; + + fresnel::OrientedEtas orientedEta = fresnel::OrientedEtas::create(1.0, hlsl::promote(__base.fresnel.ior3/__base.fresnel.ior2)); + measure_transform_type dualMeasure = __base.template __DG(g2_query, _sample, interaction, cache); + dualMeasure.absNdotL = _sample.getNdotL(_clamp); + dualMeasure.orientedEta = orientedEta.value[0]; + scalar_type DG = dualMeasure.getProjectedLightMeasure(); + + fresnel_type f = __base.getFresnel(); + f.absCosTheta = hlsl::abs(cache.getLdotH()); + return hlsl::promote(f()[0]) * DG; + } + + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_REF_ARG(vector3_type) u, NBL_REF_ARG(isocache_type) cache) + { + fresnel::OrientedEtas orientedEta = fresnel::OrientedEtas::create(1.0, hlsl::promote(__base.fresnel.ior3/__base.fresnel.ior2)); + SGGXDielectricAnisotropic ggx_aniso = SGGXDielectricAnisotropic::create(orientedEta, __base.ndf.A.x, __base.ndf.A.y); + anisocache_type anisocache; + sample_type s = ggx_aniso.generate(anisotropic_interaction_type::create(interaction), u, anisocache); + cache = anisocache.iso_cache; + return s; + } + + scalar_type pdf(NBL_CONST_REF_ARG(query_type) query, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) cache) + { + struct SGGXDG1Query + { + using scalar_type = scalar_type; + + scalar_type getNdf() NBL_CONST_MEMBER_FUNC { return ndf; } + scalar_type getG1over2NdotV() NBL_CONST_MEMBER_FUNC { return G1_over_2NdotV; } + scalar_type getOrientedEta() NBL_CONST_MEMBER_FUNC { return orientedEta; } + + scalar_type ndf; + scalar_type G1_over_2NdotV; + scalar_type orientedEta; + }; + + SGGXDG1Query dg1_query; + fresnel::OrientedEtas orientedEta = fresnel::OrientedEtas::create(1.0, hlsl::promote(__base.fresnel.ior3/__base.fresnel.ior2)); + dg1_query.orientedEta = orientedEta.value[0]; + + fresnel_type f = __base.getFresnel(); + f.absCosTheta = hlsl::abs(cache.getLdotH()); + const scalar_type reflectance = f()[0]; + + ndf_type ggx_ndf = __base.getNDF(); + dg1_query.ndf = __base.__D(cache); + dg1_query.G1_over_2NdotV = ggx_ndf.G1_wo_numerator_devsh_part(interaction.getNdotV(_clamp), query.getDevshV()); + + measure_transform_type dualMeasure = __base.template __DG1(dg1_query, cache); + return hlsl::mix(reflectance, scalar_type(1.0) - reflectance, cache.isTransmission()) * dualMeasure.getMicrofacetMeasure(); + } + + quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(query_type) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) cache) + { + scalar_type _pdf = pdf(query, interaction, cache); + const bool transmitted = cache.isTransmission(); + + struct SGGXG2XQuery + { + using scalar_type = scalar_type; + + scalar_type getDevshV() NBL_CONST_MEMBER_FUNC { return devsh_v; } + scalar_type getDevshL() NBL_CONST_MEMBER_FUNC { return devsh_l; } + BxDFClampMode getClampMode() NBL_CONST_MEMBER_FUNC { return _clamp; } + + scalar_type devsh_v; + scalar_type devsh_l; + BxDFClampMode _clamp; + }; + + ndf_type ggx_ndf = __base.getNDF(); + SGGXG2XQuery g2_query; + g2_query.devsh_v = query.getDevshV(); + g2_query.devsh_l = query.getDevshL(); + g2_query._clamp = _clamp; + + scalar_type quo; + quo = ggx_ndf.template G2_over_G1(g2_query, _sample, interaction, cache); + + return quotient_pdf_type::create(quo, _pdf); + } + + SCookTorrance __base; +}; + +} + +template +struct traits > +{ + NBL_CONSTEXPR_STATIC_INLINE BxDFType type = BT_BSDF; + NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = true; + NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; +}; + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/colorspace.hlsl b/include/nbl/builtin/hlsl/colorspace.hlsl new file mode 100644 index 0000000000..f6b5d76ae8 --- /dev/null +++ b/include/nbl/builtin/hlsl/colorspace.hlsl @@ -0,0 +1,198 @@ +// Copyright (C) 2018-2025 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h + +#ifndef _NBL_BUILTIN_HLSL_COLOR_SPACE_COLORSPACE_INCLUDED_ +#define _NBL_BUILTIN_HLSL_COLOR_SPACE_COLORSPACE_INCLUDED_ + +#include + +namespace nbl +{ +namespace hlsl +{ +namespace colorspace +{ + +struct colorspace_base +{ + NBL_CONSTEXPR_STATIC_INLINE float32_t wavelength_R = 580.0f; + NBL_CONSTEXPR_STATIC_INLINE float32_t wavelength_G = 550.0f; + NBL_CONSTEXPR_STATIC_INLINE float32_t wavelength_B = 450.0f; +}; + +struct scRGB : colorspace_base +{ + static float32_t3x3 FromXYZ() + { + return float32_t3x3( + float32_t3( 3.240970f, -1.537383f, -0.498611f), + float32_t3(-0.969244f, 1.875968f, 0.041555f), + float32_t3( 0.055630f, -0.203977f, 1.056972f) + ); + } + static float32_t3 FromXYZ(float32_t3 val) { return hlsl::mul(FromXYZ(), val); } + + static float32_t3x3 ToXYZ() + { + return float32_t3x3( + float32_t3(0.412391f, 0.357584f, 0.180481f), + float32_t3(0.212639f, 0.715169f, 0.072192f), + float32_t3(0.019331f, 0.119195f, 0.950532f) + ); + } + static float32_t3 ToXYZ(float32_t3 val) { return hlsl::mul(ToXYZ(), val); } +}; + +struct sRGB : scRGB {}; +struct BT709 : scRGB {}; + +struct Display_P3 : colorspace_base +{ + static float32_t3x3 FromXYZ() + { + return float32_t3x3( + float32_t3( 2.4934969119f, -0.9313836179f, -0.4027107845f), + float32_t3(-0.8294889696f, 1.7626640603f, 0.0236246858f), + float32_t3( 0.0358458302f, -0.0761723893f, 0.9568845240f) + ); + } + static float32_t3 FromXYZ(float32_t3 val) { return hlsl::mul(FromXYZ(), val); } + + static float32_t3x3 ToXYZ() + { + return float32_t3x3( + float32_t3(0.4865709486f, 0.2656676932f, 0.1982172852f), + float32_t3(0.2289745641f, 0.6917385218f, 0.0792869141f), + float32_t3(0.0000000000f, 0.0451133819f, 1.0439443689f) + ); + } + static float32_t3 ToXYZ(float32_t3 val) { return hlsl::mul(ToXYZ(), val); } +}; + +struct DCI_P3 : colorspace_base +{ + static float32_t3x3 FromXYZ() + { + return float32_t3x3( + float32_t3(1.0f, 0.0f, 0.0f), + float32_t3(0.0f, 1.0f, 0.0f), + float32_t3(0.0f, 0.0f, 1.0f) + ); + } + static float32_t3 FromXYZ(float32_t3 val) { return hlsl::mul(FromXYZ(), val); } + + static float32_t3x3 ToXYZ() + { + return float32_t3x3( + float32_t3(1.0f, 0.0f, 0.0f), + float32_t3(0.0f, 1.0f, 0.0f), + float32_t3(0.0f, 0.0f, 1.0f) + ); + } + static float32_t3 ToXYZ(float32_t3 val) { return hlsl::mul(ToXYZ(), val); } +}; + +struct BT2020 : colorspace_base +{ + static float32_t3x3 FromXYZ() + { + return float32_t3x3( + float32_t3( 1.716651f, -0.355671f, -0.253366f), + float32_t3(-0.666684f, 1.616481f, 0.015769f), + float32_t3( 0.017640f, -0.042771f, 0.942103f) + ); + } + static float32_t3 FromXYZ(float32_t3 val) { return hlsl::mul(FromXYZ(), val); } + + static float32_t3x3 ToXYZ() + { + return float32_t3x3( + float32_t3(0.636958f, 0.144617f, 0.168881f), + float32_t3(0.262700f, 0.677998f, 0.059302f), + float32_t3(0.000000f, 0.028073f, 1.060985f) + ); + } + static float32_t3 ToXYZ(float32_t3 val) { return hlsl::mul(ToXYZ(), val); } +}; + +struct HDR10_ST2084 : BT2020 {}; +struct DOLBYIVISION : BT2020 {}; +struct HDR10_HLG : BT2020 {}; + +struct AdobeRGB : colorspace_base +{ + static float32_t3x3 FromXYZ() + { + return float32_t3x3( + float32_t3( 2.0415879038f, -0.5650069743f, -0.3447313508f), + float32_t3(-0.9692436363f, 1.8759675015f, 0.0415550574f), + float32_t3( 0.0134442806f, -0.1183623922f, 1.0151749944f) + ); + } + static float32_t3 FromXYZ(float32_t3 val) { return hlsl::mul(FromXYZ(), val); } + + static float32_t3x3 ToXYZ() + { + return float32_t3x3( + float32_t3(0.5766690429f, 0.1855582379f, 0.1882286462f), + float32_t3(0.2973449753f, 0.6273635663f, 0.0752914585f), + float32_t3(0.0270313614f, 0.0706888525f, 0.9913375368f) + ); + } + static float32_t3 ToXYZ(float32_t3 val) { return hlsl::mul(ToXYZ(), val); } +}; + +struct ACES2065_1 : colorspace_base +{ + static float32_t3x3 FromXYZ() + { + return float32_t3x3( + float32_t3( 1.0498110175f, 0.0000000000f, -0.0000974845f), + float32_t3(-0.4959030231f, 1.3733130458f, 0.0982400361f), + float32_t3( 0.0000000000f, 0.0000000000f, 0.9912520182f) + ); + } + static float32_t3 FromXYZ(float32_t3 val) { return hlsl::mul(FromXYZ(), val); } + + static float32_t3x3 ToXYZ() + { + return float32_t3x3( + float32_t3(0.9525523959f, 0.0000000000f, 0.0000936786f), + float32_t3(0.3439664498f, 0.7281660966f, -0.0721325464f), + float32_t3(0.0000000000f, 0.0000000000f, 1.0088251844f) + ); + } + static float32_t3 ToXYZ(float32_t3 val) { return hlsl::mul(ToXYZ(), val); } +}; + +struct ACEScc : colorspace_base +{ + static float32_t3x3 FromXYZ() + { + return float32_t3x3( + float32_t3( 1.6410233797f, -0.3248032942f, -0.2364246952f), + float32_t3(-0.6636628587f, 1.6153315917f, 0.0167563477f), + float32_t3( 0.0117218943f, -0.0082844420f, 0.9883948585f) + ); + } + static float32_t3 FromXYZ(float32_t3 val) { return hlsl::mul(FromXYZ(), val); } + + static float32_t3x3 ToXYZ() + { + return float32_t3x3( + float32_t3( 0.6624541811f, 0.1340042065f, 0.1561876870f), + float32_t3( 0.2722287168f, 0.6740817658f, 0.0536895174f), + float32_t3(-0.0055746495f, 0.0040607335f, 1.0103391003f) + ); + } + static float32_t3 ToXYZ(float32_t3 val) { return hlsl::mul(ToXYZ(), val); } +}; + +struct ACEScct : ACEScc {}; + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/colorspace/decodeCIEXYZ.hlsl b/include/nbl/builtin/hlsl/colorspace/decodeCIEXYZ.hlsl deleted file mode 100644 index 29a93124d9..0000000000 --- a/include/nbl/builtin/hlsl/colorspace/decodeCIEXYZ.hlsl +++ /dev/null @@ -1,79 +0,0 @@ - -// Copyright (C) 2018-2022 - DevSH Graphics Programming Sp. z O.O. -// This file is part of the "Nabla Engine". -// For conditions of distribution and use, see copyright notice in nabla.h - -#ifndef _NBL_BUILTIN_HLSL_COLOR_SPACE_DECODE_CIE_XYZ_INCLUDED_ -#define _NBL_BUILTIN_HLSL_COLOR_SPACE_DECODE_CIE_XYZ_INCLUDED_ - -#include - -namespace nbl -{ -namespace hlsl -{ -namespace colorspace -{ -namespace decode -{ - -NBL_CONSTEXPR float32_t3x3 XYZtoscRGB = float32_t3x3( - float32_t3( 3.240970f, -1.537383f, -0.498611f), - float32_t3(-0.969244f, 1.875968f, 0.041555f), - float32_t3( 0.055630f, -0.203977f, 1.056972f) -); - -NBL_CONSTEXPR float32_t3x3 XYZtosRGB = XYZtoscRGB; -NBL_CONSTEXPR float32_t3x3 XYZtoBT709 = XYZtoscRGB; - - -NBL_CONSTEXPR float32_t3x3 XYZtoDisplay_P3 = float32_t3x3( - float32_t3( 2.4934969119f, -0.9313836179f, -0.4027107845f), - float32_t3(-0.8294889696f, 1.7626640603f, 0.0236246858f), - float32_t3( 0.0358458302f, -0.0761723893f, 0.9568845240f) -); - -NBL_CONSTEXPR float32_t3x3 XYZtoDCI_P3 = float32_t3x3( - float32_t3(1.0f, 0.0f, 0.0f), - float32_t3(0.0f, 1.0f, 0.0f), - float32_t3(0.0f, 0.0f, 1.0f) -); - -NBL_CONSTEXPR float32_t3x3 XYZtoBT2020 = float32_t3x3( - float32_t3( 1.716651f, -0.355671f, -0.253366f), - float32_t3(-0.666684f, 1.616481f, 0.015769f), - float32_t3( 0.017640f, -0.042771f, 0.942103f) -); - -NBL_CONSTEXPR float32_t3x3 XYZtoHDR10_ST2084 = XYZtoBT2020; -NBL_CONSTEXPR float32_t3x3 XYZtoDOLBYIVISION = XYZtoBT2020; -NBL_CONSTEXPR float32_t3x3 XYZtoHDR10_HLG = XYZtoBT2020; - -NBL_CONSTEXPR float32_t3x3 XYZtoAdobeRGB = float32_t3x3( - float32_t3( 2.0415879038f, -0.5650069743f, -0.3447313508f), - float32_t3(-0.9692436363f, 1.8759675015f, 0.0415550574f), - float32_t3( 0.0134442806f, -0.1183623922f, 1.0151749944f) -); - - -NBL_CONSTEXPR float32_t3x3 XYZtoACES2065_1 = float32_t3x3( - float32_t3( 1.0498110175f, 0.0000000000f, -0.0000974845f), - float32_t3(-0.4959030231f, 1.3733130458f, 0.0982400361f), - float32_t3( 0.0000000000f, 0.0000000000f, 0.9912520182f) -); - -NBL_CONSTEXPR float32_t3x3 XYZtoACEScc = float32_t3x3( - float32_t3( 1.6410233797f, -0.3248032942f, -0.2364246952f), - float32_t3(-0.6636628587f, 1.6153315917f, 0.0167563477f), - float32_t3( 0.0117218943f, -0.0082844420f, 0.9883948585f) -); - -NBL_CONSTEXPR float32_t3x3 XYZtoACEScct = XYZtoACEScc; - -} -} -} -} - - -#endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/colorspace/encodeCIEXYZ.hlsl b/include/nbl/builtin/hlsl/colorspace/encodeCIEXYZ.hlsl deleted file mode 100644 index cc8ac317b7..0000000000 --- a/include/nbl/builtin/hlsl/colorspace/encodeCIEXYZ.hlsl +++ /dev/null @@ -1,83 +0,0 @@ - - -// Copyright (C) 2018-2022 - DevSH Graphics Programming Sp. z O.O. -// This file is part of the "Nabla Engine". -// For conditions of distribution and use, see copyright notice in nabla.h - -#ifndef _NBL_BUILTIN_HLSL_COLOR_SPACE_ENCODE_CIE_XYZ_INCLUDED_ -#define _NBL_BUILTIN_HLSL_COLOR_SPACE_ENCODE_CIE_XYZ_INCLUDED_ - -#include - -namespace nbl -{ -namespace hlsl -{ -namespace colorspace -{ - -NBL_CONSTEXPR float32_t3x3 scRGBtoXYZ = float32_t3x3( - float32_t3(0.412391f, 0.357584f, 0.180481f), - float32_t3(0.212639f, 0.715169f, 0.072192f), - float32_t3(0.019331f, 0.119195f, 0.950532f) -); - -NBL_CONSTEXPR float32_t3x3 sRGBtoXYZ = scRGBtoXYZ; - -NBL_CONSTEXPR float32_t3x3 BT709toXYZ = scRGBtoXYZ; - - -NBL_CONSTEXPR float32_t3x3 Display_P3toXYZ = float32_t3x3( - float32_t3(0.4865709486f, 0.2656676932f, 0.1982172852f), - float32_t3(0.2289745641f, 0.6917385218f, 0.0792869141f), - float32_t3(0.0000000000f, 0.0451133819f, 1.0439443689f) -); - - -NBL_CONSTEXPR float32_t3x3 DCI_P3toXYZ = float32_t3x3( - float32_t3(1.0f, 0.0f, 0.0f), - float32_t3(0.0f, 1.0f, 0.0f), - float32_t3(0.0f, 0.0f, 1.0f) -); - - -NBL_CONSTEXPR float32_t3x3 BT2020toXYZ = float32_t3x3( - float32_t3(0.636958f, 0.144617f, 0.168881f), - float32_t3(0.262700f, 0.677998f, 0.059302f), - float32_t3(0.000000f, 0.028073f, 1.060985f) -); - -NBL_CONSTEXPR float32_t3x3 HDR10_ST2084toXYZ = BT2020toXYZ; - -NBL_CONSTEXPR float32_t3x3 DOLBYIVISIONtoXYZ = BT2020toXYZ; - -NBL_CONSTEXPR float32_t3x3 HDR10_HLGtoXYZ = BT2020toXYZ; - - -NBL_CONSTEXPR float32_t3x3 AdobeRGBtoXYZ = float32_t3x3( - float32_t3(0.5766690429f, 0.1855582379f, 0.1882286462f), - float32_t3(0.2973449753f, 0.6273635663f, 0.0752914585f), - float32_t3(0.0270313614f, 0.0706888525f, 0.9913375368f) -); - - -NBL_CONSTEXPR float32_t3x3 ACES2065_1toXYZ = float32_t3x3( - float32_t3(0.9525523959f, 0.0000000000f, 0.0000936786f), - float32_t3(0.3439664498f, 0.7281660966f, -0.0721325464f), - float32_t3(0.0000000000f, 0.0000000000f, 1.0088251844f) -); - - -NBL_CONSTEXPR float32_t3x3 ACEScctoXYZ = float32_t3x3( - float32_t3( 0.6624541811f, 0.1340042065f, 0.1561876870f), - float32_t3( 0.2722287168f, 0.6740817658f, 0.0536895174f), - float32_t3(-0.0055746495f, 0.0040607335f, 1.0103391003f) -); - -NBL_CONSTEXPR float32_t3x3 ACESccttoXYZ = ACEScctoXYZ; - -} -} -} - -#endif \ No newline at end of file diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 17e07257b4..8f0f90cf48 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -307,8 +307,7 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/acceleration_structures.hlsl" #colorspace LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace/EOTF.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace/OETF.hlsl") -LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace/decodeCIEXYZ.hlsl") -LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace/encodeCIEXYZ.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace.hlsl") #barycentrics LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/barycentric/utils.hlsl") #scanning append @@ -347,10 +346,12 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/reflection/beckmann.hlsl LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/reflection/ggx.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/reflection/lambertian.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/reflection/oren_nayar.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/reflection/iridescent.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/transmission/beckmann.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/transmission/ggx.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/transmission/lambertian.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/transmission/smooth_dielectric.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/bxdf/transmission/iridescent.hlsl") #subgroup LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/subgroup/ballot.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/subgroup/basic.hlsl")