Cycles: unify math functions names

This patch unifies the names of math functions for different data types and uses
overloading instead. The goal is to make it possible to swap out all the float3
variables containing RGB data with something else, with as few as possible
changes to the code. It's a requirement for future spectral rendering patches.

Differential Revision: https://developer.blender.org/D15276
This commit is contained in:
Andrii Symkin 2022-06-23 14:29:17 +02:00 committed by Brecht Van Lommel
parent b8403b065e
commit c2a2f3553a
32 changed files with 129 additions and 123 deletions

View File

@ -29,14 +29,14 @@ ccl_device void kernel_displace_evaluate(KernelGlobals kg,
object_inverse_dir_transform(kg, &sd, &D);
#ifdef __KERNEL_DEBUG_NAN__
if (!isfinite3_safe(D)) {
if (!isfinite_safe(D)) {
kernel_assert(!"Cycles displacement with non-finite value detected");
}
#endif
/* Ensure finite displacement, preventing BVH from becoming degenerate and avoiding possible
* traversal issues caused by non-finite math. */
D = ensure_finite3(D);
D = ensure_finite(D);
/* Write output. */
output[offset * 3 + 0] += D.x;
@ -68,13 +68,13 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg,
float3 color = shader_background_eval(&sd);
#ifdef __KERNEL_DEBUG_NAN__
if (!isfinite3_safe(color)) {
if (!isfinite_safe(color)) {
kernel_assert(!"Cycles background with non-finite value detected");
}
#endif
/* Ensure finite color, avoiding possible numerical instabilities in the path tracing kernels. */
color = ensure_finite3(color);
color = ensure_finite(color);
/* Write output. */
output[offset * 3 + 0] += color.x;

View File

@ -51,7 +51,7 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *
int size,
float3 weight)
{
kernel_assert(isfinite3_safe(weight));
kernel_assert(isfinite_safe(weight));
const float sample_weight = fabsf(average(weight));
@ -77,7 +77,7 @@ ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
float3 weight,
void *data)
{
kernel_assert(isfinite3_safe(weight));
kernel_assert(isfinite_safe(weight));
const float sample_weight = fabsf(average(weight));

View File

@ -439,7 +439,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
*eval *= shift_cos_in(dot(*omega_in, sc->N), frequency_multiplier);
}
if (label & LABEL_DIFFUSE) {
if (!isequal_float3(sc->N, sd->N)) {
if (!isequal(sc->N, sd->N)) {
*eval *= bump_shadowing_term((label & LABEL_TRANSMIT) ? -sd->N : sd->N, sc->N, *omega_in);
}
}
@ -550,7 +550,7 @@ ccl_device_inline
break;
}
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
if (!isequal_float3(sc->N, sd->N)) {
if (!isequal(sc->N, sd->N)) {
eval *= bump_shadowing_term(sd->N, sc->N, omega_in);
}
}
@ -635,7 +635,7 @@ ccl_device_inline
break;
}
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
if (!isequal_float3(sc->N, sd->N)) {
if (!isequal(sc->N, sd->N)) {
eval *= bump_shadowing_term(-sd->N, sc->N, omega_in);
}
}

View File

@ -203,7 +203,7 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : dot(cross(sd->Ng, X), Z);
kernel_assert(fabsf(h) < 1.0f + 1e-4f);
kernel_assert(isfinite3_safe(Y));
kernel_assert(isfinite_safe(Y));
kernel_assert(isfinite_safe(h));
bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
@ -272,7 +272,7 @@ ccl_device float3 bsdf_principled_hair_eval(KernelGlobals kg,
const float3 omega_in,
ccl_private float *pdf)
{
kernel_assert(isfinite3_safe(sd->P) && isfinite_safe(sd->ray_length));
kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length));
ccl_private const PrincipledHairBSDF *bsdf = (ccl_private const PrincipledHairBSDF *)sc;
float3 Y = float4_to_float3(bsdf->extra->geom);
@ -299,7 +299,7 @@ ccl_device float3 bsdf_principled_hair_eval(KernelGlobals kg,
float cos_gamma_t = cos_from_sin(sin_gamma_t);
float gamma_t = safe_asinf(sin_gamma_t);
float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
float3 T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
float4 Ap[4];
hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
@ -319,25 +319,25 @@ ccl_device float3 bsdf_principled_hair_eval(KernelGlobals kg,
Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
F = Ap[0] * Mp * Np;
kernel_assert(isfinite3_safe(float4_to_float3(F)));
kernel_assert(isfinite_safe(float4_to_float3(F)));
/* Transmission (TT). */
Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
F += Ap[1] * Mp * Np;
kernel_assert(isfinite3_safe(float4_to_float3(F)));
kernel_assert(isfinite_safe(float4_to_float3(F)));
/* Secondary specular (TRT). */
Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
F += Ap[2] * Mp * Np;
kernel_assert(isfinite3_safe(float4_to_float3(F)));
kernel_assert(isfinite_safe(float4_to_float3(F)));
/* Residual component (TRRT+). */
Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
Np = M_1_2PI_F;
F += Ap[3] * Mp * Np;
kernel_assert(isfinite3_safe(float4_to_float3(F)));
kernel_assert(isfinite_safe(float4_to_float3(F)));
*pdf = F.w;
return float4_to_float3(F);
@ -385,7 +385,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
float cos_gamma_t = cos_from_sin(sin_gamma_t);
float gamma_t = safe_asinf(sin_gamma_t);
float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
float3 T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
float4 Ap[4];
hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap);
@ -436,25 +436,25 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness);
Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t);
F = Ap[0] * Mp * Np;
kernel_assert(isfinite3_safe(float4_to_float3(F)));
kernel_assert(isfinite_safe(float4_to_float3(F)));
/* Transmission (TT). */
Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v);
Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t);
F += Ap[1] * Mp * Np;
kernel_assert(isfinite3_safe(float4_to_float3(F)));
kernel_assert(isfinite_safe(float4_to_float3(F)));
/* Secondary specular (TRT). */
Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t);
F += Ap[2] * Mp * Np;
kernel_assert(isfinite3_safe(float4_to_float3(F)));
kernel_assert(isfinite_safe(float4_to_float3(F)));
/* Residual component (TRRT+). */
Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
Np = M_1_2PI_F;
F += Ap[3] * Mp * Np;
kernel_assert(isfinite3_safe(float4_to_float3(F)));
kernel_assert(isfinite_safe(float4_to_float3(F)));
*eval = float4_to_float3(F);
*pdf = F.w;
@ -492,13 +492,13 @@ ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(
ccl_device float3 bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc)
{
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
return exp3(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
return exp(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
}
ccl_device_inline float3
bsdf_principled_hair_sigma_from_reflectance(const float3 color, const float azimuthal_roughness)
{
const float3 sigma = log3(color) /
const float3 sigma = log(color) /
bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness);
return sigma * sigma;
}

View File

@ -310,7 +310,7 @@ ccl_device int bsdf_microfacet_ggx_isotropic_setup(ccl_private MicrofacetBsdf *b
ccl_device int bsdf_microfacet_ggx_fresnel_setup(ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd)
{
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = saturatef(bsdf->alpha_y);
@ -325,7 +325,7 @@ ccl_device int bsdf_microfacet_ggx_fresnel_setup(ccl_private MicrofacetBsdf *bsd
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd)
{
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
bsdf->alpha_x = saturatef(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;

View File

@ -377,8 +377,8 @@ ccl_device int bsdf_microfacet_multi_ggx_common_setup(ccl_private MicrofacetBsdf
{
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
bsdf->extra->color = saturate3(bsdf->extra->color);
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
bsdf->extra->color = saturate(bsdf->extra->color);
bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
@ -565,7 +565,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_setup(ccl_private MicrofacetBsdf
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = max(0.0f, bsdf->ior);
bsdf->extra->color = saturate3(bsdf->extra->color);
bsdf->extra->color = saturate(bsdf->extra->color);
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
@ -578,8 +578,8 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->ior = max(0.0f, bsdf->ior);
bsdf->extra->color = saturate3(bsdf->extra->color);
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
bsdf->extra->color = saturate(bsdf->extra->color);
bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID;

View File

@ -166,7 +166,7 @@ ccl_device int volume_phase_sample(ccl_private const ShaderData *sd,
ccl_device float3 volume_color_transmittance(float3 sigma, float t)
{
return exp3(-sigma * t);
return exp(-sigma * t);
}
ccl_device float volume_channel_get(float3 value, int channel)

View File

@ -62,7 +62,7 @@ ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float value)
eval->sum *= value;
}
ccl_device_inline void bsdf_eval_mul3(ccl_private BsdfEval *eval, float3 value)
ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float3 value)
{
eval->diffuse *= value;
eval->glossy *= value;
@ -78,14 +78,14 @@ ccl_device_inline float3 bsdf_eval_pass_diffuse_weight(ccl_private const BsdfEva
{
/* Ratio of diffuse weight to recover proportions for writing to render pass.
* We assume reflection, transmission and volume scatter to be exclusive. */
return safe_divide_float3_float3(eval->diffuse, eval->sum);
return safe_divide(eval->diffuse, eval->sum);
}
ccl_device_inline float3 bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval *eval)
{
/* Ratio of glossy weight to recover proportions for writing to render pass.
* We assume reflection, transmission and volume scatter to be exclusive. */
return safe_divide_float3_float3(eval->glossy, eval->sum);
return safe_divide(eval->glossy, eval->sum);
}
/* --------------------------------------------------------------------
@ -98,14 +98,14 @@ ccl_device_inline float3 bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval
ccl_device_forceinline void kernel_accum_clamp(KernelGlobals kg, ccl_private float3 *L, int bounce)
{
#ifdef __KERNEL_DEBUG_NAN__
if (!isfinite3_safe(*L)) {
if (!isfinite_safe(*L)) {
kernel_assert(!"Cycles sample with non-finite value detected");
}
#endif
/* Make sure all components are finite, allowing the contribution to be usable by adaptive
* sampling convergence check, but also to make it so render result never causes issues with
* post-processing. */
*L = ensure_finite3(*L);
*L = ensure_finite(*L);
#ifdef __CLAMP_SAMPLE__
float limit = (bounce > 0) ? kernel_data.integrator.sample_clamp_indirect :
@ -518,7 +518,7 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
const float3 unshadowed_throughput = INTEGRATOR_STATE(
state, shadow_path, unshadowed_throughput);
const float3 shadowed_throughput = INTEGRATOR_STATE(state, shadow_path, throughput);
const float3 shadow = safe_divide_float3_float3(shadowed_throughput, unshadowed_throughput) *
const float3 shadow = safe_divide(shadowed_throughput, unshadowed_throughput) *
kernel_data.film.pass_shadow_scale;
kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow, shadow);
}

View File

@ -108,15 +108,14 @@ ccl_device_forceinline void kernel_write_denoising_features_surface(
const Transform worldtocamera = kernel_data.cam.worldtocamera;
normal = transform_direction(&worldtocamera, normal);
const float3 denoising_normal = ensure_finite3(normal);
const float3 denoising_normal = ensure_finite(normal);
kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_normal, denoising_normal);
}
if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
const float3 denoising_feature_throughput = INTEGRATOR_STATE(
state, path, denoising_feature_throughput);
const float3 denoising_albedo = ensure_finite3(denoising_feature_throughput *
diffuse_albedo);
const float3 denoising_albedo = ensure_finite(denoising_feature_throughput * diffuse_albedo);
kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
}
@ -149,7 +148,7 @@ ccl_device_forceinline void kernel_write_denoising_features_volume(KernelGlobals
if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
/* Write albedo. */
const float3 denoising_albedo = ensure_finite3(denoising_feature_throughput * albedo);
const float3 denoising_albedo = ensure_finite(denoising_feature_throughput * albedo);
kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
}
}

View File

@ -555,7 +555,7 @@ ccl_device_inline bool ribbon_intersect(const float3 ray_org,
/* Evaluate first point and radius scaled normal direction. */
float4 p0 = catmull_rom_basis_eval(curve, 0.0f);
float3 dp0dt = float4_to_float3(catmull_rom_basis_derivative(curve, 0.0f));
if (max3(fabs(dp0dt)) < eps) {
if (reduce_max(fabs(dp0dt)) < eps) {
const float4 p1 = catmull_rom_basis_eval(curve, step_size);
dp0dt = float4_to_float3(p1 - p0);
}
@ -570,7 +570,7 @@ ccl_device_inline bool ribbon_intersect(const float3 ray_org,
/* Evaluate next point. */
float3 dp1dt = float4_to_float3(catmull_rom_basis_derivative(curve, u + step_size));
dp1dt = (max3(fabs(dp1dt)) < eps) ? float4_to_float3(p1 - p0) : dp1dt;
dp1dt = (reduce_max(fabs(dp1dt)) < eps) ? float4_to_float3(p1 - p0) : dp1dt;
const float3 wn1 = normalize(make_float3(dp1dt.y, -dp1dt.x, 0.0f)) * p1.w;
if (valid) {
@ -729,7 +729,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
/* NOTE: It is possible that P will be the same as P_inside (precision issues, or very small
* radius). In this case use the view direction to approximate the normal. */
const float3 P_inside = float4_to_float3(catmull_rom_basis_eval(P_curve, sd->u));
const float3 N = (!isequal_float3(P, P_inside)) ? normalize(P - P_inside) : -sd->I;
const float3 N = (!isequal(P, P_inside)) ? normalize(P - P_inside) : -sd->I;
sd->N = N;
sd->v = 0.0f;

View File

@ -49,7 +49,8 @@ ccl_device const float2 bake_offset_towards_center(KernelGlobals kg,
const float3 to_center = center - P;
const float3 offset_P = P + normalize(to_center) *
min(len(to_center), max(max3(fabs(P)), 1.0f) * position_offset);
min(len(to_center),
max(reduce_max(fabs(P)), 1.0f) * position_offset);
/* Compute barycentric coordinates at new position. */
const float3 v1 = tri_verts[1] - tri_verts[0];

View File

@ -830,7 +830,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce + vertex_count;
float3 light_eval = light_sample_shader_eval(kg, state, sd_mnee, ls, sd->time);
bsdf_eval_mul3(throughput, light_eval / ls->pdf);
bsdf_eval_mul(throughput, light_eval / ls->pdf);
/* Generalized geometry term. */
@ -918,7 +918,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
* divided by corresponding sampled pdf:
* fr(vi)_do / pdf_dh(vi) x |do/dh| x |n.wo / n.h| */
float3 bsdf_contribution = mnee_eval_bsdf_contribution(v.bsdf, wi, wo);
bsdf_eval_mul3(throughput, bsdf_contribution);
bsdf_eval_mul(throughput, bsdf_contribution);
}
/* Restore original state path bounce info. */

View File

@ -250,7 +250,7 @@ ccl_device_inline float path_state_continuation_probability(KernelGlobals kg,
/* Probabilistic termination: use sqrt() to roughly match typical view
* transform and do path termination a bit later on average. */
return min(sqrtf(max3(fabs(INTEGRATOR_STATE(state, path, throughput)))), 1.0f);
return min(sqrtf(reduce_max(fabs(INTEGRATOR_STATE(state, path, throughput)))), 1.0f);
}
ccl_device_inline bool path_state_ao_bounce(KernelGlobals kg, ConstIntegratorState state)

View File

@ -48,7 +48,7 @@ ccl_device_forceinline bool integrate_surface_holdout(KernelGlobals kg,
const float transparent = average(holdout_weight * throughput);
kernel_accum_holdout(kg, state, path_flag, transparent, render_buffer);
}
if (isequal_float3(holdout_weight, one_float3())) {
if (isequal(holdout_weight, one_float3())) {
return false;
}
}
@ -170,7 +170,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
/* Evaluate BSDF. */
const float bsdf_pdf = shader_bsdf_eval(kg, sd, ls.D, is_transmission, &bsdf_eval, ls.shader);
bsdf_eval_mul3(&bsdf_eval, light_eval / ls.pdf);
bsdf_eval_mul(&bsdf_eval, light_eval / ls.pdf);
if (ls.shader & SHADER_USE_MIS) {
const float mis_weight = light_sample_mis_weight_nee(kg, ls.pdf, bsdf_pdf);

View File

@ -222,7 +222,7 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg,
* check then. */
sum += (-sigma_t * dt);
if ((i & 0x07) == 0) { /* TODO: Other interval? */
tp = *throughput * exp3(sum);
tp = *throughput * exp(sum);
/* stop if nearly all light is blocked */
if (tp.x < VOLUME_THROUGHPUT_EPSILON && tp.y < VOLUME_THROUGHPUT_EPSILON &&
@ -235,7 +235,7 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg,
t = new_t;
if (t == ray->t) {
/* Update throughput in case we haven't done it above */
tp = *throughput * exp3(sum);
tp = *throughput * exp(sum);
break;
}
}
@ -626,13 +626,13 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
/* Stop if nearly all light blocked. */
if (!result.indirect_scatter) {
if (max3(result.indirect_throughput) < VOLUME_THROUGHPUT_EPSILON) {
if (reduce_max(result.indirect_throughput) < VOLUME_THROUGHPUT_EPSILON) {
result.indirect_throughput = zero_float3();
break;
}
}
else if (!result.direct_scatter) {
if (max3(result.direct_throughput) < VOLUME_THROUGHPUT_EPSILON) {
if (reduce_max(result.direct_throughput) < VOLUME_THROUGHPUT_EPSILON) {
break;
}
}
@ -760,7 +760,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
bsdf_eval_mul(&phase_eval, mis_weight);
}
bsdf_eval_mul3(&phase_eval, light_eval / ls->pdf);
bsdf_eval_mul(&phase_eval, light_eval / ls->pdf);
/* Path termination. */
const float terminate = path_state_rng_light_termination(kg, rng_state);

View File

@ -229,7 +229,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
* Since the strength of the guided sampling increases as alpha gets lower, using a value that
* is too low results in fireflies while one that's too high just gives a bit more noise.
* Therefore, the code here uses the highest of the three albedos to be safe. */
const float diffusion_length = diffusion_length_dwivedi(max3(alpha));
const float diffusion_length = diffusion_length_dwivedi(reduce_max(alpha));
if (diffusion_length == 1.0f) {
/* With specific values of alpha the length might become 1, which in asymptotic makes phase to
@ -370,7 +370,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
* chance of connecting to it.
* TODO: Maybe use less than 10 times the mean free path? */
if (bounce == 0) {
ray.t = max(t, 10.0f / (min3(sigma_t)));
ray.t = max(t, 10.0f / (reduce_min(sigma_t)));
}
else {
ray.t = t;
@ -452,7 +452,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
}
if (hit) {
kernel_assert(isfinite3_safe(throughput));
kernel_assert(isfinite_safe(throughput));
INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput;
}

View File

@ -106,7 +106,7 @@ ccl_device_inline bool light_sample_terminate(KernelGlobals kg,
}
if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
float probability = max3(fabs(bsdf_eval_sum(eval))) *
float probability = reduce_max(fabs(bsdf_eval_sum(eval))) *
kernel_data.integrator.light_inv_rr_threshold;
if (probability < 1.0f) {
if (rand_terminate >= probability) {

View File

@ -244,7 +244,7 @@ ccl_device float3 svm_mix_linear(float t, float3 col1, float3 col2)
ccl_device float3 svm_mix_clamp(float3 col)
{
return saturate3(col);
return saturate(col);
}
ccl_device_noinline_cpu float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2)

View File

@ -112,10 +112,10 @@ ccl_device_noinline int svm_node_vector_map_range(KernelGlobals kg,
switch (range_type_stack_offset) {
default:
case NODE_MAP_RANGE_LINEAR:
factor = safe_divide_float3_float3((value - from_min), (from_max - from_min));
factor = safe_divide((value - from_min), (from_max - from_min));
break;
case NODE_MAP_RANGE_STEPPED: {
factor = safe_divide_float3_float3((value - from_min), (from_max - from_min));
factor = safe_divide((value - from_min), (from_max - from_min));
factor = make_float3((steps.x > 0.0f) ? floorf(factor.x * (steps.x + 1.0f)) / steps.x : 0.0f,
(steps.y > 0.0f) ? floorf(factor.y * (steps.y + 1.0f)) / steps.y : 0.0f,
(steps.z > 0.0f) ? floorf(factor.z * (steps.z + 1.0f)) / steps.z :
@ -123,13 +123,13 @@ ccl_device_noinline int svm_node_vector_map_range(KernelGlobals kg,
break;
}
case NODE_MAP_RANGE_SMOOTHSTEP: {
factor = safe_divide_float3_float3((value - from_min), (from_max - from_min));
factor = safe_divide((value - from_min), (from_max - from_min));
factor = clamp(factor, zero_float3(), one_float3());
factor = (make_float3(3.0f, 3.0f, 3.0f) - 2.0f * factor) * (factor * factor);
break;
}
case NODE_MAP_RANGE_SMOOTHERSTEP: {
factor = safe_divide_float3_float3((value - from_min), (from_max - from_min));
factor = safe_divide((value - from_min), (from_max - from_min));
factor = clamp(factor, zero_float3(), one_float3());
factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
break;

View File

@ -13,13 +13,12 @@ svm_mapping(NodeMappingType type, float3 vector, float3 location, float3 rotatio
case NODE_MAPPING_TYPE_POINT:
return transform_direction(&rotationTransform, (vector * scale)) + location;
case NODE_MAPPING_TYPE_TEXTURE:
return safe_divide_float3_float3(
transform_direction_transposed(&rotationTransform, (vector - location)), scale);
return safe_divide(transform_direction_transposed(&rotationTransform, (vector - location)),
scale);
case NODE_MAPPING_TYPE_VECTOR:
return transform_direction(&rotationTransform, (vector * scale));
case NODE_MAPPING_TYPE_NORMAL:
return safe_normalize(
transform_direction(&rotationTransform, safe_divide_float3_float3(vector, scale)));
return safe_normalize(transform_direction(&rotationTransform, safe_divide(vector, scale)));
default:
return make_float3(0.0f, 0.0f, 0.0f);
}

View File

@ -24,7 +24,7 @@ ccl_device void svm_vector_math(ccl_private float *value,
*vector = a * b;
break;
case NODE_VECTOR_MATH_DIVIDE:
*vector = safe_divide_float3_float3(a, b);
*vector = safe_divide(a, b);
break;
case NODE_VECTOR_MATH_CROSS_PRODUCT:
*vector = cross(a, b);
@ -60,7 +60,7 @@ ccl_device void svm_vector_math(ccl_private float *value,
*vector = safe_normalize(a);
break;
case NODE_VECTOR_MATH_SNAP:
*vector = floor(safe_divide_float3_float3(a, b)) * b;
*vector = floor(safe_divide(a, b)) * b;
break;
case NODE_VECTOR_MATH_FLOOR:
*vector = floor(a);

View File

@ -1079,7 +1079,7 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
default:
kernel_assert(0);
}
position_out = safe_divide_float3_float(position_out, scale);
position_out = safe_divide(position_out, scale);
break;
}
@ -1126,7 +1126,7 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
default:
kernel_assert(0);
}
position_out_4d = safe_divide_float4_float(position_out_4d, scale);
position_out_4d = safe_divide(position_out_4d, scale);
position_out = make_float3(position_out_4d.x, position_out_4d.y, position_out_4d.z);
w_out = position_out_4d.w;
}

View File

@ -94,7 +94,7 @@ float3 Mesh::Triangle::compute_normal(const float3 *verts) const
bool Mesh::Triangle::valid(const float3 *verts) const
{
return isfinite3_safe(verts[v[0]]) && isfinite3_safe(verts[v[1]]) && isfinite3_safe(verts[v[2]]);
return isfinite_safe(verts[v[0]]) && isfinite_safe(verts[v[1]]) && isfinite_safe(verts[v[2]]);
}
/* SubdFace */

View File

@ -137,7 +137,7 @@ static void read_shader_output(const Scene *scene,
d_output_index += 3;
/* Avoid illegal vertex coordinates. */
off = ensure_finite3(off);
off = ensure_finite(off);
mesh_verts[t.v[j]] += off;
if (attr_mP != NULL) {
for (int step = 0; step < num_motion_steps - 1; step++) {

View File

@ -340,12 +340,12 @@ float Object::compute_volume_step_size() const
if (metadata.use_transform_3d) {
voxel_tfm = tfm * transform_inverse(metadata.transform_3d);
}
voxel_step_size = min3(fabs(transform_direction(&voxel_tfm, size)));
voxel_step_size = reduce_min(fabs(transform_direction(&voxel_tfm, size)));
}
else if (volume->get_object_space()) {
/* User specified step size in object space. */
float3 size = make_float3(voxel_step_size, voxel_step_size, voxel_step_size);
voxel_step_size = min3(fabs(transform_direction(&tfm, size)));
voxel_step_size = reduce_min(fabs(transform_direction(&tfm, size)));
}
if (voxel_step_size > 0.0f) {

View File

@ -318,14 +318,14 @@ ccl_device float3 color_highlight_compress(float3 color, ccl_private float3 *var
{
color += one_float3();
if (variance) {
*variance *= sqr3(one_float3() / color);
*variance *= sqr(one_float3() / color);
}
return log3(color);
return log(color);
}
ccl_device float3 color_highlight_uncompress(float3 color)
{
return exp3(color) - one_float3();
return exp(color) - one_float3();
}
CCL_NAMESPACE_END

View File

@ -297,8 +297,15 @@ ccl_device_inline float4 __int4_as_float4(int4 i)
#endif /* !defined(__KERNEL_METAL__) */
#if defined(__KERNEL_METAL__)
# define isnan_safe(v) isnan(v)
# define isfinite_safe(v) isfinite(v)
ccl_device_forceinline bool isnan_safe(float f)
{
return isnan(f);
}
ccl_device_forceinline bool isfinite_safe(float f)
{
return isfinite(f);
}
#else
template<typename T> ccl_device_inline uint pointer_pack_to_uint_0(T *ptr)
{

View File

@ -53,26 +53,25 @@ ccl_device_inline float3 ceil(const float3 &a);
ccl_device_inline float3 reflect(const float3 incident, const float3 normal);
#endif /* !defined(__KERNEL_METAL__) */
ccl_device_inline float min3(float3 a);
ccl_device_inline float max3(float3 a);
ccl_device_inline float reduce_min(float3 a);
ccl_device_inline float reduce_max(float3 a);
ccl_device_inline float len(const float3 a);
ccl_device_inline float len_squared(const float3 a);
ccl_device_inline float3 project(const float3 v, const float3 v_proj);
ccl_device_inline float3 saturate3(float3 a);
ccl_device_inline float3 safe_normalize(const float3 a);
ccl_device_inline float3 normalize_len(const float3 a, ccl_private float *t);
ccl_device_inline float3 safe_normalize_len(const float3 a, ccl_private float *t);
ccl_device_inline float3 safe_divide_float3_float3(const float3 a, const float3 b);
ccl_device_inline float3 safe_divide_float3_float(const float3 a, const float b);
ccl_device_inline float3 safe_divide(const float3 a, const float3 b);
ccl_device_inline float3 safe_divide(const float3 a, const float b);
ccl_device_inline float3 interp(float3 a, float3 b, float t);
ccl_device_inline float3 sqr3(float3 a);
ccl_device_inline float3 sqr(float3 a);
ccl_device_inline bool is_zero(const float3 a);
ccl_device_inline float reduce_add(const float3 a);
ccl_device_inline float average(const float3 a);
ccl_device_inline bool isequal_float3(const float3 a, const float3 b);
ccl_device_inline bool isequal(const float3 a, const float3 b);
/*******************************************************************************
* Definition.
@ -377,14 +376,30 @@ ccl_device_inline float3 rcp(const float3 &a)
return make_float3(1.0f / a.x, 1.0f / a.y, 1.0f / a.z);
# endif
}
ccl_device_inline float3 saturate(float3 a)
{
return make_float3(saturatef(a.x), saturatef(a.y), saturatef(a.z));
}
ccl_device_inline float3 exp(float3 v)
{
return make_float3(expf(v.x), expf(v.y), expf(v.z));
}
ccl_device_inline float3 log(float3 v)
{
return make_float3(logf(v.x), logf(v.y), logf(v.z));
}
#endif /* !__KERNEL_METAL__ */
ccl_device_inline float min3(float3 a)
ccl_device_inline float reduce_min(float3 a)
{
return min(min(a.x, a.y), a.z);
}
ccl_device_inline float max3(float3 a)
ccl_device_inline float reduce_max(float3 a)
{
return max(max(a.x, a.y), a.z);
}
@ -433,11 +448,6 @@ ccl_device_inline float3 project(const float3 v, const float3 v_proj)
return (len_squared != 0.0f) ? (dot(v, v_proj) / len_squared) * v_proj : zero_float3();
}
ccl_device_inline float3 saturate3(float3 a)
{
return make_float3(saturatef(a.x), saturatef(a.y), saturatef(a.z));
}
ccl_device_inline float3 normalize_len(const float3 a, ccl_private float *t)
{
*t = len(a);
@ -457,14 +467,14 @@ ccl_device_inline float3 safe_normalize_len(const float3 a, ccl_private float *t
return (*t != 0.0f) ? a / (*t) : a;
}
ccl_device_inline float3 safe_divide_float3_float3(const float3 a, const float3 b)
ccl_device_inline float3 safe_divide(const float3 a, const float3 b)
{
return make_float3((b.x != 0.0f) ? a.x / b.x : 0.0f,
(b.y != 0.0f) ? a.y / b.y : 0.0f,
(b.z != 0.0f) ? a.z / b.z : 0.0f);
}
ccl_device_inline float3 safe_divide_float3_float(const float3 a, const float b)
ccl_device_inline float3 safe_divide(const float3 a, const float b)
{
return (b != 0.0f) ? a / b : zero_float3();
}
@ -474,7 +484,7 @@ ccl_device_inline float3 interp(float3 a, float3 b, float t)
return a + t * (b - a);
}
ccl_device_inline float3 sqr3(float3 a)
ccl_device_inline float3 sqr(float3 a)
{
return a * a;
}
@ -504,7 +514,7 @@ ccl_device_inline float average(const float3 a)
return reduce_add(a) * (1.0f / 3.0f);
}
ccl_device_inline bool isequal_float3(const float3 a, const float3 b)
ccl_device_inline bool isequal(const float3 a, const float3 b)
{
#if defined(__KERNEL_METAL__)
return all(a == b);
@ -513,21 +523,11 @@ ccl_device_inline bool isequal_float3(const float3 a, const float3 b)
#endif
}
ccl_device_inline float3 pow3(float3 v, float e)
ccl_device_inline float3 pow(float3 v, float e)
{
return make_float3(powf(v.x, e), powf(v.y, e), powf(v.z, e));
}
ccl_device_inline float3 exp3(float3 v)
{
return make_float3(expf(v.x), expf(v.y), expf(v.z));
}
ccl_device_inline float3 log3(float3 v)
{
return make_float3(logf(v.x), logf(v.y), logf(v.z));
}
ccl_device_inline int3 quick_floor_to_int3(const float3 a)
{
#ifdef __KERNEL_SSE__
@ -540,12 +540,12 @@ ccl_device_inline int3 quick_floor_to_int3(const float3 a)
#endif
}
ccl_device_inline bool isfinite3_safe(float3 v)
ccl_device_inline bool isfinite_safe(float3 v)
{
return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z);
}
ccl_device_inline float3 ensure_finite3(float3 v)
ccl_device_inline float3 ensure_finite(float3 v)
{
if (!isfinite_safe(v.x))
v.x = 0.0f;

View File

@ -55,7 +55,7 @@ ccl_device_inline float4 floor(const float4 &a);
ccl_device_inline float4 mix(const float4 &a, const float4 &b, float t);
#endif /* !__KERNEL_METAL__*/
ccl_device_inline float4 safe_divide_float4_float(const float4 a, const float b);
ccl_device_inline float4 safe_divide(const float4 a, const float b);
#ifdef __KERNEL_SSE__
template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
@ -500,17 +500,17 @@ ccl_device_inline float4 load_float4(ccl_private const float *v)
#endif /* !__KERNEL_GPU__ */
ccl_device_inline float4 safe_divide_float4_float(const float4 a, const float b)
ccl_device_inline float4 safe_divide(const float4 a, const float b)
{
return (b != 0.0f) ? a / b : zero_float4();
}
ccl_device_inline bool isfinite4_safe(float4 v)
ccl_device_inline bool isfinite_safe(float4 v)
{
return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z) && isfinite_safe(v.w);
}
ccl_device_inline float4 ensure_finite4(float4 v)
ccl_device_inline float4 ensure_finite(float4 v)
{
if (!isfinite_safe(v.x))
v.x = 0.0f;

View File

@ -102,7 +102,7 @@ double time_human_readable_to_seconds(const string &time_string)
}
else if (fraction_tokens.size() == 2) {
result = atof(fraction_tokens[1].c_str());
result *= pow(0.1, fraction_tokens[1].length());
result *= ::pow(0.1, fraction_tokens[1].length());
}
else {
/* This is not a valid string, the result can not be reliable. */

View File

@ -229,17 +229,17 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
/* extract scale and shear first */
float3 scale, shear;
scale.x = len(colx);
colx = safe_divide_float3_float(colx, scale.x);
colx = safe_divide(colx, scale.x);
shear.z = dot(colx, coly);
coly -= shear.z * colx;
scale.y = len(coly);
coly = safe_divide_float3_float(coly, scale.y);
coly = safe_divide(coly, scale.y);
shear.y = dot(colx, colz);
colz -= shear.y * colx;
shear.x = dot(coly, colz);
colz -= shear.x * coly;
scale.z = len(colz);
colz = safe_divide_float3_float(colz, scale.z);
colz = safe_divide(colz, scale.z);
transform_set_column(&M, 0, colx);
transform_set_column(&M, 1, coly);

View File

@ -493,13 +493,13 @@ ccl_device void transform_motion_array_interpolate(ccl_private Transform *tfm,
ccl_device_inline bool transform_isfinite_safe(ccl_private Transform *tfm)
{
return isfinite4_safe(tfm->x) && isfinite4_safe(tfm->y) && isfinite4_safe(tfm->z);
return isfinite_safe(tfm->x) && isfinite_safe(tfm->y) && isfinite_safe(tfm->z);
}
ccl_device_inline bool transform_decomposed_isfinite_safe(ccl_private DecomposedTransform *decomp)
{
return isfinite4_safe(decomp->x) && isfinite4_safe(decomp->y) && isfinite4_safe(decomp->z) &&
isfinite4_safe(decomp->w);
return isfinite_safe(decomp->x) && isfinite_safe(decomp->y) && isfinite_safe(decomp->z) &&
isfinite_safe(decomp->w);
}
#ifndef __KERNEL_GPU__