Cycles: Rework component layering in Principled BSDF #110864

Merged
Lukas Stockner merged 10 commits from LukasStockner/blender:layering-principled into main 2023-08-10 23:53:44 +02:00
21 changed files with 1081 additions and 648 deletions

View File

@ -86,6 +86,58 @@ static float precompute_ggx_glass_E(float rough, float mu, float eta, float3 ran
return 0.0f;
}
static float precompute_ggx_gen_schlick_s(
float rough, float mu, float eta, float exponent, float3 rand)
{
MicrofacetBsdf bsdf;
bsdf.weight = one_float3();
bsdf.sample_weight = 1.0f;
bsdf.N = make_float3(0.0f, 0.0f, 1.0f);
bsdf.alpha_x = bsdf.alpha_y = sqr(rough);
bsdf.ior = eta;
bsdf.T = make_float3(1.0f, 0.0f, 0.0f);
bsdf_microfacet_ggx_setup(&bsdf);
FresnelGeneralizedSchlick fresnel;
fresnel.reflection_tint = one_float3();
fresnel.transmission_tint = one_float3();
fresnel.f0 = make_float3(0.0f, 1.0f, 0.0f);
fresnel.f90 = make_float3(1.0f, 1.0f, 0.0f);
fresnel.exponent = exponent;
bsdf.fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
bsdf.fresnel = &fresnel;
float3 omega_in;
Spectrum eval;
float pdf = 0.0f, sampled_eta;
float2 sampled_roughness;
bsdf_microfacet_ggx_sample((ShaderClosure *)&bsdf,
0,
make_float3(0.0f, 0.0f, 1.0f),
make_float3(sqrtf(1.0f - sqr(mu)), 0.0f, mu),
rand,
&eval,
&omega_in,
&pdf,
&sampled_roughness,
&sampled_eta);
if (pdf != 0.0f) {
/* The idea here is that the resulting Fresnel factor is always bounded by
* F0..F90, so it's enough to precompute and store the interpolation factor. */
return saturatef(eval.x / eval.y);
}
return 0.0f;
}
inline float ior_parametrization(float z)
{
/* This parametrization ensures that the entire [1..inf] range of IORs is covered
* and that most precision is allocated to the common areas (1-2). */
return ior_from_F0(sqr(sqr(z)));
}
struct PrecomputeTerm {
int samples;
int nx, ny, nz;
@ -95,31 +147,61 @@ struct PrecomputeTerm {
static bool cycles_precompute(std::string name)
{
std::map<string, PrecomputeTerm> precompute_terms;
precompute_terms["ggx_E"] = {
1 << 23, 32, 32, 1, [](float rough, float mu, float ior, float3 rand) {
return precompute_ggx_E(rough, mu, rand);
}};
/* Overall albedo of the GGX microfacet BRDF, depending on cosI and roughness. */
precompute_terms["ggx_E"] = {1 << 23, 32, 32, 1, [](float rough, float mu, float, float3 rand) {
return precompute_ggx_E(rough, mu, rand);
}};
/* Overall albedo of the GGX microfacet BRDF, averaged over cosI */
precompute_terms["ggx_Eavg"] = {
1 << 26, 32, 1, 1, [](float rough, float mu, float ior, float3 rand) {
1 << 26, 32, 1, 1, [](float rough, float mu, float, float3 rand) {
return 2.0f * mu * precompute_ggx_E(rough, mu, rand);
}};
/* Overall albedo of the GGX microfacet BSDF with dielectric Fresnel,
* depending on cosI and roughness, for IOR>1. */
precompute_terms["ggx_glass_E"] = {
1 << 23, 16, 16, 16, [](float rough, float mu, float ior, float3 rand) {
1 << 23, 16, 16, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return precompute_ggx_glass_E(rough, mu, ior, rand);
}};
/* Overall albedo of the GGX microfacet BSDF with dielectric Fresnel,
* averaged over cosI, for IOR>1. */
precompute_terms["ggx_glass_Eavg"] = {
1 << 26, 16, 1, 16, [](float rough, float mu, float ior, float3 rand) {
1 << 26, 16, 1, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return 2.0f * mu * precompute_ggx_glass_E(rough, mu, ior, rand);
}};
/* Overall albedo of the GGX microfacet BSDF with dielectric Fresnel,
* depending on cosI and roughness, for IOR<1. */
precompute_terms["ggx_glass_inv_E"] = {
1 << 23, 16, 16, 16, [](float rough, float mu, float ior, float3 rand) {
1 << 23, 16, 16, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return precompute_ggx_glass_E(rough, mu, 1.0f / ior, rand);
}};
/* Overall albedo of the GGX microfacet BSDF with dielectric Fresnel,
* averaged over cosI, for IOR<1. */
precompute_terms["ggx_glass_inv_Eavg"] = {
1 << 26, 16, 1, 16, [](float rough, float mu, float ior, float3 rand) {
1 << 26, 16, 1, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return 2.0f * mu * precompute_ggx_glass_E(rough, mu, 1.0f / ior, rand);
}};
/* Interpolation factor between F0 and F90 for the generalized Schlick Fresnel,
* depending on cosI and roughness, for IOR>1, using dielectric Fresnel mode. */
precompute_terms["ggx_gen_schlick_ior_s"] = {
1 << 20, 16, 16, 16, [](float rough, float mu, float z, float3 rand) {
float ior = ior_parametrization(z);
return precompute_ggx_gen_schlick_s(rough, mu, ior, -1.0f, rand);
}};
/* Interpolation factor between F0 and F90 for the generalized Schlick Fresnel,
* depending on cosI and roughness, for IOR>1. */
precompute_terms["ggx_gen_schlick_s"] = {
1 << 20, 16, 16, 16, [](float rough, float mu, float z, float3 rand) {
/* Remap 0..1 to 0..inf, with 0.5 mapping to 5 (the default value). */
float exponent = 5.0f * ((1.0f - z) / z);
return precompute_ggx_gen_schlick_s(rough, mu, 1.0f, exponent, rand);
}};
if (precompute_terms.count(name) == 0) {
return false;
}
@ -142,9 +224,6 @@ static bool cycles_precompute(std::string name)
float rough = (nx == 1) ? 0.0f : clamp(float(x) / float(nx - 1), 1e-4f, 1.0f);
float mu = (ny == 1) ? rand.w : clamp(float(y) / float(ny - 1), 1e-4f, 1.0f);
float ior = (nz == 1) ? 0.0f : clamp(float(z) / float(nz - 1), 1e-4f, 0.99f);
/* This parametrization ensures that the entire [1..inf] range of IORs is covered
* and that most precision is allocated to the common areas (1-2). */
ior = ior_from_F0(sqr(sqr(ior)));
float value = term.evaluation(rough, mu, ior, float4_to_float3(rand));
if (isnan(value)) {

View File

@ -139,7 +139,6 @@ set(SRC_KERNEL_CLOSURE_HEADERS
closure/bssrdf.h
closure/emissive.h
closure/volume.h
closure/bsdf_principled_diffuse.h
closure/bsdf_hair_principled.h
)

View File

@ -17,7 +17,6 @@
#include "kernel/closure/bsdf_toon.h"
#include "kernel/closure/bsdf_hair.h"
#include "kernel/closure/bsdf_hair_principled.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/bssrdf.h"
#include "kernel/closure/volume.h"
// clang-format on
@ -50,11 +49,6 @@ ccl_device_inline float bsdf_get_roughness_squared(ccl_private const ShaderClosu
return sqr(sqr(bsdf->roughness));
}
if (sc->type == CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID) {
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)sc;
return sqr(sqr(bsdf->roughness));
}
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
return 0.0f;
}
@ -204,11 +198,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
label = bsdf_principled_hair_sample(kg, sc, sd, rand, eval, wo, pdf, sampled_roughness, eta);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, rand_xy, eval, wo, pdf);
*sampled_roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_SHEEN_ID:
label = bsdf_sheen_sample(sc, Ng, sd->wi, rand_xy, eval, wo, pdf);
*sampled_roughness = one_float2();
@ -341,10 +330,6 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
*roughness = make_float2(alpha, alpha);
*eta = ((ccl_private PrincipledHairBSDF *)sc)->eta;
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
*roughness = one_float2();
*eta = 1.0f;
break;
case CLOSURE_BSDF_SHEEN_ID:
alpha = ((ccl_private SheenBsdf *)sc)->roughness;
*roughness = make_float2(alpha, alpha);
@ -426,9 +411,6 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
else
label = LABEL_REFLECT | LABEL_GLOSSY;
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
label = LABEL_REFLECT | LABEL_DIFFUSE;
break;
case CLOSURE_BSDF_SHEEN_ID:
label = LABEL_REFLECT | LABEL_DIFFUSE;
break;
@ -520,9 +502,6 @@ ccl_device_inline
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
eval = bsdf_hair_transmission_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
eval = bsdf_principled_diffuse_eval(sc, sd->wi, wo, pdf);
break;
case CLOSURE_BSDF_SHEEN_ID:
eval = bsdf_sheen_eval(sc, sd->wi, wo, pdf);
break;
@ -581,7 +560,8 @@ ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float
#endif
}
ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd,
ccl_device_inline Spectrum bsdf_albedo(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const ShaderClosure *sc,
const bool reflection,
const bool transmission)
@ -598,8 +578,8 @@ ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd,
* extra overhead though. */
#if defined(__SVM__) || defined(__OSL__)
if (CLOSURE_IS_BSDF_MICROFACET(sc->type)) {
albedo *= bsdf_microfacet_estimate_fresnel(
sd, (ccl_private const MicrofacetBsdf *)sc, reflection, transmission);
albedo *= bsdf_microfacet_estimate_albedo(
kg, sd, (ccl_private const MicrofacetBsdf *)sc, reflection, transmission);
}
else if (sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
/* TODO(lukas): Principled Hair could also be split into a glossy and a transmission component,

View File

@ -241,7 +241,7 @@ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetB
* Used by Principled v1. */
const float F_real = fresnel_dielectric_cos(dot(wi, H), bsdf->ior);
const float F0_real = F0_from_ior(bsdf->ior);
s = inverse_lerp(F0_real, 1.0f, F_real);
s = saturatef(inverse_lerp(F0_real, 1.0f, F_real));
}
else {
/* Regular case: Generalized Schlick term. */
@ -329,16 +329,12 @@ ccl_device_inline void microfacet_ggx_preserve_energy(KernelGlobals kg,
* code for that), but e.g. a reflection-only closure with Fresnel applied can end up having
* a very low overall albedo.
* This is used to adjust the sample weight, as well as for the Diff/Gloss/Trans Color pass
* and the Denoising Albedo pass.
*
* NOTE: This code assumes the microfacet surface is fairly smooth. For very high roughness,
* the results are much more uniform across the surface.
* For better results, we'd be blending between this and Fss based on roughness, but that
* would involve storing or recomputing Fss, which is probably not worth it. */
ccl_device Spectrum bsdf_microfacet_estimate_fresnel(ccl_private const ShaderData *sd,
ccl_private const MicrofacetBsdf *bsdf,
const bool reflection,
const bool transmission)
* and the Denoising Albedo pass. */
ccl_device Spectrum bsdf_microfacet_estimate_albedo(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const MicrofacetBsdf *bsdf,
const bool reflection,
const bool transmission)
{
const bool m_refraction = CLOSURE_IS_REFRACTION(bsdf->type);
const bool m_glass = CLOSURE_IS_GLASS(bsdf->type);
@ -347,7 +343,29 @@ ccl_device Spectrum bsdf_microfacet_estimate_fresnel(ccl_private const ShaderDat
Spectrum albedo = zero_spectrum();
if (reflection && (m_reflection || m_glass)) {
/* BSDF has a reflective lobe. */
albedo += microfacet_fresnel(bsdf, sd->wi, bsdf->N, false);
if (bsdf->fresnel_type == MicrofacetFresnel::GENERALIZED_SCHLICK) {
ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *)
bsdf->fresnel;
float mu = dot(sd->wi, bsdf->N);
float rough = sqrtf(sqrtf(bsdf->alpha_x * bsdf->alpha_y));
float s;
if (fresnel->exponent < 0.0f) {
float z = sqrtf(fabsf((bsdf->ior - 1.0f) / (bsdf->ior + 1.0f)));
s = lookup_table_read_3D(
kg, rough, mu, z, kernel_data.tables.ggx_gen_schlick_ior_s, 16, 16, 16);
}
else {
float z = 1.0f / (0.2f * fresnel->exponent + 1.0f);
s = lookup_table_read_3D(
kg, rough, mu, z, kernel_data.tables.ggx_gen_schlick_s, 16, 16, 16);
}
albedo += mix(fresnel->f0, fresnel->f90, s) * fresnel->reflection_tint;
}
else {
/* If we don't (yet) have a way to estimate albedo in a way that accounts for roughness,
* fall back to assuming that the surface is smooth. */
albedo += microfacet_fresnel(bsdf, sd->wi, bsdf->N, false);
}
}
if (transmission && (m_refraction || m_glass)) {
/* BSDF has a refractive lobe (unless there's TIR). */
@ -733,7 +751,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_conductor(KernelGlobals kg,
{
bsdf->fresnel_type = MicrofacetFresnel::CONDUCTOR;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf, true, true));
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
if (preserve_energy) {
/* In order to estimate Fss of the conductor, we fit the F82-tint model to it based on the
@ -756,7 +774,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_dielectric_tint(
{
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC_TINT;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf, true, true));
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
if (preserve_energy) {
/* Assume that the transmissive tint makes up most of the overall color. */
@ -773,7 +791,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
{
bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf, true, true));
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
if (preserve_energy) {
Spectrum Fss = one_spectrum();
@ -851,7 +869,8 @@ ccl_device int bsdf_microfacet_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
return SD_BSDF | bsdf_microfacet_eval_flag(bsdf);
}
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *bsdf,
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(KernelGlobals kg,
ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd)
{
bsdf->alpha_x = saturatef(bsdf->alpha_x);
@ -860,7 +879,7 @@ ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *b
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
bsdf->energy_scale = 1.0f;
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf, true, true));
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
return SD_BSDF | bsdf_microfacet_eval_flag(bsdf);
}

View File

@ -1,157 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
/* DISNEY PRINCIPLED DIFFUSE BRDF
*
* Shading model by Brent Burley (Disney): "Physically Based Shading at Disney" (2012)
*
* "Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering" (2015)
* For the separation of retro-reflection, "2.3 Dielectric BRDF with integrated
* subsurface scattering"
*/
#include "kernel/closure/bsdf_util.h"
#include "kernel/sample/mapping.h"
CCL_NAMESPACE_BEGIN
enum PrincipledDiffuseBsdfComponents {
PRINCIPLED_DIFFUSE_FULL = 1,
PRINCIPLED_DIFFUSE_LAMBERT = 2,
PRINCIPLED_DIFFUSE_LAMBERT_EXIT = 4,
PRINCIPLED_DIFFUSE_RETRO_REFLECTION = 8,
};
typedef struct PrincipledDiffuseBsdf {
SHADER_CLOSURE_BASE;
float roughness;
int components;
} PrincipledDiffuseBsdf;
static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledDiffuseBsdf),
"PrincipledDiffuseBsdf is too large!");
ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *bsdf)
{
bsdf->type = CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID;
bsdf->components = PRINCIPLED_DIFFUSE_FULL;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device Spectrum
bsdf_principled_diffuse_compute_brdf(ccl_private const PrincipledDiffuseBsdf *bsdf,
float3 N,
float3 V,
float3 L,
ccl_private float *pdf)
{
const float NdotL = dot(N, L);
if (NdotL <= 0) {
return zero_spectrum();
}
const float NdotV = dot(N, V);
const float FV = schlick_fresnel(NdotV);
const float FL = schlick_fresnel(NdotL);
float f = 0.0f;
/* Lambertian component. */
if (bsdf->components & (PRINCIPLED_DIFFUSE_FULL | PRINCIPLED_DIFFUSE_LAMBERT)) {
f += (1.0f - 0.5f * FV) * (1.0f - 0.5f * FL);
}
else if (bsdf->components & PRINCIPLED_DIFFUSE_LAMBERT_EXIT) {
f += (1.0f - 0.5f * FL);
}
/* Retro-reflection component. */
if (bsdf->components & (PRINCIPLED_DIFFUSE_FULL | PRINCIPLED_DIFFUSE_RETRO_REFLECTION)) {
/* H = normalize(L + V); // Bisector of an angle between L and V
* LH2 = 2 * dot(L, H)^2 = 2cos(x)^2 = cos(2x) + 1 = dot(L, V) + 1,
* half-angle x between L and V is at most 90 deg. */
const float LH2 = dot(L, V) + 1;
const float RR = bsdf->roughness * LH2;
f += RR * (FL + FV + FL * FV * (RR - 1.0f));
}
float value = M_1_PI_F * NdotL * f;
return make_spectrum(value);
}
/* Compute Fresnel at entry point, to be combined with #PRINCIPLED_DIFFUSE_LAMBERT_EXIT
* at the exit point to get the complete BSDF. */
ccl_device_inline float bsdf_principled_diffuse_compute_entry_fresnel(const float NdotV)
{
const float FV = schlick_fresnel(NdotV);
return (1.0f - 0.5f * FV);
}
/* Ad-hoc weight adjustment to avoid retro-reflection taking away half the
* samples from BSSRDF. */
ccl_device_inline float bsdf_principled_diffuse_retro_reflection_sample_weight(
ccl_private PrincipledDiffuseBsdf *bsdf, const float3 I)
{
return bsdf->roughness * schlick_fresnel(dot(bsdf->N, I));
}
ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *bsdf,
int components)
{
bsdf->type = CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID;
bsdf->components = components;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device Spectrum bsdf_principled_diffuse_eval(ccl_private const ShaderClosure *sc,
const float3 wi,
const float3 wo,
ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
const float3 N = bsdf->N;
if (dot(N, wo) > 0.0f) {
const float3 V = wi;
const float3 L = wo;
*pdf = fmaxf(dot(N, wo), 0.0f) * M_1_PI_F;
return bsdf_principled_diffuse_compute_brdf(bsdf, N, V, L, pdf);
}
else {
*pdf = 0.0f;
return zero_spectrum();
}
}
ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 Ng,
float3 wi,
float2 rand,
ccl_private Spectrum *eval,
ccl_private float3 *wo,
ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
float3 N = bsdf->N;
sample_cos_hemisphere(N, rand, wo, pdf);
if (dot(Ng, *wo) > 0) {
*eval = bsdf_principled_diffuse_compute_brdf(bsdf, N, wi, *wo, pdf);
}
else {
*pdf = 0.0f;
*eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_DIFFUSE;
}
CCL_NAMESPACE_END

View File

@ -263,6 +263,11 @@ ccl_device_forceinline float bssrdf_pdf(const Spectrum radius, float r)
ccl_device_inline ccl_private Bssrdf *bssrdf_alloc(ccl_private ShaderData *sd, Spectrum weight)
{
float sample_weight = fabsf(average(weight));
if (sample_weight < CLOSURE_WEIGHT_CUTOFF) {
return NULL;
}
ccl_private Bssrdf *bssrdf = (ccl_private Bssrdf *)closure_alloc(
sd, sizeof(Bssrdf), CLOSURE_NONE_ID, weight);
@ -270,9 +275,8 @@ ccl_device_inline ccl_private Bssrdf *bssrdf_alloc(ccl_private ShaderData *sd, S
return NULL;
}
float sample_weight = fabsf(average(weight));
bssrdf->sample_weight = sample_weight;
return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? bssrdf : NULL;
return bssrdf;
}
ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
@ -282,22 +286,6 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
{
int flag = 0;
/* Add retro-reflection component as separate diffuse BSDF. */
if (bssrdf->roughness != FLT_MAX) {
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc(
sd, sizeof(PrincipledDiffuseBsdf), bssrdf->weight);
if (bsdf) {
bsdf->N = bssrdf->N;
bsdf->roughness = bssrdf->roughness;
flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_RETRO_REFLECTION);
/* Ad-hoc weight adjustment to avoid retro-reflection taking away half the
* samples from BSSRDF. */
bsdf->sample_weight *= bsdf_principled_diffuse_retro_reflection_sample_weight(bsdf, sd->wi);
}
}
/* Verify if the radii are large enough to sample without precision issues. */
int bssrdf_channels = SPECTRUM_CHANNELS;
Spectrum diffuse_weight = zero_spectrum();
@ -313,24 +301,12 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
if (bssrdf_channels < SPECTRUM_CHANNELS) {
/* Add diffuse BSDF if any radius too small. */
if (bssrdf->roughness != FLT_MAX) {
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc(
sd, sizeof(PrincipledDiffuseBsdf), diffuse_weight);
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), diffuse_weight);
if (bsdf) {
bsdf->N = bssrdf->N;
bsdf->roughness = bssrdf->roughness;
flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_LAMBERT);
}
}
else {
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), diffuse_weight);
if (bsdf) {
bsdf->N = bssrdf->N;
flag |= bsdf_diffuse_setup(bsdf);
}
if (bsdf) {
bsdf->N = bssrdf->N;
flag |= bsdf_diffuse_setup(bsdf);
}
}

