-
Notifications
You must be signed in to change notification settings - Fork 65
Iridescent fresnel, bxdfs #918
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
// 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<T>(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<T>(hlsl::exp2<scalar_type>(-numeric_limits<scalar_type>::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<T>(1.0); | ||
Rp = (rp_common - etaCosTwice) / (rp_common + etaCosTwice); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make a new struct for this e.g. ThinFilmConductor
, its separate functionality, same for the dielectric
{ | ||
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<SGGXG2XQuery>(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<spectral_type>(0.0); | ||
} | ||
|
||
sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u, NBL_REF_ARG(isocache_type) cache) | ||
{ | ||
SGGXAnisotropic<Config> ggx_aniso = SGGXAnisotropic<Config>::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<SGGXDG1Query>(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<spectral_type>(0.0); | ||
if (_sample.getNdotL() > numeric_limits<scalar_type>::min && interaction.getNdotV() > numeric_limits<scalar_type>::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<SGGXG2XQuery, sample_type, isotropic_interaction_type, isocache_type>(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<Config, ndf_type, fresnel_type, measure_transform_type> __base; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could have just added a Delta NDF, and then used a CookTorrance with Iridescent Fresnel
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
noooo, different colorspaces have different wavelengths of the primaries
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) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are you copying literals ? return the encode/decode matrices we already have!
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) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't delete these, they were useful as static const
globals
vector_type eta12 = ior2/ior1; | ||
vector_type eta23 = ior3/ior2; | ||
vector_type etak23 = iork3/ior2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you precompute those and store as members?
No description provided.