Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2021-09-20 18:59:20 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-09-21 15:55:54 +0300
commit08031197250aeecbaca3803254e6f25b8c7b7b37 (patch)
tree6fe7ab045f0dc0a423d6557c4073f34309ef4740 /intern/cycles/kernel/closure
parentfa6b1007bad065440950cd67deb16a04f368856f (diff)
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity, new shadow catcher, revamped sampling settings, subsurface scattering anisotropy, new GPU volume sampling, improved PMJ sampling pattern, and more. Some features have also been removed or changed, breaking backwards compatibility. Including the removal of the OpenCL backend, for which alternatives are under development. Release notes and code docs: https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles https://wiki.blender.org/wiki/Source/Render/Cycles Credits: * Sergey Sharybin * Brecht Van Lommel * Patrick Mours (OptiX backend) * Christophe Hery (subsurface scattering anisotropy) * William Leeson (PMJ sampling pattern) * Alaska (various fixes and tweaks) * Thomas Dinges (various fixes) For the full commit history, see the cycles-x branch. This squashes together all the changes since intermediate changes would often fail building or tests. Ref T87839, T87837, T87836 Fixes T90734, T89353, T80267, T80267, T77185, T69800
Diffstat (limited to 'intern/cycles/kernel/closure')
-rw-r--r--intern/cycles/kernel/closure/alloc.h2
-rw-r--r--intern/cycles/kernel/closure/bsdf.h91
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h25
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h15
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h13
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse_ramp.h5
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h14
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair_principled.h25
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h31
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h6
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h13
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h5
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_diffuse.h15
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_sheen.h7
-rw-r--r--intern/cycles/kernel/closure/bsdf_reflection.h5
-rw-r--r--intern/cycles/kernel/closure/bsdf_refraction.h5
-rw-r--r--intern/cycles/kernel/closure/bsdf_toon.h14
-rw-r--r--intern/cycles/kernel/closure/bsdf_transparent.h5
-rw-r--r--intern/cycles/kernel/closure/bsdf_util.h5
-rw-r--r--intern/cycles/kernel/closure/bssrdf.h406
-rw-r--r--intern/cycles/kernel/closure/emissive.h2
-rw-r--r--intern/cycles/kernel/closure/volume.h109
22 files changed, 173 insertions, 645 deletions
diff --git a/intern/cycles/kernel/closure/alloc.h b/intern/cycles/kernel/closure/alloc.h
index 99a5a675976..72a8c2ba090 100644
--- a/intern/cycles/kernel/closure/alloc.h
+++ b/intern/cycles/kernel/closure/alloc.h
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#pragma once
+
CCL_NAMESPACE_BEGIN
ccl_device ShaderClosure *closure_alloc(ShaderData *sd, int size, ClosureType type, float3 weight)
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 6f2f2ebb202..4eb8bcae997 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#pragma once
+
// clang-format off
#include "kernel/closure/bsdf_ashikhmin_velvet.h"
#include "kernel/closure/bsdf_diffuse.h"
@@ -109,7 +111,7 @@ ccl_device_inline float shift_cos_in(float cos_in, const float frequency_multipl
return val;
}
-ccl_device_inline int bsdf_sample(KernelGlobals *kg,
+ccl_device_inline int bsdf_sample(const KernelGlobals *kg,
ShaderData *sd,
const ShaderClosure *sc,
float randu,
@@ -429,21 +431,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
break;
# endif /* __PRINCIPLED__ */
#endif
-#ifdef __VOLUME__
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- label = volume_henyey_greenstein_sample(sc,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
- break;
-#endif
default:
label = LABEL_NONE;
break;
@@ -482,15 +469,16 @@ ccl_device
ccl_device_inline
#endif
float3
- bsdf_eval(KernelGlobals *kg,
+ bsdf_eval(const KernelGlobals *kg,
ShaderData *sd,
const ShaderClosure *sc,
const float3 omega_in,
+ const bool is_transmission,
float *pdf)
{
- float3 eval;
+ float3 eval = zero_float3();
- if (dot(sd->N, omega_in) >= 0.0f) {
+ if (!is_transmission) {
switch (sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
case CLOSURE_BSDF_BSSRDF_ID:
@@ -570,13 +558,7 @@ ccl_device_inline
break;
# endif /* __PRINCIPLED__ */
#endif
-#ifdef __VOLUME__
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- eval = volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
- break;
-#endif
default:
- eval = make_float3(0.0f, 0.0f, 0.0f);
break;
}
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
@@ -663,13 +645,7 @@ ccl_device_inline
break;
# endif /* __PRINCIPLED__ */
#endif
-#ifdef __VOLUME__
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- eval = volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
- break;
-#endif
default:
- eval = make_float3(0.0f, 0.0f, 0.0f);
break;
}
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
@@ -682,7 +658,7 @@ ccl_device_inline
return eval;
}
-ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
+ccl_device void bsdf_blur(const KernelGlobals *kg, ShaderClosure *sc, float roughness)
{
/* ToDo: do we want to blur volume closures? */
#ifdef __SVM__
@@ -715,55 +691,4 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
#endif
}
-ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b)
-{
-#ifdef __SVM__
- switch (a->type) {
- case CLOSURE_BSDF_TRANSPARENT_ID:
- return true;
- case CLOSURE_BSDF_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_ID:
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- return bsdf_diffuse_merge(a, b);
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- return bsdf_oren_nayar_merge(a, b);
- case CLOSURE_BSDF_REFLECTION_ID:
- case CLOSURE_BSDF_REFRACTION_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
- case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
- return bsdf_microfacet_merge(a, b);
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- return bsdf_ashikhmin_velvet_merge(a, b);
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- return bsdf_toon_merge(a, b);
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- return bsdf_hair_merge(a, b);
-# ifdef __PRINCIPLED__
- case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
- return bsdf_principled_diffuse_merge(a, b);
-# endif
-# ifdef __VOLUME__
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- return volume_henyey_greenstein_merge(a, b);
-# endif
- default:
- return false;
- }
-#else
- return false;
-#endif
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index 9814a7cf5c9..be6383e521a 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -14,20 +14,19 @@
* limitations under the License.
*/
-#ifndef __BSDF_ASHIKHMIN_SHIRLEY_H__
-#define __BSDF_ASHIKHMIN_SHIRLEY_H__
-
/*
-ASHIKHMIN SHIRLEY BSDF
-
-Implementation of
-Michael Ashikhmin and Peter Shirley: "An Anisotropic Phong BRDF Model" (2000)
-
-The Fresnel factor is missing to get a separable bsdf (intensity*color), as is
-the case with all other microfacet-based BSDF implementations in Cycles.
+ * ASHIKHMIN SHIRLEY BSDF
+ *
+ * Implementation of
+ * Michael Ashikhmin and Peter Shirley: "An Anisotropic Phong BRDF Model" (2000)
+ *
+ * The Fresnel factor is missing to get a separable bsdf (intensity*color), as is
+ * the case with all other microfacet-based BSDF implementations in Cycles.
+ *
+ * Other than that, the implementation directly follows the paper.
+ */
-Other than that, the implementation directly follows the paper.
-*/
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -240,5 +239,3 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_ASHIKHMIN_SHIRLEY_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 3d3f20edab3..f51027f5701 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -30,8 +30,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_ASHIKHMIN_VELVET_H__
-#define __BSDF_ASHIKHMIN_VELVET_H__
+#pragma once
+
+#include "kernel/kernel_montecarlo.h"
CCL_NAMESPACE_BEGIN
@@ -54,14 +55,6 @@ ccl_device int bsdf_ashikhmin_velvet_setup(VelvetBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device bool bsdf_ashikhmin_velvet_merge(const ShaderClosure *a, const ShaderClosure *b)
-{
- const VelvetBsdf *bsdf_a = (const VelvetBsdf *)a;
- const VelvetBsdf *bsdf_b = (const VelvetBsdf *)b;
-
- return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->sigma == bsdf_b->sigma);
-}
-
ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
@@ -175,5 +168,3 @@ ccl_device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_ASHIKHMIN_VELVET_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index ea604ed0311..1555aa30304 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_DIFFUSE_H__
-#define __BSDF_DIFFUSE_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -49,14 +48,6 @@ ccl_device int bsdf_diffuse_setup(DiffuseBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device bool bsdf_diffuse_merge(const ShaderClosure *a, const ShaderClosure *b)
-{
- const DiffuseBsdf *bsdf_a = (const DiffuseBsdf *)a;
- const DiffuseBsdf *bsdf_b = (const DiffuseBsdf *)b;
-
- return (isequal_float3(bsdf_a->N, bsdf_b->N));
-}
-
ccl_device float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
@@ -174,5 +165,3 @@ ccl_device int bsdf_translucent_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_DIFFUSE_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
index aa62c1c7ceb..b06dd196b9e 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_DIFFUSE_RAMP_H__
-#define __BSDF_DIFFUSE_RAMP_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -125,5 +124,3 @@ ccl_device int bsdf_diffuse_ramp_sample(const ShaderClosure *sc,
#endif /* __OSL__ */
CCL_NAMESPACE_END
-
-#endif /* __BSDF_DIFFUSE_RAMP_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index 7ca9424b815..f56f78aa1f0 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_HAIR_H__
-#define __BSDF_HAIR_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -62,15 +61,6 @@ ccl_device int bsdf_hair_transmission_setup(HairBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device bool bsdf_hair_merge(const ShaderClosure *a, const ShaderClosure *b)
-{
- const HairBsdf *bsdf_a = (const HairBsdf *)a;
- const HairBsdf *bsdf_b = (const HairBsdf *)b;
-
- return (isequal_float3(bsdf_a->T, bsdf_b->T)) && (bsdf_a->roughness1 == bsdf_b->roughness1) &&
- (bsdf_a->roughness2 == bsdf_b->roughness2) && (bsdf_a->offset == bsdf_b->offset);
-}
-
ccl_device float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
@@ -309,5 +299,3 @@ ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_HAIR_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
index f12661b3095..bfe56e5ab0e 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_principled.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -14,15 +14,14 @@
* limitations under the License.
*/
+#pragma once
+
#ifdef __KERNEL_CPU__
# include <fenv.h>
#endif
#include "kernel/kernel_color.h"
-#ifndef __BSDF_HAIR_PRINCIPLED_H__
-# define __BSDF_HAIR_PRINCIPLED_H__
-
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct PrincipledHairExtra {
@@ -181,12 +180,12 @@ ccl_device_inline float longitudinal_scattering(
}
/* Combine the three values using their luminances. */
-ccl_device_inline float4 combine_with_energy(KernelGlobals *kg, float3 c)
+ccl_device_inline float4 combine_with_energy(const KernelGlobals *kg, float3 c)
{
return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c));
}
-# ifdef __HAIR__
+#ifdef __HAIR__
/* Set up the hair closure. */
ccl_device int bsdf_principled_hair_setup(ShaderData *sd, PrincipledHairBSDF *bsdf)
{
@@ -226,10 +225,10 @@ ccl_device int bsdf_principled_hair_setup(ShaderData *sd, PrincipledHairBSDF *bs
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
-# endif /* __HAIR__ */
+#endif /* __HAIR__ */
/* Given the Fresnel term and transmittance, generate the attenuation terms for each bounce. */
-ccl_device_inline void hair_attenuation(KernelGlobals *kg, float f, float3 T, float4 *Ap)
+ccl_device_inline void hair_attenuation(const KernelGlobals *kg, float f, float3 T, float4 *Ap)
{
/* Primary specular (R). */
Ap[0] = make_float4(f, f, f, f);
@@ -278,7 +277,7 @@ ccl_device_inline void hair_alpha_angles(float sin_theta_i,
}
/* Evaluation function for our shader. */
-ccl_device float3 bsdf_principled_hair_eval(KernelGlobals *kg,
+ccl_device float3 bsdf_principled_hair_eval(const KernelGlobals *kg,
const ShaderData *sd,
const ShaderClosure *sc,
const float3 omega_in,
@@ -356,7 +355,7 @@ ccl_device float3 bsdf_principled_hair_eval(KernelGlobals *kg,
}
/* Sampling function for the hair shader. */
-ccl_device int bsdf_principled_hair_sample(KernelGlobals *kg,
+ccl_device int bsdf_principled_hair_sample(const KernelGlobals *kg,
const ShaderClosure *sc,
ShaderData *sd,
float randu,
@@ -473,11 +472,11 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals *kg,
*omega_in = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
-# ifdef __RAY_DIFFERENTIALS__
+#ifdef __RAY_DIFFERENTIALS__
float3 N = safe_normalize(sd->I + *omega_in);
*domega_in_dx = (2 * dot(N, sd->dI.dx)) * N - sd->dI.dx;
*domega_in_dy = (2 * dot(N, sd->dI.dy)) * N - sd->dI.dy;
-# endif
+#endif
return LABEL_GLOSSY | ((p == 0) ? LABEL_REFLECT : LABEL_TRANSMIT);
}
@@ -501,7 +500,7 @@ ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(
return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
}
-ccl_device float3 bsdf_principled_hair_albedo(ShaderClosure *sc)
+ccl_device float3 bsdf_principled_hair_albedo(const ShaderClosure *sc)
{
PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
return exp3(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
@@ -523,5 +522,3 @@ ccl_device_inline float3 bsdf_principled_hair_sigma_from_concentration(const flo
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_HAIR_PRINCIPLED_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index af03bab39f7..227cb448b47 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -30,8 +30,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_MICROFACET_H__
-#define __BSDF_MICROFACET_H__
+#pragma once
+
+#include "kernel/kernel_lookup_table.h"
+#include "kernel/kernel_random.h"
CCL_NAMESPACE_BEGIN
@@ -53,7 +55,7 @@ static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetBsdf), "MicrofacetBsdf i
/* Beckmann and GGX microfacet importance sampling. */
-ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals *kg,
+ccl_device_inline void microfacet_beckmann_sample_slopes(const KernelGlobals *kg,
const float cos_theta_i,
const float sin_theta_i,
float randu,
@@ -193,7 +195,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i,
*slope_y = S * z * safe_sqrtf(1.0f + (*slope_x) * (*slope_x));
}
-ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals *kg,
+ccl_device_forceinline float3 microfacet_sample_stretched(const KernelGlobals *kg,
const float3 omega_i,
const float alpha_x,
const float alpha_y,
@@ -352,21 +354,6 @@ ccl_device int bsdf_microfacet_ggx_clearcoat_setup(MicrofacetBsdf *bsdf, const S
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device bool bsdf_microfacet_merge(const ShaderClosure *a, const ShaderClosure *b)
-{
- const MicrofacetBsdf *bsdf_a = (const MicrofacetBsdf *)a;
- const MicrofacetBsdf *bsdf_b = (const MicrofacetBsdf *)b;
-
- return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->alpha_x == bsdf_b->alpha_x) &&
- (bsdf_a->alpha_y == bsdf_b->alpha_y) && (isequal_float3(bsdf_a->T, bsdf_b->T)) &&
- (bsdf_a->ior == bsdf_b->ior) &&
- ((bsdf_a->extra == NULL && bsdf_b->extra == NULL) ||
- ((bsdf_a->extra && bsdf_b->extra) &&
- (isequal_float3(bsdf_a->extra->color, bsdf_b->extra->color)) &&
- (isequal_float3(bsdf_a->extra->cspec0, bsdf_b->extra->cspec0)) &&
- (bsdf_a->extra->clearcoat == bsdf_b->extra->clearcoat)));
-}
-
ccl_device int bsdf_microfacet_ggx_refraction_setup(MicrofacetBsdf *bsdf)
{
bsdf->extra = NULL;
@@ -558,7 +545,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc,
return make_float3(out, out, out);
}
-ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg,
+ccl_device int bsdf_microfacet_ggx_sample(const KernelGlobals *kg,
const ShaderClosure *sc,
float3 Ng,
float3 I,
@@ -986,7 +973,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc
return make_float3(out, out, out);
}
-ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg,
+ccl_device int bsdf_microfacet_beckmann_sample(const KernelGlobals *kg,
const ShaderClosure *sc,
float3 Ng,
float3 I,
@@ -1175,5 +1162,3 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_MICROFACET_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index 9795c8da065..68d5071dbce 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#pragma once
+
CCL_NAMESPACE_BEGIN
/* Most of the code is based on the supplemental implementations from
@@ -466,7 +468,7 @@ ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(const ShaderClosure *sc
bsdf->extra->cspec0);
}
-ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg,
+ccl_device int bsdf_microfacet_multi_ggx_sample(const KernelGlobals *kg,
const ShaderClosure *sc,
float3 Ng,
float3 I,
@@ -628,7 +630,7 @@ ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(const ShaderClosu
bsdf->extra->cspec0);
}
-ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg,
+ccl_device int bsdf_microfacet_multi_ggx_glass_sample(const KernelGlobals *kg,
const ShaderClosure *sc,
float3 Ng,
float3 I,
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index 41e5736bf49..be12d47f0ea 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef __BSDF_OREN_NAYAR_H__
-#define __BSDF_OREN_NAYAR_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -61,14 +60,6 @@ ccl_device int bsdf_oren_nayar_setup(OrenNayarBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device bool bsdf_oren_nayar_merge(const ShaderClosure *a, const ShaderClosure *b)
-{
- const OrenNayarBsdf *bsdf_a = (const OrenNayarBsdf *)a;
- const OrenNayarBsdf *bsdf_b = (const OrenNayarBsdf *)b;
-
- return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->roughness == bsdf_b->roughness);
-}
-
ccl_device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
@@ -127,5 +118,3 @@ ccl_device int bsdf_oren_nayar_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_OREN_NAYAR_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index cf5484383f2..43f8cf71c59 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_PHONG_RAMP_H__
-#define __BSDF_PHONG_RAMP_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -153,5 +152,3 @@ ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc,
#endif /* __OSL__ */
CCL_NAMESPACE_END
-
-#endif /* __BSDF_PHONG_RAMP_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
index d5d012068ff..a72af519482 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-#ifndef __BSDF_PRINCIPLED_DIFFUSE_H__
-#define __BSDF_PRINCIPLED_DIFFUSE_H__
+#pragma once
/* DISNEY PRINCIPLED DIFFUSE BRDF
*
* Shading model by Brent Burley (Disney): "Physically Based Shading at Disney" (2012)
*/
+#include "kernel/closure/bsdf_util.h"
+
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct PrincipledDiffuseBsdf {
@@ -61,14 +62,6 @@ ccl_device int bsdf_principled_diffuse_setup(PrincipledDiffuseBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device bool bsdf_principled_diffuse_merge(const ShaderClosure *a, const ShaderClosure *b)
-{
- const PrincipledDiffuseBsdf *bsdf_a = (const PrincipledDiffuseBsdf *)a;
- const PrincipledDiffuseBsdf *bsdf_b = (const PrincipledDiffuseBsdf *)b;
-
- return (isequal_float3(bsdf_a->N, bsdf_b->N) && bsdf_a->roughness == bsdf_b->roughness);
-}
-
ccl_device float3 bsdf_principled_diffuse_eval_reflect(const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
@@ -136,5 +129,3 @@ ccl_device int bsdf_principled_diffuse_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_PRINCIPLED_DIFFUSE_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_principled_sheen.h b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
index 3707de29d73..60ce7e4eb75 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_sheen.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-#ifndef __BSDF_PRINCIPLED_SHEEN_H__
-#define __BSDF_PRINCIPLED_SHEEN_H__
+#pragma once
/* DISNEY PRINCIPLED SHEEN BRDF
*
* Shading model by Brent Burley (Disney): "Physically Based Shading at Disney" (2012)
*/
+#include "kernel/closure/bsdf_util.h"
+
CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct PrincipledSheenBsdf {
@@ -137,5 +138,3 @@ ccl_device int bsdf_principled_sheen_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_PRINCIPLED_SHEEN_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index c24ba170915..31283971d5a 100644
--- a/intern/cycles/kernel/closure/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_REFLECTION_H__
-#define __BSDF_REFLECTION_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -93,5 +92,3 @@ ccl_device int bsdf_reflection_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_REFLECTION_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h
index d4fbe86dac0..cfedb5dfe2c 100644
--- a/intern/cycles/kernel/closure/bsdf_refraction.h
+++ b/intern/cycles/kernel/closure/bsdf_refraction.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_REFRACTION_H__
-#define __BSDF_REFRACTION_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -111,5 +110,3 @@ ccl_device int bsdf_refraction_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_REFRACTION_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h
index cc5de21ed0e..acdafe0f735 100644
--- a/intern/cycles/kernel/closure/bsdf_toon.h
+++ b/intern/cycles/kernel/closure/bsdf_toon.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_TOON_H__
-#define __BSDF_TOON_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -55,15 +54,6 @@ ccl_device int bsdf_diffuse_toon_setup(ToonBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device bool bsdf_toon_merge(const ShaderClosure *a, const ShaderClosure *b)
-{
- const ToonBsdf *bsdf_a = (const ToonBsdf *)a;
- const ToonBsdf *bsdf_b = (const ToonBsdf *)b;
-
- return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->size == bsdf_b->size) &&
- (bsdf_a->smooth == bsdf_b->smooth);
-}
-
ccl_device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle)
{
float is;
@@ -248,5 +238,3 @@ ccl_device int bsdf_glossy_toon_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_TOON_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h
index 4e5513499e8..f1dc7efb345 100644
--- a/intern/cycles/kernel/closure/bsdf_transparent.h
+++ b/intern/cycles/kernel/closure/bsdf_transparent.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_TRANSPARENT_H__
-#define __BSDF_TRANSPARENT_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -123,5 +122,3 @@ ccl_device int bsdf_transparent_sample(const ShaderClosure *sc,
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_TRANSPARENT_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
index a73dee1b045..beec5f768a1 100644
--- a/intern/cycles/kernel/closure/bsdf_util.h
+++ b/intern/cycles/kernel/closure/bsdf_util.h
@@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __BSDF_UTIL_H__
-#define __BSDF_UTIL_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -150,5 +149,3 @@ interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0
}
CCL_NAMESPACE_END
-
-#endif /* __BSDF_UTIL_H__ */
diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h
index 562daf1286d..0f9278bba89 100644
--- a/intern/cycles/kernel/closure/bssrdf.h
+++ b/intern/cycles/kernel/closure/bssrdf.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef __KERNEL_BSSRDF_H__
-#define __KERNEL_BSSRDF_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -24,310 +23,71 @@ typedef ccl_addr_space struct Bssrdf {
float3 radius;
float3 albedo;
- float sharpness;
- float texture_blur;
float roughness;
- float channels;
+ float anisotropy;
} Bssrdf;
static_assert(sizeof(ShaderClosure) >= sizeof(Bssrdf), "Bssrdf is too large!");
-/* Planar Truncated Gaussian
- *
- * Note how this is different from the typical gaussian, this one integrates
- * to 1 over the plane (where you get an extra 2*pi*x factor). We are lucky
- * that integrating x*exp(-x) gives a nice closed form solution. */
-
-/* paper suggests 1/12.46 which is much too small, suspect it's *12.46 */
-#define GAUSS_TRUNCATE 12.46f
-
-ccl_device float bssrdf_gaussian_eval(const float radius, float r)
-{
- /* integrate (2*pi*r * exp(-r*r/(2*v)))/(2*pi*v)) from 0 to Rm
- * = 1 - exp(-Rm*Rm/(2*v)) */
- const float v = radius * radius * (0.25f * 0.25f);
- const float Rm = sqrtf(v * GAUSS_TRUNCATE);
-
- if (r >= Rm)
- return 0.0f;
-
- return expf(-r * r / (2.0f * v)) / (2.0f * M_PI_F * v);
-}
-
-ccl_device float bssrdf_gaussian_pdf(const float radius, float r)
+ccl_device float bssrdf_dipole_compute_Rd(float alpha_prime, float fourthirdA)
{
- /* 1.0 - expf(-Rm*Rm/(2*v)) simplified */
- const float area_truncated = 1.0f - expf(-0.5f * GAUSS_TRUNCATE);
-
- return bssrdf_gaussian_eval(radius, r) * (1.0f / (area_truncated));
+ float s = sqrtf(3.0f * (1.0f - alpha_prime));
+ return 0.5f * alpha_prime * (1.0f + expf(-fourthirdA * s)) * expf(-s);
}
-ccl_device void bssrdf_gaussian_sample(const float radius, float xi, float *r, float *h)
+ccl_device float bssrdf_dipole_compute_alpha_prime(float rd, float fourthirdA)
{
- /* xi = integrate (2*pi*r * exp(-r*r/(2*v)))/(2*pi*v)) = -exp(-r^2/(2*v))
- * r = sqrt(-2*v*logf(xi)) */
- const float v = radius * radius * (0.25f * 0.25f);
- const float Rm = sqrtf(v * GAUSS_TRUNCATE);
-
- /* 1.0 - expf(-Rm*Rm/(2*v)) simplified */
- const float area_truncated = 1.0f - expf(-0.5f * GAUSS_TRUNCATE);
-
- /* r(xi) */
- const float r_squared = -2.0f * v * logf(1.0f - xi * area_truncated);
- *r = sqrtf(r_squared);
-
- /* h^2 + r^2 = Rm^2 */
- *h = safe_sqrtf(Rm * Rm - r_squared);
-}
-
-/* Planar Cubic BSSRDF falloff
- *
- * This is basically (Rm - x)^3, with some factors to normalize it. For sampling
- * we integrate 2*pi*x * (Rm - x)^3, which gives us a quintic equation that as
- * far as I can tell has no closed form solution. So we get an iterative solution
- * instead with newton-raphson. */
-
-ccl_device float bssrdf_cubic_eval(const float radius, const float sharpness, float r)
-{
- if (sharpness == 0.0f) {
- const float Rm = radius;
-
- if (r >= Rm)
- return 0.0f;
-
- /* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */
- const float Rm5 = (Rm * Rm) * (Rm * Rm) * Rm;
- const float f = Rm - r;
- const float num = f * f * f;
-
- return (10.0f * num) / (Rm5 * M_PI_F);
+ /* Little Newton solver. */
+ if (rd < 1e-4f) {
+ return 0.0f;
+ }
+ if (rd >= 0.995f) {
+ return 0.999999f;
}
- else {
- float Rm = radius * (1.0f + sharpness);
-
- if (r >= Rm)
- return 0.0f;
- /* custom variation with extra sharpness, to match the previous code */
- const float y = 1.0f / (1.0f + sharpness);
- float Rmy, ry, ryinv;
+ float x0 = 0.0f;
+ float x1 = 1.0f;
+ float xmid, fmid;
- if (sharpness == 1.0f) {
- Rmy = sqrtf(Rm);
- ry = sqrtf(r);
- ryinv = (ry > 0.0f) ? 1.0f / ry : 0.0f;
+ constexpr const int max_num_iterations = 12;
+ for (int i = 0; i < max_num_iterations; ++i) {
+ xmid = 0.5f * (x0 + x1);
+ fmid = bssrdf_dipole_compute_Rd(xmid, fourthirdA);
+ if (fmid < rd) {
+ x0 = xmid;
}
else {
- Rmy = powf(Rm, y);
- ry = powf(r, y);
- ryinv = (r > 0.0f) ? powf(r, y - 1.0f) : 0.0f;
+ x1 = xmid;
}
-
- const float Rmy5 = (Rmy * Rmy) * (Rmy * Rmy) * Rmy;
- const float f = Rmy - ry;
- const float num = f * (f * f) * (y * ryinv);
-
- return (10.0f * num) / (Rmy5 * M_PI_F);
- }
-}
-
-ccl_device float bssrdf_cubic_pdf(const float radius, const float sharpness, float r)
-{
- return bssrdf_cubic_eval(radius, sharpness, r);
-}
-
-/* solve 10x^2 - 20x^3 + 15x^4 - 4x^5 - xi == 0 */
-ccl_device_forceinline float bssrdf_cubic_quintic_root_find(float xi)
-{
- /* newton-raphson iteration, usually succeeds in 2-4 iterations, except
- * outside 0.02 ... 0.98 where it can go up to 10, so overall performance
- * should not be too bad */
- const float tolerance = 1e-6f;
- const int max_iteration_count = 10;
- float x = 0.25f;
- int i;
-
- for (i = 0; i < max_iteration_count; i++) {
- float x2 = x * x;
- float x3 = x2 * x;
- float nx = (1.0f - x);
-
- float f = 10.0f * x2 - 20.0f * x3 + 15.0f * x2 * x2 - 4.0f * x2 * x3 - xi;
- float f_ = 20.0f * (x * nx) * (nx * nx);
-
- if (fabsf(f) < tolerance || f_ == 0.0f)
- break;
-
- x = saturate(x - f / f_);
}
- return x;
+ return xmid;
}
-ccl_device void bssrdf_cubic_sample(
- const float radius, const float sharpness, float xi, float *r, float *h)
+ccl_device void bssrdf_setup_radius(Bssrdf *bssrdf, const ClosureType type, const float eta)
{
- float Rm = radius;
- float r_ = bssrdf_cubic_quintic_root_find(xi);
-
- if (sharpness != 0.0f) {
- r_ = powf(r_, 1.0f + sharpness);
- Rm *= (1.0f + sharpness);
- }
-
- r_ *= Rm;
- *r = r_;
-
- /* h^2 + r^2 = Rm^2 */
- *h = safe_sqrtf(Rm * Rm - r_ * r_);
-}
-
-/* Approximate Reflectance Profiles
- * http://graphics.pixar.com/library/ApproxBSSRDF/paper.pdf
- */
-
-/* This is a bit arbitrary, just need big enough radius so it matches
- * the mean free length, but still not too big so sampling is still
- * effective. Might need some further tweaks.
- */
-#define BURLEY_TRUNCATE 16.0f
-#define BURLEY_TRUNCATE_CDF 0.9963790093708328f // cdf(BURLEY_TRUNCATE)
-
-ccl_device_inline float bssrdf_burley_fitting(float A)
-{
- /* Diffuse surface transmission, equation (6). */
- return 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f);
-}
-
-/* Scale mean free path length so it gives similar looking result
- * to Cubic and Gaussian models.
- */
-ccl_device_inline float3 bssrdf_burley_compatible_mfp(float3 r)
-{
- return 0.25f * M_1_PI_F * r;
-}
-
-ccl_device void bssrdf_burley_setup(Bssrdf *bssrdf)
-{
- /* Mean free path length. */
- const float3 l = bssrdf_burley_compatible_mfp(bssrdf->radius);
- /* Surface albedo. */
- const float3 A = bssrdf->albedo;
- const float3 s = make_float3(
- bssrdf_burley_fitting(A.x), bssrdf_burley_fitting(A.y), bssrdf_burley_fitting(A.z));
-
- bssrdf->radius = l / s;
-}
-
-ccl_device float bssrdf_burley_eval(const float d, float r)
-{
- const float Rm = BURLEY_TRUNCATE * d;
-
- if (r >= Rm)
- return 0.0f;
-
- /* Burley reflectance profile, equation (3).
- *
- * NOTES:
- * - Surface albedo is already included into sc->weight, no need to
- * multiply by this term here.
- * - This is normalized diffuse model, so the equation is multiplied
- * by 2*pi, which also matches cdf().
- */
- float exp_r_3_d = expf(-r / (3.0f * d));
- float exp_r_d = exp_r_3_d * exp_r_3_d * exp_r_3_d;
- return (exp_r_d + exp_r_3_d) / (4.0f * d);
-}
-
-ccl_device float bssrdf_burley_pdf(const float d, float r)
-{
- return bssrdf_burley_eval(d, r) * (1.0f / BURLEY_TRUNCATE_CDF);
-}
-
-/* Find the radius for desired CDF value.
- * Returns scaled radius, meaning the result is to be scaled up by d.
- * Since there's no closed form solution we do Newton-Raphson method to find it.
- */
-ccl_device_forceinline float bssrdf_burley_root_find(float xi)
-{
- const float tolerance = 1e-6f;
- const int max_iteration_count = 10;
- /* Do initial guess based on manual curve fitting, this allows us to reduce
- * number of iterations to maximum 4 across the [0..1] range. We keep maximum
- * number of iteration higher just to be sure we didn't miss root in some
- * corner case.
- */
- float r;
- if (xi <= 0.9f) {
- r = expf(xi * xi * 2.4f) - 1.0f;
+ if (type == CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID) {
+ /* Scale mean free path length so it gives similar looking result to older
+ * Cubic, Gaussian and Burley models. */
+ bssrdf->radius *= 0.25f * M_1_PI_F;
}
else {
- /* TODO(sergey): Some nicer curve fit is possible here. */
- r = 15.0f;
- }
- /* Solve against scaled radius. */
- for (int i = 0; i < max_iteration_count; i++) {
- float exp_r_3 = expf(-r / 3.0f);
- float exp_r = exp_r_3 * exp_r_3 * exp_r_3;
- float f = 1.0f - 0.25f * exp_r - 0.75f * exp_r_3 - xi;
- float f_ = 0.25f * exp_r + 0.25f * exp_r_3;
+ /* Adjust radius based on IOR and albedo. */
+ const float inv_eta = 1.0f / eta;
+ const float F_dr = inv_eta * (-1.440f * inv_eta + 0.710f) + 0.668f + 0.0636f * eta;
+ const float fourthirdA = (4.0f / 3.0f) * (1.0f + F_dr) /
+ (1.0f - F_dr); /* From Jensen's Fdr ratio formula. */
- if (fabsf(f) < tolerance || f_ == 0.0f) {
- break;
- }
+ const float3 alpha_prime = make_float3(
+ bssrdf_dipole_compute_alpha_prime(bssrdf->albedo.x, fourthirdA),
+ bssrdf_dipole_compute_alpha_prime(bssrdf->albedo.y, fourthirdA),
+ bssrdf_dipole_compute_alpha_prime(bssrdf->albedo.z, fourthirdA));
- r = r - f / f_;
- if (r < 0.0f) {
- r = 0.0f;
- }
+ bssrdf->radius *= sqrt(3.0f * (one_float3() - alpha_prime));
}
- return r;
}
-ccl_device void bssrdf_burley_sample(const float d, float xi, float *r, float *h)
-{
- const float Rm = BURLEY_TRUNCATE * d;
- const float r_ = bssrdf_burley_root_find(xi * BURLEY_TRUNCATE_CDF) * d;
-
- *r = r_;
-
- /* h^2 + r^2 = Rm^2 */
- *h = safe_sqrtf(Rm * Rm - r_ * r_);
-}
-
-/* None BSSRDF falloff
- *
- * Samples distributed over disk with no falloff, for reference. */
-
-ccl_device float bssrdf_none_eval(const float radius, float r)
-{
- const float Rm = radius;
- return (r < Rm) ? 1.0f : 0.0f;
-}
-
-ccl_device float bssrdf_none_pdf(const float radius, float r)
-{
- /* integrate (2*pi*r)/(pi*Rm*Rm) from 0 to Rm = 1 */
- const float Rm = radius;
- const float area = (M_PI_F * Rm * Rm);
-
- return bssrdf_none_eval(radius, r) / area;
-}
-
-ccl_device void bssrdf_none_sample(const float radius, float xi, float *r, float *h)
-{
- /* xi = integrate (2*pi*r)/(pi*Rm*Rm) = r^2/Rm^2
- * r = sqrt(xi)*Rm */
- const float Rm = radius;
- const float r_ = sqrtf(xi) * Rm;
-
- *r = r_;
-
- /* h^2 + r^2 = Rm^2 */
- *h = safe_sqrtf(Rm * Rm - r_ * r_);
-}
-
-/* Generic */
+/* Setup */
ccl_device_inline Bssrdf *bssrdf_alloc(ShaderData *sd, float3 weight)
{
@@ -342,7 +102,7 @@ ccl_device_inline Bssrdf *bssrdf_alloc(ShaderData *sd, float3 weight)
return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? bssrdf : NULL;
}
-ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type)
+ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type, const float ior)
{
int flag = 0;
int bssrdf_channels = 3;
@@ -371,7 +131,7 @@ ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type)
if (bssrdf_channels < 3) {
/* Add diffuse BSDF if any radius too small. */
#ifdef __PRINCIPLED__
- if (type == CLOSURE_BSSRDF_PRINCIPLED_ID || type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID) {
+ if (bssrdf->roughness != FLT_MAX) {
float roughness = bssrdf->roughness;
float3 N = bssrdf->N;
@@ -401,16 +161,9 @@ ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type)
/* Setup BSSRDF if radius is large enough. */
if (bssrdf_channels > 0) {
bssrdf->type = type;
- bssrdf->channels = bssrdf_channels;
- bssrdf->sample_weight = fabsf(average(bssrdf->weight)) * bssrdf->channels;
- bssrdf->texture_blur = saturate(bssrdf->texture_blur);
- bssrdf->sharpness = saturate(bssrdf->sharpness);
+ bssrdf->sample_weight = fabsf(average(bssrdf->weight)) * bssrdf_channels;
- if (type == CLOSURE_BSSRDF_BURLEY_ID || type == CLOSURE_BSSRDF_PRINCIPLED_ID ||
- type == CLOSURE_BSSRDF_RANDOM_WALK_ID ||
- type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID) {
- bssrdf_burley_setup(bssrdf);
- }
+ bssrdf_setup_radius(bssrdf, type, ior);
flag |= SD_BSSRDF;
}
@@ -422,77 +175,4 @@ ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type)
return flag;
}
-ccl_device void bssrdf_sample(const ShaderClosure *sc, float xi, float *r, float *h)
-{
- const Bssrdf *bssrdf = (const Bssrdf *)sc;
- float radius;
-
- /* Sample color channel and reuse random number. Only a subset of channels
- * may be used if their radius was too small to handle as BSSRDF. */
- xi *= bssrdf->channels;
-
- if (xi < 1.0f) {
- radius = (bssrdf->radius.x > 0.0f) ? bssrdf->radius.x :
- (bssrdf->radius.y > 0.0f) ? bssrdf->radius.y :
- bssrdf->radius.z;
- }
- else if (xi < 2.0f) {
- xi -= 1.0f;
- radius = (bssrdf->radius.x > 0.0f && bssrdf->radius.y > 0.0f) ? bssrdf->radius.y :
- bssrdf->radius.z;
- }
- else {
- xi -= 2.0f;
- radius = bssrdf->radius.z;
- }
-
- /* Sample BSSRDF. */
- if (bssrdf->type == CLOSURE_BSSRDF_CUBIC_ID) {
- bssrdf_cubic_sample(radius, bssrdf->sharpness, xi, r, h);
- }
- else if (bssrdf->type == CLOSURE_BSSRDF_GAUSSIAN_ID) {
- bssrdf_gaussian_sample(radius, xi, r, h);
- }
- else { /* if (bssrdf->type == CLOSURE_BSSRDF_BURLEY_ID ||
- * bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID) */
- bssrdf_burley_sample(radius, xi, r, h);
- }
-}
-
-ccl_device float bssrdf_channel_pdf(const Bssrdf *bssrdf, float radius, float r)
-{
- if (radius == 0.0f) {
- return 0.0f;
- }
- else if (bssrdf->type == CLOSURE_BSSRDF_CUBIC_ID) {
- return bssrdf_cubic_pdf(radius, bssrdf->sharpness, r);
- }
- else if (bssrdf->type == CLOSURE_BSSRDF_GAUSSIAN_ID) {
- return bssrdf_gaussian_pdf(radius, r);
- }
- else { /* if (bssrdf->type == CLOSURE_BSSRDF_BURLEY_ID ||
- * bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/
- return bssrdf_burley_pdf(radius, r);
- }
-}
-
-ccl_device_forceinline float3 bssrdf_eval(const ShaderClosure *sc, float r)
-{
- const Bssrdf *bssrdf = (const Bssrdf *)sc;
-
- return make_float3(bssrdf_channel_pdf(bssrdf, bssrdf->radius.x, r),
- bssrdf_channel_pdf(bssrdf, bssrdf->radius.y, r),
- bssrdf_channel_pdf(bssrdf, bssrdf->radius.z, r));
-}
-
-ccl_device_forceinline float bssrdf_pdf(const ShaderClosure *sc, float r)
-{
- const Bssrdf *bssrdf = (const Bssrdf *)sc;
- float3 pdf = bssrdf_eval(sc, r);
-
- return (pdf.x + pdf.y + pdf.z) / bssrdf->channels;
-}
-
CCL_NAMESPACE_END
-
-#endif /* __KERNEL_BSSRDF_H__ */
diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h
index 911382e6865..a2519d97618 100644
--- a/intern/cycles/kernel/closure/emissive.h
+++ b/intern/cycles/kernel/closure/emissive.h
@@ -30,6 +30,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#pragma once
+
CCL_NAMESPACE_BEGIN
/* BACKGROUND CLOSURE */
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index 1430f712701..69959a3f21b 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef __VOLUME_H__
-#define __VOLUME_H__
+#pragma once
CCL_NAMESPACE_BEGIN
@@ -62,21 +61,12 @@ ccl_device int volume_henyey_greenstein_setup(HenyeyGreensteinVolume *volume)
return SD_SCATTER;
}
-ccl_device bool volume_henyey_greenstein_merge(const ShaderClosure *a, const ShaderClosure *b)
-{
- const HenyeyGreensteinVolume *volume_a = (const HenyeyGreensteinVolume *)a;
- const HenyeyGreensteinVolume *volume_b = (const HenyeyGreensteinVolume *)b;
-
- return (volume_a->g == volume_b->g);
-}
-
-ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure *sc,
+ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderVolumeClosure *svc,
const float3 I,
float3 omega_in,
float *pdf)
{
- const HenyeyGreensteinVolume *volume = (const HenyeyGreensteinVolume *)sc;
- float g = volume->g;
+ float g = svc->g;
/* note that I points towards the viewer */
if (fabsf(g) < 1e-3f) {
@@ -122,7 +112,7 @@ henyey_greenstrein_sample(float3 D, float g, float randu, float randv, float *pd
return dir;
}
-ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc,
+ccl_device int volume_henyey_greenstein_sample(const ShaderVolumeClosure *svc,
float3 I,
float3 dIdx,
float3 dIdy,
@@ -134,8 +124,7 @@ ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc,
float3 *domega_in_dy,
float *pdf)
{
- const HenyeyGreensteinVolume *volume = (const HenyeyGreensteinVolume *)sc;
- float g = volume->g;
+ float g = svc->g;
/* note that I points towards the viewer and so is used negated */
*omega_in = henyey_greenstrein_sample(-I, g, randu, randv, pdf);
@@ -153,17 +142,15 @@ ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc,
/* VOLUME CLOSURE */
ccl_device float3 volume_phase_eval(const ShaderData *sd,
- const ShaderClosure *sc,
+ const ShaderVolumeClosure *svc,
float3 omega_in,
float *pdf)
{
- kernel_assert(sc->type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID);
-
- return volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
+ return volume_henyey_greenstein_eval_phase(svc, sd->I, omega_in, pdf);
}
ccl_device int volume_phase_sample(const ShaderData *sd,
- const ShaderClosure *sc,
+ const ShaderVolumeClosure *svc,
float randu,
float randv,
float3 *eval,
@@ -171,31 +158,65 @@ ccl_device int volume_phase_sample(const ShaderData *sd,
differential3 *domega_in,
float *pdf)
{
- int label;
-
- switch (sc->type) {
- case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- label = volume_henyey_greenstein_sample(sc,
- sd->I,
- sd->dI.dx,
- sd->dI.dy,
- randu,
- randv,
- eval,
- omega_in,
- &domega_in->dx,
- &domega_in->dy,
- pdf);
- break;
- default:
- *eval = make_float3(0.0f, 0.0f, 0.0f);
- label = LABEL_NONE;
- break;
+ return volume_henyey_greenstein_sample(svc,
+ sd->I,
+ sd->dI.dx,
+ sd->dI.dy,
+ randu,
+ randv,
+ eval,
+ omega_in,
+ &domega_in->dx,
+ &domega_in->dy,
+ pdf);
+}
+
+/* Volume sampling utilities. */
+
+/* todo: this value could be tweaked or turned into a probability to avoid
+ * unnecessary work in volumes and subsurface scattering. */
+#define VOLUME_THROUGHPUT_EPSILON 1e-6f
+
+ccl_device float3 volume_color_transmittance(float3 sigma, float t)
+{
+ return exp3(-sigma * t);
+}
+
+ccl_device float volume_channel_get(float3 value, int channel)
+{
+ return (channel == 0) ? value.x : ((channel == 1) ? value.y : value.z);
+}
+
+ccl_device int volume_sample_channel(float3 albedo, float3 throughput, float rand, float3 *pdf)
+{
+ /* Sample color channel proportional to throughput and single scattering
+ * albedo, to significantly reduce noise with many bounce, following:
+ *
+ * "Practical and Controllable Subsurface Scattering for Production Path
+ * Tracing". Matt Jen-Yuan Chiang, Peter Kutz, Brent Burley. SIGGRAPH 2016. */
+ float3 weights = fabs(throughput * albedo);
+ float sum_weights = weights.x + weights.y + weights.z;
+ float3 weights_pdf;
+
+ if (sum_weights > 0.0f) {
+ weights_pdf = weights / sum_weights;
}
+ else {
+ weights_pdf = make_float3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f);
+ }
+
+ *pdf = weights_pdf;
- return label;
+ /* OpenCL does not support -> on float3, so don't use pdf->x. */
+ if (rand < weights_pdf.x) {
+ return 0;
+ }
+ else if (rand < weights_pdf.x + weights_pdf.y) {
+ return 1;
+ }
+ else {
+ return 2;
+ }
}
CCL_NAMESPACE_END
-
-#endif