View File

@ -59,16 +59,7 @@ ccl_device_forceinline void film_write_denoising_features_surface(KernelGlobals
normal += sc->N * sc->sample_weight;
sum_weight += sc->sample_weight;
if (sc->type == CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID) {
/* BSSRDF already accounts for weight, retro-reflection would double up. */
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)
sc;
if (bsdf->components == PRINCIPLED_DIFFUSE_RETRO_REFLECTION) {
continue;
}
}
Spectrum closure_albedo = bsdf_albedo(sd, sc, true, true);
Spectrum closure_albedo = bsdf_albedo(kg, sd, sc, true, true);
if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
diffuse_albedo += closure_albedo;
sum_nonspecular_weight += sc->sample_weight;

View File

@ -10,7 +10,6 @@
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_diffuse.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/bssrdf.h"
#include "kernel/closure/volume.h"
@ -53,9 +52,6 @@ ccl_device int subsurface_bounce(KernelGlobals kg,
/* Compute weight, optionally including Fresnel from entry point. */
Spectrum weight = surface_shader_bssrdf_sample_weight(sd, sc);
if (bssrdf->roughness != FLT_MAX) {
path_flag |= PATH_RAY_SUBSURFACE_USE_FRESNEL;
}
if (sd->flag & SD_BACKFACING) {
path_flag |= PATH_RAY_SUBSURFACE_BACKFACING;
@ -103,24 +99,12 @@ ccl_device void subsurface_shader_data_setup(KernelGlobals kg,
const Spectrum weight = one_spectrum();
if (path_flag & PATH_RAY_SUBSURFACE_USE_FRESNEL) {
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc(
sd, sizeof(PrincipledDiffuseBsdf), weight);
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), weight);
if (bsdf) {
bsdf->N = N;
bsdf->roughness = FLT_MAX;
sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_LAMBERT_EXIT);
}
}
else {
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), weight);
if (bsdf) {
bsdf->N = N;
sd->flag |= bsdf_diffuse_setup(bsdf);
}
if (bsdf) {
bsdf->N = N;
sd->flag |= bsdf_diffuse_setup(bsdf);
}
}

View File

@ -1011,7 +1011,7 @@ ccl_device Spectrum surface_shader_diffuse(KernelGlobals kg, ccl_private const S
ccl_private const ShaderClosure *sc = &sd->closure[i];
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type) || CLOSURE_IS_BSSRDF(sc->type))
eval += bsdf_albedo(sd, sc, true, true);
eval += bsdf_albedo(kg, sd, sc, true, true);
}
return eval;
@ -1025,7 +1025,7 @@ ccl_device Spectrum surface_shader_glossy(KernelGlobals kg, ccl_private const Sh
ccl_private const ShaderClosure *sc = &sd->closure[i];
if (CLOSURE_IS_BSDF_GLOSSY(sc->type) || CLOSURE_IS_GLASS(sc->type))
eval += bsdf_albedo(sd, sc, true, false);
eval += bsdf_albedo(kg, sd, sc, true, false);
}
return eval;
@ -1039,7 +1039,7 @@ ccl_device Spectrum surface_shader_transmission(KernelGlobals kg, ccl_private co
ccl_private const ShaderClosure *sc = &sd->closure[i];
if (CLOSURE_IS_BSDF_TRANSMISSION(sc->type) || CLOSURE_IS_GLASS(sc->type))
eval += bsdf_albedo(sd, sc, false, true);
eval += bsdf_albedo(kg, sd, sc, false, true);
}
return eval;

View File

@ -55,6 +55,14 @@ static_assert(sizeof(ShaderGlobals) == sizeof(OSL::ShaderGlobals) &&
#include "closures_template.h"
static OSL::ClosureParam *osl_closure_layer_params()
{
static OSL::ClosureParam params[] = {CLOSURE_CLOSURE_PARAM(LayerClosure, top),
CLOSURE_CLOSURE_PARAM(LayerClosure, base),
CLOSURE_FINISH_PARAM(LayerClosure)};
return params;
}
void OSLRenderServices::register_closures(OSL::ShadingSystem *ss)
{
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
@ -62,6 +70,8 @@ void OSLRenderServices::register_closures(OSL::ShadingSystem *ss)
#lower, OSL_CLOSURE_##Upper##_ID, osl_closure_##lower##_params(), nullptr, nullptr);
#include "closures_template.h"
ss->register_closure(
"layer", OSL_CLOSURE_LAYER_ID, osl_closure_layer_params(), nullptr, nullptr);
}
/* Surface & Background */

View File

@ -7,26 +7,9 @@
#pragma once
// clang-format off
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_util.h"
#include "kernel/closure/bsdf_ashikhmin_velvet.h"
#include "kernel/closure/bsdf_diffuse.h"
#include "kernel/closure/bsdf_microfacet.h"
#include "kernel/closure/bsdf_oren_nayar.h"
#include "kernel/closure/bsdf_sheen.h"
#include "kernel/closure/bsdf_transparent.h"
#include "kernel/closure/bsdf_ashikhmin_shirley.h"
#include "kernel/closure/bsdf_toon.h"
#include "kernel/closure/bsdf_hair.h"
#include "kernel/closure/bsdf_hair_principled.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/volume.h"
#include "kernel/closure/bsdf_diffuse_ramp.h"
#include "kernel/closure/bsdf_phong_ramp.h"
#include "kernel/closure/bssrdf.h"
#include "kernel/closure/bsdf.h"
#include "kernel/closure/emissive.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@ -42,6 +25,12 @@ CCL_NAMESPACE_BEGIN
#include "closures_template.h"
struct ccl_align(8) LayerClosure
{
ccl_private const OSLClosure *base;
ccl_private const OSLClosure *top;
};
ccl_device_forceinline bool osl_closure_skip(KernelGlobals kg,
ccl_private const ShaderData *sd,
uint32_t path_flag,
@ -65,7 +54,8 @@ ccl_device void osl_closure_diffuse_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const DiffuseClosure *closure)
ccl_private const DiffuseClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -86,7 +76,8 @@ ccl_device void osl_closure_oren_nayar_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const OrenNayarClosure *closure)
ccl_private const OrenNayarClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -108,7 +99,8 @@ ccl_device void osl_closure_translucent_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const TranslucentClosure *closure)
ccl_private const TranslucentClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -129,7 +121,8 @@ ccl_device void osl_closure_reflection_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const ReflectionClosure *closure)
ccl_private const ReflectionClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_SINGULAR)) {
return;
@ -151,7 +144,8 @@ ccl_device void osl_closure_refraction_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const RefractionClosure *closure)
ccl_private const RefractionClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_SINGULAR)) {
return;
@ -174,7 +168,8 @@ ccl_device void osl_closure_transparent_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const TransparentClosure *closure)
ccl_private const TransparentClosure *closure,
float3 *layer_albedo)
{
bsdf_transparent_setup(sd, rgb_to_spectrum(weight), path_flag);
}
@ -184,7 +179,8 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const DielectricBSDFClosure *closure)
ccl_private const DielectricBSDFClosure *closure,
float3 *layer_albedo)
{
const bool has_reflection = !is_zero(closure->reflection_tint);
const bool has_transmission = !is_zero(closure->transmission_tint);
@ -243,13 +239,18 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg,
fresnel->reflection_tint = rgb_to_spectrum(closure->reflection_tint);
fresnel->transmission_tint = rgb_to_spectrum(closure->transmission_tint);
bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, preserve_energy);
if (layer_albedo != NULL && has_reflection && !has_transmission) {
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
}
}
ccl_device void osl_closure_conductor_bsdf_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const ConductorBSDFClosure *closure)
ccl_private const ConductorBSDFClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
@ -295,7 +296,8 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const GeneralizedSchlickBSDFClosure *closure)
ccl_private const GeneralizedSchlickBSDFClosure *closure,
float3 *layer_albedo)
{
const bool has_reflection = !is_zero(closure->reflection_tint);
const bool has_transmission = !is_zero(closure->transmission_tint);
@ -319,11 +321,21 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = ior_from_F0(average(closure->f0));
bsdf->T = closure->T;
if (closure->exponent < 0.0f) {
/* Trick for principled BSDF: Since we use the real Fresnel equation and remap
* to the F0...F90 range, this allows us to use the real IOR.
* Computing it back from F0 might give a different result in case of specular
* tinting. */
bsdf->ior = -closure->exponent;
}
else {
bsdf->ior = ior_from_F0(average(closure->f0));
}
if (sd->flag & SD_BACKFACING) {
bsdf->ior = 1.0f / bsdf->ior;
}
bsdf->T = closure->T;
bool preserve_energy = false;
@ -360,6 +372,10 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup(
fresnel->f90 = rgb_to_spectrum(closure->f90);
fresnel->exponent = closure->exponent;
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy);
if (layer_albedo != NULL && has_reflection && !has_transmission) {
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
}
}
/* Standard microfacet closures */
@ -368,7 +384,8 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetClosure *closure)
ccl_private const MicrofacetClosure *closure,
float3 *layer_albedo)
{
const int label = (closure->refract) ? LABEL_TRANSMIT : LABEL_REFLECT;
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | label)) {
@ -405,7 +422,7 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
}
/* Clearcoat */
else if (closure->distribution == make_string("clearcoat", 3490136178980547276ull)) {
sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(kg, bsdf, sd);
}
/* GGX (either single- or multi-scattering) */
else {
@ -424,6 +441,10 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(weight));
}
}
if (layer_albedo != NULL && closure->refract == 0) {
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
}
}
/* Special-purpose Microfacet closures */
@ -433,7 +454,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_glass_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXGlassClosure *closure)
ccl_private const MicrofacetMultiGGXGlassClosure *closure,
float3 *layer_albedo)
{
/* Technically, the MultiGGX closure may also transmit. However,
* since this is set statically and only used for caustic flags, this
@ -464,7 +486,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetMultiGGXClosure *closure)
ccl_private const MicrofacetMultiGGXClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
@ -485,49 +508,10 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup(
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(closure->color));
}
ccl_device void osl_closure_microfacet_aniso_fresnel_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetAnisoFresnelClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
if (layer_albedo != NULL) {
*layer_albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *)
closure_alloc_extra(sd, sizeof(FresnelGeneralizedSchlick));
if (!fresnel) {
return;
}
bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = closure->ior;
bsdf->T = closure->T;
/* Only GGX (either single- or multi-scattering) supported here */
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
const bool preserve_energy = (closure->distribution ==
make_string("multi_ggx", 16842698693386468366ull));
fresnel->reflection_tint = one_spectrum();
fresnel->transmission_tint = zero_spectrum();
fresnel->f0 = rgb_to_spectrum(closure->f0);
fresnel->f90 = rgb_to_spectrum(closure->f90);
fresnel->exponent = -1.0f;
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy);
}
/* Ashikhmin Velvet */
@ -537,7 +521,8 @@ ccl_device void osl_closure_ashikhmin_velvet_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const AshikhminVelvetClosure *closure)
ccl_private const AshikhminVelvetClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -561,7 +546,8 @@ ccl_device void osl_closure_sheen_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const SheenClosure *closure)
ccl_private const SheenClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -577,13 +563,18 @@ ccl_device void osl_closure_sheen_setup(KernelGlobals kg,
bsdf->roughness = closure->roughness;
sd->flag |= bsdf_sheen_setup(kg, sd, bsdf);
if (layer_albedo != NULL) {
*layer_albedo = bsdf->weight;
}
}
ccl_device void osl_closure_diffuse_toon_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const DiffuseToonClosure *closure)
ccl_private const DiffuseToonClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
@ -606,7 +597,8 @@ ccl_device void osl_closure_glossy_toon_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const GlossyToonClosure *closure)
ccl_private const GlossyToonClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
return;
@ -625,31 +617,6 @@ ccl_device void osl_closure_glossy_toon_setup(KernelGlobals kg,
sd->flag |= bsdf_glossy_toon_setup(bsdf);
}
/* Disney principled closures */
ccl_device void osl_closure_principled_diffuse_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const PrincipledDiffuseClosure *closure)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) {
return;
}
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc(
sd, sizeof(PrincipledDiffuseBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
bsdf->N = closure->N;
bsdf->roughness = closure->roughness;
sd->flag |= bsdf_principled_diffuse_setup(bsdf);
}
/* Variable cone emissive closure
*
* This primitive emits in a cone having a configurable penumbra area where the light decays to 0
@ -660,7 +627,8 @@ ccl_device void osl_closure_emission_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t /* path_flag */,
float3 weight,
ccl_private const GenericEmissiveClosure *closure)
ccl_private const GenericEmissiveClosure *closure,
float3 *layer_albedo)
{
emission_setup(sd, rgb_to_spectrum(weight));
}
@ -674,7 +642,8 @@ ccl_device void osl_closure_background_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t /* path_flag */,
float3 weight,
ccl_private const GenericBackgroundClosure *closure)
ccl_private const GenericBackgroundClosure *closure,
float3 *layer_albedo)
{
background_setup(sd, rgb_to_spectrum(weight));
}
@ -688,7 +657,8 @@ ccl_device void osl_closure_holdout_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t /* path_flag */,
float3 weight,
ccl_private const HoldoutClosure *closure)
ccl_private const HoldoutClosure *closure,
float3 *layer_albedo)
{
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight));
sd->flag |= SD_HOLDOUT;
@ -698,7 +668,8 @@ ccl_device void osl_closure_diffuse_ramp_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t /* path_flag */,
float3 weight,
ccl_private const DiffuseRampClosure *closure)
ccl_private const DiffuseRampClosure *closure,
float3 *layer_albedo)
{
ccl_private DiffuseRampBsdf *bsdf = (ccl_private DiffuseRampBsdf *)bsdf_alloc(
sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight));
@ -724,7 +695,8 @@ ccl_device void osl_closure_phong_ramp_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t /* path_flag */,
float3 weight,
ccl_private const PhongRampClosure *closure)
ccl_private const PhongRampClosure *closure,
float3 *layer_albedo)
{
ccl_private PhongRampBsdf *bsdf = (ccl_private PhongRampBsdf *)bsdf_alloc(
sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight));
@ -750,7 +722,8 @@ ccl_device void osl_closure_bssrdf_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const BSSRDFClosure *closure)
ccl_private const BSSRDFClosure *closure,
float3 *layer_albedo)
{
ClosureType type;
if (closure->method == make_string("burley", 186330084368958868ull)) {
@ -796,7 +769,8 @@ ccl_device void osl_closure_hair_reflection_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const HairReflectionClosure *closure)
ccl_private const HairReflectionClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
return;
@ -822,7 +796,8 @@ ccl_device void osl_closure_hair_transmission_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const HairTransmissionClosure *closure)
ccl_private const HairTransmissionClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
return;
@ -847,7 +822,8 @@ ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const PrincipledHairClosure *closure)
ccl_private const PrincipledHairClosure *closure,
float3 *layer_albedo)
{
#ifdef __HAIR__
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
@ -886,7 +862,8 @@ ccl_device void osl_closure_absorption_setup(KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const VolumeAbsorptionClosure *closure)
ccl_private const VolumeAbsorptionClosure *closure,
float3 *layer_albedo)
{
volume_extinction_setup(sd, rgb_to_spectrum(weight));
}
@ -896,7 +873,8 @@ ccl_device void osl_closure_henyey_greenstein_setup(
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const VolumeHenyeyGreensteinClosure *closure)
ccl_private const VolumeHenyeyGreensteinClosure *closure,
float3 *layer_albedo)
{
volume_extinction_setup(sd, rgb_to_spectrum(weight));

View File

@ -99,17 +99,6 @@ OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx_aniso)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx_aniso)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetAnisoFresnel, microfacet_aniso_fresnel)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, f0, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, f90, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, ior, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, STRING, DeviceString, distribution, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetAnisoFresnel, microfacet_aniso_fresnel)
OSL_CLOSURE_STRUCT_BEGIN(AshikhminVelvet, ashikhmin_velvet)
OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, FLOAT, float, sigma, NULL)
@ -132,11 +121,6 @@ OSL_CLOSURE_STRUCT_BEGIN(GlossyToon, glossy_toon)
OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, smooth, NULL)
OSL_CLOSURE_STRUCT_END(GlossyToon, glossy_toon)
OSL_CLOSURE_STRUCT_BEGIN(PrincipledDiffuse, principled_diffuse)
OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, FLOAT, float, roughness, NULL)
OSL_CLOSURE_STRUCT_END(PrincipledDiffuse, principled_diffuse)
OSL_CLOSURE_STRUCT_BEGIN(GenericEmissive, emission)
OSL_CLOSURE_STRUCT_END(GenericEmissive, emission)

View File

@ -70,6 +70,8 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
float3 weight = one_float3();
float3 weight_stack[16];
ccl_private const OSLClosure *closure_stack[16];
int layer_stack_level = -1;
float3 layer_albedo = zero_float3();
brecht marked this conversation as resolved Outdated

Typically better for the GPU compiler to initialize this.

Typically better for the GPU compiler to initialize this.
while (closure) {
switch (closure->id) {
@ -92,15 +94,39 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
closure_stack[stack_size++] = add->closureB;
continue;
}
case OSL_CLOSURE_LAYER_ID: {
ccl_private const OSLClosureComponent *comp =
static_cast<ccl_private const OSLClosureComponent *>(closure);
ccl_private const LayerClosure *layer = reinterpret_cast<ccl_private const LayerClosure *>(
comp + 1);
/* Layer closures may not appear in the top layer subtree of another layer closure. */
kernel_assert(layer_stack_level == -1);
/* Push base layer onto the stack, will be handled after the top layers */
weight_stack[stack_size] = weight;
closure_stack[stack_size] = layer->base;
/* Start accumulating albedo of the top layers */
layer_stack_level = stack_size++;
layer_albedo = zero_float3();
/* Continue with the top layers */
closure = layer->top;
continue;
}
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
case OSL_CLOSURE_##Upper##_ID: { \
ccl_private const OSLClosureComponent *comp = \
static_cast<ccl_private const OSLClosureComponent *>(closure); \
float3 albedo = one_float3(); \
osl_closure_##lower##_setup(kg, \
sd, \
path_flag, \
weight * comp->weight, \
reinterpret_cast<ccl_private const Upper##Closure *>(comp + 1)); \
reinterpret_cast<ccl_private const Upper##Closure *>(comp + 1), \
(layer_stack_level >= 0) ? &albedo : NULL); \
if (layer_stack_level >= 0) { \
layer_albedo += albedo; \
} \
break; \
}
#include "closures_template.h"
@ -111,6 +137,23 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
if (stack_size > 0) {
weight = weight_stack[--stack_size];
closure = closure_stack[stack_size];
if (stack_size == layer_stack_level) {
/* We just finished processing the top layers of a Layer closure, so adjust the weight to
* account for the layering. */
weight *= saturatef(1.0f - reduce_max(layer_albedo / weight));
layer_stack_level = -1;
brecht marked this conversation as resolved Outdated

Is this still intended to be resolved?

Is this still intended to be resolved?

Yep, resolved now. I had tried to find a way to not repeat the stack popping code, but didn't come up with anything.

Yep, resolved now. I had tried to find a way to not repeat the stack popping code, but didn't come up with anything.
if (is_zero(weight)) {
/* If it's fully occluded, skip the base layer we just popped from the stack and grab
* the next entry instead. */
if (stack_size > 0) {
weight = weight_stack[--stack_size];
closure = closure_stack[stack_size];
}
else {
closure = nullptr;
}
}
}
}
else {
closure = nullptr;

View File

@ -31,74 +31,80 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
normal Tangent = normalize(dPdu),
output closure color BSDF = 0)
{
float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transmission, 0.0, 1.0));
float final_transmission = clamp(Transmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
float specular_weight = (1.0 - final_transmission);
float r2 = Roughness * Roughness;
float alpha_x = r2, alpha_y = r2;
/* Handle anisotropy. */
vector T = Tangent;
if (Anisotropic > 0.0) {
float aspect = sqrt(1.0 - clamp(Anisotropic, 0.0, 1.0) * 0.9);
alpha_x /= aspect;
alpha_y *= aspect;
if (AnisotropicRotation != 0.0)
T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
}
float m_cdlum = luminance(BaseColor);
color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum :
color(1.0, 1.0, 1.0); // normalize lum. to isolate hue+sat
/* rotate tangent */
if (AnisotropicRotation != 0.0)
T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
if (diffuse_weight > 1e-5) {
if (Metallic < 1.0 && Transmission < 1.0) {
color diffuse_color = mix(BaseColor, SubsurfaceColor, Subsurface);
if (Subsurface > 1e-5) {
color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface);
BSDF = mixed_ss_base_color * bssrdf(subsurface_method,
Normal,
Subsurface * SubsurfaceRadius,
mixed_ss_base_color,
"roughness",
Roughness,
"ior",
SubsurfaceIOR,
"anisotropy",
SubsurfaceAnisotropy);
BSDF = diffuse_color * bssrdf(subsurface_method,
Normal,
Subsurface * SubsurfaceRadius,
diffuse_color,
"roughness",
Roughness,
"ior",
SubsurfaceIOR,
"anisotropy",
SubsurfaceAnisotropy);
}
else {
BSDF = BaseColor * principled_diffuse(Normal, Roughness);
BSDF = diffuse_color * diffuse(Normal);
}
if (Sheen > 1e-5) {
BSDF += SheenTint * Sheen * sheen(Normal, SheenRoughness);
}
color f0 = color(F0_from_ior(IOR));
color f90 = color(1.0);
BSDF *= diffuse_weight;
/* Apply specular tint */
float m_cdlum = luminance(BaseColor);
color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum : color(1.0);
color specTint = mix(color(1.0), m_ctint, SpecularTint);
f0 *= (specTint * 2.0 * Specular);
BSDF = layer(
generalized_schlick_bsdf(
Normal, T, color(1.0), color(0.0), alpha_x, alpha_y, f0, f90, -IOR, distribution),
BSDF);
}
if (specular_weight > 1e-5) {
float aspect = sqrt(1.0 - Anisotropic * 0.9);
float alpha_x = r2 / aspect;
float alpha_y = r2 * aspect;
color tmp_col = mix(color(1.0), m_ctint, SpecularTint);
color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic;
float eta = (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0;
string spec_dist = (Roughness <= 0.075) ? "ggx" : distribution;
BSDF += specular_weight * microfacet_aniso_fresnel(
Normal, T, alpha_x, alpha_y, Cspec0, color(1.0), eta, spec_dist);
}
if (final_transmission > 1e-5) {
color Cspec0 = mix(color(1.0), BaseColor, SpecularTint);
closure color TransmissionBSDF = 0;
if (Metallic < 1.0 && Transmission > 1.0) {
color reflectTint = mix(color(1.0), BaseColor, SpecularTint);
float eta = max(IOR, 1e-5);
eta = backfacing() ? 1.0 / eta : eta;
BSDF += final_transmission *
dielectric_bsdf(Normal, vector(0.0), Cspec0, BaseColor, r2, r2, eta, distribution);
TransmissionBSDF = dielectric_bsdf(
Normal, vector(0.0), reflectTint, BaseColor, r2, r2, eta, distribution);
BSDF = mix(BSDF, TransmissionBSDF, clamp(Transmission, 0.0, 1.0));
}
closure color MetallicBSDF = 0;
if (Metallic > 0.0) {
color f0 = BaseColor;
color f90 = color(1.0);
MetallicBSDF = generalized_schlick_bsdf(
Normal, T, color(1.0), color(0.0), alpha_x, alpha_y, f0, f90, 5.0, distribution);
BSDF = mix(BSDF, MetallicBSDF, clamp(Metallic, 0.0, 1.0));
}
if (Clearcoat > 1e-5) {
float clearcoat_r2 = ClearcoatRoughness * ClearcoatRoughness;
BSDF += 0.25 * Clearcoat * microfacet("clearcoat", ClearcoatNormal, clearcoat_r2, 1.5, 0);
closure color ClearcoatBSDF = microfacet("clearcoat", ClearcoatNormal, clearcoat_r2, 1.5, 0);
BSDF = layer(0.25 * Clearcoat * ClearcoatBSDF, BSDF);
}
if (Sheen > 1e-5) {
closure color SheenBSDF = sheen(Normal, SheenRoughness);
BSDF = layer(SheenTint * Sheen * SheenBSDF, BSDF);
}
}

View File

@ -25,16 +25,11 @@ closure color glossy_toon(normal N, float size, float smooth) BUILTIN;
closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
closure color sheen(normal N, float roughness) BUILTIN;
closure color ambient_occlusion() BUILTIN;
closure color principled_diffuse(normal N, float roughness) BUILTIN;
/* Needed to pass along the color for multi-scattering saturation adjustment,
* otherwise could be replaced by microfacet() */
closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN;
closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN;
/* Needed to pass along the IOR for the Principled V1 Fresnel calculation,
* otherwise could be replaced by generalized_schlick_bsdf() */
closure color microfacet_aniso_fresnel(
normal N, vector T, float ax, float ay, color f0, color f90, float eta, string dist) BUILTIN;
// BSSRDF
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN;

View File

@ -39,6 +39,7 @@ enum OSLClosureType {
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) OSL_CLOSURE_##Upper##_ID,
#include "closures_template.h"
OSL_CLOSURE_LAYER_ID,
};
struct OSLClosure {

View File

@ -88,7 +88,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
data_node2.x, &eta_offset, &transmission_offset, &anisotropic_rotation_offset, &pad1);
// get Disney principled parameters
float metallic = param1;
float metallic = saturatef(param1);
float subsurface = param2;
float specular = stack_load_float(stack, specular_offset);
float roughness = stack_load_float(stack, roughness_offset);
@ -99,25 +99,15 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
float sheen_roughness = stack_load_float(stack, data_node2.w);
float clearcoat = stack_load_float(stack, clearcoat_offset);
float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset);
float transmission = stack_load_float(stack, transmission_offset);
float transmission = saturatef(stack_load_float(stack, transmission_offset));
float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
ClosureType distribution = (ClosureType)data_node2.y;
ClosureType subsurface_method = (ClosureType)data_node2.z;
/* rotate tangent */
if (anisotropic_rotation != 0.0f)
T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
float3 valid_reflection_N = maybe_ensure_valid_specular_reflection(sd, N);
// calculate weights of the diffuse and specular part
float diffuse_weight = (1.0f - saturatef(metallic)) * (1.0f - saturatef(transmission));
float final_transmission = saturatef(transmission) * (1.0f - saturatef(metallic));
float specular_weight = (1.0f - final_transmission);
// get the base color
uint4 data_base_color = read_node(kg, &offset);
float3 base_color = stack_valid(data_base_color.x) ?
@ -151,45 +141,178 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
Spectrum weight = closure_weight * mix_weight;
#ifdef __SUBSURFACE__
float3 mixed_ss_base_color = subsurface_color * subsurface +
base_color * (1.0f - subsurface);
Spectrum subsurf_weight = weight * rgb_to_spectrum(mixed_ss_base_color) * diffuse_weight;
float alpha_x = sqr(roughness), alpha_y = sqr(roughness);
if (anisotropic > 0.0f) {
float aspect = sqrtf(1.0f - saturatef(anisotropic) * 0.9f);
alpha_x /= aspect;
alpha_y *= aspect;
if (anisotropic_rotation != 0.0f)
T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
}
#ifdef __CAUSTICS_TRICKS__
const bool reflective_caustics = (kernel_data.integrator.caustics_reflective ||
(path_flag & PATH_RAY_DIFFUSE) == 0);
const bool glass_caustics = (kernel_data.integrator.caustics_reflective ||
kernel_data.integrator.caustics_refractive ||
(path_flag & PATH_RAY_DIFFUSE) == 0);
#else
const bool reflective_caustics = true;
const bool glass_caustics = true;
#endif
/* First layer: Sheen */
if (sheen > CLOSURE_WEIGHT_CUTOFF) {
ccl_private SheenBsdf *bsdf = (ccl_private SheenBsdf *)bsdf_alloc(
sd, sizeof(SheenBsdf), sheen * rgb_to_spectrum(sheen_tint) * weight);
if (bsdf) {
bsdf->N = N;
bsdf->roughness = sheen_roughness;
/* setup bsdf */
sd->flag |= bsdf_sheen_setup(kg, sd, bsdf);
/* Attenuate lower layers */
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
weight *= 1.0f - reduce_max(albedo / weight);
}
}
/* Second layer: Clearcoat */
if (reflective_caustics && clearcoat > CLOSURE_WEIGHT_CUTOFF) {
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), 0.25f * clearcoat * weight);
if (bsdf) {
bsdf->N = clearcoat_normal;
bsdf->T = zero_float3();
bsdf->ior = 1.5f;
bsdf->alpha_x = bsdf->alpha_y = sqr(clearcoat_roughness);
/* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(kg, bsdf, sd);
/* Attenuate lower layers */
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
weight *= 1.0f - reduce_max(albedo / weight);
}
}
/* Metallic component */
if (reflective_caustics && metallic > CLOSURE_WEIGHT_CUTOFF) {
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), metallic * weight);
ccl_private FresnelGeneralizedSchlick *fresnel =
(bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra(
sd, sizeof(FresnelGeneralizedSchlick)) :
NULL;
if (bsdf && fresnel) {
bsdf->N = valid_reflection_N;
bsdf->ior = 1.0f;
bsdf->T = T;
bsdf->alpha_x = alpha_x;
bsdf->alpha_y = alpha_y;
fresnel->f0 = rgb_to_spectrum(base_color);
fresnel->f90 = one_spectrum();
fresnel->exponent = 5.0f;
fresnel->reflection_tint = one_spectrum();
fresnel->transmission_tint = zero_spectrum();
/* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
/* Attenuate other components */
weight *= (1.0f - metallic);
}
}
/* Transmission component */
if (glass_caustics && transmission > CLOSURE_WEIGHT_CUTOFF) {
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), transmission * weight);
ccl_private FresnelDielectricTint *fresnel =
(bsdf != NULL) ? (ccl_private FresnelDielectricTint *)closure_alloc_extra(
sd, sizeof(FresnelDielectricTint)) :
NULL;
if (bsdf && fresnel) {
bsdf->N = valid_reflection_N;
bsdf->T = zero_float3();
bsdf->alpha_x = bsdf->alpha_y = sqr(roughness);
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
fresnel->reflection_tint = mix(
one_spectrum(), rgb_to_spectrum(base_color), specular_tint);
fresnel->transmission_tint = rgb_to_spectrum(base_color);
/* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, is_multiggx);
/* Attenuate other components */
weight *= (1.0f - transmission);
}
}
/* Specular component */
if (reflective_caustics) {
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), weight);
ccl_private FresnelGeneralizedSchlick *fresnel =
(bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra(
sd, sizeof(FresnelGeneralizedSchlick)) :
NULL;
if (bsdf && fresnel) {
bsdf->N = valid_reflection_N;
bsdf->ior = eta;
bsdf->T = T;
bsdf->alpha_x = alpha_x;
bsdf->alpha_y = alpha_y;
float m_cdlum = linear_rgb_to_gray(kg, base_color);
float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : one_float3();
float3 specTint = mix(one_spectrum(), rgb_to_spectrum(m_ctint), specular_tint);
fresnel->f0 = F0_from_ior(eta) * 2.0f * specular * specTint;
fresnel->f90 = one_spectrum();
fresnel->exponent = -eta;
fresnel->reflection_tint = one_spectrum();
fresnel->transmission_tint = zero_spectrum();
/* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
/* Attenuate lower layers */
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
weight *= 1.0f - reduce_max(albedo / weight);
}
}
/* Diffuse component */
float3 diffuse_color = mix(base_color, subsurface_color, subsurface);
#ifdef __SUBSURFACE__
/* disable in case of diffuse ancestor, can't see it well then and
* adds considerably noise due to probabilities of continuing path
* getting lower and lower */
if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
subsurface = 0.0f;
/* need to set the base color in this case such that the
* rays get the correctly mixed color after transmitting
* the object */
base_color = mixed_ss_base_color;
}
/* diffuse */
if (fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) {
if (subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
Spectrum diff_weight = weight * rgb_to_spectrum(base_color) * diffuse_weight;
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)
bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
if (bsdf) {
bsdf->N = N;
bsdf->roughness = roughness;
/* setup bsdf */
sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_FULL);
}
}
else if (subsurface > CLOSURE_WEIGHT_CUTOFF) {
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight);
if ((subsurface > CLOSURE_WEIGHT_CUTOFF) && !(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)) {
/* Skip in case of extremely low albedo. */
if (fabsf(average(diffuse_color)) > CLOSURE_WEIGHT_CUTOFF) {
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(diffuse_color) * weight);
if (bssrdf) {
bssrdf->radius = rgb_to_spectrum(subsurface_radius * subsurface);
bssrdf->albedo = rgb_to_spectrum(mixed_ss_base_color);
bssrdf->albedo = rgb_to_spectrum(diffuse_color);
bssrdf->N = N;
bssrdf->roughness = roughness;
@ -202,149 +325,19 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
}
}
}
#else
/* diffuse */
if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
Spectrum diff_weight = weight * rgb_to_spectrum(base_color) * diffuse_weight;
ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc(
sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
if (bsdf) {
bsdf->N = N;
bsdf->roughness = roughness;
/* setup bsdf */
sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_FULL);
}
}
else
#endif
/* sheen */
if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
Spectrum sheen_weight = weight * sheen * rgb_to_spectrum(sheen_tint) * diffuse_weight;
ccl_private SheenBsdf *bsdf = (ccl_private SheenBsdf *)bsdf_alloc(
sd, sizeof(SheenBsdf), sheen_weight);
if (bsdf) {
bsdf->N = N;
bsdf->roughness = sheen_roughness;
/* setup bsdf */
sd->flag |= bsdf_sheen_setup(kg, sd, bsdf);
}
}
/* specular reflection */
#ifdef __CAUSTICS_TRICKS__
if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
#endif
if (specular_weight > CLOSURE_WEIGHT_CUTOFF &&
(specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF))
{
Spectrum spec_weight = weight * specular_weight;
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), spec_weight);
ccl_private FresnelGeneralizedSchlick *fresnel =
(bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra(
sd, sizeof(FresnelGeneralizedSchlick)) :
NULL;
if (bsdf && fresnel) {
bsdf->N = valid_reflection_N;
bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
bsdf->T = T;
float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f);
float r2 = roughness * roughness;
bsdf->alpha_x = r2 / aspect;
bsdf->alpha_y = r2 * aspect;
float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y +
0.1f * base_color.z; // luminance approx.
float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum :
one_float3(); // normalize lum. to isolate hue+sat
float3 tmp_col = make_float3(1.0f - specular_tint) + m_ctint * specular_tint;
fresnel->f0 = rgb_to_spectrum((specular * 0.08f * tmp_col) * (1.0f - metallic) +
base_color * metallic);
fresnel->f90 = one_spectrum();
fresnel->exponent = -1.0f;
fresnel->reflection_tint = one_spectrum();
fresnel->transmission_tint = zero_spectrum();
/* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
}
}
#ifdef __CAUSTICS_TRICKS__
}
#endif
/* Transmission */
#ifdef __CAUSTICS_TRICKS__
if (kernel_data.integrator.caustics_reflective ||
kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
{
#endif
if (final_transmission > CLOSURE_WEIGHT_CUTOFF) {
Spectrum glass_weight = weight * final_transmission;
Spectrum cspec0 = base_color * specular_tint + make_float3(1.0f - specular_tint);
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), glass_weight);
ccl_private FresnelDielectricTint *fresnel =
(bsdf != NULL) ? (ccl_private FresnelDielectricTint *)closure_alloc_extra(
sd, sizeof(FresnelDielectricTint)) :
NULL;
if (bsdf && fresnel) {
bsdf->N = valid_reflection_N;
bsdf->T = zero_float3();
bsdf->alpha_x = bsdf->alpha_y = sqr(roughness);
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
fresnel->reflection_tint = cspec0;
fresnel->transmission_tint = base_color;
/* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, is_multiggx);
}
}
#ifdef __CAUSTICS_TRICKS__
}
#endif
/* clearcoat */
#ifdef __CAUSTICS_TRICKS__
if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
#endif
Spectrum clearcoat_weight = 0.25f * clearcoat * weight;
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), clearcoat_weight);
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), rgb_to_spectrum(diffuse_color) * weight);
if (bsdf) {
bsdf->N = clearcoat_normal;
bsdf->T = zero_float3();
bsdf->ior = 1.5f;
bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness;
bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness;
bsdf->N = N;
/* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
sd->flag |= bsdf_diffuse_setup(bsdf);
}
#ifdef __CAUSTICS_TRICKS__
}
#endif
break;
}

View File

@ -415,7 +415,6 @@ typedef enum ClosureType {
CLOSURE_BSDF_DIFFUSE_ID,
CLOSURE_BSDF_OREN_NAYAR_ID,
CLOSURE_BSDF_DIFFUSE_RAMP_ID,
CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID,
CLOSURE_BSDF_SHEEN_ID,
CLOSURE_BSDF_DIFFUSE_TOON_ID,
CLOSURE_BSDF_TRANSLUCENT_ID,

View File

@ -289,10 +289,9 @@ enum PathRayFlag : uint32_t {
/* Perform subsurface scattering. */
PATH_RAY_SUBSURFACE_RANDOM_WALK = (1U << 21U),
PATH_RAY_SUBSURFACE_DISK = (1U << 22U),
PATH_RAY_SUBSURFACE_USE_FRESNEL = (1U << 23U),
PATH_RAY_SUBSURFACE_BACKFACING = (1U << 24U),
PATH_RAY_SUBSURFACE = (PATH_RAY_SUBSURFACE_RANDOM_WALK | PATH_RAY_SUBSURFACE_DISK |
PATH_RAY_SUBSURFACE_USE_FRESNEL | PATH_RAY_SUBSURFACE_BACKFACING),
PATH_RAY_SUBSURFACE_BACKFACING),
/* Contribute to denoising features. */
PATH_RAY_DENOISING_FEATURES = (1U << 25U),
@ -1233,6 +1232,10 @@ typedef struct KernelTables {
int ggx_glass_inv_E;
int ggx_glass_inv_Eavg;
int sheen_ltc;
int ggx_gen_schlick_ior_s;
int ggx_gen_schlick_s;
int pad1;
int pad2;
} KernelTables;
static_assert_align(KernelTables, 16);

View File

@ -588,6 +588,8 @@ void ShaderManager::device_update_common(Device * /*device*/,
ktables->ggx_glass_inv_E = ensure_bsdf_table(dscene, scene, table_ggx_glass_inv_E);
ktables->ggx_glass_inv_Eavg = ensure_bsdf_table(dscene, scene, table_ggx_glass_inv_Eavg);
ktables->sheen_ltc = ensure_bsdf_table(dscene, scene, table_sheen_ltc);
ktables->ggx_gen_schlick_ior_s = ensure_bsdf_table(dscene, scene, table_ggx_gen_schlick_ior_s);
ktables->ggx_gen_schlick_s = ensure_bsdf_table(dscene, scene, table_ggx_gen_schlick_s);
/* integrator */
KernelIntegrator *kintegrator = &dscene->data.integrator;

View File

@ -734,4 +734,552 @@ static const float table_sheen_ltc[3072] = {
0.74973f, 0.73527f, 0.71668f, 0.69953f, 0.68291f, 0.66623f, 0.64940f, 0.63212f, 0.61545f, 0.59849f, 0.58226f, 0.56605f, 0.55034f, 0.53461f, 0.51974f, 0.50561f, 0.49191f, 0.47875f, 0.46632f, 0.45401f, 0.44209f, 0.43044f, 0.42005f, 0.40990f, 0.39997f, 0.39069f, 0.38171f, 0.37342f, 0.36523f, 0.35675f, 0.34897f, 0.34187f
};
static const float table_ggx_gen_schlick_ior_s[4096] = {
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.996991f, 0.702628f, 0.395717f, 0.213165f, 0.116143f, 0.065649f, 0.038910f, 0.024263f, 0.015917f, 0.010967f, 0.007917f, 0.005975f, 0.004695f, 0.003829f, 0.003228f, 0.002800f,
0.144157f, 0.142998f, 0.128546f, 0.094809f, 0.061456f, 0.038366f, 0.024126f, 0.015592f, 0.010425f, 0.007219f, 0.005173f, 0.003825f, 0.002910f, 0.002269f, 0.001808f, 0.001470f,
0.028337f, 0.028427f, 0.028465f, 0.026456f, 0.021559f, 0.015898f, 0.011201f, 0.007809f, 0.005487f, 0.003919f, 0.002855f, 0.002122f, 0.001609f, 0.001242f, 0.000975f, 0.000776f,
0.007734f, 0.007767f, 0.007963f, 0.008077f, 0.007577f, 0.006414f, 0.005032f, 0.003793f, 0.002816f, 0.002089f, 0.001561f, 0.001179f, 0.000901f, 0.000698f, 0.000546f, 0.000433f,
0.002677f, 0.002688f, 0.002764f, 0.002890f, 0.002916f, 0.002715f, 0.002330f, 0.001887f, 0.001479f, 0.001142f, 0.000877f, 0.000676f, 0.000523f, 0.000409f, 0.000321f, 0.000255f,
0.001086f, 0.001090f, 0.001119f, 0.001182f, 0.001237f, 0.001226f, 0.001128f, 0.000973f, 0.000802f, 0.000644f, 0.000510f, 0.000401f, 0.000316f, 0.000249f, 0.000197f, 0.000157f,
0.000489f, 0.000490f, 0.000503f, 0.000532f, 0.000568f, 0.000586f, 0.000569f, 0.000518f, 0.000448f, 0.000373f, 0.000304f, 0.000245f, 0.000196f, 0.000157f, 0.000125f, 0.000100f,
0.000235f, 0.000236f, 0.000241f, 0.000256f, 0.000276f, 0.000293f, 0.000297f, 0.000283f, 0.000255f, 0.000221f, 0.000186f, 0.000153f, 0.000125f, 0.000101f, 0.000081f, 0.000066f,
0.000118f, 0.000118f, 0.000121f, 0.000128f, 0.000139f, 0.000151f, 0.000158f, 0.000157f, 0.000148f, 0.000132f, 0.000115f, 0.000097f, 0.000080f, 0.000066f, 0.000054f, 0.000044f,
0.000059f, 0.000060f, 0.000061f, 0.000065f, 0.000071f, 0.000079f, 0.000085f, 0.000088f, 0.000086f, 0.000079f, 0.000071f, 0.000062f, 0.000052f, 0.000044f, 0.000036f, 0.000030f,
0.000030f, 0.000030f, 0.000030f, 0.000032f, 0.000036f, 0.000041f, 0.000045f, 0.000049f, 0.000049f, 0.000047f, 0.000044f, 0.000039f, 0.000034f, 0.000029f, 0.000024f, 0.000020f,
0.000014f, 0.000014f, 0.000015f, 0.000016f, 0.000018f, 0.000021f, 0.000024f, 0.000026f, 0.000028f, 0.000028f, 0.000027f, 0.000024f, 0.000022f, 0.000019f, 0.000016f, 0.000014f,
0.000006f, 0.000006f, 0.000006f, 0.000007f, 0.000008f, 0.000010f, 0.000012f, 0.000014f, 0.000015f, 0.000016f, 0.000016f, 0.000015f, 0.000014f, 0.000012f, 0.000011f, 0.000009f,
0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000005f, 0.000006f, 0.000007f, 0.000008f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000007f, 0.000006f,
0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000004f, 0.000005f, 0.000005f, 0.000004f, 0.000004f, 0.000004f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
0.998473f, 0.807694f, 0.556943f, 0.364811f, 0.235556f, 0.153039f, 0.101299f, 0.068838f, 0.048247f, 0.034966f, 0.026230f, 0.020368f, 0.016351f, 0.013545f, 0.011547f, 0.010099f,
0.364253f, 0.360607f, 0.326245f, 0.253347f, 0.178389f, 0.121058f, 0.081838f, 0.056138f, 0.039424f, 0.028453f, 0.021135f, 0.016142f, 0.012660f, 0.010170f, 0.008347f, 0.006988f,
0.138936f, 0.138672f, 0.134753f, 0.120906f, 0.097734f, 0.073355f, 0.053206f, 0.038275f, 0.027723f, 0.020379f, 0.015261f, 0.011658f, 0.009080f, 0.007204f, 0.005812f, 0.004757f,
0.056933f, 0.056966f, 0.056798f, 0.054773f, 0.049150f, 0.040717f, 0.031880f, 0.024257f, 0.018282f, 0.013805f, 0.010514f, 0.008103f, 0.006326f, 0.005004f, 0.004007f, 0.003245f,
0.025156f, 0.025194f, 0.025402f, 0.025430f, 0.024418f, 0.021924f, 0.018461f, 0.014871f, 0.011699f, 0.009112f, 0.007089f, 0.005539f, 0.004356f, 0.003455f, 0.002762f, 0.002227f,
0.011869f, 0.011891f, 0.012050f, 0.012310f, 0.012340f, 0.011769f, 0.010556f, 0.008985f, 0.007380f, 0.005939f, 0.004734f, 0.003759f, 0.002990f, 0.002385f, 0.001913f, 0.001541f,
0.005892f, 0.005903f, 0.005996f, 0.006196f, 0.006387f, 0.006368f, 0.006021f, 0.005389f, 0.004618f, 0.003844f, 0.003144f, 0.002545f, 0.002051f, 0.001651f, 0.001330f, 0.001074f,
0.003027f, 0.003033f, 0.003084f, 0.003210f, 0.003373f, 0.003478f, 0.003435f, 0.003217f, 0.002874f, 0.002474f, 0.002078f, 0.001718f, 0.001406f, 0.001145f, 0.000930f, 0.000754f,
0.001583f, 0.001586f, 0.001614f, 0.001689f, 0.001802f, 0.001909f, 0.001956f, 0.001909f, 0.001774f, 0.001581f, 0.001366f, 0.001155f, 0.000962f, 0.000793f, 0.000651f, 0.000532f,
0.000827f, 0.000829f, 0.000845f, 0.000889f, 0.000961f, 0.001043f, 0.001105f, 0.001121f, 0.001082f, 0.000999f, 0.000890f, 0.000770f, 0.000654f, 0.000548f, 0.000455f, 0.000375f,
0.000423f, 0.000424f, 0.000433f, 0.000458f, 0.000503f, 0.000559f, 0.000612f, 0.000645f, 0.000648f, 0.000621f, 0.000571f, 0.000508f, 0.000441f, 0.000376f, 0.000316f, 0.000264f,
0.000205f, 0.000206f, 0.000210f, 0.000225f, 0.000252f, 0.000288f, 0.000328f, 0.000360f, 0.000377f, 0.000375f, 0.000357f, 0.000328f, 0.000292f, 0.000254f, 0.000217f, 0.000184f,
0.000090f, 0.000090f, 0.000092f, 0.000100f, 0.000116f, 0.000138f, 0.000165f, 0.000190f, 0.000208f, 0.000217f, 0.000215f, 0.000205f, 0.000188f, 0.000168f, 0.000147f, 0.000126f,
0.000032f, 0.000032f, 0.000033f, 0.000037f, 0.000045f, 0.000058f, 0.000074f, 0.000091f, 0.000107f, 0.000117f, 0.000122f, 0.000121f, 0.000116f, 0.000107f, 0.000096f, 0.000085f,
0.000006f, 0.000006f, 0.000007f, 0.000009f, 0.000013f, 0.000019f, 0.000027f, 0.000037f, 0.000047f, 0.000056f, 0.000062f, 0.000066f, 0.000066f, 0.000063f, 0.000059f, 0.000054f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000006f, 0.000010f, 0.000015f, 0.000020f, 0.000025f, 0.000029f, 0.000032f, 0.000033f, 0.000033f, 0.000032f,
0.998956f, 0.852188f, 0.639206f, 0.457138f, 0.320751f, 0.224500f, 0.158479f, 0.113696f, 0.083340f, 0.062639f, 0.048380f, 0.038439f, 0.031410f, 0.026372f, 0.022707f, 0.020006f,
0.499657f, 0.495240f, 0.454315f, 0.366984f, 0.273236f, 0.196358f, 0.139812f, 0.100283f, 0.073131f, 0.054486f, 0.041579f, 0.032506f, 0.026024f, 0.021299f, 0.017789f, 0.015137f,
0.252667f, 0.251959f, 0.243893f, 0.219151f, 0.179961f, 0.138766f, 0.103798f, 0.076941f, 0.057274f, 0.043149f, 0.033038f, 0.025759f, 0.020453f, 0.016528f, 0.013574f, 0.011308f,
0.130254f, 0.130159f, 0.128597f, 0.122171f, 0.108573f, 0.090097f, 0.071310f, 0.055103f, 0.042244f, 0.032454f, 0.025139f, 0.019698f, 0.015632f, 0.012567f, 0.010227f, 0.008416f,
0.068675f, 0.068694f, 0.068589f, 0.067288f, 0.063203f, 0.055930f, 0.046884f, 0.037891f, 0.030044f, 0.023645f, 0.018615f, 0.014729f, 0.011738f, 0.009435f, 0.007648f, 0.006251f,
0.036993f, 0.037023f, 0.037193f, 0.037233f, 0.036359f, 0.033897f, 0.029970f, 0.025360f, 0.020839f, 0.016849f, 0.013527f, 0.010841f, 0.008709f, 0.007023f, 0.005694f, 0.004639f,
0.020267f, 0.020290f, 0.020462f, 0.020763f, 0.020854f, 0.020265f, 0.018787f, 0.016619f, 0.014172f, 0.011796f, 0.009680f, 0.007881f, 0.006398f, 0.005193f, 0.004221f, 0.003439f,
0.011211f, 0.011226f, 0.011350f, 0.011630f, 0.011936f, 0.011996f, 0.011591f, 0.010695f, 0.009470f, 0.008127f, 0.006829f, 0.005662f, 0.004657f, 0.003813f, 0.003117f, 0.002547f,
0.006200f, 0.006209f, 0.006291f, 0.006497f, 0.006786f, 0.007019f, 0.007037f, 0.006758f, 0.006213f, 0.005506f, 0.004749f, 0.004017f, 0.003356f, 0.002779f, 0.002290f, 0.001881f,
0.003383f, 0.003389f, 0.003440f, 0.003579f, 0.003799f, 0.004035f, 0.004188f, 0.004179f, 0.003990f, 0.003658f, 0.003245f, 0.002808f, 0.002388f, 0.002005f, 0.001669f, 0.001381f,
0.001788f, 0.001792f, 0.001823f, 0.001912f, 0.002065f, 0.002253f, 0.002421f, 0.002512f, 0.002494f, 0.002370f, 0.002169f, 0.001926f, 0.001672f, 0.001428f, 0.001204f, 0.001007f,
0.000891f, 0.000892f, 0.000911f, 0.000966f, 0.001066f, 0.001200f, 0.001340f, 0.001451f, 0.001503f, 0.001485f, 0.001407f, 0.001288f, 0.001145f, 0.000998f, 0.000855f, 0.000725f,
0.000397f, 0.000398f, 0.000409f, 0.000441f, 0.000503f, 0.000591f, 0.000693f, 0.000789f, 0.000858f, 0.000887f, 0.000876f, 0.000830f, 0.000760f, 0.000679f, 0.000594f, 0.000512f,
0.000142f, 0.000143f, 0.000148f, 0.000166f, 0.000201f, 0.000253f, 0.000319f, 0.000389f, 0.000450f, 0.000492f, 0.000511f, 0.000506f, 0.000481f, 0.000443f, 0.000399f, 0.000352f,
0.000029f, 0.000029f, 0.000032f, 0.000040f, 0.000056f, 0.000083f, 0.000119f, 0.000161f, 0.000204f, 0.000241f, 0.000267f, 0.000281f, 0.000281f, 0.000271f, 0.000253f, 0.000231f,
0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000006f, 0.000014f, 0.000027f, 0.000045f, 0.000066f, 0.000090f, 0.000111f, 0.000129f, 0.000141f, 0.000147f, 0.000146f, 0.000140f,
0.999185f, 0.876362f, 0.688099f, 0.517114f, 0.380994f, 0.279131f, 0.205342f, 0.152757f, 0.115517f, 0.089136f, 0.070359f, 0.056895f, 0.047147f, 0.040017f, 0.034744f, 0.030800f,
0.581881f, 0.577319f, 0.534857f, 0.443347f, 0.342374f, 0.255721f, 0.188787f, 0.139839f, 0.104867f, 0.080030f, 0.062337f, 0.049600f, 0.040320f, 0.033445f, 0.028272f, 0.024319f,
0.340255f, 0.339275f, 0.328680f, 0.297273f, 0.248016f, 0.195634f, 0.150028f, 0.113925f, 0.086696f, 0.066616f, 0.051912f, 0.041119f, 0.033124f, 0.027128f, 0.022561f, 0.019022f,
0.200043f, 0.199809f, 0.196864f, 0.186398f, 0.165830f, 0.138700f, 0.111207f, 0.087246f, 0.067930f, 0.052973f, 0.041617f, 0.033047f, 0.026561f, 0.021615f, 0.017799f, 0.014817f,
0.118215f, 0.118181f, 0.117499f, 0.114304f, 0.106492f, 0.093917f, 0.078914f, 0.064205f, 0.051368f, 0.040839f, 0.032492f, 0.025984f, 0.020928f, 0.017001f, 0.013927f, 0.011502f,
0.070107f, 0.070125f, 0.070118f, 0.069451f, 0.066919f, 0.061704f, 0.054241f, 0.045869f, 0.037813f, 0.030744f, 0.024858f, 0.020081f, 0.016269f, 0.013235f, 0.010826f, 0.008901f,
0.041592f, 0.041617f, 0.041779f, 0.041922f, 0.041446f, 0.039654f, 0.036341f, 0.031946f, 0.027196f, 0.022673f, 0.018678f, 0.015289f, 0.012492f, 0.010209f, 0.008360f, 0.006863f,
0.024558f, 0.024579f, 0.024749f, 0.025085f, 0.025322f, 0.025001f, 0.023797f, 0.021732f, 0.019137f, 0.016395f, 0.013792f, 0.011470f, 0.009476f, 0.007801f, 0.006414f, 0.005272f,
0.014324f, 0.014339f, 0.014475f, 0.014799f, 0.015208f, 0.015442f, 0.015222f, 0.014431f, 0.013158f, 0.011612f, 0.010004f, 0.008471f, 0.007096f, 0.005898f, 0.004881f, 0.004028f,
0.008164f, 0.008174f, 0.008271f, 0.008527f, 0.008914f, 0.009294f, 0.009478f, 0.009325f, 0.008814f, 0.008031f, 0.007105f, 0.006146f, 0.005232f, 0.004404f, 0.003678f, 0.003054f,
0.004473f, 0.004479f, 0.004545f, 0.004727f, 0.005033f, 0.005395f, 0.005697f, 0.005825f, 0.005721f, 0.005398f, 0.004920f, 0.004362f, 0.003786f, 0.003237f, 0.002735f, 0.002293f,
0.002293f, 0.002298f, 0.002340f, 0.002462f, 0.002680f, 0.002968f, 0.003260f, 0.003478f, 0.003563f, 0.003496f, 0.003297f, 0.003008f, 0.002674f, 0.002330f, 0.002000f, 0.001697f,
0.001048f, 0.001051f, 0.001076f, 0.001153f, 0.001297f, 0.001501f, 0.001733f, 0.001946f, 0.002095f, 0.002151f, 0.002112f, 0.001996f, 0.001826f, 0.001630f, 0.001427f, 0.001232f,
0.000384f, 0.000385f, 0.000399f, 0.000442f, 0.000528f, 0.000657f, 0.000817f, 0.000984f, 0.001128f, 0.001226f, 0.001267f, 0.001250f, 0.001188f, 0.001094f, 0.000984f, 0.000868f,
0.000080f, 0.000080f, 0.000087f, 0.000107f, 0.000149f, 0.000217f, 0.000309f, 0.000416f, 0.000523f, 0.000616f, 0.000681f, 0.000714f, 0.000714f, 0.000688f, 0.000642f, 0.000585f,
0.000000f, 0.000000f, 0.000001f, 0.000005f, 0.000016f, 0.000037f, 0.000071f, 0.000118f, 0.000175f, 0.000236f, 0.000293f, 0.000339f, 0.000370f, 0.000384f, 0.000381f, 0.000366f,
0.999308f, 0.890603f, 0.718551f, 0.556602f, 0.422866f, 0.319099f, 0.241281f, 0.184005f, 0.142233f, 0.111851f, 0.089716f, 0.073518f, 0.061581f, 0.052715f, 0.046071f, 0.041046f,
0.632497f, 0.627981f, 0.585635f, 0.493738f, 0.390647f, 0.299525f, 0.226772f, 0.171883f, 0.131556f, 0.102204f, 0.080844f, 0.065187f, 0.053601f, 0.044907f, 0.038296f, 0.033198f,
0.401801f, 0.400681f, 0.388755f, 0.353748f, 0.298842f, 0.239804f, 0.187389f, 0.144932f, 0.112177f, 0.087521f, 0.069138f, 0.055433f, 0.045147f, 0.037343f, 0.031344f, 0.026656f,
0.255716f, 0.255380f, 0.251440f, 0.238109f, 0.212618f, 0.179303f, 0.145418f, 0.115552f, 0.091127f, 0.071933f, 0.057156f, 0.045865f, 0.037227f, 0.030576f, 0.025401f, 0.021324f,
0.162647f, 0.162560f, 0.161321f, 0.156408f, 0.145365f, 0.128309f, 0.108300f, 0.088741f, 0.071596f, 0.057426f, 0.046094f, 0.037181f, 0.030200f, 0.024736f, 0.020425f, 0.017002f,
0.103097f, 0.103093f, 0.102831f, 0.101299f, 0.096971f, 0.088989f, 0.078116f, 0.066178f, 0.054781f, 0.044787f, 0.036440f, 0.029635f, 0.024175f, 0.019806f, 0.016314f, 0.013507f,
0.064890f, 0.064910f, 0.064986f, 0.064781f, 0.063462f, 0.060189f, 0.054824f, 0.048063f, 0.040928f, 0.034203f, 0.028284f, 0.023263f, 0.019109f, 0.015707f, 0.012938f, 0.010686f,
0.040353f, 0.040376f, 0.040543f, 0.040804f, 0.040752f, 0.039777f, 0.037500f, 0.034030f, 0.029874f, 0.025585f, 0.021557f, 0.017980f, 0.014911f, 0.012331f, 0.010187f, 0.008415f,
0.024620f, 0.024640f, 0.024806f, 0.025180f, 0.025583f, 0.025638f, 0.024972f, 0.023461f, 0.021268f, 0.018718f, 0.016118f, 0.013667f, 0.011476f, 0.009570f, 0.007950f, 0.006587f,
0.014588f, 0.014603f, 0.014739f, 0.015087f, 0.015589f, 0.016027f, 0.016126f, 0.015694f, 0.014719f, 0.013351f, 0.011786f, 0.010193f, 0.008689f, 0.007329f, 0.006137f, 0.005112f,
0.008264f, 0.008275f, 0.008376f, 0.008653f, 0.009105f, 0.009620f, 0.010015f, 0.010118f, 0.009849f, 0.009237f, 0.008390f, 0.007428f, 0.006449f, 0.005520f, 0.004674f, 0.003927f,
0.004362f, 0.004369f, 0.004438f, 0.004639f, 0.004992f, 0.005450f, 0.005899f, 0.006216f, 0.006307f, 0.006146f, 0.005772f, 0.005255f, 0.004668f, 0.004069f, 0.003496f, 0.002972f,
0.002044f, 0.002048f, 0.002093f, 0.002227f, 0.002476f, 0.002825f, 0.003216f, 0.003568f, 0.003804f, 0.003880f, 0.003792f, 0.003573f, 0.003266f, 0.002915f, 0.002553f, 0.002205f,
0.000764f, 0.000766f, 0.000792f, 0.000873f, 0.001029f, 0.001263f, 0.001550f, 0.001845f, 0.002098f, 0.002266f, 0.002330f, 0.002294f, 0.002176f, 0.002003f, 0.001801f, 0.001590f,
0.000162f, 0.000163f, 0.000175f, 0.000214f, 0.000295f, 0.000424f, 0.000597f, 0.000796f, 0.000995f, 0.001165f, 0.001284f, 0.001343f, 0.001341f, 0.001291f, 0.001205f, 0.001098f,
0.000000f, 0.000000f, 0.000002f, 0.000010f, 0.000032f, 0.000073f, 0.000140f, 0.000232f, 0.000342f, 0.000460f, 0.000570f, 0.000658f, 0.000717f, 0.000742f, 0.000737f, 0.000707f,
0.999374f, 0.898694f, 0.736620f, 0.581057f, 0.449900f, 0.345942f, 0.266319f, 0.206511f, 0.162051f, 0.129141f, 0.104780f, 0.086696f, 0.073199f, 0.063064f, 0.055394f, 0.049543f,
0.661910f, 0.657482f, 0.615713f, 0.524706f, 0.421689f, 0.328968f, 0.253347f, 0.195106f, 0.151498f, 0.119213f, 0.095362f, 0.077645f, 0.064384f, 0.054336f, 0.046632f, 0.040650f,
0.441042f, 0.439861f, 0.427339f, 0.390653f, 0.332989f, 0.270476f, 0.214213f, 0.167896f, 0.131578f, 0.103825f, 0.082854f, 0.067036f, 0.055041f, 0.045862f, 0.038751f, 0.033160f,
0.294528f, 0.294131f, 0.289595f, 0.274546f, 0.246073f, 0.208940f, 0.170990f, 0.137223f, 0.109290f, 0.087082f, 0.069798f, 0.056460f, 0.046167f, 0.038181f, 0.031925f, 0.026967f,
0.196358f, 0.196231f, 0.194584f, 0.188436f, 0.175106f, 0.154896f, 0.131341f, 0.108292f, 0.087983f, 0.071077f, 0.057454f, 0.046658f, 0.038145f, 0.031437f, 0.026116f, 0.021865f,
0.130185f, 0.130159f, 0.129663f, 0.127383f, 0.121571f, 0.111376f, 0.097819f, 0.083085f, 0.069054f, 0.056731f, 0.046399f, 0.037940f, 0.031118f, 0.025633f, 0.021227f, 0.017667f,
0.085462f, 0.085472f, 0.085438f, 0.084847f, 0.082693f, 0.078055f, 0.070887f, 0.062100f, 0.052944f, 0.044357f, 0.036807f, 0.030394f, 0.025074f, 0.020704f, 0.017133f, 0.014217f,
0.055252f, 0.055272f, 0.055405f, 0.055513f, 0.055074f, 0.053375f, 0.050028f, 0.045234f, 0.039653f, 0.033972f, 0.028671f, 0.023976f, 0.019947f, 0.016554f, 0.013728f, 0.011387f,
0.034928f, 0.034949f, 0.035121f, 0.035476f, 0.035767f, 0.035527f, 0.034327f, 0.032055f, 0.028951f, 0.025439f, 0.021907f, 0.018599f, 0.015650f, 0.013086f, 0.010903f, 0.009064f,
0.021371f, 0.021389f, 0.021548f, 0.021944f, 0.022483f, 0.022883f, 0.022800f, 0.022013f, 0.020532f, 0.018562f, 0.016363f, 0.014153f, 0.012077f, 0.010205f, 0.008566f, 0.007154f,
0.012461f, 0.012475f, 0.012604f, 0.012953f, 0.013508f, 0.014117f, 0.014536f, 0.014549f, 0.014063f, 0.013129f, 0.011895f, 0.010521f, 0.009136f, 0.007827f, 0.006638f, 0.005588f,
0.006749f, 0.006759f, 0.006854f, 0.007126f, 0.007597f, 0.008197f, 0.008770f, 0.009147f, 0.009208f, 0.008925f, 0.008352f, 0.007591f, 0.006740f, 0.005877f, 0.005054f, 0.004302f,
0.003236f, 0.003243f, 0.003308f, 0.003500f, 0.003853f, 0.004344f, 0.004885f, 0.005364f, 0.005671f, 0.005751f, 0.005600f, 0.005264f, 0.004805f, 0.004288f, 0.003757f, 0.003248f,
0.001235f, 0.001239f, 0.001278f, 0.001399f, 0.001632f, 0.001978f, 0.002399f, 0.002828f, 0.003191f, 0.003427f, 0.003511f, 0.003447f, 0.003265f, 0.003004f, 0.002701f, 0.002385f,
0.000267f, 0.000269f, 0.000287f, 0.000348f, 0.000474f, 0.000673f, 0.000938f, 0.001242f, 0.001543f, 0.001799f, 0.001976f, 0.002061f, 0.002057f, 0.001977f, 0.001845f, 0.001682f,
0.000000f, 0.000000f, 0.000003f, 0.000017f, 0.000051f, 0.000117f, 0.000223f, 0.000368f, 0.000543f, 0.000728f, 0.000900f, 0.001039f, 0.001129f, 0.001168f, 0.001158f, 0.001110f,
0.999398f, 0.902088f, 0.744723f, 0.592705f, 0.463498f, 0.360123f, 0.280132f, 0.219410f, 0.173793f, 0.139681f, 0.114186f, 0.095092f, 0.080726f, 0.069858f, 0.061580f, 0.055228f,
0.674640f, 0.670291f, 0.629109f, 0.539241f, 0.437166f, 0.344488f, 0.268043f, 0.208483f, 0.163390f, 0.129656f, 0.104495f, 0.085644f, 0.071426f, 0.060581f, 0.052219f, 0.045691f,
0.460273f, 0.459081f, 0.446430f, 0.409329f, 0.350883f, 0.287211f, 0.229441f, 0.181408f, 0.143357f, 0.113993f, 0.091606f, 0.074583f, 0.061584f, 0.051575f, 0.043779f, 0.037621f,
0.315614f, 0.315191f, 0.310403f, 0.294616f, 0.264841f, 0.225986f, 0.186114f, 0.150399f, 0.120619f, 0.096750f, 0.078027f, 0.063477f, 0.052178f, 0.043362f, 0.036423f, 0.030898f,
0.216387f, 0.216237f, 0.214368f, 0.207556f, 0.193007f, 0.171112f, 0.145639f, 0.120659f, 0.098546f, 0.080036f, 0.065031f, 0.053073f, 0.043594f, 0.036089f, 0.030109f, 0.025311f,
0.147611f, 0.147569f, 0.146917f, 0.144154f, 0.137414f, 0.125864f, 0.110679f, 0.094245f, 0.078594f, 0.064817f, 0.053226f, 0.043700f, 0.035987f, 0.029761f, 0.024741f, 0.020671f,
0.099677f, 0.099679f, 0.099552f, 0.098660f, 0.095893f, 0.090303f, 0.081915f, 0.071779f, 0.061284f, 0.051461f, 0.042820f, 0.035470f, 0.029357f, 0.024323f, 0.020198f, 0.016817f,
0.066236f, 0.066252f, 0.066340f, 0.066292f, 0.065506f, 0.063222f, 0.059061f, 0.053300f, 0.046703f, 0.040040f, 0.033844f, 0.028362f, 0.023655f, 0.019686f, 0.016372f, 0.013620f,
0.042986f, 0.043007f, 0.043167f, 0.043465f, 0.043604f, 0.043065f, 0.041397f, 0.038509f, 0.034703f, 0.030469f, 0.026246f, 0.022308f, 0.018803f, 0.015756f, 0.013159f, 0.010966f,
0.026964f, 0.026983f, 0.027149f, 0.027549f, 0.028063f, 0.028364f, 0.028073f, 0.026956f, 0.025048f, 0.022595f, 0.019901f, 0.017217f, 0.014705f, 0.012444f, 0.010464f, 0.008757f,
0.016093f, 0.016109f, 0.016253f, 0.016639f, 0.017240f, 0.017874f, 0.018258f, 0.018150f, 0.017455f, 0.016241f, 0.014688f, 0.012983f, 0.011276f, 0.009669f, 0.008210f, 0.006923f,
0.008907f, 0.008919f, 0.009032f, 0.009351f, 0.009899f, 0.010586f, 0.011225f, 0.011617f, 0.011624f, 0.011218f, 0.010471f, 0.009504f, 0.008435f, 0.007357f, 0.006332f, 0.005396f,
0.004358f, 0.004366f, 0.004446f, 0.004684f, 0.005117f, 0.005713f, 0.006363f, 0.006928f, 0.007278f, 0.007344f, 0.007129f, 0.006689f, 0.006101f, 0.005444f, 0.004771f, 0.004128f,
0.001694f, 0.001699f, 0.001749f, 0.001905f, 0.002204f, 0.002643f, 0.003174f, 0.003711f, 0.004160f, 0.004447f, 0.004541f, 0.004449f, 0.004209f, 0.003871f, 0.003481f, 0.003075f,
0.000372f, 0.000375f, 0.000400f, 0.000481f, 0.000647f, 0.000911f, 0.001258f, 0.001653f, 0.002043f, 0.002373f, 0.002600f, 0.002707f, 0.002698f, 0.002592f, 0.002418f, 0.002203f,
0.000000f, 0.000000f, 0.000005f, 0.000023f, 0.000069f, 0.000159f, 0.000302f, 0.000498f, 0.000732f, 0.000980f, 0.001210f, 0.001395f, 0.001514f, 0.001564f, 0.001549f, 0.001484f,
0.999384f, 0.901027f, 0.743159f, 0.591596f, 0.463305f, 0.360875f, 0.281636f, 0.221413f, 0.176070f, 0.142062f, 0.116559f, 0.097391f, 0.082918f, 0.071931f, 0.063535f, 0.057074f,
0.671538f, 0.667239f, 0.626489f, 0.537609f, 0.436804f, 0.345295f, 0.269702f, 0.210648f, 0.165786f, 0.132098f, 0.106872f, 0.087900f, 0.073537f, 0.062544f, 0.054041f, 0.047386f,
0.459468f, 0.458301f, 0.445881f, 0.409359f, 0.351731f, 0.288853f, 0.231659f, 0.183935f, 0.145971f, 0.116547f, 0.094017f, 0.076816f, 0.063630f, 0.053443f, 0.045484f, 0.039181f,
0.317648f, 0.317231f, 0.312500f, 0.296872f, 0.267348f, 0.228751f, 0.189043f, 0.153352f, 0.123470f, 0.099415f, 0.080467f, 0.065683f, 0.054160f, 0.045139f, 0.038017f, 0.032333f,
0.220393f, 0.220241f, 0.218346f, 0.211474f, 0.196830f, 0.174806f, 0.149158f, 0.123952f, 0.101569f, 0.082765f, 0.067465f, 0.055229f, 0.045497f, 0.037769f, 0.031593f, 0.026627f,
0.152536f, 0.152489f, 0.151788f, 0.148889f, 0.141916f, 0.130055f, 0.114512f, 0.097699f, 0.081671f, 0.067530f, 0.055602f, 0.045772f, 0.037792f, 0.031333f, 0.026113f, 0.021870f,
0.104680f, 0.104677f, 0.104503f, 0.103477f, 0.100466f, 0.094536f, 0.085747f, 0.075188f, 0.064279f, 0.054070f, 0.045080f, 0.037422f, 0.031042f, 0.025776f, 0.021453f, 0.017902f,
0.070761f, 0.070775f, 0.070829f, 0.070679f, 0.069700f, 0.067132f, 0.062619f, 0.056473f, 0.049488f, 0.042460f, 0.035934f, 0.030159f, 0.025199f, 0.021010f, 0.017508f, 0.014594f,
0.046738f, 0.046756f, 0.046897f, 0.047134f, 0.047149f, 0.046415f, 0.044488f, 0.041300f, 0.037176f, 0.032632f, 0.028120f, 0.023923f, 0.020189f, 0.016942f, 0.014173f, 0.011832f,
0.029838f, 0.029857f, 0.030015f, 0.030390f, 0.030844f, 0.031039f, 0.030592f, 0.029276f, 0.027141f, 0.024451f, 0.021528f, 0.018628f, 0.015922f, 0.013489f, 0.011357f, 0.009518f,
0.018121f, 0.018137f, 0.018282f, 0.018667f, 0.019258f, 0.019858f, 0.020177f, 0.019967f, 0.019137f, 0.017766f, 0.016048f, 0.014180f, 0.012319f, 0.010570f, 0.008984f, 0.007583f,
0.010200f, 0.010213f, 0.010331f, 0.010665f, 0.011234f, 0.011938f, 0.012577f, 0.012945f, 0.012896f, 0.012409f, 0.011561f, 0.010484f, 0.009302f, 0.008116f, 0.006989f, 0.005961f,
0.005073f, 0.005082f, 0.005169f, 0.005427f, 0.005895f, 0.006533f, 0.007225f, 0.007817f, 0.008171f, 0.008217f, 0.007957f, 0.007456f, 0.006797f, 0.006063f, 0.005316f, 0.004601f,
0.002003f, 0.002008f, 0.002065f, 0.002240f, 0.002574f, 0.003062f, 0.003648f, 0.004238f, 0.004727f, 0.005034f, 0.005127f, 0.005015f, 0.004741f, 0.004358f, 0.003919f, 0.003463f,
0.000447f, 0.000449f, 0.000479f, 0.000573f, 0.000764f, 0.001065f, 0.001461f, 0.001909f, 0.002350f, 0.002720f, 0.002974f, 0.003092f, 0.003078f, 0.002955f, 0.002756f, 0.002512f,
0.000000f, 0.000000f, 0.000005f, 0.000027f, 0.000081f, 0.000186f, 0.000353f, 0.000581f, 0.000854f, 0.001142f, 0.001408f, 0.001620f, 0.001757f, 0.001813f, 0.001795f, 0.001718f,
0.999324f, 0.894704f, 0.730255f, 0.575564f, 0.446956f, 0.345813f, 0.268525f, 0.210349f, 0.166868f, 0.134434f, 0.110208f, 0.092050f, 0.078364f, 0.067988f, 0.060063f, 0.053967f,
0.650077f, 0.645799f, 0.605321f, 0.517255f, 0.418029f, 0.328870f, 0.255928f, 0.199379f, 0.156661f, 0.124711f, 0.100852f, 0.082938f, 0.069390f, 0.059026f, 0.051011f, 0.044737f,
0.435682f, 0.434581f, 0.422772f, 0.387891f, 0.332793f, 0.272804f, 0.218444f, 0.173259f, 0.137422f, 0.109703f, 0.088506f, 0.072333f, 0.059939f, 0.050362f, 0.042879f, 0.036950f,
0.297639f, 0.297261f, 0.292913f, 0.278400f, 0.250803f, 0.214618f, 0.177368f, 0.143903f, 0.115900f, 0.093365f, 0.075614f, 0.061760f, 0.050959f, 0.042498f, 0.035814f, 0.030477f,
0.205419f, 0.205284f, 0.203581f, 0.197311f, 0.183818f, 0.163403f, 0.139552f, 0.116069f, 0.095193f, 0.077638f, 0.063343f, 0.051900f, 0.042791f, 0.035551f, 0.029762f, 0.025102f,
0.142132f, 0.142091f, 0.141465f, 0.138836f, 0.132442f, 0.121494f, 0.107087f, 0.091463f, 0.076539f, 0.063354f, 0.052217f, 0.043028f, 0.035560f, 0.029510f, 0.024615f, 0.020634f,
0.097881f, 0.097879f, 0.097721f, 0.096778f, 0.093997f, 0.088499f, 0.080330f, 0.070498f, 0.060325f, 0.050793f, 0.042389f, 0.035222f, 0.029245f, 0.024307f, 0.020249f, 0.016914f,
0.066585f, 0.066597f, 0.066641f, 0.066485f, 0.065548f, 0.063124f, 0.058885f, 0.053121f, 0.046574f, 0.039986f, 0.033865f, 0.028447f, 0.023788f, 0.019852f, 0.016558f, 0.013815f,
0.044350f, 0.044367f, 0.044489f, 0.044686f, 0.044658f, 0.043919f, 0.042063f, 0.039029f, 0.035128f, 0.030839f, 0.026586f, 0.022631f, 0.019112f, 0.016051f, 0.013439f, 0.011229f,
0.028596f, 0.028612f, 0.028753f, 0.029082f, 0.029468f, 0.029598f, 0.029120f, 0.027829f, 0.025776f, 0.023212f, 0.020436f, 0.017688f, 0.015125f, 0.012821f, 0.010803f, 0.009061f,
0.017557f, 0.017572f, 0.017703f, 0.018050f, 0.018578f, 0.019103f, 0.019355f, 0.019109f, 0.018283f, 0.016956f, 0.015308f, 0.013524f, 0.011751f, 0.010087f, 0.008578f, 0.007246f,
0.009998f, 0.010010f, 0.010120f, 0.010428f, 0.010950f, 0.011592f, 0.012167f, 0.012482f, 0.012404f, 0.011915f, 0.011089f, 0.010050f, 0.008916f, 0.007781f, 0.006703f, 0.005720f,
0.005032f, 0.005041f, 0.005124f, 0.005367f, 0.005807f, 0.006406f, 0.007050f, 0.007597f, 0.007916f, 0.007943f, 0.007680f, 0.007190f, 0.006552f, 0.005845f, 0.005126f, 0.004438f,
0.002011f, 0.002016f, 0.002072f, 0.002240f, 0.002562f, 0.003030f, 0.003590f, 0.004152f, 0.004615f, 0.004903f, 0.004985f, 0.004870f, 0.004602f, 0.004229f, 0.003803f, 0.003361f,
0.000454f, 0.000457f, 0.000486f, 0.000579f, 0.000767f, 0.001062f, 0.001448f, 0.001885f, 0.002313f, 0.002671f, 0.002916f, 0.003028f, 0.003012f, 0.002891f, 0.002696f, 0.002456f,
0.000000f, 0.000000f, 0.000005f, 0.000026f, 0.000081f, 0.000185f, 0.000352f, 0.000579f, 0.000850f, 0.001134f, 0.001397f, 0.001606f, 0.001740f, 0.001794f, 0.001775f, 0.001697f,
0.999195f, 0.880737f, 0.701400f, 0.539100f, 0.408965f, 0.309926f, 0.236407f, 0.182436f, 0.142949f, 0.114017f, 0.092727f, 0.076965f, 0.065205f, 0.056364f, 0.049658f, 0.044528f,
0.602849f, 0.598587f, 0.558416f, 0.471435f, 0.374735f, 0.289881f, 0.222188f, 0.170866f, 0.132817f, 0.104797f, 0.084137f, 0.068785f, 0.057270f, 0.048520f, 0.041788f, 0.036542f,
0.381572f, 0.380594f, 0.369963f, 0.338279f, 0.288166f, 0.233979f, 0.185495f, 0.145772f, 0.114692f, 0.090934f, 0.072941f, 0.059321f, 0.048951f, 0.040980f, 0.034779f, 0.029883f,
0.249640f, 0.249342f, 0.245790f, 0.233617f, 0.210103f, 0.179101f, 0.147245f, 0.118798f, 0.095174f, 0.076302f, 0.061535f, 0.050074f, 0.041179f, 0.034240f, 0.028776f, 0.024426f,
0.166839f, 0.166747f, 0.165488f, 0.160615f, 0.149790f, 0.133124f, 0.113506f, 0.094164f, 0.077003f, 0.062618f, 0.050946f, 0.041633f, 0.034242f, 0.028383f, 0.023710f, 0.019957f,
0.112793f, 0.112771f, 0.112365f, 0.110478f, 0.105628f, 0.097066f, 0.085614f, 0.073098f, 0.061107f, 0.050507f, 0.041562f, 0.034190f, 0.028209f, 0.023371f, 0.019464f, 0.016290f,
0.076454f, 0.076458f, 0.076390f, 0.075787f, 0.073798f, 0.069661f, 0.063354f, 0.055658f, 0.047638f, 0.040098f, 0.033441f, 0.027762f, 0.023027f, 0.019118f, 0.015909f, 0.013274f,
0.051496f, 0.051508f, 0.051571f, 0.051527f, 0.050919f, 0.049167f, 0.045974f, 0.041545f, 0.036462f, 0.031317f, 0.026522f, 0.022271f, 0.018614f, 0.015524f, 0.012939f, 0.010788f,
0.034126f, 0.034139f, 0.034247f, 0.034435f, 0.034476f, 0.033982f, 0.032617f, 0.030320f, 0.027324f, 0.024006f, 0.020702f, 0.017623f, 0.014880f, 0.012493f, 0.010456f, 0.008733f,
0.021976f, 0.021989f, 0.022102f, 0.022368f, 0.022691f, 0.022825f, 0.022493f, 0.021528f, 0.019962f, 0.017991f, 0.015846f, 0.013717f, 0.011731f, 0.009943f, 0.008376f, 0.007024f,
0.013518f, 0.013529f, 0.013631f, 0.013900f, 0.014311f, 0.014724f, 0.014930f, 0.014752f, 0.014124f, 0.013106f, 0.011836f, 0.010459f, 0.009089f, 0.007802f, 0.006635f, 0.005604f,
0.007731f, 0.007740f, 0.007824f, 0.008059f, 0.008458f, 0.008950f, 0.009392f, 0.009634f, 0.009575f, 0.009198f, 0.008562f, 0.007760f, 0.006885f, 0.006009f, 0.005177f, 0.004418f,
0.003915f, 0.003922f, 0.003985f, 0.004170f, 0.004506f, 0.004963f, 0.005455f, 0.005872f, 0.006115f, 0.006133f, 0.005928f, 0.005550f, 0.005057f, 0.004511f, 0.003956f, 0.003426f,
0.001577f, 0.001581f, 0.001623f, 0.001753f, 0.001999f, 0.002358f, 0.002788f, 0.003217f, 0.003571f, 0.003791f, 0.003852f, 0.003762f, 0.003554f, 0.003266f, 0.002937f, 0.002596f,
0.000359f, 0.000361f, 0.000384f, 0.000456f, 0.000602f, 0.000830f, 0.001129f, 0.001466f, 0.001795f, 0.002071f, 0.002259f, 0.002344f, 0.002331f, 0.002237f, 0.002086f, 0.001901f,
0.000000f, 0.000000f, 0.000004f, 0.000021f, 0.000063f, 0.000145f, 0.000275f, 0.000452f, 0.000663f, 0.000884f, 0.001088f, 0.001250f, 0.001353f, 0.001395f, 0.001379f, 0.001319f,
0.998931f, 0.853324f, 0.645842f, 0.469952f, 0.337720f, 0.243123f, 0.176873f, 0.130789f, 0.098689f, 0.076187f, 0.060269f, 0.048887f, 0.040651f, 0.034620f, 0.030151f, 0.026799f,
0.512646f, 0.508471f, 0.469338f, 0.385240f, 0.294040f, 0.217660f, 0.159883f, 0.118248f, 0.088771f, 0.067935f, 0.053116f, 0.042442f, 0.034648f, 0.028857f, 0.024485f, 0.021133f,
0.281721f, 0.280975f, 0.272560f, 0.246892f, 0.206115f, 0.162685f, 0.124987f, 0.095223f, 0.072792f, 0.056228f, 0.044064f, 0.035102f, 0.028433f, 0.023410f, 0.019567f, 0.016577f,
0.162447f, 0.162288f, 0.160141f, 0.152132f, 0.135941f, 0.114261f, 0.092117f, 0.072713f, 0.056991f, 0.044749f, 0.035399f, 0.028300f, 0.022895f, 0.018750f, 0.015535f, 0.013010f,
0.096946f, 0.096926f, 0.096434f, 0.093998f, 0.087876f, 0.077870f, 0.065814f, 0.053903f, 0.043434f, 0.034785f, 0.027879f, 0.022457f, 0.018216f, 0.014902f, 0.012291f, 0.010221f,
0.059278f, 0.059290f, 0.059265f, 0.058680f, 0.056564f, 0.052255f, 0.046100f, 0.039181f, 0.032495f, 0.026597f, 0.021654f, 0.017617f, 0.014374f, 0.011778f, 0.009704f, 0.008036f,
0.036816f, 0.036833f, 0.036928f, 0.036945f, 0.036397f, 0.034736f, 0.031819f, 0.028020f, 0.023941f, 0.020056f, 0.016617f, 0.013688f, 0.011258f, 0.009265f, 0.007641f, 0.006319f,
0.023025f, 0.023039f, 0.023146f, 0.023332f, 0.023369f, 0.022895f, 0.021669f, 0.019735f, 0.017379f, 0.014922f, 0.012601f, 0.010531f, 0.008750f, 0.007249f, 0.006000f, 0.004966f,
0.014356f, 0.014367f, 0.014458f, 0.014664f, 0.014887f, 0.014915f, 0.014533f, 0.013667f, 0.012406f, 0.010935f, 0.009432f, 0.008012f, 0.006741f, 0.005633f, 0.004690f, 0.003895f,
0.008810f, 0.008818f, 0.008889f, 0.009068f, 0.009323f, 0.009534f, 0.009551f, 0.009266f, 0.008677f, 0.007866f, 0.006946f, 0.006013f, 0.005134f, 0.004339f, 0.003641f, 0.003041f,
0.005227f, 0.005233f, 0.005285f, 0.005427f, 0.005656f, 0.005911f, 0.006091f, 0.006105f, 0.005909f, 0.005523f, 0.005009f, 0.004434f, 0.003852f, 0.003302f, 0.002801f, 0.002359f,
0.002915f, 0.002919f, 0.002956f, 0.003063f, 0.003249f, 0.003486f, 0.003712f, 0.003859f, 0.003877f, 0.003753f, 0.003511f, 0.003191f, 0.002833f, 0.002472f, 0.002127f, 0.001812f,
0.001454f, 0.001456f, 0.001482f, 0.001558f, 0.001698f, 0.001891f, 0.002105f, 0.002292f, 0.002409f, 0.002434f, 0.002364f, 0.002220f, 0.002025f, 0.001808f, 0.001584f, 0.001371f,
0.000581f, 0.000583f, 0.000599f, 0.000649f, 0.000745f, 0.000887f, 0.001058f, 0.001231f, 0.001376f, 0.001469f, 0.001499f, 0.001468f, 0.001389f, 0.001277f, 0.001148f, 0.001014f,
0.000132f, 0.000133f, 0.000141f, 0.000169f, 0.000223f, 0.000310f, 0.000423f, 0.000553f, 0.000680f, 0.000786f, 0.000860f, 0.000894f, 0.000890f, 0.000855f, 0.000797f, 0.000726f,
0.000000f, 0.000000f, 0.000002f, 0.000008f, 0.000023f, 0.000054f, 0.000102f, 0.000168f, 0.000247f, 0.000329f, 0.000405f, 0.000466f, 0.000505f, 0.000521f, 0.000515f, 0.000493f,
0.998343f, 0.797145f, 0.537565f, 0.341480f, 0.211432f, 0.130243f, 0.081132f, 0.051808f, 0.034257f, 0.023596f, 0.016970f, 0.012743f, 0.009968f, 0.008098f, 0.006805f, 0.005891f,
0.337443f, 0.333724f, 0.298932f, 0.225420f, 0.150757f, 0.095691f, 0.060202f, 0.038567f, 0.025490f, 0.017461f, 0.012403f, 0.009107f, 0.006892f, 0.005352f, 0.004248f, 0.003440f,
0.103266f, 0.102994f, 0.099252f, 0.086627f, 0.066503f, 0.046703f, 0.031636f, 0.021370f, 0.014640f, 0.010240f, 0.007323f, 0.005352f, 0.003987f, 0.003022f, 0.002324f, 0.001807f,
0.014672f, 0.014836f, 0.016218f, 0.018325f, 0.018457f, 0.016029f, 0.012571f, 0.009361f, 0.006827f, 0.004956f, 0.003612f, 0.002653f, 0.001964f, 0.001467f, 0.001104f, 0.000838f,
0.000000f, 0.000024f, 0.000361f, 0.001434f, 0.002833f, 0.003635f, 0.003606f, 0.003095f, 0.002461f, 0.001879f, 0.001405f, 0.001042f, 0.000770f, 0.000569f, 0.000422f, 0.000315f,
0.000000f, 0.000002f, 0.000027f, 0.000124f, 0.000317f, 0.000531f, 0.000652f, 0.000650f, 0.000567f, 0.000457f, 0.000352f, 0.000263f, 0.000194f, 0.000143f, 0.000105f, 0.000077f,
0.000000f, 0.000000f, 0.000001f, 0.000004f, 0.000012f, 0.000022f, 0.000030f, 0.000034f, 0.000031f, 0.000026f, 0.000021f, 0.000015f, 0.000011f, 0.000008f, 0.000006f, 0.000004f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.996677f, 0.667314f, 0.327561f, 0.142588f, 0.061686f, 0.028738f, 0.014773f, 0.008336f, 0.005102f, 0.003349f, 0.002337f, 0.001722f, 0.001331f, 0.001073f, 0.000897f, 0.000774f,
0.000000f, 0.002379f, 0.013334f, 0.014447f, 0.009557f, 0.005628f, 0.003304f, 0.002000f, 0.001255f, 0.000813f, 0.000543f, 0.000371f, 0.000259f, 0.000184f, 0.000132f, 0.000096f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.987910f, 0.306049f, 0.047683f, 0.010577f, 0.003433f, 0.001425f, 0.000698f, 0.000385f, 0.000233f, 0.000152f, 0.000105f, 0.000078f, 0.000060f, 0.000048f, 0.000040f, 0.000034f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.504788f, 0.000292f, 0.000019f, 0.000005f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000001f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f
};
static const float table_ggx_gen_schlick_s[4096] = {
0.006734f, 0.000006f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.993023f, 0.522799f, 0.198475f, 0.075259f, 0.031135f, 0.014396f, 0.007409f, 0.004189f, 0.002568f, 0.001687f, 0.001177f, 0.000869f, 0.000671f, 0.000541f, 0.000453f, 0.000390f,
0.007991f, 0.008373f, 0.009108f, 0.007205f, 0.004448f, 0.002574f, 0.001506f, 0.000915f, 0.000578f, 0.000379f, 0.000257f, 0.000179f, 0.000128f, 0.000094f, 0.000069f, 0.000052f,
0.000045f, 0.000052f, 0.000112f, 0.000199f, 0.000219f, 0.000179f, 0.000128f, 0.000087f, 0.000059f, 0.000040f, 0.000027f, 0.000019f, 0.000013f, 0.000010f, 0.000007f, 0.000005f,
0.000000f, 0.000000f, 0.000001f, 0.000005f, 0.000008f, 0.000009f, 0.000008f, 0.000006f, 0.000004f, 0.000003f, 0.000002f, 0.000002f, 0.000001f, 0.000001f, 0.000001f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.996755f, 0.685775f, 0.369401f, 0.188026f, 0.096247f, 0.051176f, 0.028718f, 0.017107f, 0.010819f, 0.007246f, 0.005119f, 0.003802f, 0.002953f, 0.002388f, 0.002001f, 0.001728f,
0.106217f, 0.105498f, 0.094529f, 0.067655f, 0.041664f, 0.024627f, 0.014743f, 0.009140f, 0.005901f, 0.003963f, 0.002763f, 0.001989f, 0.001472f, 0.001116f, 0.000863f, 0.000680f,
0.009554f, 0.009715f, 0.010510f, 0.010684f, 0.009064f, 0.006672f, 0.004603f, 0.003121f, 0.002129f, 0.001474f, 0.001039f, 0.000746f, 0.000545f, 0.000404f, 0.000303f, 0.000230f,
0.000709f, 0.000734f, 0.000927f, 0.001271f, 0.001481f, 0.001397f, 0.001141f, 0.000863f, 0.000631f, 0.000456f, 0.000329f, 0.000239f, 0.000175f, 0.000129f, 0.000096f, 0.000072f,
0.000042f, 0.000045f, 0.000069f, 0.000132f, 0.000207f, 0.000248f, 0.000241f, 0.000205f, 0.000162f, 0.000123f, 0.000092f, 0.000068f, 0.000050f, 0.000037f, 0.000027f, 0.000021f,
0.000002f, 0.000002f, 0.000005f, 0.000013f, 0.000027f, 0.000039f, 0.000045f, 0.000043f, 0.000037f, 0.000030f, 0.000023f, 0.000017f, 0.000013f, 0.000010f, 0.000007f, 0.000005f,
0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000006f, 0.000007f, 0.000008f, 0.000007f, 0.000006f, 0.000005f, 0.000004f, 0.000003f, 0.000002f, 0.000002f, 0.000001f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.998002f, 0.767478f, 0.486411f, 0.289650f, 0.169581f, 0.100246f, 0.060850f, 0.038321f, 0.025181f, 0.017305f, 0.012440f, 0.009344f, 0.007312f, 0.005942f, 0.004996f, 0.004325f,
0.251614f, 0.248829f, 0.221581f, 0.163680f, 0.106859f, 0.066821f, 0.041823f, 0.026800f, 0.017747f, 0.012177f, 0.008656f, 0.006354f, 0.004804f, 0.003725f, 0.002951f, 0.002386f,
0.057153f, 0.057234f, 0.056586f, 0.051399f, 0.040878f, 0.029460f, 0.020314f, 0.013884f, 0.009582f, 0.006734f, 0.004831f, 0.003540f, 0.002643f, 0.002009f, 0.001551f, 0.001212f,
0.011529f, 0.011626f, 0.012240f, 0.012909f, 0.012422f, 0.010578f, 0.008239f, 0.006127f, 0.004475f, 0.003259f, 0.002387f, 0.001765f, 0.001318f, 0.000995f, 0.000759f, 0.000584f,
0.002023f, 0.002054f, 0.002299f, 0.002797f, 0.003236f, 0.003281f, 0.002932f, 0.002403f, 0.001877f, 0.001429f, 0.001077f, 0.000809f, 0.000609f, 0.000460f, 0.000349f, 0.000267f,
0.000301f, 0.000308f, 0.000373f, 0.000537f, 0.000752f, 0.000909f, 0.000936f, 0.000853f, 0.000717f, 0.000575f, 0.000448f, 0.000344f, 0.000262f, 0.000200f, 0.000152f, 0.000116f,
0.000037f, 0.000038f, 0.000052f, 0.000093f, 0.000160f, 0.000229f, 0.000271f, 0.000275f, 0.000250f, 0.000212f, 0.000172f, 0.000136f, 0.000105f, 0.000081f, 0.000062f, 0.000048f,
0.000003f, 0.000004f, 0.000006f, 0.000015f, 0.000032f, 0.000054f, 0.000072f, 0.000081f, 0.000080f, 0.000072f, 0.000061f, 0.000049f, 0.000039f, 0.000031f, 0.000024f, 0.000018f,
0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000006f, 0.000012f, 0.000017f, 0.000021f, 0.000023f, 0.000022f, 0.000019f, 0.000016f, 0.000013f, 0.000011f, 0.000008f, 0.000006f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000004f, 0.000005f, 0.000006f, 0.000006f, 0.000006f, 0.000005f, 0.000004f, 0.000003f, 0.000003f, 0.000002f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.998626f, 0.818545f, 0.572693f, 0.377520f, 0.242823f, 0.155691f, 0.101007f, 0.067013f, 0.045804f, 0.032403f, 0.023783f, 0.018127f, 0.014330f, 0.011728f, 0.009905f, 0.008604f,
0.387263f, 0.383162f, 0.345300f, 0.265679f, 0.183968f, 0.121916f, 0.080143f, 0.053384f, 0.036432f, 0.025602f, 0.018564f, 0.013872f, 0.010666f, 0.008412f, 0.006784f, 0.005585f,
0.139787f, 0.139478f, 0.135096f, 0.119977f, 0.095124f, 0.069503f, 0.048887f, 0.034082f, 0.023954f, 0.017120f, 0.012488f, 0.009305f, 0.007075f, 0.005481f, 0.004316f, 0.003446f,
0.046504f, 0.046586f, 0.046806f, 0.045601f, 0.041003f, 0.033616f, 0.025800f, 0.019153f, 0.014061f, 0.010339f, 0.007668f, 0.005755f, 0.004372f, 0.003362f, 0.002614f, 0.002053f,
0.014057f, 0.014127f, 0.014625f, 0.015398f, 0.015537f, 0.014373f, 0.012208f, 0.009773f, 0.007574f, 0.005779f, 0.004389f, 0.003340f, 0.002551f, 0.001962f, 0.001517f, 0.001182f,
0.003791f, 0.003823f, 0.004084f, 0.004663f, 0.005289f, 0.005543f, 0.005257f, 0.004587f, 0.003783f, 0.003016f, 0.002361f, 0.001830f, 0.001414f, 0.001092f, 0.000846f, 0.000656f,
0.000890f, 0.000902f, 0.001003f, 0.001263f, 0.001632f, 0.001950f, 0.002076f, 0.001987f, 0.001756f, 0.001472f, 0.001194f, 0.000948f, 0.000744f, 0.000580f, 0.000451f, 0.000350f,
0.000176f, 0.000180f, 0.000212f, 0.000305f, 0.000459f, 0.000630f, 0.000755f, 0.000795f, 0.000757f, 0.000670f, 0.000565f, 0.000462f, 0.000370f, 0.000292f, 0.000229f, 0.000179f,
0.000028f, 0.000029f, 0.000038f, 0.000066f, 0.000119f, 0.000188f, 0.000253f, 0.000293f, 0.000301f, 0.000283f, 0.000249f, 0.000210f, 0.000172f, 0.000138f, 0.000110f, 0.000087f,
0.000003f, 0.000004f, 0.000006f, 0.000013f, 0.000029f, 0.000052f, 0.000078f, 0.000099f, 0.000109f, 0.000109f, 0.000101f, 0.000088f, 0.000074f, 0.000061f, 0.000049f, 0.000039f,
0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000007f, 0.000013f, 0.000022f, 0.000030f, 0.000036f, 0.000038f, 0.000037f, 0.000033f, 0.000029f, 0.000025f, 0.000020f, 0.000016f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000005f, 0.000008f, 0.000010f, 0.000011f, 0.000012f, 0.000011f, 0.000010f, 0.000009f, 0.000007f, 0.000006f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000003f, 0.000003f, 0.000003f, 0.000002f, 0.000002f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.999000f, 0.854351f, 0.640177f, 0.454136f, 0.313646f, 0.214606f, 0.147344f, 0.102508f, 0.072807f, 0.053082f, 0.039870f, 0.030911f, 0.024743f, 0.020429f, 0.017362f, 0.015144f,
0.501612f, 0.496918f, 0.453835f, 0.362209f, 0.264105f, 0.184548f, 0.127210f, 0.088176f, 0.062158f, 0.044843f, 0.033220f, 0.025281f, 0.019755f, 0.015816f, 0.012946f, 0.010812f,
0.239068f, 0.238319f, 0.229906f, 0.204425f, 0.164549f, 0.123346f, 0.089252f, 0.063890f, 0.045953f, 0.033508f, 0.024886f, 0.018857f, 0.014576f, 0.011481f, 0.009196f, 0.007473f,
0.107374f, 0.107323f, 0.106147f, 0.100708f, 0.088688f, 0.072219f, 0.055670f, 0.041739f, 0.031015f, 0.023106f, 0.017374f, 0.013227f, 0.010203f, 0.007975f, 0.006308f, 0.005043f,
0.044979f, 0.045044f, 0.045365f, 0.045215f, 0.043043f, 0.038188f, 0.031712f, 0.025172f, 0.019507f, 0.014966f, 0.011470f, 0.008828f, 0.006836f, 0.005336f, 0.004194f, 0.003322f,
0.017342f, 0.017398f, 0.017823f, 0.018611f, 0.019089f, 0.018483f, 0.016663f, 0.014143f, 0.011522f, 0.009166f, 0.007205f, 0.005633f, 0.004402f, 0.003446f, 0.002707f, 0.002134f,
0.006047f, 0.006078f, 0.006347f, 0.006977f, 0.007750f, 0.008229f, 0.008108f, 0.007416f, 0.006401f, 0.005314f, 0.004307f, 0.003437f, 0.002723f, 0.002147f, 0.001691f, 0.001333f,
0.001862f, 0.001876f, 0.002008f, 0.002352f, 0.002870f, 0.003373f, 0.003656f, 0.003627f, 0.003340f, 0.002910f, 0.002443f, 0.002000f, 0.001612f, 0.001286f, 0.001020f, 0.000806f,
0.000490f, 0.000495f, 0.000549f, 0.000703f, 0.000963f, 0.001271f, 0.001526f, 0.001650f, 0.001629f, 0.001498f, 0.001309f, 0.001103f, 0.000908f, 0.000736f, 0.000590f, 0.000470f,
0.000105f, 0.000107f, 0.000125f, 0.000183f, 0.000292f, 0.000439f, 0.000587f, 0.000694f, 0.000737f, 0.000718f, 0.000656f, 0.000572f, 0.000483f, 0.000399f, 0.000324f, 0.000261f,
0.000017f, 0.000017f, 0.000023f, 0.000042f, 0.000081f, 0.000139f, 0.000207f, 0.000267f, 0.000306f, 0.000316f, 0.000303f, 0.000275f, 0.000239f, 0.000202f, 0.000167f, 0.000136f,
0.000002f, 0.000002f, 0.000003f, 0.000009f, 0.000020f, 0.000040f, 0.000066f, 0.000093f, 0.000114f, 0.000125f, 0.000126f, 0.000119f, 0.000108f, 0.000093f, 0.000079f, 0.000066f,
0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000005f, 0.000010f, 0.000018f, 0.000028f, 0.000037f, 0.000043f, 0.000046f, 0.000045f, 0.000042f, 0.000038f, 0.000033f, 0.000028f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000004f, 0.000007f, 0.000009f, 0.000012f, 0.000013f, 0.000014f, 0.000014f, 0.000013f, 0.000011f, 0.000010f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000003f, 0.000003f, 0.000003f, 0.000003f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
0.999250f, 0.881327f, 0.695314f, 0.522068f, 0.381680f, 0.275653f, 0.198800f, 0.144418f, 0.106419f, 0.079981f, 0.061556f, 0.048640f, 0.039501f, 0.032964f, 0.028230f, 0.024758f,
0.596041f, 0.591217f, 0.546557f, 0.450173f, 0.343240f, 0.251479f, 0.181201f, 0.130594f, 0.095165f, 0.070588f, 0.053511f, 0.041521f, 0.032990f, 0.026806f, 0.022243f, 0.018815f,
0.341893f, 0.340794f, 0.329149f, 0.295195f, 0.242533f, 0.187148f, 0.139720f, 0.103016f, 0.076061f, 0.056740f, 0.042986f, 0.033159f, 0.026058f, 0.020850f, 0.016961f, 0.013999f,
0.187575f, 0.187331f, 0.184286f, 0.173529f, 0.152540f, 0.125158f, 0.097880f, 0.074658f, 0.056452f, 0.042765f, 0.032669f, 0.025255f, 0.019782f, 0.015700f, 0.012614f, 0.010247f,
0.097670f, 0.097668f, 0.097265f, 0.094787f, 0.088117f, 0.076987f, 0.063617f, 0.050635f, 0.039522f, 0.030618f, 0.023733f, 0.018494f, 0.014515f, 0.011490f, 0.009169f, 0.007376f,
0.047788f, 0.047839f, 0.048149f, 0.048349f, 0.047285f, 0.043979f, 0.038624f, 0.032350f, 0.026251f, 0.020928f, 0.016554f, 0.013061f, 0.010323f, 0.008184f, 0.006518f, 0.005213f,
0.021684f, 0.021732f, 0.022113f, 0.022893f, 0.023571f, 0.023385f, 0.021944f, 0.019478f, 0.016554f, 0.013666f, 0.011087f, 0.008900f, 0.007111f, 0.005670f, 0.004521f, 0.003610f,
0.008964f, 0.008995f, 0.009270f, 0.009942f, 0.010846f, 0.011548f, 0.011649f, 0.011035f, 0.009894f, 0.008508f, 0.007113f, 0.005837f, 0.004732f, 0.003809f, 0.003054f, 0.002443f,
0.003293f, 0.003310f, 0.003468f, 0.003892f, 0.004556f, 0.005264f, 0.005754f, 0.005859f, 0.005577f, 0.005028f, 0.004356f, 0.003667f, 0.003031f, 0.002471f, 0.001999f, 0.001608f,
0.001036f, 0.001044f, 0.001120f, 0.001341f, 0.001723f, 0.002196f, 0.002630f, 0.002897f, 0.002945f, 0.002799f, 0.002525f, 0.002193f, 0.001854f, 0.001538f, 0.001259f, 0.001021f,
0.000264f, 0.000267f, 0.000298f, 0.000395f, 0.000577f, 0.000831f, 0.001101f, 0.001322f, 0.001443f, 0.001452f, 0.001372f, 0.001234f, 0.001072f, 0.000908f, 0.000755f, 0.000621f,
0.000050f, 0.000050f, 0.000061f, 0.000096f, 0.000170f, 0.000282f, 0.000418f, 0.000548f, 0.000644f, 0.000690f, 0.000685f, 0.000643f, 0.000577f, 0.000501f, 0.000425f, 0.000355f,
0.000006f, 0.000006f, 0.000009f, 0.000020f, 0.000044f, 0.000085f, 0.000141f, 0.000201f, 0.000255f, 0.000292f, 0.000306f, 0.000301f, 0.000280f, 0.000251f, 0.000219f, 0.000187f,
0.000000f, 0.000000f, 0.000001f, 0.000004f, 0.000010f, 0.000022f, 0.000040f, 0.000062f, 0.000085f, 0.000104f, 0.000116f, 0.000120f, 0.000117f, 0.000109f, 0.000098f, 0.000086f,
0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000004f, 0.000008f, 0.000014f, 0.000020f, 0.000027f, 0.000032f, 0.000035f, 0.000037f, 0.000036f, 0.000034f, 0.000031f,
0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000003f, 0.000004f, 0.000005f, 0.000005f, 0.000005f, 0.000005f,
0.999429f, 0.902696f, 0.741916f, 0.583382f, 0.447240f, 0.338334f, 0.254889f, 0.192674f, 0.147061f, 0.113921f, 0.089921f, 0.072527f, 0.059860f, 0.050578f, 0.043717f, 0.038600f,
0.674189f, 0.669511f, 0.625563f, 0.529453f, 0.419763f, 0.320911f, 0.240949f, 0.180307f, 0.135826f, 0.103679f, 0.080539f, 0.063802f, 0.051596f, 0.042573f, 0.035809f, 0.030663f,
0.441437f, 0.440114f, 0.426338f, 0.386542f, 0.324527f, 0.257868f, 0.198748f, 0.151123f, 0.114754f, 0.087755f, 0.067948f, 0.053435f, 0.042727f, 0.034737f, 0.028688f, 0.024027f,
0.279401f, 0.278969f, 0.274104f, 0.258187f, 0.228435f, 0.190125f, 0.151635f, 0.118175f, 0.091267f, 0.070519f, 0.054862f, 0.043135f, 0.034332f, 0.027673f, 0.022576f, 0.018620f,
0.169939f, 0.169831f, 0.168349f, 0.162641f, 0.150062f, 0.130926f, 0.108791f, 0.087496f, 0.069170f, 0.054328f, 0.042704f, 0.033746f, 0.026864f, 0.021574f, 0.017471f, 0.014263f,
0.098574f, 0.098583f, 0.098421f, 0.097069f, 0.092861f, 0.084820f, 0.073750f, 0.061627f, 0.050172f, 0.040276f, 0.032150f, 0.025641f, 0.020509f, 0.016470f, 0.013296f, 0.010785f,
0.053987f, 0.054031f, 0.054313f, 0.054634f, 0.054119f, 0.051758f, 0.047264f, 0.041276f, 0.034831f, 0.028738f, 0.023406f, 0.018925f, 0.015263f, 0.012305f, 0.009933f, 0.008035f,
0.027542f, 0.027584f, 0.027937f, 0.028710f, 0.029522f, 0.029655f, 0.028565f, 0.026230f, 0.023095f, 0.019697f, 0.016444f, 0.013538f, 0.011052f, 0.008977f, 0.007273f, 0.005886f,
0.012841f, 0.012873f, 0.013157f, 0.013875f, 0.014906f, 0.015837f, 0.016196f, 0.015743f, 0.014556f, 0.012915f, 0.011113f, 0.009353f, 0.007760f, 0.006372f, 0.005199f, 0.004224f,
0.005322f, 0.005341f, 0.005526f, 0.006032f, 0.006854f, 0.007793f, 0.008546f, 0.008862f, 0.008665f, 0.008048f, 0.007176f, 0.006207f, 0.005254f, 0.004378f, 0.003609f, 0.002953f,
0.001878f, 0.001888f, 0.001989f, 0.002284f, 0.002805f, 0.003480f, 0.004147f, 0.004632f, 0.004827f, 0.004722f, 0.004390f, 0.003922f, 0.003402f, 0.002889f, 0.002415f, 0.001998f,
0.000525f, 0.000529f, 0.000575f, 0.000718f, 0.000992f, 0.001382f, 0.001821f, 0.002215f, 0.002478f, 0.002572f, 0.002507f, 0.002328f, 0.002080f, 0.001809f, 0.001540f, 0.001293f,
0.000101f, 0.000103f, 0.000120f, 0.000176f, 0.000294f, 0.000478f, 0.000709f, 0.000947f, 0.001146f, 0.001270f, 0.001307f, 0.001269f, 0.001176f, 0.001053f, 0.000918f, 0.000785f,
0.000010f, 0.000010f, 0.000015f, 0.000032f, 0.000072f, 0.000140f, 0.000236f, 0.000348f, 0.000457f, 0.000543f, 0.000595f, 0.000609f, 0.000590f, 0.000548f, 0.000493f, 0.000433f,
0.000000f, 0.000000f, 0.000001f, 0.000005f, 0.000014f, 0.000033f, 0.000061f, 0.000099f, 0.000141f, 0.000181f, 0.000213f, 0.000233f, 0.000239f, 0.000234f, 0.000220f, 0.000200f,
0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000004f, 0.000008f, 0.000013f, 0.000021f, 0.000029f, 0.000039f, 0.000047f, 0.000054f, 0.000058f, 0.000059f, 0.000058f,
0.999563f, 0.920276f, 0.782410f, 0.639695f, 0.510912f, 0.402654f, 0.315576f, 0.247554f, 0.195444f, 0.156013f, 0.126382f, 0.104180f, 0.087530f, 0.075010f, 0.065547f, 0.058351f,
0.739454f, 0.735078f, 0.693262f, 0.600892f, 0.493225f, 0.391952f, 0.305836f, 0.237299f, 0.184748f, 0.145215f, 0.115727f, 0.093726f, 0.077246f, 0.064787f, 0.055272f, 0.047918f,
0.534691f, 0.533264f, 0.518413f, 0.475399f, 0.407724f, 0.333383f, 0.265184f, 0.208036f, 0.162649f, 0.127711f, 0.101242f, 0.081296f, 0.066227f, 0.054754f, 0.045920f, 0.039017f,
0.376720f, 0.376139f, 0.369819f, 0.349699f, 0.312606f, 0.264761f, 0.215928f, 0.172392f, 0.136340f, 0.107724f, 0.085543f, 0.068532f, 0.055502f, 0.045471f, 0.037676f, 0.031544f,
0.257451f, 0.257225f, 0.254584f, 0.245439f, 0.226607f, 0.198944f, 0.167278f, 0.136636f, 0.109873f, 0.087796f, 0.070176f, 0.056355f, 0.045568f, 0.037153f, 0.030540f, 0.025304f,
0.169668f, 0.169606f, 0.168708f, 0.165090f, 0.156544f, 0.142219f, 0.123694f, 0.103936f, 0.085396f, 0.069327f, 0.056024f, 0.045266f, 0.036691f, 0.029872f, 0.024452f, 0.020115f,
0.107007f, 0.107017f, 0.106936f, 0.106056f, 0.103058f, 0.096797f, 0.087297f, 0.075812f, 0.063990f, 0.053032f, 0.043509f, 0.035512f, 0.028952f, 0.023619f, 0.019308f, 0.015823f,
0.063917f, 0.063953f, 0.064206f, 0.064558f, 0.064324f, 0.062536f, 0.058644f, 0.052890f, 0.046122f, 0.039222f, 0.032808f, 0.027160f, 0.022350f, 0.018332f, 0.015016f, 0.012295f,
0.035637f, 0.035676f, 0.036012f, 0.036785f, 0.037694f, 0.038081f, 0.037300f, 0.035128f, 0.031831f, 0.027939f, 0.023951f, 0.020190f, 0.016834f, 0.013927f, 0.011468f, 0.009413f,
0.018156f, 0.018189f, 0.018486f, 0.019262f, 0.020434f, 0.021610f, 0.022271f, 0.022053f, 0.020904f, 0.019056f, 0.016833f, 0.014521f, 0.012315f, 0.010315f, 0.008565f, 0.007068f,
0.008177f, 0.008200f, 0.008414f, 0.009014f, 0.010019f, 0.011236f, 0.012322f, 0.012950f, 0.012948f, 0.012343f, 0.011306f, 0.010034f, 0.008694f, 0.007403f, 0.006222f, 0.005181f,
0.003080f, 0.003094f, 0.003223f, 0.003605f, 0.004295f, 0.005223f, 0.006201f, 0.007005f, 0.007458f, 0.007498f, 0.007171f, 0.006588f, 0.005866f, 0.005101f, 0.004358f, 0.003676f,
0.000875f, 0.000881f, 0.000945f, 0.001144f, 0.001530f, 0.002095f, 0.002763f, 0.003411f, 0.003912f, 0.004187f, 0.004216f, 0.004040f, 0.003720f, 0.003324f, 0.002902f, 0.002491f,
0.000148f, 0.000151f, 0.000174f, 0.000254f, 0.000421f, 0.000691f, 0.001046f, 0.001438f, 0.001800f, 0.002072f, 0.002219f, 0.002239f, 0.002153f, 0.001993f, 0.001792f, 0.001575f,
0.000007f, 0.000008f, 0.000013f, 0.000034f, 0.000085f, 0.000176f, 0.000312f, 0.000483f, 0.000668f, 0.000838f, 0.000968f, 0.001044f, 0.001063f, 0.001034f, 0.000970f, 0.000885f,
0.000000f, 0.000000f, 0.000001f, 0.000004f, 0.000011f, 0.000027f, 0.000054f, 0.000094f, 0.000146f, 0.000205f, 0.000266f, 0.000319f, 0.000360f, 0.000383f, 0.000389f, 0.000381f,
0.999667f, 0.935186f, 0.818452f, 0.692316f, 0.573418f, 0.468981f, 0.381239f, 0.309730f, 0.252675f, 0.207813f, 0.172872f, 0.145813f, 0.124903f, 0.108747f, 0.096237f, 0.086517f,
0.794553f, 0.790567f, 0.751766f, 0.665569f, 0.563749f, 0.464307f, 0.375719f, 0.301927f, 0.242886f, 0.196696f, 0.160988f, 0.133478f, 0.112275f, 0.095842f, 0.083021f, 0.072927f,
0.620641f, 0.619210f, 0.604184f, 0.560301f, 0.490525f, 0.412348f, 0.338321f, 0.273871f, 0.220643f, 0.178126f, 0.144810f, 0.118936f, 0.098862f, 0.083222f, 0.070938f, 0.061177f,
0.475299f, 0.474624f, 0.467361f, 0.444395f, 0.402093f, 0.347080f, 0.289879f, 0.237483f, 0.192720f, 0.156047f, 0.126763f, 0.103691f, 0.085592f, 0.071364f, 0.060105f, 0.051105f,
0.355635f, 0.355309f, 0.351653f, 0.339471f, 0.315018f, 0.279498f, 0.238732f, 0.198747f, 0.163098f, 0.132995f, 0.108395f, 0.088664f, 0.072951f, 0.060468f, 0.050498f, 0.042484f,
0.258839f, 0.258694f, 0.256965f, 0.250820f, 0.237477f, 0.216209f, 0.189367f, 0.160909f, 0.134053f, 0.110490f, 0.090686f, 0.074416f, 0.061247f, 0.050620f, 0.042052f, 0.035106f,
0.182182f, 0.182137f, 0.181485f, 0.178819f, 0.172315f, 0.160754f, 0.144609f, 0.125881f, 0.106938f, 0.089448f, 0.074192f, 0.061293f, 0.050610f, 0.041838f, 0.034667f, 0.028800f,
0.123026f, 0.123032f, 0.122967f, 0.122271f, 0.119864f, 0.114590f, 0.106047f, 0.094918f, 0.082604f, 0.070426f, 0.059254f, 0.049458f, 0.041103f, 0.034090f, 0.028258f, 0.023428f,
0.078830f, 0.078860f, 0.079083f, 0.079423f, 0.079305f, 0.077840f, 0.074317f, 0.068679f, 0.061526f, 0.053739f, 0.046077f, 0.038999f, 0.032737f, 0.027322f, 0.022725f, 0.018857f,
0.047156f, 0.047193f, 0.047519f, 0.048299f, 0.049293f, 0.049884f, 0.049376f, 0.047364f, 0.043929f, 0.039530f, 0.034717f, 0.029935f, 0.025475f, 0.021471f, 0.017973f, 0.014970f,
0.025680f, 0.025714f, 0.026033f, 0.026886f, 0.028229f, 0.029692f, 0.030715f, 0.030821f, 0.029816f, 0.027827f, 0.025185f, 0.022240f, 0.019271f, 0.016468f, 0.013924f, 0.011682f,
0.012206f, 0.012232f, 0.012485f, 0.013202f, 0.014441f, 0.016018f, 0.017552f, 0.018638f, 0.018987f, 0.018537f, 0.017416f, 0.015850f, 0.014066f, 0.012243f, 0.010500f, 0.008905f,
0.004678f, 0.004695f, 0.004861f, 0.005354f, 0.006264f, 0.007529f, 0.008944f, 0.010228f, 0.011122f, 0.011484f, 0.011305f, 0.010691f, 0.009782f, 0.008727f, 0.007631f, 0.006576f,
0.001211f, 0.001219f, 0.001303f, 0.001570f, 0.002095f, 0.002887f, 0.003870f, 0.004897f, 0.005793f, 0.006417f, 0.006703f, 0.006657f, 0.006345f, 0.005850f, 0.005258f, 0.004633f,
0.000120f, 0.000123f, 0.000150f, 0.000246f, 0.000456f, 0.000810f, 0.001303f, 0.001894f, 0.002501f, 0.003037f, 0.003428f, 0.003638f, 0.003669f, 0.003549f, 0.003321f, 0.003029f,
0.000000f, 0.000000f, 0.000004f, 0.000019f, 0.000060f, 0.000141f, 0.000277f, 0.000474f, 0.000723f, 0.001001f, 0.001274f, 0.001507f, 0.001674f, 0.001762f, 0.001772f, 0.001719f,
0.999750f, 0.948167f, 0.851251f, 0.742370f, 0.635608f, 0.538019f, 0.452702f, 0.380389f, 0.320449f, 0.271558f, 0.232130f, 0.200578f, 0.175441f, 0.155462f, 0.139586f, 0.126956f,
0.841573f, 0.838026f, 0.802800f, 0.724555f, 0.631762f, 0.538125f, 0.450920f, 0.375015f, 0.311718f, 0.260247f, 0.219001f, 0.186157f, 0.160067f, 0.139290f, 0.122683f, 0.109323f,
0.699246f, 0.697888f, 0.683427f, 0.640702f, 0.572126f, 0.494042f, 0.417929f, 0.349152f, 0.290090f, 0.241099f, 0.201336f, 0.169443f, 0.143967f, 0.123594f, 0.107218f, 0.093939f,
0.572433f, 0.571724f, 0.564068f, 0.539771f, 0.494762f, 0.435602f, 0.372915f, 0.313897f, 0.261817f, 0.217692f, 0.181298f, 0.151747f, 0.127926f, 0.108735f, 0.093214f, 0.080565f,
0.460525f, 0.460129f, 0.455761f, 0.441375f, 0.412699f, 0.371026f, 0.322759f, 0.274577f, 0.230577f, 0.192401f, 0.160332f, 0.133919f, 0.112368f, 0.094861f, 0.080596f, 0.068916f,
0.362887f, 0.362669f, 0.360188f, 0.351735f, 0.333952f, 0.306134f, 0.271236f, 0.234046f, 0.198478f, 0.166686f, 0.139400f, 0.116507f, 0.097593f, 0.082037f, 0.069269f, 0.058743f,
0.278855f, 0.278747f, 0.277443f, 0.272756f, 0.262309f, 0.244804f, 0.221161f, 0.194141f, 0.166853f, 0.141482f, 0.119087f, 0.099885f, 0.083739f, 0.070284f, 0.059117f, 0.049845f,
0.207729f, 0.207688f, 0.207133f, 0.204893f, 0.199408f, 0.189359f, 0.174590f, 0.156346f, 0.136682f, 0.117441f, 0.099801f, 0.084264f, 0.070904f, 0.059578f, 0.050050f, 0.042063f,
0.148771f, 0.148772f, 0.148687f, 0.148022f, 0.145825f, 0.140999f, 0.132887f, 0.121760f, 0.108695f, 0.095035f, 0.081861f, 0.069797f, 0.059134f, 0.049880f, 0.041968f, 0.035249f,
0.101193f, 0.101219f, 0.101408f, 0.101698f, 0.101587f, 0.100236f, 0.096858f, 0.091152f, 0.083471f, 0.074620f, 0.065445f, 0.056586f, 0.048432f, 0.041146f, 0.034772f, 0.029266f,
0.064150f, 0.064186f, 0.064507f, 0.065300f, 0.066370f, 0.067140f, 0.066866f, 0.065002f, 0.061433f, 0.056483f, 0.050720f, 0.044689f, 0.038804f, 0.033328f, 0.028385f, 0.024021f,
0.036722f, 0.036759f, 0.037110f, 0.038069f, 0.039639f, 0.041474f, 0.042967f, 0.043538f, 0.042822f, 0.040813f, 0.037786f, 0.034139f, 0.030241f, 0.026379f, 0.022734f, 0.019412f,
0.017889f, 0.017920f, 0.018227f, 0.019112f, 0.020683f, 0.022773f, 0.024969f, 0.026771f, 0.027756f, 0.027727f, 0.026722f, 0.024960f, 0.022713f, 0.020247f, 0.017751f, 0.015369f,
0.006492f, 0.006513f, 0.006728f, 0.007380f, 0.008606f, 0.010371f, 0.012457f, 0.014524f, 0.016211f, 0.017254f, 0.017552f, 0.017149f, 0.016199f, 0.014883f, 0.013379f, 0.011821f,
0.001148f, 0.001157f, 0.001262f, 0.001602f, 0.002293f, 0.003381f, 0.004810f, 0.006427f, 0.008014f, 0.009347f, 0.010264f, 0.010694f, 0.010662f, 0.010246f, 0.009561f, 0.008716f,
0.000000f, 0.000001f, 0.000016f, 0.000083f, 0.000255f, 0.000594f, 0.001145f, 0.001914f, 0.002851f, 0.003855f, 0.004798f, 0.005563f, 0.006070f, 0.006293f, 0.006251f, 0.006000f,
0.999818f, 0.959747f, 0.881767f, 0.790918f, 0.698524f, 0.610892f, 0.531385f, 0.461464f, 0.401366f, 0.350581f, 0.308204f, 0.273165f, 0.244368f, 0.220799f, 0.201547f, 0.185831f,
0.882107f, 0.879024f, 0.847747f, 0.778845f, 0.697900f, 0.613959f, 0.532297f, 0.458048f, 0.393533f, 0.339004f, 0.293687f, 0.256345f, 0.225719f, 0.200597f, 0.179966f, 0.162950f,
0.770910f, 0.769686f, 0.756386f, 0.716566f, 0.652262f, 0.578275f, 0.504304f, 0.434994f, 0.373074f, 0.319675f, 0.274705f, 0.237366f, 0.206570f, 0.181207f, 0.160267f, 0.142871f,
0.666500f, 0.665811f, 0.658300f, 0.634211f, 0.589184f, 0.529383f, 0.464907f, 0.402564f, 0.345691f, 0.295761f, 0.253106f, 0.217297f, 0.187518f, 0.162834f, 0.142343f, 0.125246f,
0.568975f, 0.568551f, 0.563862f, 0.548395f, 0.517460f, 0.472214f, 0.419174f, 0.365195f, 0.314598f, 0.269359f, 0.230147f, 0.196845f, 0.168874f, 0.145532f, 0.126039f, 0.109712f,
0.478447f, 0.478179f, 0.475173f, 0.465056f, 0.443961f, 0.411068f, 0.369645f, 0.324995f, 0.281504f, 0.241713f, 0.206665f, 0.176474f, 0.150879f, 0.129314f, 0.111204f, 0.095957f,
0.395038f, 0.394874f, 0.392988f, 0.386475f, 0.372412f, 0.349351f, 0.318525f, 0.283306f, 0.247440f, 0.213598f, 0.183155f, 0.156513f, 0.133631f, 0.114164f, 0.097683f, 0.083734f,
0.318885f, 0.318791f, 0.317690f, 0.313730f, 0.304826f, 0.289465f, 0.267723f, 0.241402f, 0.213219f, 0.185564f, 0.159976f, 0.137143f, 0.117213f, 0.100045f, 0.085363f, 0.072852f,
0.250146f, 0.250104f, 0.249568f, 0.247467f, 0.242380f, 0.232996f, 0.218770f, 0.200397f, 0.179529f, 0.158053f, 0.137438f, 0.118515f, 0.101669f, 0.086905f, 0.074128f, 0.063133f,
0.189005f, 0.189001f, 0.188867f, 0.188116f, 0.185859f, 0.181033f, 0.172854f, 0.161266f, 0.147043f, 0.131458f, 0.115732f, 0.100746f, 0.087004f, 0.074699f, 0.063863f, 0.054416f,
0.135677f, 0.135698f, 0.135843f, 0.136039f, 0.135817f, 0.134379f, 0.130882f, 0.124850f, 0.116400f, 0.106181f, 0.095093f, 0.083926f, 0.073242f, 0.063383f, 0.054486f, 0.046593f,
0.090429f, 0.090465f, 0.090784f, 0.091592f, 0.092733f, 0.093666f, 0.093601f, 0.091871f, 0.088149f, 0.082597f, 0.075718f, 0.068139f, 0.060407f, 0.052917f, 0.045915f, 0.039538f,
0.053598f, 0.053640f, 0.054042f, 0.055165f, 0.057077f, 0.059453f, 0.061653f, 0.062968f, 0.062841f, 0.061081f, 0.057832f, 0.053488f, 0.048492f, 0.043261f, 0.038082f, 0.033174f,
0.025644f, 0.025684f, 0.026078f, 0.027240f, 0.029362f, 0.032308f, 0.035637f, 0.038733f, 0.040991f, 0.042002f, 0.041651f, 0.040059f, 0.037525f, 0.034375f, 0.030926f, 0.027415f,
0.007272f, 0.007301f, 0.007596f, 0.008505f, 0.010265f, 0.012902f, 0.016201f, 0.019765f, 0.023100f, 0.025748f, 0.027405f, 0.027967f, 0.027515f, 0.026238f, 0.024388f, 0.022203f,
0.000000f, 0.000004f, 0.000069f, 0.000340f, 0.001018f, 0.002287f, 0.004235f, 0.006797f, 0.009739f, 0.012714f, 0.015347f, 0.017332f, 0.018498f, 0.018827f, 0.018426f, 0.017473f,
0.999875f, 0.970334f, 0.910852f, 0.839095f, 0.763548f, 0.689346f, 0.619611f, 0.556084f, 0.499536f, 0.450073f, 0.407382f, 0.370904f, 0.339959f, 0.313848f, 0.291888f, 0.273457f,
0.917373f, 0.914766f, 0.887717f, 0.829379f, 0.763012f, 0.692852f, 0.621457f, 0.553534f, 0.491968f, 0.437825f, 0.391099f, 0.351188f, 0.317314f, 0.288613f, 0.264309f, 0.243681f,
0.836210f, 0.835165f, 0.823521f, 0.788156f, 0.731077f, 0.665389f, 0.598432f, 0.533423f, 0.472908f, 0.418522f, 0.370866f, 0.329775f, 0.294652f, 0.264738f, 0.239253f, 0.217456f,
0.756593f, 0.755976f, 0.749116f, 0.726755f, 0.684529f, 0.628045f, 0.566351f, 0.505220f, 0.447530f, 0.394912f, 0.348183f, 0.307448f, 0.272338f, 0.242236f, 0.216450f, 0.194298f,
0.678620f, 0.678212f, 0.673644f, 0.658403f, 0.627617f, 0.582172f, 0.528260f, 0.472345f, 0.418498f, 0.368741f, 0.324052f, 0.284717f, 0.250517f, 0.221023f, 0.195627f, 0.173738f,
0.602401f, 0.602118f, 0.598925f, 0.588143f, 0.565564f, 0.530151f, 0.485149f, 0.435932f, 0.386961f, 0.340923f, 0.299100f, 0.261891f, 0.229320f, 0.201019f, 0.176549f, 0.155380f,
0.528067f, 0.527869f, 0.525620f, 0.517922f, 0.501406f, 0.474397f, 0.438211f, 0.396521f, 0.353432f, 0.311918f, 0.273625f, 0.239180f, 0.208750f, 0.182138f, 0.158998f, 0.138911f,
0.455773f, 0.455636f, 0.454085f, 0.448679f, 0.436835f, 0.416791f, 0.388718f, 0.354808f, 0.318286f, 0.281994f, 0.247808f, 0.216654f, 0.188828f, 0.164292f, 0.142814f, 0.124093f,
0.385708f, 0.385621f, 0.384613f, 0.381010f, 0.372874f, 0.358637f, 0.337818f, 0.311493f, 0.281860f, 0.251341f, 0.221814f, 0.194368f, 0.169537f, 0.147385f, 0.127850f, 0.110710f,
0.318108f, 0.318063f, 0.317492f, 0.315344f, 0.310249f, 0.300878f, 0.286471f, 0.267275f, 0.244563f, 0.220145f, 0.195687f, 0.172360f, 0.150826f, 0.131342f, 0.113954f, 0.098563f,
0.253279f, 0.253265f, 0.253053f, 0.252101f, 0.249524f, 0.244273f, 0.235467f, 0.222827f, 0.206852f, 0.188648f, 0.169547f, 0.150645f, 0.132683f, 0.116091f, 0.101025f, 0.087520f,
0.191629f, 0.191643f, 0.191725f, 0.191755f, 0.191265f, 0.189491f, 0.185536f, 0.178799f, 0.169162f, 0.157111f, 0.143499f, 0.129246f, 0.115101f, 0.101575f, 0.088963f, 0.077426f,
0.133748f, 0.133783f, 0.134103f, 0.134927f, 0.136142f, 0.137238f, 0.137408f, 0.135848f, 0.132013f, 0.125849f, 0.117706f, 0.108220f, 0.098035f, 0.087730f, 0.077685f, 0.068193f,
0.080570f, 0.080621f, 0.081114f, 0.082539f, 0.085062f, 0.088415f, 0.091925f, 0.094722f, 0.095994f, 0.095233f, 0.092359f, 0.087618f, 0.081495f, 0.074498f, 0.067115f, 0.059712f,
0.033876f, 0.033934f, 0.034517f, 0.036278f, 0.039601f, 0.044444f, 0.050311f, 0.056411f, 0.061826f, 0.065758f, 0.067710f, 0.067549f, 0.065471f, 0.061854f, 0.057183f, 0.051915f,
0.000000f, 0.000026f, 0.000366f, 0.001608f, 0.004343f, 0.008898f, 0.015196f, 0.022734f, 0.030687f, 0.038103f, 0.044120f, 0.048155f, 0.049992f, 0.049760f, 0.047839f, 0.044722f,
0.999923f, 0.980285f, 0.939385f, 0.888316f, 0.832710f, 0.776218f, 0.721284f, 0.669496f, 0.621789f, 0.578611f, 0.540065f, 0.506017f, 0.476178f, 0.450188f, 0.427646f, 0.408150f,
0.948312f, 0.946192f, 0.923628f, 0.877097f, 0.828280f, 0.776594f, 0.721241f, 0.665774f, 0.613090f, 0.564716f, 0.521231f, 0.482599f, 0.448544f, 0.418606f, 0.392341f, 0.369270f,
0.895765f, 0.894938f, 0.885381f, 0.855934f, 0.809109f, 0.756404f, 0.702362f, 0.648041f, 0.595124f, 0.545291f, 0.499600f, 0.458452f, 0.421781f, 0.389274f, 0.360498f, 0.334972f,
0.842275f, 0.841774f, 0.836042f, 0.816927f, 0.780509f, 0.731894f, 0.678709f, 0.625032f, 0.572600f, 0.522686f, 0.476313f, 0.434037f, 0.395981f, 0.361965f, 0.331645f, 0.304604f,
0.787745f, 0.787398f, 0.783420f, 0.769858f, 0.742043f, 0.700630f, 0.651146f, 0.599080f, 0.547602f, 0.498275f, 0.452084f, 0.409621f, 0.371073f, 0.336412f, 0.305359f, 0.277564f,
0.732057f, 0.731800f, 0.728845f, 0.718696f, 0.697130f, 0.662914f, 0.618966f, 0.570218f, 0.520636f, 0.472579f, 0.427276f, 0.385311f, 0.347034f, 0.312405f, 0.281277f, 0.253345f,
0.675067f, 0.674871f, 0.672614f, 0.664807f, 0.647889f, 0.619958f, 0.582159f, 0.538039f, 0.491578f, 0.445652f, 0.401916f, 0.361134f, 0.323719f, 0.289742f, 0.259094f, 0.231539f,
0.616594f, 0.616441f, 0.614705f, 0.608654f, 0.595378f, 0.572846f, 0.541121f, 0.502452f, 0.460201f, 0.417350f, 0.375914f, 0.336980f, 0.301036f, 0.268249f, 0.238569f, 0.211847f,
0.556403f, 0.556288f, 0.554973f, 0.550349f, 0.540054f, 0.522222f, 0.496283f, 0.463467f, 0.426271f, 0.387453f, 0.349168f, 0.312726f, 0.278850f, 0.247750f, 0.219506f, 0.193991f,
0.494188f, 0.494107f, 0.493150f, 0.489746f, 0.482039f, 0.468381f, 0.447936f, 0.421137f, 0.389642f, 0.355715f, 0.321421f, 0.288227f, 0.256991f, 0.228100f, 0.201689f, 0.177725f,
0.429520f, 0.429467f, 0.428835f, 0.426527f, 0.421153f, 0.411346f, 0.396145f, 0.375460f, 0.350189f, 0.321928f, 0.292483f, 0.263300f, 0.235337f, 0.209162f, 0.184983f, 0.162877f,
0.361774f, 0.361750f, 0.361426f, 0.360147f, 0.356972f, 0.350836f, 0.340759f, 0.326298f, 0.307675f, 0.285836f, 0.262097f, 0.237742f, 0.213771f, 0.190821f, 0.169248f, 0.149248f,
0.289955f, 0.289958f, 0.289944f, 0.289691f, 0.288697f, 0.286201f, 0.281301f, 0.273273f, 0.261790f, 0.247133f, 0.230004f, 0.211370f, 0.192101f, 0.172946f, 0.154369f, 0.136732f,
0.212264f, 0.212298f, 0.212612f, 0.213460f, 0.214779f, 0.216127f, 0.216709f, 0.215589f, 0.211950f, 0.205350f, 0.195861f, 0.183911f, 0.170196f, 0.155414f, 0.140237f, 0.125187f,
0.124542f, 0.124614f, 0.125342f, 0.127534f, 0.131650f, 0.137579f, 0.144578f, 0.151482f, 0.156928f, 0.159732f, 0.159170f, 0.155089f, 0.147856f, 0.138132f, 0.126755f, 0.114528f,
0.000000f, 0.000457f, 0.003430f, 0.010522f, 0.022216f, 0.037967f, 0.056414f, 0.075680f, 0.093709f, 0.108640f, 0.119118f, 0.124502f, 0.124891f, 0.120985f, 0.113852f, 0.104653f,
0.999964f, 0.989978f, 0.968492f, 0.940685f, 0.909376f, 0.876485f, 0.843404f, 0.811139f, 0.780384f, 0.751580f, 0.724971f, 0.700657f, 0.678620f, 0.658778f, 0.640997f, 0.625118f,
0.975661f, 0.974039f, 0.956274f, 0.923086f, 0.895543f, 0.868397f, 0.836882f, 0.802624f, 0.767866f, 0.734104f, 0.702159f, 0.672348f, 0.644785f, 0.619379f, 0.596032f, 0.574559f,
0.950177f, 0.949601f, 0.942548f, 0.920564f, 0.887449f, 0.853479f, 0.820136f, 0.785575f, 0.749777f, 0.713781f, 0.678641f, 0.645052f, 0.613352f, 0.583659f, 0.555921f, 0.530007f,
0.923399f, 0.923057f, 0.918925f, 0.904660f, 0.877462f, 0.842299f, 0.805230f, 0.768027f, 0.730447f, 0.692625f, 0.655217f, 0.618891f, 0.584104f, 0.551096f, 0.519939f, 0.490586f,
0.895145f, 0.894905f, 0.892014f, 0.881756f, 0.860282f, 0.828322f, 0.790615f, 0.751141f, 0.711389f, 0.671663f, 0.632322f, 0.593867f, 0.556707f, 0.521191f, 0.487451f, 0.455513f,
0.865188f, 0.865003f, 0.862785f, 0.854873f, 0.837580f, 0.809739f, 0.773816f, 0.733808f, 0.692460f, 0.651030f, 0.610056f, 0.569869f, 0.530950f, 0.493552f, 0.457920f, 0.424124f,
0.833237f, 0.833088f, 0.831306f, 0.824917f, 0.810666f, 0.786632f, 0.753648f, 0.714675f, 0.672903f, 0.630384f, 0.588168f, 0.546726f, 0.506509f, 0.467829f, 0.430912f, 0.395874f,
0.798913f, 0.798787f, 0.797313f, 0.792016f, 0.780086f, 0.759377f, 0.729689f, 0.692901f, 0.651906f, 0.609176f, 0.566301f, 0.524135f, 0.483158f, 0.443722f, 0.406065f, 0.370369f,
0.761707f, 0.761602f, 0.760369f, 0.755935f, 0.745854f, 0.728061f, 0.701728f, 0.667847f, 0.628686f, 0.586778f, 0.544075f, 0.501775f, 0.460618f, 0.420954f, 0.383113f, 0.347242f,
0.720906f, 0.720819f, 0.719790f, 0.716083f, 0.707605f, 0.692421f, 0.669445f, 0.638950f, 0.602543f, 0.562502f, 0.520916f, 0.479294f, 0.438573f, 0.399282f, 0.361746f, 0.326177f,
0.675460f, 0.675388f, 0.674545f, 0.671502f, 0.664492f, 0.651796f, 0.632197f, 0.605519f, 0.572740f, 0.535645f, 0.496274f, 0.456273f, 0.416762f, 0.378477f, 0.341781f, 0.306948f,
0.623719f, 0.623664f, 0.623009f, 0.620619f, 0.615064f, 0.604885f, 0.588856f, 0.566510f, 0.538238f, 0.505318f, 0.469441f, 0.432222f, 0.394919f, 0.358349f, 0.323018f, 0.289287f,
0.562818f, 0.562781f, 0.562337f, 0.560670f, 0.556720f, 0.549314f, 0.537348f, 0.520128f, 0.497562f, 0.470326f, 0.439549f, 0.406601f, 0.372644f, 0.338665f, 0.305294f, 0.273067f,
0.486943f, 0.486931f, 0.486754f, 0.486029f, 0.484127f, 0.480251f, 0.473480f, 0.462959f, 0.448093f, 0.428744f, 0.405336f, 0.378609f, 0.349577f, 0.319207f, 0.288454f, 0.258098f,
0.380161f, 0.380192f, 0.380496f, 0.381395f, 0.383000f, 0.385053f, 0.386779f, 0.386986f, 0.384183f, 0.377028f, 0.364714f, 0.347200f, 0.325180f, 0.299771f, 0.272356f, 0.244265f,
0.000000f, 0.020267f, 0.054131f, 0.094938f, 0.139128f, 0.183506f, 0.225014f, 0.260811f, 0.288479f, 0.306323f, 0.313595f, 0.310639f, 0.298794f, 0.280100f, 0.256901f, 0.231442f,
0.999995f, 0.998398f, 0.995006f, 0.990413f, 0.985087f, 0.979328f, 0.973364f, 0.967374f, 0.961495f, 0.955821f, 0.950420f, 0.945337f, 0.940588f, 0.936183f, 0.932118f, 0.928379f,
0.996522f, 0.995341f, 0.982040f, 0.961965f, 0.956747f, 0.957435f, 0.955399f, 0.949932f, 0.942096f, 0.932835f, 0.922755f, 0.912156f, 0.901250f, 0.890101f, 0.878806f, 0.867374f,
0.992799f, 0.992465f, 0.987919f, 0.973778f, 0.955884f, 0.944121f, 0.937349f, 0.930660f, 0.921771f, 0.910424f, 0.897056f, 0.882175f, 0.866150f, 0.849277f, 0.831713f, 0.813583f,
0.988793f, 0.988620f, 0.986255f, 0.977598f, 0.961631f, 0.943851f, 0.929168f, 0.917009f, 0.904678f, 0.890468f, 0.873944f, 0.855284f, 0.834826f, 0.812918f, 0.789858f, 0.765878f,
0.984458f, 0.984346f, 0.982815f, 0.976893f, 0.964185f, 0.946091f, 0.926901f, 0.909048f, 0.891907f, 0.873813f, 0.853717f, 0.831334f, 0.806756f, 0.780341f, 0.752426f, 0.723319f,
0.979730f, 0.979650f, 0.978521f, 0.974088f, 0.963840f, 0.947213f, 0.926500f, 0.904677f, 0.882823f, 0.860383f, 0.836377f, 0.810124f, 0.781627f, 0.751024f, 0.718729f, 0.685105f,
0.974531f, 0.974467f, 0.973574f, 0.970016f, 0.961484f, 0.946539f, 0.925918f, 0.901858f, 0.876268f, 0.849638f, 0.821563f, 0.791412f, 0.759026f, 0.724525f, 0.688237f, 0.650576f,
0.968751f, 0.968694f, 0.967947f, 0.964948f, 0.957632f, 0.944200f, 0.924343f, 0.899362f, 0.871147f, 0.840882f, 0.808853f, 0.774856f, 0.738694f, 0.700468f, 0.660494f, 0.619274f,
0.962240f, 0.962190f, 0.961542f, 0.958938f, 0.952485f, 0.940330f, 0.921476f, 0.896401f, 0.866549f, 0.833414f, 0.797852f, 0.760120f, 0.720323f, 0.678541f, 0.635195f, 0.590762f,
0.954777f, 0.954735f, 0.954158f, 0.951840f, 0.946057f, 0.934941f, 0.917160f, 0.892478f, 0.861800f, 0.826566f, 0.788005f, 0.746868f, 0.703574f, 0.658463f, 0.611959f, 0.564676f,
0.946026f, 0.945986f, 0.945463f, 0.943369f, 0.938117f, 0.927899f, 0.911159f, 0.887193f, 0.856357f, 0.819768f, 0.778852f, 0.734736f, 0.688214f, 0.639978f, 0.590583f, 0.540752f,
0.935424f, 0.935389f, 0.934911f, 0.932998f, 0.928190f, 0.918777f, 0.903081f, 0.880080f, 0.849596f, 0.812419f, 0.769870f, 0.723333f, 0.674027f, 0.622911f, 0.570832f, 0.518665f,
0.921931f, 0.921898f, 0.921467f, 0.919724f, 0.915339f, 0.906699f, 0.892131f, 0.870358f, 0.840796f, 0.803833f, 0.760501f, 0.712301f, 0.660664f, 0.607019f, 0.552515f, 0.498283f,
0.903244f, 0.903216f, 0.902829f, 0.901293f, 0.897392f, 0.889659f, 0.876494f, 0.856476f, 0.828686f, 0.792953f, 0.750000f, 0.701077f, 0.647884f, 0.592113f, 0.535459f, 0.479380f,
0.872171f, 0.872149f, 0.871852f, 0.870662f, 0.867630f, 0.861543f, 0.850923f, 0.834276f, 0.810200f, 0.777828f, 0.737128f, 0.689031f, 0.635288f, 0.578015f, 0.519501f, 0.461815f,
0.000000f, 0.559516f, 0.644881f, 0.698590f, 0.736655f, 0.762997f, 0.778331f, 0.782183f, 0.773776f, 0.752689f, 0.719302f, 0.675070f, 0.622442f, 0.564517f, 0.504549f, 0.445448f
};
CCL_NAMESPACE_END