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
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/python.cpp4
-rw-r--r--intern/cycles/blender/session.cpp9
-rw-r--r--intern/cycles/blender/sync.cpp6
-rw-r--r--intern/cycles/blender/sync.h4
-rw-r--r--intern/cycles/kernel/CMakeLists.txt3
-rw-r--r--intern/cycles/kernel/bake/bake.h12
-rw-r--r--intern/cycles/kernel/closure/alloc.h6
-rw-r--r--intern/cycles/kernel/closure/bsdf.h6
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h20
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h32
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h52
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse_ramp.h27
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h52
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair_principled.h131
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h98
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h89
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h58
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h34
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h20
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_diffuse.h30
-rw-r--r--intern/cycles/kernel/closure/bsdf_principled_sheen.h30
-rw-r--r--intern/cycles/kernel/closure/bsdf_reflection.h26
-rw-r--r--intern/cycles/kernel/closure/bsdf_refraction.h26
-rw-r--r--intern/cycles/kernel/closure/bsdf_toon.h70
-rw-r--r--intern/cycles/kernel/closure/bsdf_transparent.h26
-rw-r--r--intern/cycles/kernel/closure/bsdf_util.h6
-rw-r--r--intern/cycles/kernel/closure/bssrdf.h118
-rw-r--r--intern/cycles/kernel/closure/emissive.h8
-rw-r--r--intern/cycles/kernel/closure/volume.h59
-rw-r--r--intern/cycles/kernel/device/cpu/compat.h34
-rw-r--r--intern/cycles/kernel/device/metal/compat.h69
-rw-r--r--intern/cycles/kernel/device/oneapi/compat.h16
-rw-r--r--intern/cycles/kernel/film/accumulate.h125
-rw-r--r--intern/cycles/kernel/film/passes.h48
-rw-r--r--intern/cycles/kernel/film/write_passes.h8
-rw-r--r--intern/cycles/kernel/integrator/mnee.h12
-rw-r--r--intern/cycles/kernel/integrator/path_state.h4
-rw-r--r--intern/cycles/kernel/integrator/shade_background.h20
-rw-r--r--intern/cycles/kernel/integrator/shade_light.h4
-rw-r--r--intern/cycles/kernel/integrator/shade_shadow.h14
-rw-r--r--intern/cycles/kernel/integrator/shade_surface.h32
-rw-r--r--intern/cycles/kernel/integrator/shade_volume.h125
-rw-r--r--intern/cycles/kernel/integrator/shader_eval.h87
-rw-r--r--intern/cycles/kernel/integrator/shadow_catcher.h2
-rw-r--r--intern/cycles/kernel/integrator/shadow_state_template.h8
-rw-r--r--intern/cycles/kernel/integrator/state_template.h12
-rw-r--r--intern/cycles/kernel/integrator/subsurface.h8
-rw-r--r--intern/cycles/kernel/integrator/subsurface_disk.h14
-rw-r--r--intern/cycles/kernel/integrator/subsurface_random_walk.h87
-rw-r--r--intern/cycles/kernel/light/sample.h7
-rw-r--r--intern/cycles/kernel/osl/background.cpp8
-rw-r--r--intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp7
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong_ramp.cpp7
-rw-r--r--intern/cycles/kernel/osl/bssrdf.cpp9
-rw-r--r--intern/cycles/kernel/osl/closures.cpp52
-rw-r--r--intern/cycles/kernel/osl/closures.h3
-rw-r--r--intern/cycles/kernel/osl/emissive.cpp6
-rw-r--r--intern/cycles/kernel/svm/closure.h167
-rw-r--r--intern/cycles/kernel/types.h23
-rw-r--r--intern/cycles/kernel/util/color.h15
-rw-r--r--intern/cycles/scene/image_oiio.cpp5
-rw-r--r--intern/cycles/session/session.cpp5
-rw-r--r--intern/cycles/util/CMakeLists.txt3
-rw-r--r--intern/cycles/util/debug.cpp10
-rw-r--r--intern/cycles/util/debug.h31
-rw-r--r--intern/cycles/util/defines.h3
-rw-r--r--intern/cycles/util/math.h28
-rw-r--r--intern/cycles/util/progress.h20
-rw-r--r--intern/cycles/util/types.h23
-rw-r--r--intern/cycles/util/types_float2.h14
-rw-r--r--intern/cycles/util/types_float2_impl.h19
-rw-r--r--intern/cycles/util/types_float3.h33
-rw-r--r--intern/cycles/util/types_float3_impl.h46
-rw-r--r--intern/cycles/util/types_float4.h18
-rw-r--r--intern/cycles/util/types_float4_impl.h53
-rw-r--r--intern/cycles/util/types_float8.h7
-rw-r--r--intern/cycles/util/types_float8_impl.h9
-rw-r--r--intern/cycles/util/types_int2.h11
-rw-r--r--intern/cycles/util/types_int2_impl.h11
-rw-r--r--intern/cycles/util/types_int3.h28
-rw-r--r--intern/cycles/util/types_int3_impl.h47
-rw-r--r--intern/cycles/util/types_int4.h20
-rw-r--r--intern/cycles/util/types_int4_impl.h70
-rw-r--r--intern/cycles/util/types_spectrum.h34
-rw-r--r--intern/cycles/util/types_uchar2.h11
-rw-r--r--intern/cycles/util/types_uchar2_impl.h6
-rw-r--r--intern/cycles/util/types_uchar3.h6
-rw-r--r--intern/cycles/util/types_uchar3_impl.h6
-rw-r--r--intern/cycles/util/types_uchar4.h11
-rw-r--r--intern/cycles/util/types_uchar4_impl.h6
-rw-r--r--intern/cycles/util/types_uint2.h11
-rw-r--r--intern/cycles/util/types_uint2_impl.h11
-rw-r--r--intern/cycles/util/types_uint3.h11
-rw-r--r--intern/cycles/util/types_uint3_impl.h11
-rw-r--r--intern/cycles/util/types_uint4.h11
-rw-r--r--intern/cycles/util/types_uint4_impl.h11
-rw-r--r--intern/cycles/util/types_ushort4.h2
-rw-r--r--intern/cycles/util/types_vector3.h26
-rw-r--r--intern/cycles/util/types_vector3_impl.h30
-rw-r--r--intern/ghost/CMakeLists.txt3
-rw-r--r--intern/ghost/intern/GHOST_Context.cpp9
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.cpp82
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.h8
-rw-r--r--intern/ghost/intern/GHOST_Event.h2
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp3
-rw-r--r--intern/ghost/intern/GHOST_Path-api.cpp4
-rw-r--r--intern/ghost/intern/GHOST_PathUtils.cpp101
-rw-r--r--intern/ghost/intern/GHOST_PathUtils.h24
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp135
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp25
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.cpp12
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp24
-rw-r--r--intern/ghost/test/gears/GHOST_Test.cpp9
-rw-r--r--intern/ghost/test/multitest/MultiTest.c25
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h9
-rw-r--r--intern/guardedalloc/intern/mallocn.c3
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c14
-rw-r--r--intern/guardedalloc/intern/mallocn_intern.h2
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c4
-rw-r--r--intern/mantaflow/intern/MANTA_main.cpp4
121 files changed, 1770 insertions, 1547 deletions
diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp
index 8b2b331f73e..1e33b0b7207 100644
--- a/intern/cycles/blender/python.cpp
+++ b/intern/cycles/blender/python.cpp
@@ -59,8 +59,6 @@ static void debug_flags_sync_from_scene(BL::Scene b_scene)
{
DebugFlagsRef flags = DebugFlags();
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- /* Synchronize shared flags. */
- flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type");
/* Synchronize CPU flags. */
flags.cpu.avx2 = get_boolean(cscene, "debug_use_cpu_avx2");
flags.cpu.avx = get_boolean(cscene, "debug_use_cpu_avx");
@@ -140,8 +138,6 @@ static PyObject *init_func(PyObject * /*self*/, PyObject *args)
BlenderSession::headless = headless;
- DebugFlags().running_inside_blender = true;
-
Py_RETURN_NONE;
}
diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp
index 6d27b8e7d87..e1da85b84ff 100644
--- a/intern/cycles/blender/session.cpp
+++ b/intern/cycles/blender/session.cpp
@@ -110,7 +110,8 @@ void BlenderSession::create_session()
{
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
- const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+ const SceneParams scene_params = BlenderSync::get_scene_params(
+ b_scene, background, use_developer_ui);
const bool session_pause = BlenderSync::get_session_pause(b_scene, background);
/* reset status/progress */
@@ -196,7 +197,8 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
- const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+ const SceneParams scene_params = BlenderSync::get_scene_params(
+ b_scene, background, use_developer_ui);
if (scene->params.modified(scene_params) || session->params.modified(session_params) ||
!this->b_render.use_persistent_data()) {
@@ -724,7 +726,8 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
/* on session/scene parameter changes, we recreate session entirely */
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
- const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+ const SceneParams scene_params = BlenderSync::get_scene_params(
+ b_scene, background, use_developer_ui);
const bool session_pause = BlenderSync::get_session_pause(b_scene, background);
if (session->params.modified(session_params) || scene->params.modified(scene_params)) {
diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp
index 429a8e665af..0d4c1d70180 100644
--- a/intern/cycles/blender/sync.cpp
+++ b/intern/cycles/blender/sync.cpp
@@ -801,7 +801,9 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
/* Scene Parameters */
-SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
+SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene,
+ const bool background,
+ const bool use_developer_ui)
{
SceneParams params;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -812,7 +814,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
else if (shadingsystem == 1)
params.shadingsystem = SHADINGSYSTEM_OSL;
- if (background || DebugFlags().viewport_static_bvh)
+ if (background || (use_developer_ui && get_enum(cscene, "debug_bvh_type")))
params.bvh_type = BVH_TYPE_STATIC;
else
params.bvh_type = BVH_TYPE_DYNAMIC;
diff --git a/intern/cycles/blender/sync.h b/intern/cycles/blender/sync.h
index 0ad4ca6fe83..ae6c2420e55 100644
--- a/intern/cycles/blender/sync.h
+++ b/intern/cycles/blender/sync.h
@@ -84,7 +84,9 @@ class BlenderSync {
}
/* get parameters */
- static SceneParams get_scene_params(BL::Scene &b_scene, bool background);
+ static SceneParams get_scene_params(BL::Scene &b_scene,
+ const bool background,
+ const bool use_developer_ui);
static SessionParams get_session_params(BL::RenderEngine &b_engine,
BL::Preferences &b_userpref,
BL::Scene &b_scene,
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index b00515eb037..fbc30234dac 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -343,6 +343,7 @@ set(SRC_UTIL_HEADERS
../util/types_int3_impl.h
../util/types_int4.h
../util/types_int4_impl.h
+ ../util/types_spectrum.h
../util/types_uchar2.h
../util/types_uchar2_impl.h
../util/types_uchar3.h
@@ -356,8 +357,6 @@ set(SRC_UTIL_HEADERS
../util/types_uint4.h
../util/types_uint4_impl.h
../util/types_ushort4.h
- ../util/types_vector3.h
- ../util/types_vector3_impl.h
)
set(LIB
diff --git a/intern/cycles/kernel/bake/bake.h b/intern/cycles/kernel/bake/bake.h
index ec87990b699..9d53d71b431 100644
--- a/intern/cycles/kernel/bake/bake.h
+++ b/intern/cycles/kernel/bake/bake.h
@@ -8,6 +8,8 @@
#include "kernel/geom/geom.h"
+#include "kernel/util/color.h"
+
CCL_NAMESPACE_BEGIN
ccl_device void kernel_displace_evaluate(KernelGlobals kg,
@@ -65,7 +67,7 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg,
shader_eval_surface<KERNEL_FEATURE_NODE_MASK_SURFACE_LIGHT &
~(KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_NODE_LIGHT_PATH)>(
kg, INTEGRATOR_STATE_NULL, &sd, NULL, path_flag);
- float3 color = shader_background_eval(&sd);
+ Spectrum color = shader_background_eval(&sd);
#ifdef __KERNEL_DEBUG_NAN__
if (!isfinite_safe(color)) {
@@ -76,10 +78,12 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg,
/* Ensure finite color, avoiding possible numerical instabilities in the path tracing kernels. */
color = ensure_finite(color);
+ float3 color_rgb = spectrum_to_rgb(color);
+
/* Write output. */
- output[offset * 3 + 0] += color.x;
- output[offset * 3 + 1] += color.y;
- output[offset * 3 + 2] += color.z;
+ output[offset * 3 + 0] += color_rgb.x;
+ output[offset * 3 + 1] += color_rgb.y;
+ output[offset * 3 + 2] += color_rgb.z;
}
ccl_device void kernel_curve_shadow_transparency_evaluate(
diff --git a/intern/cycles/kernel/closure/alloc.h b/intern/cycles/kernel/closure/alloc.h
index 933c07a5102..9847898ee89 100644
--- a/intern/cycles/kernel/closure/alloc.h
+++ b/intern/cycles/kernel/closure/alloc.h
@@ -8,7 +8,7 @@ CCL_NAMESPACE_BEGIN
ccl_device ccl_private ShaderClosure *closure_alloc(ccl_private ShaderData *sd,
int size,
ClosureType type,
- float3 weight)
+ Spectrum weight)
{
kernel_assert(size <= sizeof(ShaderClosure));
@@ -49,7 +49,7 @@ ccl_device ccl_private void *closure_alloc_extra(ccl_private ShaderData *sd, int
ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *sd,
int size,
- float3 weight)
+ Spectrum weight)
{
kernel_assert(isfinite_safe(weight));
@@ -74,7 +74,7 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *
#ifdef __OSL__
ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
int size,
- float3 weight,
+ Spectrum weight,
void *data)
{
kernel_assert(isfinite_safe(weight));
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 4feb21c43e3..7b28018afad 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -103,7 +103,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private differential3 *domega_in,
ccl_private float *pdf)
@@ -458,7 +458,7 @@ ccl_device
#else
ccl_device_inline
#endif
- float3
+ Spectrum
bsdf_eval(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private const ShaderClosure *sc,
@@ -466,7 +466,7 @@ ccl_device_inline
const bool is_transmission,
ccl_private float *pdf)
{
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
if (!is_transmission) {
switch (sc->type) {
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index 47066542122..2f6ac2dceb0 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -39,7 +39,7 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough
return 2.0f / (roughness * roughness) - 2.0f;
}
-ccl_device_forceinline float3
+ccl_device_forceinline Spectrum
bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
@@ -55,7 +55,7 @@ bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
if (NdotI > 0.0f && NdotO > 0.0f) {
NdotI = fmaxf(NdotI, 1e-6f);
@@ -105,16 +105,16 @@ bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
}
}
- return make_float3(out, out, out);
+ return make_spectrum(out);
}
-ccl_device float3 bsdf_ashikhmin_shirley_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_ashikhmin_shirley_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x,
@@ -137,7 +137,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -214,7 +214,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
/* Some high number for MIS. */
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
label = LABEL_REFLECT | LABEL_SINGULAR;
}
else {
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 3d7906eef7d..ee58bd50aa1 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -31,10 +31,10 @@ ccl_device int bsdf_ashikhmin_velvet_setup(ccl_private VelvetBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc;
float m_invsigma2 = bsdf->invsigma2;
@@ -50,7 +50,7 @@ ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClo
if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
float cosNHdivHO = cosNH / cosHO;
cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
@@ -68,20 +68,20 @@ ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClo
float out = 0.25f * (D * G) / cosNO;
*pdf = 0.5f * M_1_PI_F;
- return make_float3(out, out, out);
+ return make_spectrum(out);
}
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_ashikhmin_velvet_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_ashikhmin_velvet_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
@@ -91,7 +91,7 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -129,7 +129,7 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
float power = 0.25f * (D * G) / cosNO;
- *eval = make_float3(power, power, power);
+ *eval = make_spectrum(power);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the retroreflective bounce
@@ -139,12 +139,12 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_DIFFUSE;
}
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index 759ad03f8e8..2a082796043 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -26,26 +26,26 @@ ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_diffuse_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = cos_pi;
- return make_float3(cos_pi, cos_pi, cos_pi);
+ return make_spectrum(cos_pi);
}
-ccl_device float3 bsdf_diffuse_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
@@ -55,7 +55,7 @@ ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -68,7 +68,7 @@ ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
if (dot(Ng, *omega_in) > 0.0f) {
- *eval = make_float3(*pdf, *pdf, *pdf);
+ *eval = make_spectrum(*pdf);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
@@ -77,7 +77,7 @@ ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_DIFFUSE;
}
@@ -90,26 +90,26 @@ ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_translucent_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_translucent_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_translucent_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_translucent_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
float3 N = bsdf->N;
float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F;
*pdf = cos_pi;
- return make_float3(cos_pi, cos_pi, cos_pi);
+ return make_spectrum(cos_pi);
}
ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc,
@@ -119,7 +119,7 @@ ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -132,7 +132,7 @@ ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc,
// distribution over the hemisphere
sample_cos_hemisphere(-N, randu, randv, omega_in, pdf);
if (dot(Ng, *omega_in) < 0) {
- *eval = make_float3(*pdf, *pdf, *pdf);
+ *eval = make_spectrum(*pdf);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
*domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
@@ -141,7 +141,7 @@ ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc,
}
else {
*pdf = 0;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
return LABEL_TRANSMIT | LABEL_DIFFUSE;
}
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
index aa4c091f587..8b88edb37f7 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -9,6 +9,7 @@
#pragma once
#include "kernel/sample/mapping.h"
+#include "kernel/util/color.h"
CCL_NAMESPACE_BEGIN
@@ -46,25 +47,25 @@ ccl_device void bsdf_diffuse_ramp_blur(ccl_private ShaderClosure *sc, float roug
{
}
-ccl_device float3 bsdf_diffuse_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc;
float3 N = bsdf->N;
float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
*pdf = cos_pi * M_1_PI_F;
- return bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F;
+ return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F);
}
-ccl_device float3 bsdf_diffuse_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
@@ -74,7 +75,7 @@ ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -87,7 +88,7 @@ ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
if (dot(Ng, *omega_in) > 0.0f) {
- *eval = bsdf_diffuse_ramp_get_color(bsdf->colors, *pdf * M_PI_F) * M_1_PI_F;
+ *eval = rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, *pdf * M_PI_F) * M_1_PI_F);
# ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
@@ -95,7 +96,7 @@ ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_DIFFUSE;
}
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index a136ed05800..4179f73e22c 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -37,10 +37,10 @@ ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
float offset = bsdf->offset;
@@ -61,7 +61,7 @@ ccl_device float3 bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClos
if (M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f) {
*pdf = 0.0f;
- return make_float3(*pdf, *pdf, *pdf);
+ return zero_spectrum();
}
float roughness1_inv = 1.0f / roughness1;
@@ -81,31 +81,31 @@ ccl_device float3 bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClos
(2 * (t * t + roughness1 * roughness1) * (a_R - b_R) * costheta_i);
*pdf = phi_pdf * theta_pdf;
- return make_float3(*pdf, *pdf, *pdf);
+ return make_spectrum(*pdf);
}
-ccl_device float3 bsdf_hair_transmission_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_hair_transmission_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_hair_reflection_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_hair_reflection_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_hair_transmission_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_hair_transmission_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc;
float offset = bsdf->offset;
@@ -125,7 +125,7 @@ ccl_device float3 bsdf_hair_transmission_eval_transmit(ccl_private const ShaderC
if (M_PI_2_F - fabsf(theta_i) < 0.001f) {
*pdf = 0.0f;
- return make_float3(*pdf, *pdf, *pdf);
+ return zero_spectrum();
}
float costheta_i = fast_cosf(theta_i);
@@ -145,7 +145,7 @@ ccl_device float3 bsdf_hair_transmission_eval_transmit(ccl_private const ShaderC
float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
*pdf = phi_pdf * theta_pdf;
- return make_float3(*pdf, *pdf, *pdf);
+ return make_spectrum(*pdf);
}
ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
@@ -155,7 +155,7 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -204,7 +204,7 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc,
if (M_PI_2_F - fabsf(theta_i) < 0.001f)
*pdf = 0.0f;
- *eval = make_float3(*pdf, *pdf, *pdf);
+ *eval = make_spectrum(*pdf);
return LABEL_REFLECT | LABEL_GLOSSY;
}
@@ -216,7 +216,7 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -266,7 +266,7 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc
*pdf = 0.0f;
}
- *eval = make_float3(*pdf, *pdf, *pdf);
+ *eval = make_spectrum(*pdf);
/* TODO(sergey): Should always be negative, but seems some precision issue
* is involved here.
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
index e7f24b89458..f78a05ea212 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_principled.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -20,7 +20,7 @@ typedef struct PrincipledHairBSDF {
SHADER_CLOSURE_BASE;
/* Absorption coefficient. */
- float3 sigma;
+ Spectrum sigma;
/* Variance of the underlying logistic distribution. */
float v;
/* Scale factor of the underlying logistic distribution. */
@@ -166,12 +166,6 @@ ccl_device_inline float longitudinal_scattering(
}
}
-/* Combine the three values using their luminances. */
-ccl_device_inline float4 combine_with_energy(KernelGlobals kg, float3 c)
-{
- return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c));
-}
-
#ifdef __HAIR__
/* Set up the hair closure. */
ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
@@ -214,34 +208,36 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
#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,
- ccl_private float4 *Ap)
+ccl_device_inline void hair_attenuation(
+ KernelGlobals kg, float f, Spectrum T, ccl_private Spectrum *Ap, ccl_private float *Ap_energy)
{
/* Primary specular (R). */
- Ap[0] = make_float4(f, f, f, f);
+ Ap[0] = make_spectrum(f);
+ Ap_energy[0] = f;
/* Transmission (TT). */
- float3 col = sqr(1.0f - f) * T;
- Ap[1] = combine_with_energy(kg, col);
+ Spectrum col = sqr(1.0f - f) * T;
+ Ap[1] = col;
+ Ap_energy[1] = spectrum_to_gray(kg, col);
/* Secondary specular (TRT). */
col *= T * f;
- Ap[2] = combine_with_energy(kg, col);
+ Ap[2] = col;
+ Ap_energy[2] = spectrum_to_gray(kg, col);
/* Residual component (TRRT+). */
- col *= safe_divide_color(T * f, make_float3(1.0f, 1.0f, 1.0f) - T * f);
- Ap[3] = combine_with_energy(kg, col);
+ col *= safe_divide(T * f, one_spectrum() - T * f);
+ Ap[3] = col;
+ Ap_energy[3] = spectrum_to_gray(kg, col);
/* Normalize sampling weights. */
- float totweight = Ap[0].w + Ap[1].w + Ap[2].w + Ap[3].w;
+ float totweight = Ap_energy[0] + Ap_energy[1] + Ap_energy[2] + Ap_energy[3];
float fac = safe_divide(1.0f, totweight);
- Ap[0].w *= fac;
- Ap[1].w *= fac;
- Ap[2].w *= fac;
- Ap[3].w *= fac;
+ Ap_energy[0] *= fac;
+ Ap_energy[1] *= fac;
+ Ap_energy[2] *= fac;
+ Ap_energy[3] *= fac;
}
/* Given the tilt angle, generate the rotated theta_i for the different bounces. */
@@ -266,11 +262,11 @@ 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_private const ShaderData *sd,
- ccl_private const ShaderClosure *sc,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg,
+ ccl_private const ShaderData *sd,
+ ccl_private const ShaderClosure *sc,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length));
@@ -299,9 +295,11 @@ 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 = 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);
+ Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
+ Spectrum Ap[4];
+ float Ap_energy[4];
+ hair_attenuation(
+ kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy);
float sin_theta_i = wi.x;
float cos_theta_i = cos_from_sin(sin_theta_i);
@@ -312,35 +310,40 @@ ccl_device float3 bsdf_principled_hair_eval(KernelGlobals kg,
float angles[6];
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
- float4 F;
+ Spectrum F;
+ float F_energy;
float Mp, Np;
/* Primary specular (R). */
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(isfinite_safe(float4_to_float3(F)));
+ F_energy = Ap_energy[0] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
/* 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(isfinite_safe(float4_to_float3(F)));
+ F_energy += Ap_energy[1] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
/* 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(isfinite_safe(float4_to_float3(F)));
+ F_energy += Ap_energy[2] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
/* 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(isfinite_safe(float4_to_float3(F)));
+ F_energy += Ap_energy[3] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
- *pdf = F.w;
- return float4_to_float3(F);
+ *pdf = F_energy;
+ return F;
}
/* Sampling function for the hair shader. */
@@ -349,7 +352,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
ccl_private ShaderData *sd,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -385,16 +388,18 @@ 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 = 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);
+ Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
+ Spectrum Ap[4];
+ float Ap_energy[4];
+ hair_attenuation(
+ kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy);
int p = 0;
for (; p < 3; p++) {
- if (u[0].x < Ap[p].w) {
+ if (u[0].x < Ap_energy[p]) {
break;
}
- u[0].x -= Ap[p].w;
+ u[0].x -= Ap_energy[p];
}
float v = bsdf->v;
@@ -429,35 +434,40 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
- float4 F;
+ Spectrum F;
+ float F_energy;
float Mp, Np;
/* Primary specular (R). */
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(isfinite_safe(float4_to_float3(F)));
+ F_energy = Ap_energy[0] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
/* 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(isfinite_safe(float4_to_float3(F)));
+ F_energy += Ap_energy[1] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
/* 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(isfinite_safe(float4_to_float3(F)));
+ F_energy += Ap_energy[2] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
/* 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(isfinite_safe(float4_to_float3(F)));
+ F_energy += Ap_energy[3] * Mp * Np;
+ kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
- *eval = float4_to_float3(F);
- *pdf = F.w;
+ *eval = F;
+ *pdf = F_energy;
*omega_in = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
@@ -489,25 +499,28 @@ 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(ccl_private const ShaderClosure *sc)
+ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc)
{
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
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)
+ccl_device_inline Spectrum
+bsdf_principled_hair_sigma_from_reflectance(const Spectrum color, const float azimuthal_roughness)
{
- const float3 sigma = log(color) /
- bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness);
+ const Spectrum sigma = log(color) /
+ bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness);
return sigma * sigma;
}
-ccl_device_inline float3 bsdf_principled_hair_sigma_from_concentration(const float eumelanin,
- const float pheomelanin)
+ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_concentration(const float eumelanin,
+ const float pheomelanin)
{
- return eumelanin * make_float3(0.506f, 0.841f, 1.653f) +
- pheomelanin * make_float3(0.343f, 0.733f, 1.924f);
+ const float3 eumelanin_color = make_float3(0.506f, 0.841f, 1.653f);
+ const float3 pheomelanin_color = make_float3(0.343f, 0.733f, 1.924f);
+
+ return eumelanin * rgb_to_spectrum(eumelanin_color) +
+ pheomelanin * rgb_to_spectrum(pheomelanin_color);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index c6cbd1ffae7..091fbde5585 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -17,8 +17,8 @@
CCL_NAMESPACE_BEGIN
typedef struct MicrofacetExtra {
- float3 color, cspec0;
- float3 fresnel_color;
+ Spectrum color, cspec0;
+ Spectrum fresnel_color;
float clearcoat;
} MicrofacetExtra;
@@ -233,11 +233,11 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg,
*
* Else it is simply white
*/
-ccl_device_forceinline float3 reflection_color(ccl_private const MicrofacetBsdf *bsdf,
- float3 L,
- float3 H)
+ccl_device_forceinline Spectrum reflection_color(ccl_private const MicrofacetBsdf *bsdf,
+ float3 L,
+ float3 H)
{
- float3 F = make_float3(1.0f, 1.0f, 1.0f);
+ Spectrum F = one_spectrum();
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
if (use_fresnel) {
@@ -357,10 +357,10 @@ ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float ro
bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
}
-ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float alpha_x = bsdf->alpha_x;
@@ -370,7 +370,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosu
if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
float cosNO = dot(N, I);
@@ -451,12 +451,12 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosu
/* eq. 20 */
float common = D * 0.25f / cosNO;
- float3 F = reflection_color(bsdf, omega_in, m);
+ Spectrum F = reflection_color(bsdf, omega_in, m);
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
F *= 0.25f * bsdf->extra->clearcoat;
}
- float3 out = F * G * common;
+ Spectrum out = F * G * common;
/* eq. 2 in distribution of visible normals sampling
* `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
@@ -469,13 +469,13 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosu
return out;
}
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float alpha_x = bsdf->alpha_x;
@@ -486,7 +486,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClos
if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
float cosNO = dot(N, I);
@@ -494,7 +494,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClos
if (cosNO <= 0 || cosNI >= 0) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f); /* vectors on same side -- not possible */
+ return zero_spectrum(); /* vectors on same side -- not possible */
}
/* compute half-vector of the refraction (eq. 16) */
float3 ht = -(m_eta * omega_in + I);
@@ -530,7 +530,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClos
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * fabsf(cosHO * cosHI) * common;
- return make_float3(out, out, out);
+ return make_spectrum(out);
}
ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
@@ -541,7 +541,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -588,7 +588,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
if (alpha_x * alpha_y <= 1e-7f) {
/* some high number for MIS */
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
@@ -664,7 +664,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
float common = (G1o * D) * 0.25f / cosNO;
*pdf = common;
- float3 F = reflection_color(bsdf, *omega_in, m);
+ Spectrum F = reflection_color(bsdf, *omega_in, m);
*eval = G1i * common * F;
}
@@ -679,7 +679,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
#endif
}
else {
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
*pdf = 0.0f;
}
}
@@ -722,7 +722,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
/* some high number for MIS */
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
label = LABEL_TRANSMIT | LABEL_SINGULAR;
}
else {
@@ -750,11 +750,11 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
float out = G1i * fabsf(cosHI * cosHO) * common;
*pdf = cosHO * fabsf(cosHI) * common;
- *eval = make_float3(out, out, out);
+ *eval = make_spectrum(out);
}
}
else {
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
*pdf = 0.0f;
}
}
@@ -835,10 +835,10 @@ ccl_device_inline float bsdf_beckmann_aniso_G1(
return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f);
}
-ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float alpha_x = bsdf->alpha_x;
@@ -848,7 +848,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(ccl_private const Shader
if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
float cosNO = dot(N, I);
@@ -910,16 +910,16 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(ccl_private const Shader
* pdf = pm * 0.25 / dot(m, I); */
*pdf = G1o * common;
- return make_float3(out, out, out);
+ return make_spectrum(out);
}
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
float alpha_x = bsdf->alpha_x;
@@ -930,7 +930,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const Shade
if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
float cosNO = dot(N, I);
@@ -938,7 +938,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const Shade
if (cosNO <= 0 || cosNI >= 0) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
/* compute half-vector of the refraction (eq. 16) */
float3 ht = -(m_eta * omega_in + I);
@@ -971,7 +971,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const Shade
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * fabsf(cosHO * cosHI) * common;
- return make_float3(out, out, out);
+ return make_spectrum(out);
}
ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
@@ -982,7 +982,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -1028,7 +1028,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
if (alpha_x * alpha_y <= 1e-7f) {
/* some high number for MIS */
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
label = LABEL_REFLECT | LABEL_SINGULAR;
}
else {
@@ -1074,7 +1074,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
float out = G * common;
*pdf = G1o * common;
- *eval = make_float3(out, out, out);
+ *eval = make_spectrum(out);
}
#ifdef __RAY_DIFFERENTIALS__
@@ -1083,7 +1083,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
#endif
}
else {
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
*pdf = 0.0f;
}
}
@@ -1126,7 +1126,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
/* some high number for MIS */
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
label = LABEL_TRANSMIT | LABEL_SINGULAR;
}
else {
@@ -1155,11 +1155,11 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * cosHO * fabsf(cosHI) * common;
- *eval = make_float3(out, out, out);
+ *eval = make_spectrum(out);
}
}
else {
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
*pdf = 0.0f;
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index b2e068daf17..e6ab116519b 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -95,29 +95,29 @@ ccl_device_forceinline float3 mf_sample_vndf(const float3 wi,
/* Phase function for reflective materials. */
ccl_device_forceinline float3 mf_sample_phase_glossy(const float3 wi,
- ccl_private float3 *weight,
+ ccl_private Spectrum *weight,
const float3 wm)
{
return -wi + 2.0f * wm * dot(wi, wm);
}
-ccl_device_forceinline float3 mf_eval_phase_glossy(const float3 w,
- const float lambda,
- const float3 wo,
- const float2 alpha)
+ccl_device_forceinline Spectrum mf_eval_phase_glossy(const float3 w,
+ const float lambda,
+ const float3 wo,
+ const float2 alpha)
{
if (w.z > 0.9999f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
const float3 wh = normalize(wo - w);
if (wh.z < 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z;
const float dotW_WH = dot(-w, wh);
if (dotW_WH < 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f);
if (alpha.x == alpha.y)
@@ -125,7 +125,7 @@ ccl_device_forceinline float3 mf_eval_phase_glossy(const float3 w,
else
phase *= D_ggx_aniso(wh, alpha);
- return make_float3(phase, phase, phase);
+ return make_spectrum(phase);
}
/* Phase function for dielectric transmissive materials, including both reflection and refraction
@@ -148,22 +148,22 @@ ccl_device_forceinline float3 mf_sample_phase_glass(const float3 wi,
return normalize(wm * (cosI * inv_eta + cosT) - wi * inv_eta);
}
-ccl_device_forceinline float3 mf_eval_phase_glass(const float3 w,
- const float lambda,
- const float3 wo,
- const bool wo_outside,
- const float2 alpha,
- const float eta)
+ccl_device_forceinline Spectrum mf_eval_phase_glass(const float3 w,
+ const float lambda,
+ const float3 wo,
+ const bool wo_outside,
+ const float2 alpha,
+ const float eta)
{
if (w.z > 0.9999f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z;
float v;
if (wo_outside) {
const float3 wh = normalize(wo - w);
if (wh.z < 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
const float dotW_WH = dot(-w, wh);
v = fresnel_dielectric_cos(dotW_WH, eta) * max(0.0f, dotW_WH) * D_ggx(wh, alpha.x) * 0.25f /
@@ -175,14 +175,14 @@ ccl_device_forceinline float3 mf_eval_phase_glass(const float3 w,
wh = -wh;
const float dotW_WH = dot(-w, wh), dotWO_WH = dot(wo, wh);
if (dotW_WH < 0.0f)
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
float temp = dotW_WH + eta * dotWO_WH;
v = (1.0f - fresnel_dielectric_cos(dotW_WH, eta)) * max(0.0f, dotW_WH) * max(0.0f, -dotWO_WH) *
D_ggx(wh, alpha.x) / (pArea * temp * temp);
}
- return make_float3(v, v, v);
+ return make_spectrum(v);
}
/* === Utility functions for the random walks === */
@@ -415,27 +415,27 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
-ccl_device float3 bsdf_microfacet_multi_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf,
+ ccl_private uint *lcg_state)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf,
+ ccl_private uint *lcg_state)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
float3 X, Y, Z;
@@ -444,7 +444,7 @@ ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const Shade
/* Ensure that the both directions are on the outside w.r.t. the shading normal. */
if (dot(Z, I) <= 0.0f || dot(Z, omega_in) <= 0.0f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
@@ -482,7 +482,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -509,7 +509,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
return LABEL_NONE;
}
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
*domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
@@ -588,7 +588,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
-ccl_device float3
+ccl_device Spectrum
bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *sc,
const float3 I,
const float3 omega_in,
@@ -599,7 +599,7 @@ bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *s
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
float3 X, Y, Z;
@@ -622,17 +622,18 @@ bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *s
bsdf->extra->color);
}
-ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf,
- ccl_private uint *lcg_state)
+ccl_device Spectrum
+bsdf_microfacet_multi_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf,
+ ccl_private uint *lcg_state)
{
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
@@ -665,7 +666,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -699,7 +700,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg,
&inside);
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
if (randu < fresnel) {
*omega_in = R;
#ifdef __RAY_DIFFERENTIALS__
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
index e4fcf0e6ba3..91fb9158050 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
@@ -12,16 +12,16 @@
* multi-scattered energy is used. In combination with MIS, that is enough to produce an unbiased
* result, although the balance heuristic isn't necessarily optimal anymore.
*/
-ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
- float3 wo,
- const bool wo_outside,
- const float3 color,
- const float alpha_x,
- const float alpha_y,
- ccl_private uint *lcg_state,
- const float eta,
- bool use_fresnel,
- const float3 cspec0)
+ccl_device_forceinline Spectrum MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
+ float3 wo,
+ const bool wo_outside,
+ const Spectrum color,
+ const float alpha_x,
+ const float alpha_y,
+ ccl_private uint *lcg_state,
+ const float eta,
+ bool use_fresnel,
+ const Spectrum cspec0)
{
/* Evaluating for a shallower incoming direction produces less noise, and the properties of the
* BSDF guarantee reciprocity. */
@@ -46,7 +46,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
}
if (wi.z < 1e-5f || (wo.z < 1e-5f && wo_outside) || (wo.z > -1e-5f && !wo_outside))
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
const float2 alpha = make_float2(alpha_x, alpha_y);
@@ -54,8 +54,8 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
float shadowing_lambda = mf_lambda(wo_outside ? wo : -wo, alpha);
/* Analytically compute single scattering for lower noise. */
- float3 eval;
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ Spectrum eval;
+ Spectrum throughput = one_spectrum();
const float3 wh = normalize(wi + wo);
#ifdef MF_MULTI_GLASS
eval = mf_eval_phase_glass(-wi, lambda_r, wo, wo_outside, alpha, eta);
@@ -70,7 +70,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
val *= D_ggx(wh, alpha.x);
else
val *= D_ggx_aniso(wh, alpha);
- eval = make_float3(val, val, val);
+ eval = make_spectrum(val);
#endif
float F0 = fresnel_dielectric_cos(1.0f, eta);
@@ -99,7 +99,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
#ifdef MF_MULTI_GLASS
if (order == 0 && use_fresnel) {
/* Evaluate amount of scattering towards wo on this microfacet. */
- float3 phase;
+ Spectrum phase;
if (outside)
phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
else
@@ -113,7 +113,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
#endif
if (order > 0) {
/* Evaluate amount of scattering towards wo on this microfacet. */
- float3 phase;
+ Spectrum phase;
#ifdef MF_MULTI_GLASS
if (outside)
phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
@@ -172,19 +172,19 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
* walk escaped the surface in wo. The function returns the throughput between wi and wo. Without
* reflection losses due to coloring or fresnel absorption in conductors, the sampling is optimal.
*/
-ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
- ccl_private float3 *wo,
- const float3 color,
- const float alpha_x,
- const float alpha_y,
- ccl_private uint *lcg_state,
- const float eta,
- bool use_fresnel,
- const float3 cspec0)
+ccl_device_forceinline Spectrum MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
+ ccl_private float3 *wo,
+ const Spectrum color,
+ const float alpha_x,
+ const float alpha_y,
+ ccl_private uint *lcg_state,
+ const float eta,
+ bool use_fresnel,
+ const Spectrum cspec0)
{
const float2 alpha = make_float2(alpha_x, alpha_y);
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+ Spectrum throughput = one_spectrum();
float3 wr = -wi;
float lambda_r = mf_lambda(wr, alpha);
float hr = 1.0f;
@@ -229,7 +229,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
throughput *= color;
}
else {
- float3 t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
+ Spectrum t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
if (order == 0)
throughput = t_color;
@@ -239,7 +239,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
}
#else /* MF_MULTI_GLOSSY */
if (use_fresnel) {
- float3 t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
+ Spectrum t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
if (order == 0)
throughput = t_color;
@@ -254,7 +254,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
G1_r = mf_G1(wr, C1_r, lambda_r);
}
*wo = make_float3(0.0f, 0.0f, 1.0f);
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
#undef MF_MULTI_GLASS
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index 56c7ec869c7..fcfeb9257f1 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -15,10 +15,10 @@ typedef struct OrenNayarBsdf {
static_assert(sizeof(ShaderClosure) >= sizeof(OrenNayarBsdf), "OrenNayarBsdf is too large!");
-ccl_device float3 bsdf_oren_nayar_get_intensity(ccl_private const ShaderClosure *sc,
- float3 n,
- float3 v,
- float3 l)
+ccl_device Spectrum bsdf_oren_nayar_get_intensity(ccl_private const ShaderClosure *sc,
+ float3 n,
+ float3 v,
+ float3 l)
{
ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc;
float nl = max(dot(n, l), 0.0f);
@@ -28,7 +28,7 @@ ccl_device float3 bsdf_oren_nayar_get_intensity(ccl_private const ShaderClosure
if (t > 0.0f)
t /= max(nl, nv) + FLT_MIN;
float is = nl * (bsdf->a + bsdf->b * t);
- return make_float3(is, is, is);
+ return make_spectrum(is);
}
ccl_device int bsdf_oren_nayar_setup(ccl_private OrenNayarBsdf *bsdf)
@@ -47,10 +47,10 @@ ccl_device int bsdf_oren_nayar_setup(ccl_private OrenNayarBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc;
if (dot(bsdf->N, omega_in) > 0.0f) {
@@ -59,17 +59,17 @@ ccl_device float3 bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure *
}
else {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
}
-ccl_device float3 bsdf_oren_nayar_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_oren_nayar_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc,
@@ -79,7 +79,7 @@ ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -99,7 +99,7 @@ ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc,
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_DIFFUSE;
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index 74a1f7ae090..d010e74cb65 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -8,6 +8,8 @@
#pragma once
+#include "kernel/util/color.h"
+
CCL_NAMESPACE_BEGIN
#ifdef __OSL__
@@ -42,10 +44,10 @@ ccl_device int bsdf_phong_ramp_setup(ccl_private PhongRampBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
float m_exponent = bsdf->exponent;
@@ -61,11 +63,11 @@ ccl_device float3 bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure *
float common = 0.5f * M_1_PI_F * cosp;
float out = cosNI * (m_exponent + 2) * common;
*pdf = (m_exponent + 1) * common;
- return bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
+ return rgb_to_spectrum(bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out);
}
}
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device float3 bsdf_phong_ramp_eval_transmit(ccl_private const ShaderClosure *sc,
@@ -84,7 +86,7 @@ ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -119,12 +121,12 @@ ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc,
float common = 0.5f * M_1_PI_F * cosp;
*pdf = (m_exponent + 1) * common;
float out = cosNI * (m_exponent + 2) * common;
- *eval = bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
+ *eval = rgb_to_spectrum(bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out);
}
}
}
else {
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
*pdf = 0.0f;
}
return LABEL_REFLECT | LABEL_GLOSSY;
diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
index 5a7020e82d2..90ef252b3b9 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h
@@ -42,7 +42,7 @@ ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3
+ccl_device Spectrum
bsdf_principled_diffuse_compute_brdf(ccl_private const PrincipledDiffuseBsdf *bsdf,
float3 N,
float3 V,
@@ -52,7 +52,7 @@ bsdf_principled_diffuse_compute_brdf(ccl_private const PrincipledDiffuseBsdf *bs
const float NdotL = dot(N, L);
if (NdotL <= 0) {
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
const float NdotV = dot(N, V);
@@ -82,7 +82,7 @@ bsdf_principled_diffuse_compute_brdf(ccl_private const PrincipledDiffuseBsdf *bs
float value = M_1_PI_F * NdotL * f;
- return make_float3(value, value, value);
+ return make_spectrum(value);
}
/* Compute Fresnel at entry point, to be combined with #PRINCIPLED_DIFFUSE_LAMBERT_EXIT
@@ -109,10 +109,10 @@ ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_principled_diffuse_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_diffuse_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc;
@@ -126,17 +126,17 @@ ccl_device float3 bsdf_principled_diffuse_eval_reflect(ccl_private const ShaderC
}
else {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
}
-ccl_device float3 bsdf_principled_diffuse_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_diffuse_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *sc,
@@ -146,7 +146,7 @@ ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *s
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -169,7 +169,7 @@ ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *s
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_DIFFUSE;
}
diff --git a/intern/cycles/kernel/closure/bsdf_principled_sheen.h b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
index 3a96a93db73..42a776299eb 100644
--- a/intern/cycles/kernel/closure/bsdf_principled_sheen.h
+++ b/intern/cycles/kernel/closure/bsdf_principled_sheen.h
@@ -32,7 +32,7 @@ ccl_device_inline float calculate_avg_principled_sheen_brdf(float3 N, float3 I)
return schlick_fresnel(NdotI) * NdotI;
}
-ccl_device float3
+ccl_device Spectrum
calculate_principled_sheen_brdf(float3 N, float3 V, float3 L, float3 H, ccl_private float *pdf)
{
float NdotL = dot(N, L);
@@ -40,14 +40,14 @@ calculate_principled_sheen_brdf(float3 N, float3 V, float3 L, float3 H, ccl_priv
if (NdotL < 0 || NdotV < 0) {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
float LdotH = dot(L, H);
float value = schlick_fresnel(LdotH) * NdotL;
- return make_float3(value, value, value);
+ return make_spectrum(value);
}
ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd,
@@ -59,10 +59,10 @@ ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd,
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc;
@@ -77,17 +77,17 @@ ccl_device float3 bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClo
}
else {
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
}
-ccl_device float3 bsdf_principled_sheen_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_principled_sheen_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc,
@@ -97,7 +97,7 @@ ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -121,7 +121,7 @@ ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc,
#endif
}
else {
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
*pdf = 0.0f;
}
return LABEL_REFLECT | LABEL_DIFFUSE;
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index c8db2b7cf13..40d02b13b46 100644
--- a/intern/cycles/kernel/closure/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -18,22 +18,22 @@ ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf)
return SD_BSDF;
}
-ccl_device float3 bsdf_reflection_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_reflection_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_reflection_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_reflection_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc,
@@ -43,7 +43,7 @@ ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -63,12 +63,12 @@ ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc,
#endif
/* Some high number for MIS. */
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
}
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
return LABEL_REFLECT | LABEL_SINGULAR;
}
diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h
index 862e774da87..3faa51025d6 100644
--- a/intern/cycles/kernel/closure/bsdf_refraction.h
+++ b/intern/cycles/kernel/closure/bsdf_refraction.h
@@ -18,22 +18,22 @@ ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
return SD_BSDF;
}
-ccl_device float3 bsdf_refraction_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_refraction_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_refraction_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_refraction_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
@@ -43,7 +43,7 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -77,7 +77,7 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
if (!inside && fresnel != 1.0f) {
/* Some high number for MIS. */
*pdf = 1e6f;
- *eval = make_float3(1e6f, 1e6f, 1e6f);
+ *eval = make_spectrum(1e6f);
*omega_in = T;
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = dTdx;
@@ -86,7 +86,7 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc,
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
return LABEL_TRANSMIT | LABEL_SINGULAR;
}
diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h
index 0400fc61860..f2f48417319 100644
--- a/intern/cycles/kernel/closure/bsdf_toon.h
+++ b/intern/cycles/kernel/closure/bsdf_toon.h
@@ -30,7 +30,7 @@ ccl_device int bsdf_diffuse_toon_setup(ccl_private ToonBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle)
+ccl_device float bsdf_toon_get_intensity(float max_angle, float smooth, float angle)
{
float is;
@@ -41,7 +41,7 @@ ccl_device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float a
else
is = 0.0f;
- return make_float3(is, is, is);
+ return is;
}
ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
@@ -49,35 +49,35 @@ ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
return fminf(max_angle + smooth, M_PI_2_F);
}
-ccl_device float3 bsdf_diffuse_toon_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_toon_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
float max_angle = bsdf->size * M_PI_2_F;
float smooth = bsdf->smooth * M_PI_2_F;
float angle = safe_acosf(fmaxf(dot(bsdf->N, omega_in), 0.0f));
- float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+ float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
- if (eval.x > 0.0f) {
+ if (eval > 0.0f) {
float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
*pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
- return *pdf * eval;
+ return make_spectrum(*pdf * eval);
}
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_diffuse_toon_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_diffuse_toon_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc,
@@ -87,7 +87,7 @@ ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -103,7 +103,7 @@ ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc,
sample_uniform_cone(bsdf->N, sample_angle, randu, randv, omega_in, pdf);
if (dot(Ng, *omega_in) > 0.0f) {
- *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
+ *eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle));
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the bounce
@@ -112,12 +112,12 @@ ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc,
#endif
}
else {
- *eval = make_float3(0.f, 0.f, 0.f);
+ *eval = zero_spectrum();
*pdf = 0.0f;
}
}
else {
- *eval = make_float3(0.f, 0.f, 0.f);
+ *eval = zero_spectrum();
*pdf = 0.0f;
}
@@ -135,10 +135,10 @@ ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc;
float max_angle = bsdf->size * M_PI_2_F;
@@ -153,23 +153,23 @@ ccl_device float3 bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosure
float angle = safe_acosf(fmaxf(cosRI, 0.0f));
- float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+ float eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
*pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
- return *pdf * eval;
+ return make_spectrum(*pdf * eval);
}
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_glossy_toon_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_glossy_toon_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc,
@@ -179,7 +179,7 @@ ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -204,7 +204,7 @@ ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc,
/* make sure the direction we chose is still in the right hemisphere */
if (cosNI > 0) {
- *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
+ *eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle));
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
@@ -213,12 +213,12 @@ ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc,
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
}
else {
*pdf = 0.0f;
- *eval = make_float3(0.0f, 0.0f, 0.0f);
+ *eval = zero_spectrum();
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h
index 636d9d664f2..89b36c709e4 100644
--- a/intern/cycles/kernel/closure/bsdf_transparent.h
+++ b/intern/cycles/kernel/closure/bsdf_transparent.h
@@ -11,7 +11,7 @@
CCL_NAMESPACE_BEGIN
ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd,
- const float3 weight,
+ const Spectrum weight,
uint32_t path_flag)
{
/* Check cutoff weight. */
@@ -59,22 +59,22 @@ ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd,
}
}
-ccl_device float3 bsdf_transparent_eval_reflect(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_transparent_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
-ccl_device float3 bsdf_transparent_eval_transmit(ccl_private const ShaderClosure *sc,
- const float3 I,
- const float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum bsdf_transparent_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
{
*pdf = 0.0f;
- return make_float3(0.0f, 0.0f, 0.0f);
+ return zero_spectrum();
}
ccl_device int bsdf_transparent_sample(ccl_private const ShaderClosure *sc,
@@ -84,7 +84,7 @@ ccl_device int bsdf_transparent_sample(ccl_private const ShaderClosure *sc,
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -97,7 +97,7 @@ ccl_device int bsdf_transparent_sample(ccl_private const ShaderClosure *sc,
*domega_in_dy = -dIdy;
#endif
*pdf = 1;
- *eval = make_float3(1, 1, 1);
+ *eval = one_spectrum();
return LABEL_TRANSMIT | LABEL_TRANSPARENT;
}
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
index e3b24d487f1..10f2643721e 100644
--- a/intern/cycles/kernel/closure/bsdf_util.h
+++ b/intern/cycles/kernel/closure/bsdf_util.h
@@ -110,8 +110,8 @@ ccl_device float schlick_fresnel(float u)
}
/* Calculate the fresnel color which is a blend between white and the F0 color (cspec0) */
-ccl_device_forceinline float3
-interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0)
+ccl_device_forceinline Spectrum
+interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, Spectrum cspec0)
{
/* Calculate the fresnel interpolation factor
* The value from fresnel_dielectric_cos(...) has to be normalized because
@@ -121,7 +121,7 @@ interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0
float FH = (fresnel_dielectric_cos(dot(L, H), ior) - F0) * F0_norm;
/* Blend between white and a specular color with respect to the fresnel */
- return cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
+ return cspec0 * (1.0f - FH) + make_spectrum(FH);
}
ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)
diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h
index b87790f5f8a..cdd4d128c1f 100644
--- a/intern/cycles/kernel/closure/bssrdf.h
+++ b/intern/cycles/kernel/closure/bssrdf.h
@@ -8,8 +8,8 @@ CCL_NAMESPACE_BEGIN
typedef struct Bssrdf {
SHADER_CLOSURE_BASE;
- float3 radius;
- float3 albedo;
+ Spectrum radius;
+ Spectrum albedo;
float roughness;
float anisotropy;
} Bssrdf;
@@ -69,12 +69,13 @@ ccl_device void bssrdf_setup_radius(ccl_private Bssrdf *bssrdf,
const float fourthirdA = (4.0f / 3.0f) * (1.0f + F_dr) /
(1.0f - F_dr); /* From Jensen's `Fdr` ratio formula. */
- 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));
+ Spectrum alpha_prime;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ GET_SPECTRUM_CHANNEL(alpha_prime, i) = bssrdf_dipole_compute_alpha_prime(
+ GET_SPECTRUM_CHANNEL(bssrdf->albedo, i), fourthirdA);
+ }
- bssrdf->radius *= sqrt(3.0f * (one_float3() - alpha_prime));
+ bssrdf->radius *= sqrt(3.0f * (one_spectrum() - alpha_prime));
}
}
@@ -98,7 +99,7 @@ ccl_device_inline float bssrdf_burley_fitting(float A)
/* 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)
+ccl_device_inline Spectrum bssrdf_burley_compatible_mfp(Spectrum r)
{
return 0.25f * M_1_PI_F * r;
}
@@ -106,11 +107,13 @@ ccl_device_inline float3 bssrdf_burley_compatible_mfp(float3 r)
ccl_device void bssrdf_burley_setup(ccl_private Bssrdf *bssrdf)
{
/* Mean free path length. */
- const float3 l = bssrdf_burley_compatible_mfp(bssrdf->radius);
+ const Spectrum 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));
+ const Spectrum A = bssrdf->albedo;
+ Spectrum s;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ GET_SPECTRUM_CHANNEL(s, i) = bssrdf_burley_fitting(GET_SPECTRUM_CHANNEL(A, i));
+ }
bssrdf->radius = l / s;
}
@@ -198,22 +201,18 @@ ccl_device void bssrdf_burley_sample(const float d,
*h = safe_sqrtf(Rm * Rm - r_ * r_);
}
-ccl_device float bssrdf_num_channels(const float3 radius)
+ccl_device float bssrdf_num_channels(const Spectrum radius)
{
float channels = 0;
- if (radius.x > 0.0f) {
- channels += 1.0f;
- }
- if (radius.y > 0.0f) {
- channels += 1.0f;
- }
- if (radius.z > 0.0f) {
- channels += 1.0f;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ if (GET_SPECTRUM_CHANNEL(radius, i) > 0.0f) {
+ channels += 1.0f;
+ }
}
return channels;
}
-ccl_device void bssrdf_sample(const float3 radius,
+ccl_device void bssrdf_sample(const Spectrum radius,
float xi,
ccl_private float *r,
ccl_private float *h)
@@ -224,39 +223,44 @@ ccl_device void bssrdf_sample(const float3 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 *= num_channels;
-
- if (xi < 1.0f) {
- sampled_radius = (radius.x > 0.0f) ? radius.x : (radius.y > 0.0f) ? radius.y : radius.z;
- }
- else if (xi < 2.0f) {
- xi -= 1.0f;
- sampled_radius = (radius.x > 0.0f && radius.y > 0.0f) ? radius.y : radius.z;
- }
- else {
- xi -= 2.0f;
- sampled_radius = radius.z;
+ sampled_radius = 0.0f;
+
+ float sum = 0.0f;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ const float channel_radius = GET_SPECTRUM_CHANNEL(radius, i);
+ if (channel_radius > 0.0f) {
+ const float next_sum = sum + 1.0f;
+ if (xi < next_sum) {
+ xi -= sum;
+ sampled_radius = channel_radius;
+ break;
+ }
+ sum = next_sum;
+ }
}
/* Sample BSSRDF. */
bssrdf_burley_sample(sampled_radius, xi, r, h);
}
-ccl_device_forceinline float3 bssrdf_eval(const float3 radius, float r)
+ccl_device_forceinline Spectrum bssrdf_eval(const Spectrum radius, float r)
{
- return make_float3(bssrdf_burley_pdf(radius.x, r),
- bssrdf_burley_pdf(radius.y, r),
- bssrdf_burley_pdf(radius.z, r));
+ Spectrum result;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ GET_SPECTRUM_CHANNEL(result, i) = bssrdf_burley_pdf(GET_SPECTRUM_CHANNEL(radius, i), r);
+ }
+ return result;
}
-ccl_device_forceinline float bssrdf_pdf(const float3 radius, float r)
+ccl_device_forceinline float bssrdf_pdf(const Spectrum radius, float r)
{
- float3 pdf = bssrdf_eval(radius, r);
- return (pdf.x + pdf.y + pdf.z) / bssrdf_num_channels(radius);
+ Spectrum pdf = bssrdf_eval(radius, r);
+ return reduce_add(pdf) / bssrdf_num_channels(radius);
}
/* Setup */
-ccl_device_inline ccl_private Bssrdf *bssrdf_alloc(ccl_private ShaderData *sd, float3 weight)
+ccl_device_inline ccl_private Bssrdf *bssrdf_alloc(ccl_private ShaderData *sd, Spectrum weight)
{
ccl_private Bssrdf *bssrdf = (ccl_private Bssrdf *)closure_alloc(
sd, sizeof(Bssrdf), CLOSURE_NONE_ID, weight);
@@ -294,29 +298,19 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
}
/* Verify if the radii are large enough to sample without precision issues. */
- int bssrdf_channels = 3;
- float3 diffuse_weight = make_float3(0.0f, 0.0f, 0.0f);
-
- if (bssrdf->radius.x < BSSRDF_MIN_RADIUS) {
- diffuse_weight.x = bssrdf->weight.x;
- bssrdf->weight.x = 0.0f;
- bssrdf->radius.x = 0.0f;
- bssrdf_channels--;
- }
- if (bssrdf->radius.y < BSSRDF_MIN_RADIUS) {
- diffuse_weight.y = bssrdf->weight.y;
- bssrdf->weight.y = 0.0f;
- bssrdf->radius.y = 0.0f;
- bssrdf_channels--;
- }
- if (bssrdf->radius.z < BSSRDF_MIN_RADIUS) {
- diffuse_weight.z = bssrdf->weight.z;
- bssrdf->weight.z = 0.0f;
- bssrdf->radius.z = 0.0f;
- bssrdf_channels--;
+ int bssrdf_channels = SPECTRUM_CHANNELS;
+ Spectrum diffuse_weight = zero_spectrum();
+
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ if (GET_SPECTRUM_CHANNEL(bssrdf->radius, i) < BSSRDF_MIN_RADIUS) {
+ GET_SPECTRUM_CHANNEL(diffuse_weight, i) = GET_SPECTRUM_CHANNEL(bssrdf->weight, i);
+ GET_SPECTRUM_CHANNEL(bssrdf->weight, i) = 0.0f;
+ GET_SPECTRUM_CHANNEL(bssrdf->radius, i) = 0.0f;
+ bssrdf_channels--;
+ }
}
- if (bssrdf_channels < 3) {
+ if (bssrdf_channels < SPECTRUM_CHANNELS) {
/* Add diffuse BSDF if any radius too small. */
#ifdef __PRINCIPLED__
if (bssrdf->roughness != FLT_MAX) {
diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h
index 03e19cbde21..d896721f77b 100644
--- a/intern/cycles/kernel/closure/emissive.h
+++ b/intern/cycles/kernel/closure/emissive.h
@@ -12,7 +12,7 @@ CCL_NAMESPACE_BEGIN
/* BACKGROUND CLOSURE */
-ccl_device void background_setup(ccl_private ShaderData *sd, const float3 weight)
+ccl_device void background_setup(ccl_private ShaderData *sd, const Spectrum weight)
{
if (sd->flag & SD_EMISSION) {
sd->closure_emission_background += weight;
@@ -25,7 +25,7 @@ ccl_device void background_setup(ccl_private ShaderData *sd, const float3 weight
/* EMISSION CLOSURE */
-ccl_device void emission_setup(ccl_private ShaderData *sd, const float3 weight)
+ccl_device void emission_setup(ccl_private ShaderData *sd, const Spectrum weight)
{
if (sd->flag & SD_EMISSION) {
sd->closure_emission_background += weight;
@@ -54,11 +54,11 @@ ccl_device void emissive_sample(const float3 Ng,
/* todo: not implemented and used yet */
}
-ccl_device float3 emissive_simple_eval(const float3 Ng, const float3 I)
+ccl_device Spectrum emissive_simple_eval(const float3 Ng, const float3 I)
{
float res = emissive_pdf(Ng, I);
- return make_float3(res, res, res);
+ return make_spectrum(res);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index ef414c7b821..10494be87cb 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -7,7 +7,7 @@ CCL_NAMESPACE_BEGIN
/* VOLUME EXTINCTION */
-ccl_device void volume_extinction_setup(ccl_private ShaderData *sd, float3 weight)
+ccl_device void volume_extinction_setup(ccl_private ShaderData *sd, Spectrum weight)
{
if (sd->flag & SD_EXTINCTION) {
sd->closure_transparent_extinction += weight;
@@ -48,10 +48,10 @@ ccl_device int volume_henyey_greenstein_setup(ccl_private HenyeyGreensteinVolume
return SD_SCATTER;
}
-ccl_device float3 volume_henyey_greenstein_eval_phase(ccl_private const ShaderVolumeClosure *svc,
- const float3 I,
- float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum volume_henyey_greenstein_eval_phase(ccl_private const ShaderVolumeClosure *svc,
+ const float3 I,
+ float3 omega_in,
+ ccl_private float *pdf)
{
float g = svc->g;
@@ -64,7 +64,7 @@ ccl_device float3 volume_henyey_greenstein_eval_phase(ccl_private const ShaderVo
*pdf = single_peaked_henyey_greenstein(cos_theta, g);
}
- return make_float3(*pdf, *pdf, *pdf);
+ return make_spectrum(*pdf);
}
ccl_device float3
@@ -105,7 +105,7 @@ ccl_device int volume_henyey_greenstein_sample(ccl_private const ShaderVolumeClo
float3 dIdy,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private float3 *domega_in_dx,
ccl_private float3 *domega_in_dy,
@@ -115,7 +115,7 @@ ccl_device int volume_henyey_greenstein_sample(ccl_private const ShaderVolumeClo
/* note that I points towards the viewer and so is used negated */
*omega_in = henyey_greenstrein_sample(-I, g, randu, randv, pdf);
- *eval = make_float3(*pdf, *pdf, *pdf); /* perfect importance sampling */
+ *eval = make_spectrum(*pdf); /* perfect importance sampling */
#ifdef __RAY_DIFFERENTIALS__
/* todo: implement ray differential estimation */
@@ -128,10 +128,10 @@ ccl_device int volume_henyey_greenstein_sample(ccl_private const ShaderVolumeClo
/* VOLUME CLOSURE */
-ccl_device float3 volume_phase_eval(ccl_private const ShaderData *sd,
- ccl_private const ShaderVolumeClosure *svc,
- float3 omega_in,
- ccl_private float *pdf)
+ccl_device Spectrum volume_phase_eval(ccl_private const ShaderData *sd,
+ ccl_private const ShaderVolumeClosure *svc,
+ float3 omega_in,
+ ccl_private float *pdf)
{
return volume_henyey_greenstein_eval_phase(svc, sd->I, omega_in, pdf);
}
@@ -140,7 +140,7 @@ ccl_device int volume_phase_sample(ccl_private const ShaderData *sd,
ccl_private const ShaderVolumeClosure *svc,
float randu,
float randv,
- ccl_private float3 *eval,
+ ccl_private Spectrum *eval,
ccl_private float3 *omega_in,
ccl_private differential3 *domega_in,
ccl_private float *pdf)
@@ -164,45 +164,44 @@ ccl_device int volume_phase_sample(ccl_private const ShaderData *sd,
* unnecessary work in volumes and subsurface scattering. */
#define VOLUME_THROUGHPUT_EPSILON 1e-6f
-ccl_device float3 volume_color_transmittance(float3 sigma, float t)
+ccl_device Spectrum volume_color_transmittance(Spectrum sigma, float t)
{
return exp(-sigma * t);
}
-ccl_device float volume_channel_get(float3 value, int channel)
+ccl_device float volume_channel_get(Spectrum value, int channel)
{
- return (channel == 0) ? value.x : ((channel == 1) ? value.y : value.z);
+ return GET_SPECTRUM_CHANNEL(value, channel);
}
-ccl_device int volume_sample_channel(float3 albedo,
- float3 throughput,
+ccl_device int volume_sample_channel(Spectrum albedo,
+ Spectrum throughput,
float rand,
- ccl_private float3 *pdf)
+ ccl_private Spectrum *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;
+ Spectrum weights = fabs(throughput * albedo);
+ float sum_weights = reduce_add(weights);
if (sum_weights > 0.0f) {
*pdf = weights / sum_weights;
}
else {
- *pdf = make_float3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f);
+ *pdf = make_spectrum(1.0f / SPECTRUM_CHANNELS);
}
- if (rand < pdf->x) {
- return 0;
- }
- else if (rand < pdf->x + pdf->y) {
- return 1;
- }
- else {
- return 2;
+ float pdf_sum = 0.0f;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ pdf_sum += GET_SPECTRUM_CHANNEL(*pdf, i);
+ if (rand < pdf_sum) {
+ return i;
+ }
}
+ return SPECTRUM_CHANNELS - 1;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/device/cpu/compat.h b/intern/cycles/kernel/device/cpu/compat.h
index 631e55e0d42..1e3e790ca1f 100644
--- a/intern/cycles/kernel/device/cpu/compat.h
+++ b/intern/cycles/kernel/device/cpu/compat.h
@@ -33,38 +33,4 @@ CCL_NAMESPACE_BEGIN
#define kernel_assert(cond) assert(cond)
-/* Macros to handle different memory storage on different devices */
-
-#ifdef __KERNEL_SSE2__
-typedef vector3<sseb> sse3b;
-typedef vector3<ssef> sse3f;
-typedef vector3<ssei> sse3i;
-
-ccl_device_inline void print_sse3b(const char *label, sse3b &a)
-{
- print_sseb(label, a.x);
- print_sseb(label, a.y);
- print_sseb(label, a.z);
-}
-
-ccl_device_inline void print_sse3f(const char *label, sse3f &a)
-{
- print_ssef(label, a.x);
- print_ssef(label, a.y);
- print_ssef(label, a.z);
-}
-
-ccl_device_inline void print_sse3i(const char *label, sse3i &a)
-{
- print_ssei(label, a.x);
- print_ssei(label, a.y);
- print_ssei(label, a.z);
-}
-
-# if defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__)
-typedef vector3<avxf> avx3f;
-# endif
-
-#endif
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/device/metal/compat.h b/intern/cycles/kernel/device/metal/compat.h
index 80ee8ef5b57..b20cfca9a9c 100644
--- a/intern/cycles/kernel/device/metal/compat.h
+++ b/intern/cycles/kernel/device/metal/compat.h
@@ -189,35 +189,46 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \
} volume_write_lambda_pass{kg, this, state};
/* make_type definitions with Metal style element initializers */
-#ifdef make_float2
-# undef make_float2
-#endif
-#ifdef make_float3
-# undef make_float3
-#endif
-#ifdef make_float4
-# undef make_float4
-#endif
-#ifdef make_int2
-# undef make_int2
-#endif
-#ifdef make_int3
-# undef make_int3
-#endif
-#ifdef make_int4
-# undef make_int4
-#endif
-#ifdef make_uchar4
-# undef make_uchar4
-#endif
-
-#define make_float2(x, y) float2(x, y)
-#define make_float3(x, y, z) float3(x, y, z)
-#define make_float4(x, y, z, w) float4(x, y, z, w)
-#define make_int2(x, y) int2(x, y)
-#define make_int3(x, y, z) int3(x, y, z)
-#define make_int4(x, y, z, w) int4(x, y, z, w)
-#define make_uchar4(x, y, z, w) uchar4(x, y, z, w)
+ccl_device_forceinline float2 make_float2(const float x, const float y)
+{
+ return float2(x, y);
+}
+
+ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
+{
+ return float3(x, y, z);
+}
+
+ccl_device_forceinline float4 make_float4(const float x,
+ const float y,
+ const float z,
+ const float w)
+{
+ return float4(x, y, z, w);
+}
+
+ccl_device_forceinline int2 make_int2(const int x, const int y)
+{
+ return int2(x, y);
+}
+
+ccl_device_forceinline int3 make_int3(const int x, const int y, const int z)
+{
+ return int3(x, y, z);
+}
+
+ccl_device_forceinline int4 make_int4(const int x, const int y, const int z, const int w)
+{
+ return int4(x, y, z, w);
+}
+
+ccl_device_forceinline uchar4 make_uchar4(const uchar x,
+ const uchar y,
+ const uchar z,
+ const uchar w)
+{
+ return uchar4(x, y, z, w);
+}
/* Math functions */
diff --git a/intern/cycles/kernel/device/oneapi/compat.h b/intern/cycles/kernel/device/oneapi/compat.h
index d8234ee1400..5c49674f247 100644
--- a/intern/cycles/kernel/device/oneapi/compat.h
+++ b/intern/cycles/kernel/device/oneapi/compat.h
@@ -149,25 +149,13 @@ void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \
/* clang-format on */
/* Types */
+
/* It's not possible to use sycl types like sycl::float3, sycl::int3, etc
- * because these types have different interfaces from blender version */
+ * because these types have different interfaces from blender version. */
using uchar = unsigned char;
using sycl::half;
-struct float3 {
- float x, y, z;
-};
-
-ccl_always_inline float3 make_float3(float x, float y, float z)
-{
- return {x, y, z};
-}
-ccl_always_inline float3 make_float3(float x)
-{
- return {x, x, x};
-}
-
/* math functions */
#define fabsf(x) sycl::fabs((x))
#define copysignf(x, y) sycl::copysign((x), (y))
diff --git a/intern/cycles/kernel/film/accumulate.h b/intern/cycles/kernel/film/accumulate.h
index 33c35a68ad0..97ec915a8ad 100644
--- a/intern/cycles/kernel/film/accumulate.h
+++ b/intern/cycles/kernel/film/accumulate.h
@@ -21,10 +21,10 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline void bsdf_eval_init(ccl_private BsdfEval *eval,
const ClosureType closure_type,
- float3 value)
+ Spectrum value)
{
- eval->diffuse = zero_float3();
- eval->glossy = zero_float3();
+ eval->diffuse = zero_spectrum();
+ eval->glossy = zero_spectrum();
if (CLOSURE_IS_BSDF_DIFFUSE(closure_type)) {
eval->diffuse = value;
@@ -38,7 +38,7 @@ ccl_device_inline void bsdf_eval_init(ccl_private BsdfEval *eval,
ccl_device_inline void bsdf_eval_accum(ccl_private BsdfEval *eval,
const ClosureType closure_type,
- float3 value)
+ Spectrum value)
{
if (CLOSURE_IS_BSDF_DIFFUSE(closure_type)) {
eval->diffuse += value;
@@ -62,26 +62,26 @@ ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float value)
eval->sum *= value;
}
-ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float3 value)
+ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, Spectrum value)
{
eval->diffuse *= value;
eval->glossy *= value;
eval->sum *= value;
}
-ccl_device_inline float3 bsdf_eval_sum(ccl_private const BsdfEval *eval)
+ccl_device_inline Spectrum bsdf_eval_sum(ccl_private const BsdfEval *eval)
{
return eval->sum;
}
-ccl_device_inline float3 bsdf_eval_pass_diffuse_weight(ccl_private const BsdfEval *eval)
+ccl_device_inline Spectrum bsdf_eval_pass_diffuse_weight(ccl_private const BsdfEval *eval)
{
/* 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(eval->diffuse, eval->sum);
}
-ccl_device_inline float3 bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval *eval)
+ccl_device_inline Spectrum 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. */
@@ -95,7 +95,9 @@ ccl_device_inline float3 bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval
* to render buffers instead of using per-thread memory, and to avoid the
* impact of clamping on other contributions. */
-ccl_device_forceinline void kernel_accum_clamp(KernelGlobals kg, ccl_private float3 *L, int bounce)
+ccl_device_forceinline void kernel_accum_clamp(KernelGlobals kg,
+ ccl_private Spectrum *L,
+ int bounce)
{
#ifdef __KERNEL_DEBUG_NAN__
if (!isfinite_safe(*L)) {
@@ -154,7 +156,7 @@ ccl_device_inline int kernel_accum_sample(KernelGlobals kg,
ccl_device void kernel_accum_adaptive_buffer(KernelGlobals kg,
const int sample,
- const float3 contribution,
+ const Spectrum contribution,
ccl_global float *ccl_restrict buffer)
{
/* Adaptive Sampling. Fill the additional buffer with the odd samples and calculate our stopping
@@ -167,9 +169,13 @@ ccl_device void kernel_accum_adaptive_buffer(KernelGlobals kg,
}
if (sample_is_even(kernel_data.integrator.sampling_pattern, sample)) {
- kernel_write_pass_float4(
- buffer + kernel_data.film.pass_adaptive_aux_buffer,
- make_float4(contribution.x * 2.0f, contribution.y * 2.0f, contribution.z * 2.0f, 0.0f));
+ const float3 contribution_rgb = spectrum_to_rgb(contribution);
+
+ kernel_write_pass_float4(buffer + kernel_data.film.pass_adaptive_aux_buffer,
+ make_float4(contribution_rgb.x * 2.0f,
+ contribution_rgb.y * 2.0f,
+ contribution_rgb.z * 2.0f,
+ 0.0f));
}
}
@@ -186,7 +192,7 @@ ccl_device void kernel_accum_adaptive_buffer(KernelGlobals kg,
ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg,
const uint32_t path_flag,
- const float3 contribution,
+ const Spectrum contribution,
ccl_global float *ccl_restrict buffer)
{
if (!kernel_data.integrator.has_shadow_catcher) {
@@ -198,7 +204,7 @@ ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg,
/* Matte pass. */
if (kernel_shadow_catcher_is_matte_path(path_flag)) {
- kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher_matte, contribution);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_shadow_catcher_matte, contribution);
/* NOTE: Accumulate the combined pass and to the samples count pass, so that the adaptive
* sampling is based on how noisy the combined pass is as if there were no catchers in the
* scene. */
@@ -206,7 +212,7 @@ ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg,
/* Shadow catcher pass. */
if (kernel_shadow_catcher_is_object_pass(path_flag)) {
- kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher, contribution);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_shadow_catcher, contribution);
return true;
}
@@ -215,7 +221,7 @@ ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg,
ccl_device bool kernel_accum_shadow_catcher_transparent(KernelGlobals kg,
const uint32_t path_flag,
- const float3 contribution,
+ const Spectrum contribution,
const float transparent,
ccl_global float *ccl_restrict buffer)
{
@@ -232,9 +238,11 @@ ccl_device bool kernel_accum_shadow_catcher_transparent(KernelGlobals kg,
/* Matte pass. */
if (kernel_shadow_catcher_is_matte_path(path_flag)) {
+ const float3 contribution_rgb = spectrum_to_rgb(contribution);
+
kernel_write_pass_float4(
buffer + kernel_data.film.pass_shadow_catcher_matte,
- make_float4(contribution.x, contribution.y, contribution.z, transparent));
+ make_float4(contribution_rgb.x, contribution_rgb.y, contribution_rgb.z, transparent));
/* NOTE: Accumulate the combined pass and to the samples count pass, so that the adaptive
* sampling is based on how noisy the combined pass is as if there were no catchers in the
* scene. */
@@ -245,7 +253,7 @@ ccl_device bool kernel_accum_shadow_catcher_transparent(KernelGlobals kg,
/* NOTE: The transparency of the shadow catcher pass is ignored. It is not needed for the
* calculation and the alpha channel of the pass contains numbers of samples contributed to a
* pixel of the pass. */
- kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher, contribution);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_shadow_catcher, contribution);
return true;
}
@@ -279,7 +287,7 @@ ccl_device void kernel_accum_shadow_catcher_transparent_only(KernelGlobals kg,
ccl_device_inline void kernel_accum_combined_pass(KernelGlobals kg,
const uint32_t path_flag,
const int sample,
- const float3 contribution,
+ const Spectrum contribution,
ccl_global float *ccl_restrict buffer)
{
#ifdef __SHADOW_CATCHER__
@@ -289,7 +297,7 @@ ccl_device_inline void kernel_accum_combined_pass(KernelGlobals kg,
#endif
if (kernel_data.film.light_pass_flag & PASSMASK(COMBINED)) {
- kernel_write_pass_float3(buffer + kernel_data.film.pass_combined, contribution);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_combined, contribution);
}
kernel_accum_adaptive_buffer(kg, sample, contribution, buffer);
@@ -299,7 +307,7 @@ ccl_device_inline void kernel_accum_combined_pass(KernelGlobals kg,
ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg,
const uint32_t path_flag,
const int sample,
- const float3 contribution,
+ const Spectrum contribution,
const float transparent,
ccl_global float *ccl_restrict
buffer)
@@ -311,9 +319,11 @@ ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg,
#endif
if (kernel_data.film.light_pass_flag & PASSMASK(COMBINED)) {
+ const float3 contribution_rgb = spectrum_to_rgb(contribution);
+
kernel_write_pass_float4(
buffer + kernel_data.film.pass_combined,
- make_float4(contribution.x, contribution.y, contribution.z, transparent));
+ make_float4(contribution_rgb.x, contribution_rgb.y, contribution_rgb.z, transparent));
}
kernel_accum_adaptive_buffer(kg, sample, contribution, buffer);
@@ -323,7 +333,7 @@ ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg,
ccl_device_inline void kernel_accum_emission_or_background_pass(
KernelGlobals kg,
ConstIntegratorState state,
- float3 contribution,
+ Spectrum contribution,
ccl_global float *ccl_restrict buffer,
const int pass,
const int lightgroup = LIGHTGROUP_NONE)
@@ -340,17 +350,18 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(
# ifdef __DENOISING_FEATURES__
if (path_flag & PATH_RAY_DENOISING_FEATURES) {
if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
- const float3 denoising_feature_throughput = INTEGRATOR_STATE(
+ const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
state, path, denoising_feature_throughput);
- const float3 denoising_albedo = denoising_feature_throughput * contribution;
- kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
+ const Spectrum denoising_albedo = denoising_feature_throughput * contribution;
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo,
+ denoising_albedo);
}
}
# endif /* __DENOISING_FEATURES__ */
if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) {
- kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup,
- contribution);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup,
+ contribution);
}
if (!(path_flag & PATH_RAY_ANY_PASS)) {
@@ -366,15 +377,15 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(
if (path_flag & PATH_RAY_SURFACE_PASS) {
/* Indirectly visible through reflection. */
- const float3 diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
- const float3 glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight);
+ const Spectrum diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
+ const Spectrum glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight);
/* Glossy */
const int glossy_pass_offset = ((INTEGRATOR_STATE(state, path, bounce) == 1) ?
kernel_data.film.pass_glossy_direct :
kernel_data.film.pass_glossy_indirect);
if (glossy_pass_offset != PASS_UNUSED) {
- kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_weight * contribution);
+ kernel_write_pass_spectrum(buffer + glossy_pass_offset, glossy_weight * contribution);
}
/* Transmission */
@@ -385,9 +396,9 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(
if (transmission_pass_offset != PASS_UNUSED) {
/* Transmission is what remains if not diffuse and glossy, not stored explicitly to save
* GPU memory. */
- const float3 transmission_weight = one_float3() - diffuse_weight - glossy_weight;
- kernel_write_pass_float3(buffer + transmission_pass_offset,
- transmission_weight * contribution);
+ const Spectrum transmission_weight = one_spectrum() - diffuse_weight - glossy_weight;
+ kernel_write_pass_spectrum(buffer + transmission_pass_offset,
+ transmission_weight * contribution);
}
/* Reconstruct diffuse subset of throughput. */
@@ -408,7 +419,7 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(
/* Single write call for GPU coherence. */
if (pass_offset != PASS_UNUSED) {
- kernel_write_pass_float3(buffer + pass_offset, contribution);
+ kernel_write_pass_spectrum(buffer + pass_offset, contribution);
}
#endif /* __PASSES__ */
}
@@ -419,7 +430,7 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
ccl_global float *ccl_restrict render_buffer)
{
/* The throughput for shadow paths already contains the light shader evaluation. */
- float3 contribution = INTEGRATOR_STATE(state, shadow_path, throughput);
+ Spectrum contribution = INTEGRATOR_STATE(state, shadow_path, throughput);
kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, shadow_path, bounce));
const uint32_t render_pixel_index = INTEGRATOR_STATE(state, shadow_path, render_pixel_index);
@@ -433,10 +444,10 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
/* Ambient occlusion. */
if (path_flag & PATH_RAY_SHADOW_FOR_AO) {
if ((kernel_data.kernel_features & KERNEL_FEATURE_AO_PASS) && (path_flag & PATH_RAY_CAMERA)) {
- kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, contribution);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_ao, contribution);
}
if (kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) {
- const float3 ao_weight = INTEGRATOR_STATE(state, shadow_path, unshadowed_throughput);
+ const Spectrum ao_weight = INTEGRATOR_STATE(state, shadow_path, unshadowed_throughput);
kernel_accum_combined_pass(kg, path_flag, sample, contribution * ao_weight, buffer);
}
return;
@@ -458,8 +469,8 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
/* Write lightgroup pass. LIGHTGROUP_NONE is ~0 so decode from unsigned to signed */
const int lightgroup = (int)(INTEGRATOR_STATE(state, shadow_path, lightgroup)) - 1;
if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) {
- kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup,
- contribution);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup,
+ contribution);
}
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
@@ -467,15 +478,15 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
if (path_flag & PATH_RAY_SURFACE_PASS) {
/* Indirectly visible through reflection. */
- const float3 diffuse_weight = INTEGRATOR_STATE(state, shadow_path, pass_diffuse_weight);
- const float3 glossy_weight = INTEGRATOR_STATE(state, shadow_path, pass_glossy_weight);
+ const Spectrum diffuse_weight = INTEGRATOR_STATE(state, shadow_path, pass_diffuse_weight);
+ const Spectrum glossy_weight = INTEGRATOR_STATE(state, shadow_path, pass_glossy_weight);
/* Glossy */
const int glossy_pass_offset = ((INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ?
kernel_data.film.pass_glossy_direct :
kernel_data.film.pass_glossy_indirect);
if (glossy_pass_offset != PASS_UNUSED) {
- kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_weight * contribution);
+ kernel_write_pass_spectrum(buffer + glossy_pass_offset, glossy_weight * contribution);
}
/* Transmission */
@@ -486,9 +497,9 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
if (transmission_pass_offset != PASS_UNUSED) {
/* Transmission is what remains if not diffuse and glossy, not stored explicitly to save
* GPU memory. */
- const float3 transmission_weight = one_float3() - diffuse_weight - glossy_weight;
- kernel_write_pass_float3(buffer + transmission_pass_offset,
- transmission_weight * contribution);
+ const Spectrum transmission_weight = one_spectrum() - diffuse_weight - glossy_weight;
+ kernel_write_pass_spectrum(buffer + transmission_pass_offset,
+ transmission_weight * contribution);
}
/* Reconstruct diffuse subset of throughput. */
@@ -508,19 +519,19 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
/* Single write call for GPU coherence. */
if (pass_offset != PASS_UNUSED) {
- kernel_write_pass_float3(buffer + pass_offset, contribution);
+ kernel_write_pass_spectrum(buffer + pass_offset, contribution);
}
}
/* Write shadow pass. */
if (kernel_data.film.pass_shadow != PASS_UNUSED && (path_flag & PATH_RAY_SHADOW_FOR_LIGHT) &&
(path_flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
- const float3 unshadowed_throughput = INTEGRATOR_STATE(
+ const Spectrum unshadowed_throughput = INTEGRATOR_STATE(
state, shadow_path, unshadowed_throughput);
- const float3 shadowed_throughput = INTEGRATOR_STATE(state, shadow_path, 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);
+ const Spectrum shadowed_throughput = INTEGRATOR_STATE(state, shadow_path, throughput);
+ const Spectrum shadow = safe_divide(shadowed_throughput, unshadowed_throughput) *
+ kernel_data.film.pass_shadow_scale;
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_shadow, shadow);
}
}
#endif
@@ -560,12 +571,12 @@ ccl_device_inline void kernel_accum_holdout(KernelGlobals kg,
* Includes transparency, matching kernel_accum_transparent. */
ccl_device_inline void kernel_accum_background(KernelGlobals kg,
ConstIntegratorState state,
- const float3 L,
+ const Spectrum L,
const float transparent,
const bool is_transparent_background_ray,
ccl_global float *ccl_restrict render_buffer)
{
- float3 contribution = float3(INTEGRATOR_STATE(state, path, throughput)) * L;
+ Spectrum contribution = INTEGRATOR_STATE(state, path, throughput) * L;
kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1);
ccl_global float *buffer = kernel_accum_pixel_render_buffer(kg, state, render_buffer);
@@ -590,11 +601,11 @@ ccl_device_inline void kernel_accum_background(KernelGlobals kg,
/* Write emission to render buffer. */
ccl_device_inline void kernel_accum_emission(KernelGlobals kg,
ConstIntegratorState state,
- const float3 L,
+ const Spectrum L,
ccl_global float *ccl_restrict render_buffer,
const int lightgroup = LIGHTGROUP_NONE)
{
- float3 contribution = L;
+ Spectrum contribution = L;
kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1);
ccl_global float *buffer = kernel_accum_pixel_render_buffer(kg, state, render_buffer);
diff --git a/intern/cycles/kernel/film/passes.h b/intern/cycles/kernel/film/passes.h
index 1f5cf2048f1..bea23411000 100644
--- a/intern/cycles/kernel/film/passes.h
+++ b/intern/cycles/kernel/film/passes.h
@@ -40,7 +40,7 @@ ccl_device_forceinline void kernel_write_denoising_features_surface(
ccl_global float *buffer = kernel_pass_pixel_render_buffer(kg, state, render_buffer);
if (kernel_data.film.pass_denoising_depth != PASS_UNUSED) {
- const float3 denoising_feature_throughput = INTEGRATOR_STATE(
+ const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
state, path, denoising_feature_throughput);
const float denoising_depth = ensure_finite(average(denoising_feature_throughput) *
sd->ray_length);
@@ -48,8 +48,8 @@ ccl_device_forceinline void kernel_write_denoising_features_surface(
}
float3 normal = zero_float3();
- float3 diffuse_albedo = zero_float3();
- float3 specular_albedo = zero_float3();
+ Spectrum diffuse_albedo = zero_spectrum();
+ Spectrum specular_albedo = zero_spectrum();
float sum_weight = 0.0f, sum_nonspecular_weight = 0.0f;
for (int i = 0; i < sd->num_closure; i++) {
@@ -63,7 +63,7 @@ ccl_device_forceinline void kernel_write_denoising_features_surface(
normal += sc->N * sc->sample_weight;
sum_weight += sc->sample_weight;
- float3 closure_albedo = sc->weight;
+ Spectrum closure_albedo = sc->weight;
/* Closures that include a Fresnel term typically have weights close to 1 even though their
* actual contribution is significantly lower.
* To account for this, we scale their weight by the average fresnel factor (the same is also
@@ -113,10 +113,12 @@ ccl_device_forceinline void kernel_write_denoising_features_surface(
}
if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
- const float3 denoising_feature_throughput = INTEGRATOR_STATE(
+ const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
state, path, denoising_feature_throughput);
- const float3 denoising_albedo = ensure_finite(denoising_feature_throughput * diffuse_albedo);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
+ const Spectrum denoising_albedo = ensure_finite(denoising_feature_throughput *
+ diffuse_albedo);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo,
+ denoising_albedo);
}
INTEGRATOR_STATE_WRITE(state, path, flag) &= ~PATH_RAY_DENOISING_FEATURES;
@@ -128,13 +130,13 @@ ccl_device_forceinline void kernel_write_denoising_features_surface(
ccl_device_forceinline void kernel_write_denoising_features_volume(KernelGlobals kg,
IntegratorState state,
- const float3 albedo,
+ const Spectrum albedo,
const bool scatter,
ccl_global float *ccl_restrict
render_buffer)
{
ccl_global float *buffer = kernel_pass_pixel_render_buffer(kg, state, render_buffer);
- const float3 denoising_feature_throughput = INTEGRATOR_STATE(
+ const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
state, path, denoising_feature_throughput);
if (scatter && kernel_data.film.pass_denoising_normal != PASS_UNUSED) {
@@ -148,8 +150,8 @@ 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_finite(denoising_feature_throughput * albedo);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
+ const Spectrum denoising_albedo = ensure_finite(denoising_feature_throughput * albedo);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
}
}
#endif /* __DENOISING_FEATURES__ */
@@ -228,7 +230,7 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals kg,
}
if (kernel_data.film.cryptomatte_passes) {
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
const float matte_weight = average(throughput) *
(1.0f - average(shader_bsdf_transparency(kg, sd)));
if (matte_weight > 0.0f) {
@@ -252,19 +254,19 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals kg,
}
if (flag & PASSMASK(DIFFUSE_COLOR)) {
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color,
- shader_bsdf_diffuse(kg, sd) * throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_diffuse_color,
+ shader_bsdf_diffuse(kg, sd) * throughput);
}
if (flag & PASSMASK(GLOSSY_COLOR)) {
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color,
- shader_bsdf_glossy(kg, sd) * throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_glossy_color,
+ shader_bsdf_glossy(kg, sd) * throughput);
}
if (flag & PASSMASK(TRANSMISSION_COLOR)) {
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color,
- shader_bsdf_transmission(kg, sd) * throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
+ kernel_write_pass_spectrum(buffer + kernel_data.film.pass_transmission_color,
+ shader_bsdf_transmission(kg, sd) * throughput);
}
if (flag & PASSMASK(MIST)) {
/* Bring depth into 0..1 range. */
@@ -287,8 +289,8 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals kg,
mist = powf(mist, mist_falloff);
/* Modulate by transparency */
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
- const float3 alpha = shader_bsdf_alpha(kg, sd);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum alpha = shader_bsdf_alpha(kg, sd);
const float mist_output = (1.0f - mist) * average(throughput * alpha);
/* Note that the final value in the render buffer we want is 1 - mist_output,
diff --git a/intern/cycles/kernel/film/write_passes.h b/intern/cycles/kernel/film/write_passes.h
index 9148d73518f..c78116cedc6 100644
--- a/intern/cycles/kernel/film/write_passes.h
+++ b/intern/cycles/kernel/film/write_passes.h
@@ -3,6 +3,8 @@
#pragma once
+#include "kernel/util/color.h"
+
#ifdef __KERNEL_GPU__
# define __ATOMIC_PASS_WRITE__
#endif
@@ -36,6 +38,12 @@ ccl_device_inline void kernel_write_pass_float3(ccl_global float *ccl_restrict b
#endif
}
+ccl_device_inline void kernel_write_pass_spectrum(ccl_global float *ccl_restrict buffer,
+ Spectrum value)
+{
+ kernel_write_pass_float3(buffer, spectrum_to_rgb(value));
+}
+
ccl_device_inline void kernel_write_pass_float4(ccl_global float *ccl_restrict buffer,
float4 value)
{
diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h
index aa72b93c9d2..c95f1557f04 100644
--- a/intern/cycles/kernel/integrator/mnee.h
+++ b/intern/cycles/kernel/integrator/mnee.h
@@ -392,7 +392,7 @@ ccl_device_forceinline bool mnee_compute_constraint_derivatives(
/* Invert (block) constraint derivative matrix and solve linear system so we can map dh back to dx:
* dh / dx = A
* dx = inverse(A) x dh
- * to use for specular specular manifold walk
+ * to use for specular manifold walk
* (See for example http://faculty.washington.edu/finlayso/ebook/algebraic/advanced/LUtri.htm
* for block tridiagonal matrix based linear system solve) */
ccl_device_forceinline bool mnee_solve_matrix_h_to_x(int vertex_count,
@@ -634,9 +634,9 @@ mnee_sample_bsdf_dh(ClosureType type, float alpha_x, float alpha_y, float sample
* We assume here that the pdf (in half-vector measure) is the same as
* the one calculation when sampling the microfacet normals from the
* specular chain above: this allows us to simplify the bsdf weight */
-ccl_device_forceinline float3 mnee_eval_bsdf_contribution(ccl_private ShaderClosure *closure,
- float3 wi,
- float3 wo)
+ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderClosure *closure,
+ float3 wi,
+ float3 wo)
{
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)closure;
@@ -835,7 +835,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
1;
INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce + vertex_count;
- float3 light_eval = light_sample_shader_eval(kg, state, sd_mnee, ls, sd->time);
+ Spectrum light_eval = light_sample_shader_eval(kg, state, sd_mnee, ls, sd->time);
bsdf_eval_mul(throughput, light_eval / ls->pdf);
/* Generalized geometry term. */
@@ -924,7 +924,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
/* Evaluate product term inside eq.6 at solution interface. vi
* 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);
+ Spectrum bsdf_contribution = mnee_eval_bsdf_contribution(v.bsdf, wi, wo);
bsdf_eval_mul(throughput, bsdf_contribution);
}
diff --git a/intern/cycles/kernel/integrator/path_state.h b/intern/cycles/kernel/integrator/path_state.h
index b09bc117d78..5ec94b934ca 100644
--- a/intern/cycles/kernel/integrator/path_state.h
+++ b/intern/cycles/kernel/integrator/path_state.h
@@ -54,7 +54,7 @@ ccl_device_inline void path_state_init_integrator(KernelGlobals kg,
INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = 0.0f;
INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = FLT_MAX;
INTEGRATOR_STATE_WRITE(state, path, continuation_probability) = 1.0f;
- INTEGRATOR_STATE_WRITE(state, path, throughput) = make_float3(1.0f, 1.0f, 1.0f);
+ INTEGRATOR_STATE_WRITE(state, path, throughput) = one_spectrum();
#ifdef __MNEE__
INTEGRATOR_STATE_WRITE(state, path, mnee) = 0;
@@ -74,7 +74,7 @@ ccl_device_inline void path_state_init_integrator(KernelGlobals kg,
#ifdef __DENOISING_FEATURES__
if (kernel_data.kernel_features & KERNEL_FEATURE_DENOISING) {
INTEGRATOR_STATE_WRITE(state, path, flag) |= PATH_RAY_DENOISING_FEATURES;
- INTEGRATOR_STATE_WRITE(state, path, denoising_feature_throughput) = one_float3();
+ INTEGRATOR_STATE_WRITE(state, path, denoising_feature_throughput) = one_spectrum();
}
#endif
}
diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index a7edfffd175..57d060d58df 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -10,9 +10,9 @@
CCL_NAMESPACE_BEGIN
-ccl_device float3 integrator_eval_background_shader(KernelGlobals kg,
- IntegratorState state,
- ccl_global float *ccl_restrict render_buffer)
+ccl_device Spectrum integrator_eval_background_shader(KernelGlobals kg,
+ IntegratorState state,
+ ccl_global float *ccl_restrict render_buffer)
{
#ifdef __BACKGROUND__
const int shader = kernel_data.background.surface_shader;
@@ -26,11 +26,11 @@ ccl_device float3 integrator_eval_background_shader(KernelGlobals kg,
((shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) ||
((shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)) ||
((shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER)))
- return zero_float3();
+ return zero_spectrum();
}
/* Use fast constant background color if available. */
- float3 L = zero_float3();
+ Spectrum L = zero_spectrum();
if (!shader_constant_emission_eval(kg, shader, &L)) {
/* Evaluate background shader. */
@@ -73,7 +73,7 @@ ccl_device float3 integrator_eval_background_shader(KernelGlobals kg,
return L;
#else
- return make_float3(0.8f, 0.8f, 0.8f);
+ return make_spectrum(0.8f);
#endif
}
@@ -117,8 +117,8 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
#endif /* __MNEE__ */
/* Evaluate background shader. */
- float3 L = (eval_background) ? integrator_eval_background_shader(kg, state, render_buffer) :
- zero_float3();
+ Spectrum L = (eval_background) ? integrator_eval_background_shader(kg, state, render_buffer) :
+ zero_spectrum();
/* When using the ao bounces approximation, adjust background
* shader intensity with ao factor. */
@@ -169,7 +169,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
/* TODO: does aliasing like this break automatic SoA in CUDA? */
ShaderDataTinyStorage emission_sd_storage;
ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
- float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
+ Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
if (is_zero(light_eval)) {
return;
}
@@ -184,7 +184,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
}
/* Write to render buffer. */
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
kernel_accum_emission(
kg, state, throughput * light_eval, render_buffer, kernel_data.background.lightgroup);
}
diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h
index 910e3383f51..ac9d1415abb 100644
--- a/intern/cycles/kernel/integrator/shade_light.h
+++ b/intern/cycles/kernel/integrator/shade_light.h
@@ -51,7 +51,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
/* TODO: does aliasing like this break automatic SoA in CUDA? */
ShaderDataTinyStorage emission_sd_storage;
ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
- float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
+ Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time);
if (is_zero(light_eval)) {
return;
}
@@ -66,7 +66,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
}
/* Write to render buffer. */
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
kernel_accum_emission(kg, state, throughput * light_eval, render_buffer, ls.group);
}
diff --git a/intern/cycles/kernel/integrator/shade_shadow.h b/intern/cycles/kernel/integrator/shade_shadow.h
index 4b002a47bee..a52706a77f1 100644
--- a/intern/cycles/kernel/integrator/shade_shadow.h
+++ b/intern/cycles/kernel/integrator/shade_shadow.h
@@ -15,9 +15,9 @@ ccl_device_inline bool shadow_intersections_has_remaining(const uint num_hits)
}
#ifdef __TRANSPARENT_SHADOWS__
-ccl_device_inline float3 integrate_transparent_surface_shadow(KernelGlobals kg,
- IntegratorShadowState state,
- const int hit)
+ccl_device_inline Spectrum integrate_transparent_surface_shadow(KernelGlobals kg,
+ IntegratorShadowState state,
+ const int hit)
{
PROFILING_INIT(kg, PROFILING_SHADE_SHADOW_SURFACE);
@@ -58,7 +58,7 @@ ccl_device_inline void integrate_transparent_volume_shadow(KernelGlobals kg,
IntegratorShadowState state,
const int hit,
const int num_recorded_hits,
- ccl_private float3 *ccl_restrict
+ ccl_private Spectrum *ccl_restrict
throughput)
{
PROFILING_INIT(kg, PROFILING_SHADE_SHADOW_VOLUME);
@@ -100,7 +100,7 @@ ccl_device_inline bool integrate_transparent_shadow(KernelGlobals kg,
if (hit < num_recorded_hits || !shadow_intersections_has_remaining(num_hits)) {
# ifdef __VOLUME__
if (!integrator_state_shadow_volume_stack_is_empty(kg, state)) {
- float3 throughput = INTEGRATOR_STATE(state, shadow_path, throughput);
+ Spectrum throughput = INTEGRATOR_STATE(state, shadow_path, throughput);
integrate_transparent_volume_shadow(kg, state, hit, num_recorded_hits, &throughput);
if (is_zero(throughput)) {
return true;
@@ -113,8 +113,8 @@ ccl_device_inline bool integrate_transparent_shadow(KernelGlobals kg,
/* Surface shaders. */
if (hit < num_recorded_hits) {
- const float3 shadow = integrate_transparent_surface_shadow(kg, state, hit);
- const float3 throughput = INTEGRATOR_STATE(state, shadow_path, throughput) * shadow;
+ const Spectrum shadow = integrate_transparent_surface_shadow(kg, state, hit);
+ const Spectrum throughput = INTEGRATOR_STATE(state, shadow_path, throughput) * shadow;
if (is_zero(throughput)) {
return true;
}
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index 19b8946e865..4eb50171532 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -44,7 +44,7 @@ ccl_device_forceinline float3 integrate_surface_ray_offset(KernelGlobals kg,
/* Self intersection tests already account for the case where a ray hits the
* same primitive. However precision issues can still cause neighboring
* triangles to be hit. Here we test if the ray-triangle intersection with
- * the same primitive would miss, implying that a neighbouring triangle would
+ * the same primitive would miss, implying that a neighboring triangle would
* be hit instead.
*
* This relies on triangle intersection to be watertight, and the object inverse
@@ -88,11 +88,11 @@ ccl_device_forceinline bool integrate_surface_holdout(KernelGlobals kg,
if (((sd->flag & SD_HOLDOUT) || (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
(path_flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
- const float3 holdout_weight = shader_holdout_apply(kg, sd);
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum holdout_weight = shader_holdout_apply(kg, sd);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
const float transparent = average(holdout_weight * throughput);
kernel_accum_holdout(kg, state, path_flag, transparent, render_buffer);
- if (isequal(holdout_weight, one_float3())) {
+ if (isequal(holdout_weight, one_spectrum())) {
return false;
}
}
@@ -111,7 +111,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
/* Evaluate emissive closure. */
- float3 L = shader_emissive_eval(sd);
+ Spectrum L = shader_emissive_eval(sd);
# ifdef __HAIR__
if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) &&
@@ -130,7 +130,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
L *= mis_weight;
}
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
kernel_accum_emission(
kg, state, throughput * L, render_buffer, object_lightgroup(kg, sd->object));
}
@@ -207,7 +207,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
else
# endif /* __MNEE__ */
{
- const float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, sd->time);
+ const Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, sd->time);
if (is_zero(light_eval)) {
return;
}
@@ -261,11 +261,12 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
/* Copy state from main path to shadow path. */
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * bsdf_eval_sum(&bsdf_eval);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput) *
+ bsdf_eval_sum(&bsdf_eval);
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
- packed_float3 pass_diffuse_weight;
- packed_float3 pass_glossy_weight;
+ PackedSpectrum pass_diffuse_weight;
+ PackedSpectrum pass_glossy_weight;
if (shadow_flag & PATH_RAY_ANY_PASS) {
/* Indirect bounce, use weights from earlier surface or volume bounce. */
@@ -275,8 +276,8 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
else {
/* Direct light, use BSDFs at this bounce. */
shadow_flag |= PATH_RAY_SURFACE_PASS;
- pass_diffuse_weight = packed_float3(bsdf_eval_pass_diffuse_weight(&bsdf_eval));
- pass_glossy_weight = packed_float3(bsdf_eval_pass_glossy_weight(&bsdf_eval));
+ pass_diffuse_weight = PackedSpectrum(bsdf_eval_pass_diffuse_weight(&bsdf_eval));
+ pass_glossy_weight = PackedSpectrum(bsdf_eval_pass_glossy_weight(&bsdf_eval));
}
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
@@ -389,7 +390,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
}
/* Update throughput. */
- float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
throughput *= bsdf_eval_sum(&bsdf_eval) / bsdf_pdf;
INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput;
@@ -461,7 +462,7 @@ ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg,
path_state_rng_2D(kg, rng_state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
float3 ao_N;
- const float3 ao_weight = shader_bsdf_ao(
+ const Spectrum ao_weight = shader_bsdf_ao(
kg, sd, kernel_data.integrator.ao_additive_factor, &ao_N);
float3 ao_D;
@@ -504,7 +505,8 @@ ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg,
const uint16_t bounce = INTEGRATOR_STATE(state, path, bounce);
const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag) | PATH_RAY_SHADOW_FOR_AO;
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * shader_bsdf_alpha(kg, sd);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput) *
+ shader_bsdf_alpha(kg, sd);
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE(
state, path, render_pixel_index);
diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h
index 4aab097a7d8..0d35011c359 100644
--- a/intern/cycles/kernel/integrator/shade_volume.h
+++ b/intern/cycles/kernel/integrator/shade_volume.h
@@ -29,13 +29,13 @@ typedef enum VolumeIntegrateEvent {
typedef struct VolumeIntegrateResult {
/* Throughput and offset for direct light scattering. */
bool direct_scatter;
- float3 direct_throughput;
+ Spectrum direct_throughput;
float direct_t;
ShaderVolumePhases direct_phases;
/* Throughput and offset for indirect light scattering. */
bool indirect_scatter;
- float3 indirect_throughput;
+ Spectrum indirect_throughput;
float indirect_t;
ShaderVolumePhases indirect_phases;
} VolumeIntegrateResult;
@@ -52,16 +52,16 @@ typedef struct VolumeIntegrateResult {
* sigma_t = sigma_a + sigma_s */
typedef struct VolumeShaderCoefficients {
- float3 sigma_t;
- float3 sigma_s;
- float3 emission;
+ Spectrum sigma_t;
+ Spectrum sigma_s;
+ Spectrum emission;
} VolumeShaderCoefficients;
/* Evaluate shader to get extinction coefficient at P. */
ccl_device_inline bool shadow_volume_shader_sample(KernelGlobals kg,
IntegratorShadowState state,
ccl_private ShaderData *ccl_restrict sd,
- ccl_private float3 *ccl_restrict extinction)
+ ccl_private Spectrum *ccl_restrict extinction)
{
VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i))
shader_eval_volume<true>(kg, state, sd, PATH_RAY_SHADOW, volume_read_lambda_pass);
@@ -89,9 +89,10 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals kg,
return false;
}
- coeff->sigma_s = zero_float3();
- coeff->sigma_t = (sd->flag & SD_EXTINCTION) ? sd->closure_transparent_extinction : zero_float3();
- coeff->emission = (sd->flag & SD_EMISSION) ? sd->closure_emission_background : zero_float3();
+ coeff->sigma_s = zero_spectrum();
+ coeff->sigma_t = (sd->flag & SD_EXTINCTION) ? sd->closure_transparent_extinction :
+ zero_spectrum();
+ coeff->emission = (sd->flag & SD_EMISSION) ? sd->closure_emission_background : zero_spectrum();
if (sd->flag & SD_SCATTER) {
for (int i = 0; i < sd->num_closure; i++) {
@@ -162,9 +163,9 @@ ccl_device_forceinline void volume_step_init(KernelGlobals kg,
ccl_device void volume_shadow_homogeneous(KernelGlobals kg, IntegratorState state,
ccl_private Ray *ccl_restrict ray,
ccl_private ShaderData *ccl_restrict sd,
- ccl_global float3 *ccl_restrict throughput)
+ ccl_global Spectrum *ccl_restrict throughput)
{
- float3 sigma_t = zero_float3();
+ Spectrum sigma_t = zero_spectrum();
if (shadow_volume_shader_sample(kg, state, sd, &sigma_t)) {
*throughput *= volume_color_transmittance(sigma_t, ray->tmax - ray->tmin);
@@ -178,14 +179,14 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg,
IntegratorShadowState state,
ccl_private Ray *ccl_restrict ray,
ccl_private ShaderData *ccl_restrict sd,
- ccl_private float3 *ccl_restrict throughput,
+ ccl_private Spectrum *ccl_restrict throughput,
const float object_step_size)
{
/* Load random number state. */
RNGState rng_state;
shadow_path_state_rng_load(state, &rng_state);
- float3 tp = *throughput;
+ Spectrum tp = *throughput;
/* Prepare for stepping.
* For shadows we do not offset all segments, since the starting point is
@@ -207,7 +208,7 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg,
/* compute extinction at the start */
float t = ray->tmin;
- float3 sum = zero_float3();
+ Spectrum sum = zero_spectrum();
for (int i = 0; i < max_steps; i++) {
/* advance to new position */
@@ -215,7 +216,7 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg,
float dt = new_t - t;
float3 new_P = ray->P + ray->D * (t + dt * step_shade_offset);
- float3 sigma_t = zero_float3();
+ Spectrum sigma_t = zero_spectrum();
/* compute attenuation over segment */
sd->P = new_P;
@@ -228,8 +229,7 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg,
tp = *throughput * exp(sum);
/* stop if nearly all light is blocked */
- if (tp.x < VOLUME_THROUGHPUT_EPSILON && tp.y < VOLUME_THROUGHPUT_EPSILON &&
- tp.z < VOLUME_THROUGHPUT_EPSILON)
+ if (reduce_max(tp) < VOLUME_THROUGHPUT_EPSILON)
break;
}
}
@@ -334,22 +334,22 @@ ccl_device float volume_equiangular_cdf(ccl_private const Ray *ccl_restrict ray,
/* Distance sampling */
ccl_device float volume_distance_sample(float max_t,
- float3 sigma_t,
+ Spectrum sigma_t,
int channel,
float xi,
- ccl_private float3 *transmittance,
- ccl_private float3 *pdf)
+ ccl_private Spectrum *transmittance,
+ ccl_private Spectrum *pdf)
{
/* xi is [0, 1[ so log(0) should never happen, division by zero is
* avoided because sample_sigma_t > 0 when SD_SCATTER is set */
float sample_sigma_t = volume_channel_get(sigma_t, channel);
- float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
+ Spectrum full_transmittance = volume_color_transmittance(sigma_t, max_t);
float sample_transmittance = volume_channel_get(full_transmittance, channel);
float sample_t = min(max_t, -logf(1.0f - xi * (1.0f - sample_transmittance)) / sample_sigma_t);
*transmittance = volume_color_transmittance(sigma_t, sample_t);
- *pdf = safe_divide_color(sigma_t * *transmittance, one_float3() - full_transmittance);
+ *pdf = safe_divide_color(sigma_t * *transmittance, one_spectrum() - full_transmittance);
/* todo: optimization: when taken together with hit/miss decision,
* the full_transmittance cancels out drops out and xi does not
@@ -358,33 +358,36 @@ ccl_device float volume_distance_sample(float max_t,
return sample_t;
}
-ccl_device float3 volume_distance_pdf(float max_t, float3 sigma_t, float sample_t)
+ccl_device Spectrum volume_distance_pdf(float max_t, Spectrum sigma_t, float sample_t)
{
- float3 full_transmittance = volume_color_transmittance(sigma_t, max_t);
- float3 transmittance = volume_color_transmittance(sigma_t, sample_t);
+ Spectrum full_transmittance = volume_color_transmittance(sigma_t, max_t);
+ Spectrum transmittance = volume_color_transmittance(sigma_t, sample_t);
- return safe_divide_color(sigma_t * transmittance, one_float3() - full_transmittance);
+ return safe_divide_color(sigma_t * transmittance, one_spectrum() - full_transmittance);
}
/* Emission */
-ccl_device float3 volume_emission_integrate(ccl_private VolumeShaderCoefficients *coeff,
- int closure_flag,
- float3 transmittance,
- float t)
+ccl_device Spectrum volume_emission_integrate(ccl_private VolumeShaderCoefficients *coeff,
+ int closure_flag,
+ Spectrum transmittance,
+ float t)
{
/* integral E * exp(-sigma_t * t) from 0 to t = E * (1 - exp(-sigma_t * t))/sigma_t
* this goes to E * t as sigma_t goes to zero
*
* todo: we should use an epsilon to avoid precision issues near zero sigma_t */
- float3 emission = coeff->emission;
+ Spectrum emission = coeff->emission;
if (closure_flag & SD_EXTINCTION) {
- float3 sigma_t = coeff->sigma_t;
+ Spectrum sigma_t = coeff->sigma_t;
- emission.x *= (sigma_t.x > 0.0f) ? (1.0f - transmittance.x) / sigma_t.x : t;
- emission.y *= (sigma_t.y > 0.0f) ? (1.0f - transmittance.y) / sigma_t.y : t;
- emission.z *= (sigma_t.z > 0.0f) ? (1.0f - transmittance.z) / sigma_t.z : t;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ GET_SPECTRUM_CHANNEL(emission, i) *= (GET_SPECTRUM_CHANNEL(sigma_t, i) > 0.0f) ?
+ (1.0f - GET_SPECTRUM_CHANNEL(transmittance, i)) /
+ GET_SPECTRUM_CHANNEL(sigma_t, i) :
+ t;
+ }
}
else
emission *= t;
@@ -419,14 +422,14 @@ ccl_device_forceinline void volume_integrate_step_scattering(
ccl_private const Ray *ray,
const float3 equiangular_light_P,
ccl_private const VolumeShaderCoefficients &ccl_restrict coeff,
- const float3 transmittance,
+ const Spectrum transmittance,
ccl_private VolumeIntegrateState &ccl_restrict vstate,
ccl_private VolumeIntegrateResult &ccl_restrict result)
{
/* Pick random color channel, we use the Veach one-sample
* model with balance heuristic for the channels. */
- const float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
- float3 channel_pdf;
+ const Spectrum albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
+ Spectrum channel_pdf;
const int channel = volume_sample_channel(
albedo, result.indirect_throughput, vstate.rphase, &channel_pdf);
@@ -435,7 +438,7 @@ ccl_device_forceinline void volume_integrate_step_scattering(
if (result.direct_t >= vstate.tmin && result.direct_t <= vstate.tmax &&
vstate.equiangular_pdf > VOLUME_SAMPLE_PDF_CUTOFF) {
const float new_dt = result.direct_t - vstate.tmin;
- const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
+ const Spectrum new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
result.direct_scatter = true;
result.direct_throughput *= coeff.sigma_s * new_transmittance / vstate.equiangular_pdf;
@@ -467,7 +470,7 @@ ccl_device_forceinline void volume_integrate_step_scattering(
const float new_t = vstate.tmin + new_dt;
/* transmittance and pdf */
- const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
+ const Spectrum new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
const float distance_pdf = dot(channel_pdf, coeff.sigma_t * new_transmittance);
if (vstate.distance_pdf * distance_pdf > VOLUME_SAMPLE_PDF_CUTOFF) {
@@ -566,7 +569,7 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
vstate.distance_pdf = 1.0f;
/* Initialize volume integration result. */
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
result.direct_throughput = throughput;
result.indirect_throughput = throughput;
@@ -579,9 +582,9 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
# ifdef __DENOISING_FEATURES__
const bool write_denoising_features = (INTEGRATOR_STATE(state, path, flag) &
PATH_RAY_DENOISING_FEATURES);
- float3 accum_albedo = zero_float3();
+ Spectrum accum_albedo = zero_spectrum();
# endif
- float3 accum_emission = zero_float3();
+ Spectrum accum_emission = zero_spectrum();
for (int i = 0; i < max_steps; i++) {
/* Advance to new position */
@@ -596,16 +599,16 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
/* Evaluate transmittance over segment. */
const float dt = (vstate.tmax - vstate.tmin);
- const float3 transmittance = (closure_flag & SD_EXTINCTION) ?
- volume_color_transmittance(coeff.sigma_t, dt) :
- one_float3();
+ const Spectrum transmittance = (closure_flag & SD_EXTINCTION) ?
+ volume_color_transmittance(coeff.sigma_t, dt) :
+ one_spectrum();
/* Emission. */
if (closure_flag & SD_EMISSION) {
/* Only write emission before indirect light scatter position, since we terminate
* stepping at that point if we have already found a direct light scatter position. */
if (!result.indirect_scatter) {
- const float3 emission = volume_emission_integrate(
+ const Spectrum emission = volume_emission_integrate(
&coeff, closure_flag, transmittance, dt);
accum_emission += result.indirect_throughput * emission;
}
@@ -616,8 +619,8 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
# ifdef __DENOISING_FEATURES__
/* Accumulate albedo for denoising features. */
if (write_denoising_features && (closure_flag & SD_SCATTER)) {
- const float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
- accum_albedo += result.indirect_throughput * albedo * (one_float3() - transmittance);
+ const Spectrum albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
+ accum_albedo += result.indirect_throughput * albedo * (one_spectrum() - transmittance);
}
# endif
@@ -634,7 +637,7 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
/* Stop if nearly all light blocked. */
if (!result.indirect_scatter) {
if (reduce_max(result.indirect_throughput) < VOLUME_THROUGHPUT_EPSILON) {
- result.indirect_throughput = zero_float3();
+ result.indirect_throughput = zero_spectrum();
break;
}
}
@@ -715,7 +718,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
ccl_private const RNGState *ccl_restrict rng_state,
const float3 P,
ccl_private const ShaderVolumePhases *ccl_restrict phases,
- ccl_private const float3 throughput,
+ ccl_private const Spectrum throughput,
ccl_private LightSample *ccl_restrict ls)
{
PROFILING_INIT(kg, PROFILING_SHADE_VOLUME_DIRECT_LIGHT);
@@ -753,7 +756,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
* non-constant light sources. */
ShaderDataTinyStorage emission_sd_storage;
ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
- const float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, ls, sd->time);
+ const Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, ls, sd->time);
if (is_zero(light_eval)) {
return;
}
@@ -796,11 +799,11 @@ ccl_device_forceinline void integrate_volume_direct_light(
const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
- const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval);
+ const Spectrum throughput_phase = throughput * bsdf_eval_sum(&phase_eval);
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
- packed_float3 pass_diffuse_weight;
- packed_float3 pass_glossy_weight;
+ PackedSpectrum pass_diffuse_weight;
+ PackedSpectrum pass_glossy_weight;
if (shadow_flag & PATH_RAY_ANY_PASS) {
/* Indirect bounce, use weights from earlier surface or volume bounce. */
@@ -810,8 +813,8 @@ ccl_device_forceinline void integrate_volume_direct_light(
else {
/* Direct light, no diffuse/glossy distinction needed for volumes. */
shadow_flag |= PATH_RAY_VOLUME_PASS;
- pass_diffuse_weight = packed_float3(one_float3());
- pass_glossy_weight = packed_float3(zero_float3());
+ pass_diffuse_weight = one_spectrum();
+ pass_glossy_weight = zero_spectrum();
}
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
@@ -898,13 +901,13 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
INTEGRATOR_STATE_WRITE(state, isect, object) = sd->object;
/* Update throughput. */
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
- const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval) / phase_pdf;
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum throughput_phase = throughput * bsdf_eval_sum(&phase_eval) / phase_pdf;
INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput_phase;
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
- INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_float3();
- INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_float3();
+ INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_spectrum();
+ INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_spectrum();
}
/* Update path state */
diff --git a/intern/cycles/kernel/integrator/shader_eval.h b/intern/cycles/kernel/integrator/shader_eval.h
index ed4d973e864..d9c14b25a4b 100644
--- a/intern/cycles/kernel/integrator/shader_eval.h
+++ b/intern/cycles/kernel/integrator/shader_eval.h
@@ -98,7 +98,7 @@ ccl_device_inline void shader_prepare_surface_closures(KernelGlobals kg,
/* Filter out closures. */
if (kernel_data.integrator.filter_closures) {
if (kernel_data.integrator.filter_closures & FILTER_CLOSURE_EMISSION) {
- sd->closure_emission_background = zero_float3();
+ sd->closure_emission_background = zero_spectrum();
}
if (kernel_data.integrator.filter_closures & FILTER_CLOSURE_DIRECT_LIGHT) {
@@ -231,7 +231,7 @@ ccl_device_inline float _shader_bsdf_multi_eval(KernelGlobals kg,
if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
if (CLOSURE_IS_BSDF(sc->type) && !_shader_bsdf_exclude(sc->type, light_shader_flags)) {
float bsdf_pdf = 0.0f;
- float3 eval = bsdf_eval(kg, sd, sc, omega_in, is_transmission, &bsdf_pdf);
+ Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, is_transmission, &bsdf_pdf);
if (bsdf_pdf != 0.0f) {
bsdf_eval_accum(result_eval, sc->type, eval * sc->weight);
@@ -259,7 +259,7 @@ ccl_device_inline
ccl_private BsdfEval *bsdf_eval,
const uint light_shader_flags)
{
- bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_float3());
+ bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_spectrum());
return _shader_bsdf_multi_eval(
kg, sd, omega_in, is_transmission, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags);
@@ -309,11 +309,11 @@ ccl_device_inline ccl_private const ShaderClosure *shader_bsdf_bssrdf_pick(
}
/* Return weight for picked BSSRDF. */
-ccl_device_inline float3
+ccl_device_inline Spectrum
shader_bssrdf_sample_weight(ccl_private const ShaderData *ccl_restrict sd,
ccl_private const ShaderClosure *ccl_restrict bssrdf_sc)
{
- float3 weight = bssrdf_sc->weight;
+ Spectrum weight = bssrdf_sc->weight;
if (sd->num_closure > 1) {
float sum = 0.0f;
@@ -346,7 +346,7 @@ ccl_device int shader_bsdf_sample_closure(KernelGlobals kg,
kernel_assert(CLOSURE_IS_BSDF(sc->type));
int label;
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
*pdf = 0.0f;
label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
@@ -385,16 +385,16 @@ ccl_device float shader_bsdf_average_roughness(ccl_private const ShaderData *sd)
return (sum_weight > 0.0f) ? roughness / sum_weight : 0.0f;
}
-ccl_device float3 shader_bsdf_transparency(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device Spectrum shader_bsdf_transparency(KernelGlobals kg, ccl_private const ShaderData *sd)
{
if (sd->flag & SD_HAS_ONLY_VOLUME) {
- return one_float3();
+ return one_spectrum();
}
else if (sd->flag & SD_TRANSPARENT) {
return sd->closure_transparent_extinction;
}
else {
- return zero_float3();
+ return zero_spectrum();
}
}
@@ -406,7 +406,7 @@ ccl_device void shader_bsdf_disable_transparency(KernelGlobals kg, ccl_private S
if (sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
sc->sample_weight = 0.0f;
- sc->weight = zero_float3();
+ sc->weight = zero_spectrum();
}
}
@@ -414,19 +414,18 @@ ccl_device void shader_bsdf_disable_transparency(KernelGlobals kg, ccl_private S
}
}
-ccl_device float3 shader_bsdf_alpha(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device Spectrum shader_bsdf_alpha(KernelGlobals kg, ccl_private const ShaderData *sd)
{
- float3 alpha = one_float3() - shader_bsdf_transparency(kg, sd);
+ Spectrum alpha = one_spectrum() - shader_bsdf_transparency(kg, sd);
- alpha = max(alpha, zero_float3());
- alpha = min(alpha, one_float3());
+ alpha = saturate(alpha);
return alpha;
}
-ccl_device float3 shader_bsdf_diffuse(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device Spectrum shader_bsdf_diffuse(KernelGlobals kg, ccl_private const ShaderData *sd)
{
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
for (int i = 0; i < sd->num_closure; i++) {
ccl_private const ShaderClosure *sc = &sd->closure[i];
@@ -438,9 +437,9 @@ ccl_device float3 shader_bsdf_diffuse(KernelGlobals kg, ccl_private const Shader
return eval;
}
-ccl_device float3 shader_bsdf_glossy(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device Spectrum shader_bsdf_glossy(KernelGlobals kg, ccl_private const ShaderData *sd)
{
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
for (int i = 0; i < sd->num_closure; i++) {
ccl_private const ShaderClosure *sc = &sd->closure[i];
@@ -452,9 +451,9 @@ ccl_device float3 shader_bsdf_glossy(KernelGlobals kg, ccl_private const ShaderD
return eval;
}
-ccl_device float3 shader_bsdf_transmission(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device Spectrum shader_bsdf_transmission(KernelGlobals kg, ccl_private const ShaderData *sd)
{
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
for (int i = 0; i < sd->num_closure; i++) {
ccl_private const ShaderClosure *sc = &sd->closure[i];
@@ -479,12 +478,12 @@ ccl_device float3 shader_bsdf_average_normal(KernelGlobals kg, ccl_private const
return (is_zero(N)) ? sd->N : normalize(N);
}
-ccl_device float3 shader_bsdf_ao(KernelGlobals kg,
- ccl_private const ShaderData *sd,
- const float ao_factor,
- ccl_private float3 *N_)
+ccl_device Spectrum shader_bsdf_ao(KernelGlobals kg,
+ ccl_private const ShaderData *sd,
+ const float ao_factor,
+ ccl_private float3 *N_)
{
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
float3 N = zero_float3();
for (int i = 0; i < sd->num_closure; i++) {
@@ -525,15 +524,17 @@ ccl_device float3 shader_bssrdf_normal(ccl_private const ShaderData *sd)
ccl_device bool shader_constant_emission_eval(KernelGlobals kg,
int shader,
- ccl_private float3 *eval)
+ ccl_private Spectrum *eval)
{
int shader_index = shader & SHADER_MASK;
int shader_flag = kernel_data_fetch(shaders, shader_index).flags;
if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
- *eval = make_float3(kernel_data_fetch(shaders, shader_index).constant_emission[0],
- kernel_data_fetch(shaders, shader_index).constant_emission[1],
- kernel_data_fetch(shaders, shader_index).constant_emission[2]);
+ const float3 emission_rgb = make_float3(
+ kernel_data_fetch(shaders, shader_index).constant_emission[0],
+ kernel_data_fetch(shaders, shader_index).constant_emission[1],
+ kernel_data_fetch(shaders, shader_index).constant_emission[2]);
+ *eval = rgb_to_spectrum(emission_rgb);
return true;
}
@@ -543,39 +544,39 @@ ccl_device bool shader_constant_emission_eval(KernelGlobals kg,
/* Background */
-ccl_device float3 shader_background_eval(ccl_private const ShaderData *sd)
+ccl_device Spectrum shader_background_eval(ccl_private const ShaderData *sd)
{
if (sd->flag & SD_EMISSION) {
return sd->closure_emission_background;
}
else {
- return zero_float3();
+ return zero_spectrum();
}
}
/* Emission */
-ccl_device float3 shader_emissive_eval(ccl_private const ShaderData *sd)
+ccl_device Spectrum shader_emissive_eval(ccl_private const ShaderData *sd)
{
if (sd->flag & SD_EMISSION) {
return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
}
else {
- return zero_float3();
+ return zero_spectrum();
}
}
/* Holdout */
-ccl_device float3 shader_holdout_apply(KernelGlobals kg, ccl_private ShaderData *sd)
+ccl_device Spectrum shader_holdout_apply(KernelGlobals kg, ccl_private ShaderData *sd)
{
- float3 weight = zero_float3();
+ Spectrum weight = zero_spectrum();
/* For objects marked as holdout, preserve transparency and remove all other
* closures, replacing them with a holdout weight. */
if (sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
if ((sd->flag & SD_TRANSPARENT) && !(sd->flag & SD_HAS_ONLY_VOLUME)) {
- weight = one_float3() - sd->closure_transparent_extinction;
+ weight = one_spectrum() - sd->closure_transparent_extinction;
for (int i = 0; i < sd->num_closure; i++) {
ccl_private ShaderClosure *sc = &sd->closure[i];
@@ -587,7 +588,7 @@ ccl_device float3 shader_holdout_apply(KernelGlobals kg, ccl_private ShaderData
sd->flag &= ~(SD_CLOSURE_FLAGS - (SD_TRANSPARENT | SD_BSDF));
}
else {
- weight = one_float3();
+ weight = one_spectrum();
}
}
else {
@@ -642,12 +643,12 @@ ccl_device void shader_eval_surface(KernelGlobals kg,
svm_eval_nodes<node_feature_mask, SHADER_TYPE_SURFACE>(kg, state, sd, buffer, path_flag);
#else
if (sd->object == OBJECT_NONE) {
- sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f);
+ sd->closure_emission_background = make_spectrum(0.8f);
sd->flag |= SD_EMISSION;
}
else {
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
- sd, sizeof(DiffuseBsdf), make_float3(0.8f, 0.8f, 0.8f));
+ sd, sizeof(DiffuseBsdf), make_spectrum(0.8f));
if (bsdf != NULL) {
bsdf->N = sd->N;
sd->flag |= bsdf_diffuse_setup(bsdf);
@@ -676,7 +677,7 @@ ccl_device_inline float _shader_volume_phase_multi_eval(
ccl_private const ShaderVolumeClosure *svc = &phases->closure[i];
float phase_pdf = 0.0f;
- float3 eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf);
+ Spectrum eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf);
if (phase_pdf != 0.0f) {
bsdf_eval_accum(result_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
@@ -695,7 +696,7 @@ ccl_device float shader_volume_phase_eval(KernelGlobals kg,
const float3 omega_in,
ccl_private BsdfEval *phase_eval)
{
- bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_float3());
+ bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_spectrum());
return _shader_volume_phase_multi_eval(sd, phases, omega_in, -1, phase_eval, 0.0f, 0.0f);
}
@@ -747,7 +748,7 @@ ccl_device int shader_volume_phase_sample(KernelGlobals kg,
* depending on color channels, even if this is perhaps not a common case */
ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
int label;
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
*pdf = 0.0f;
label = volume_phase_sample(sd, svc, randu, randv, &eval, omega_in, domega_in, pdf);
@@ -770,7 +771,7 @@ ccl_device int shader_phase_sample_closure(KernelGlobals kg,
ccl_private float *pdf)
{
int label;
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
*pdf = 0.0f;
label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
diff --git a/intern/cycles/kernel/integrator/shadow_catcher.h b/intern/cycles/kernel/integrator/shadow_catcher.h
index ff63625aceb..7103b6032ac 100644
--- a/intern/cycles/kernel/integrator/shadow_catcher.h
+++ b/intern/cycles/kernel/integrator/shadow_catcher.h
@@ -93,7 +93,7 @@ ccl_device_forceinline void kernel_write_shadow_catcher_bounce_data(
/* Since the split is done, the sample does not contribute to the matte, so accumulate it as
* transparency to the matte. */
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
kernel_write_pass_float(buffer + kernel_data.film.pass_shadow_catcher_matte + 3,
average(throughput));
}
diff --git a/intern/cycles/kernel/integrator/shadow_state_template.h b/intern/cycles/kernel/integrator/shadow_state_template.h
index c340467606d..3b490ecffdd 100644
--- a/intern/cycles/kernel/integrator/shadow_state_template.h
+++ b/intern/cycles/kernel/integrator/shadow_state_template.h
@@ -27,15 +27,15 @@ KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, queued_kernel, KERNEL_FEATURE_PATH_T
/* enum PathRayFlag */
KERNEL_STRUCT_MEMBER(shadow_path, uint32_t, flag, KERNEL_FEATURE_PATH_TRACING)
/* Throughput. */
-KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, throughput, KERNEL_FEATURE_PATH_TRACING)
+KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, throughput, KERNEL_FEATURE_PATH_TRACING)
/* Throughput for shadow pass. */
KERNEL_STRUCT_MEMBER(shadow_path,
- packed_float3,
+ PackedSpectrum,
unshadowed_throughput,
KERNEL_FEATURE_SHADOW_PASS | KERNEL_FEATURE_AO_ADDITIVE)
/* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */
-KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
-KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
+KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
+KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
/* Number of intersections found by ray-tracing. */
KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, num_hits, KERNEL_FEATURE_PATH_TRACING)
/* Light group. */
diff --git a/intern/cycles/kernel/integrator/state_template.h b/intern/cycles/kernel/integrator/state_template.h
index 5c2af131945..f4e280e4cb2 100644
--- a/intern/cycles/kernel/integrator/state_template.h
+++ b/intern/cycles/kernel/integrator/state_template.h
@@ -46,12 +46,12 @@ KERNEL_STRUCT_MEMBER(path, float, min_ray_pdf, KERNEL_FEATURE_PATH_TRACING)
/* Continuation probability for path termination. */
KERNEL_STRUCT_MEMBER(path, float, continuation_probability, KERNEL_FEATURE_PATH_TRACING)
/* Throughput. */
-KERNEL_STRUCT_MEMBER(path, packed_float3, throughput, KERNEL_FEATURE_PATH_TRACING)
+KERNEL_STRUCT_MEMBER(path, PackedSpectrum, throughput, KERNEL_FEATURE_PATH_TRACING)
/* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */
-KERNEL_STRUCT_MEMBER(path, packed_float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
-KERNEL_STRUCT_MEMBER(path, packed_float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
+KERNEL_STRUCT_MEMBER(path, PackedSpectrum, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
+KERNEL_STRUCT_MEMBER(path, PackedSpectrum, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
/* Denoising. */
-KERNEL_STRUCT_MEMBER(path, packed_float3, denoising_feature_throughput, KERNEL_FEATURE_DENOISING)
+KERNEL_STRUCT_MEMBER(path, PackedSpectrum, denoising_feature_throughput, KERNEL_FEATURE_DENOISING)
/* Shader sorting. */
/* TODO: compress as uint16? or leave out entirely and recompute key in sorting code? */
KERNEL_STRUCT_MEMBER(path, uint32_t, shader_sort_key, KERNEL_FEATURE_PATH_TRACING)
@@ -84,8 +84,8 @@ KERNEL_STRUCT_END(isect)
/*************** Subsurface closure state for subsurface kernel ***************/
KERNEL_STRUCT_BEGIN(subsurface)
-KERNEL_STRUCT_MEMBER(subsurface, packed_float3, albedo, KERNEL_FEATURE_SUBSURFACE)
-KERNEL_STRUCT_MEMBER(subsurface, packed_float3, radius, KERNEL_FEATURE_SUBSURFACE)
+KERNEL_STRUCT_MEMBER(subsurface, PackedSpectrum, albedo, KERNEL_FEATURE_SUBSURFACE)
+KERNEL_STRUCT_MEMBER(subsurface, PackedSpectrum, radius, KERNEL_FEATURE_SUBSURFACE)
KERNEL_STRUCT_MEMBER(subsurface, float, anisotropy, KERNEL_FEATURE_SUBSURFACE)
KERNEL_STRUCT_MEMBER(subsurface, packed_float3, Ng, KERNEL_FEATURE_SUBSURFACE)
KERNEL_STRUCT_END(subsurface)
diff --git a/intern/cycles/kernel/integrator/subsurface.h b/intern/cycles/kernel/integrator/subsurface.h
index 2f96f215d8a..ee3a619f968 100644
--- a/intern/cycles/kernel/integrator/subsurface.h
+++ b/intern/cycles/kernel/integrator/subsurface.h
@@ -51,7 +51,7 @@ ccl_device int subsurface_bounce(KernelGlobals kg,
PATH_RAY_SUBSURFACE_RANDOM_WALK);
/* Compute weight, optionally including Fresnel from entry point. */
- float3 weight = shader_bssrdf_sample_weight(sd, sc);
+ Spectrum weight = shader_bssrdf_sample_weight(sd, sc);
# ifdef __PRINCIPLED__
if (bssrdf->roughness != FLT_MAX) {
path_flag |= PATH_RAY_SUBSURFACE_USE_FRESNEL;
@@ -70,8 +70,8 @@ ccl_device int subsurface_bounce(KernelGlobals kg,
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
if (INTEGRATOR_STATE(state, path, bounce) == 0) {
- INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_float3();
- INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_float3();
+ INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_spectrum();
+ INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_spectrum();
}
}
@@ -99,7 +99,7 @@ ccl_device void subsurface_shader_data_setup(KernelGlobals kg,
sd->num_closure = 0;
sd->num_closure_left = kernel_data.max_closures;
- const float3 weight = one_float3();
+ const Spectrum weight = one_spectrum();
# ifdef __PRINCIPLED__
if (path_flag & PATH_RAY_SUBSURFACE_USE_FRESNEL) {
diff --git a/intern/cycles/kernel/integrator/subsurface_disk.h b/intern/cycles/kernel/integrator/subsurface_disk.h
index 60b63c075a0..77763f702d8 100644
--- a/intern/cycles/kernel/integrator/subsurface_disk.h
+++ b/intern/cycles/kernel/integrator/subsurface_disk.h
@@ -9,11 +9,11 @@ CCL_NAMESPACE_BEGIN
* http://library.imageworks.com/pdfs/imageworks-library-BSSRDF-sampling.pdf
*/
-ccl_device_inline float3 subsurface_disk_eval(const float3 radius, float disk_r, float r)
+ccl_device_inline Spectrum subsurface_disk_eval(const Spectrum radius, float disk_r, float r)
{
- const float3 eval = bssrdf_eval(radius, r);
+ const Spectrum eval = bssrdf_eval(radius, r);
const float pdf = bssrdf_pdf(radius, disk_r);
- return (pdf > 0.0f) ? eval / pdf : zero_float3();
+ return (pdf > 0.0f) ? eval / pdf : zero_spectrum();
}
/* Subsurface scattering step, from a point on the surface to other
@@ -37,7 +37,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
/* Read subsurface scattering parameters. */
- const float3 radius = INTEGRATOR_STATE(state, subsurface, radius);
+ const Spectrum radius = INTEGRATOR_STATE(state, subsurface, radius);
/* Pick random axis in local frame and point on disk. */
float3 disk_N, disk_T, disk_B;
@@ -108,7 +108,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
* traversal algorithm. */
sort_intersections_and_normals(ss_isect.hits, ss_isect.Ng, num_eval_hits);
- float3 weights[BSSRDF_MAX_HITS]; /* TODO: zero? */
+ Spectrum weights[BSSRDF_MAX_HITS]; /* TODO: zero? */
float sum_weights = 0.0f;
for (int hit = 0; hit < num_eval_hits; hit++) {
@@ -150,7 +150,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
const float r = len(hit_P - P);
/* Evaluate profiles. */
- const float3 weight = subsurface_disk_eval(radius, disk_r, r) * w;
+ const Spectrum weight = subsurface_disk_eval(radius, disk_r, r) * w;
/* Store result. */
ss_isect.Ng[hit] = hit_Ng;
@@ -167,7 +167,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
float partial_sum = 0.0f;
for (int hit = 0; hit < num_eval_hits; hit++) {
- const float3 weight = weights[hit];
+ const Spectrum weight = weights[hit];
const float sample_weight = average(fabs(weight));
float next_sum = partial_sum + sample_weight;
diff --git a/intern/cycles/kernel/integrator/subsurface_random_walk.h b/intern/cycles/kernel/integrator/subsurface_random_walk.h
index e43bbb3c50a..9c67d909bd4 100644
--- a/intern/cycles/kernel/integrator/subsurface_random_walk.h
+++ b/intern/cycles/kernel/integrator/subsurface_random_walk.h
@@ -65,19 +65,20 @@ ccl_device void subsurface_random_walk_remap(const float albedo,
*sigma_t = sigma_t_prime / (1.0f - g);
}
-ccl_device void subsurface_random_walk_coefficients(const float3 albedo,
- const float3 radius,
+ccl_device void subsurface_random_walk_coefficients(const Spectrum albedo,
+ const Spectrum radius,
const float anisotropy,
- ccl_private float3 *sigma_t,
- ccl_private float3 *alpha,
- ccl_private float3 *throughput)
+ ccl_private Spectrum *sigma_t,
+ ccl_private Spectrum *alpha,
+ ccl_private Spectrum *throughput)
{
- float sigma_t_x, sigma_t_y, sigma_t_z;
- float alpha_x, alpha_y, alpha_z;
-
- subsurface_random_walk_remap(albedo.x, radius.x, anisotropy, &sigma_t_x, &alpha_x);
- subsurface_random_walk_remap(albedo.y, radius.y, anisotropy, &sigma_t_y, &alpha_y);
- subsurface_random_walk_remap(albedo.z, radius.z, anisotropy, &sigma_t_z, &alpha_z);
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ subsurface_random_walk_remap(GET_SPECTRUM_CHANNEL(albedo, i),
+ GET_SPECTRUM_CHANNEL(radius, i),
+ anisotropy,
+ &GET_SPECTRUM_CHANNEL(*sigma_t, i),
+ &GET_SPECTRUM_CHANNEL(*alpha, i));
+ }
/* Throughput already contains closure weight at this point, which includes the
* albedo, as well as closure mixing and Fresnel weights. Divide out the albedo
@@ -88,21 +89,12 @@ ccl_device void subsurface_random_walk_coefficients(const float3 albedo,
* infinite phase functions. To avoid a sharp discontinuity as we go from
* such values to 0.0, increase alpha and reduce the throughput to compensate. */
const float min_alpha = 0.2f;
- if (alpha_x < min_alpha) {
- (*throughput).x *= alpha_x / min_alpha;
- alpha_x = min_alpha;
- }
- if (alpha_y < min_alpha) {
- (*throughput).y *= alpha_y / min_alpha;
- alpha_y = min_alpha;
- }
- if (alpha_z < min_alpha) {
- (*throughput).z *= alpha_z / min_alpha;
- alpha_z = min_alpha;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ if (GET_SPECTRUM_CHANNEL(*alpha, i) < min_alpha) {
+ GET_SPECTRUM_CHANNEL(*throughput, i) *= GET_SPECTRUM_CHANNEL(*alpha, i) / min_alpha;
+ GET_SPECTRUM_CHANNEL(*alpha, i) = min_alpha;
+ }
}
-
- *sigma_t = make_float3(sigma_t_x, sigma_t_y, sigma_t_z);
- *alpha = make_float3(alpha_x, alpha_y, alpha_z);
}
/* References for Dwivedi sampling:
@@ -151,12 +143,12 @@ ccl_device_forceinline float3 direction_from_cosine(float3 D, float cos_theta, f
return dir.x * T + dir.y * B + dir.z * D;
}
-ccl_device_forceinline float3 subsurface_random_walk_pdf(float3 sigma_t,
- float t,
- bool hit,
- ccl_private float3 *transmittance)
+ccl_device_forceinline Spectrum subsurface_random_walk_pdf(Spectrum sigma_t,
+ float t,
+ bool hit,
+ ccl_private Spectrum *transmittance)
{
- float3 T = volume_color_transmittance(sigma_t, t);
+ Spectrum T = volume_color_transmittance(sigma_t, t);
if (transmittance) {
*transmittance = T;
}
@@ -207,14 +199,14 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
/* Convert subsurface to volume coefficients.
* The single-scattering albedo is named alpha to avoid confusion with the surface albedo. */
- const float3 albedo = INTEGRATOR_STATE(state, subsurface, albedo);
- const float3 radius = INTEGRATOR_STATE(state, subsurface, radius);
+ const Spectrum albedo = INTEGRATOR_STATE(state, subsurface, albedo);
+ const Spectrum radius = INTEGRATOR_STATE(state, subsurface, radius);
const float anisotropy = INTEGRATOR_STATE(state, subsurface, anisotropy);
- float3 sigma_t, alpha;
- float3 throughput = INTEGRATOR_STATE_WRITE(state, path, throughput);
+ Spectrum sigma_t, alpha;
+ Spectrum throughput = INTEGRATOR_STATE_WRITE(state, path, throughput);
subsurface_random_walk_coefficients(albedo, radius, anisotropy, &sigma_t, &alpha, &throughput);
- float3 sigma_s = sigma_t * alpha;
+ Spectrum sigma_s = sigma_t * alpha;
/* Theoretically it should be better to use the exact alpha for the channel we're sampling at
* each bounce, but in practice there doesn't seem to be a noticeable difference in exchange
@@ -249,10 +241,10 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
const float guided_fraction = 1.0f - fmaxf(0.5f, powf(fabsf(anisotropy), 0.125f));
#ifdef SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL
- float3 sigma_s_star = sigma_s * (1.0f - anisotropy);
- float3 sigma_t_star = sigma_t - sigma_s + sigma_s_star;
- float3 sigma_t_org = sigma_t;
- float3 sigma_s_org = sigma_s;
+ Spectrum sigma_s_star = sigma_s * (1.0f - anisotropy);
+ Spectrum sigma_t_star = sigma_t - sigma_s + sigma_s_star;
+ Spectrum sigma_t_org = sigma_t;
+ Spectrum sigma_s_org = sigma_s;
const float anisotropy_org = anisotropy;
const float guided_fraction_org = guided_fraction;
#endif
@@ -264,7 +256,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
#ifdef SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL
// shadow with local variables according to depth
float anisotropy, guided_fraction;
- float3 sigma_s, sigma_t;
+ Spectrum sigma_s, sigma_t;
if (bounce <= SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL) {
anisotropy = anisotropy_org;
guided_fraction = guided_fraction_org;
@@ -281,7 +273,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
/* Sample color channel, use MIS with balance heuristic. */
float rphase = path_state_rng_1D(kg, &rng_state, PRNG_PHASE_CHANNEL);
- float3 channel_pdf;
+ Spectrum channel_pdf;
int channel = volume_sample_channel(alpha, throughput, rphase, &channel_pdf);
float sample_sigma_t = volume_channel_get(sigma_t, channel);
float randt = path_state_rng_1D(kg, &rng_state, PRNG_SCATTER_DISTANCE);
@@ -399,16 +391,17 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
/* Advance to new scatter location. */
ray.P += t * ray.D;
- float3 transmittance;
- float3 pdf = subsurface_random_walk_pdf(sigma_t, t, hit, &transmittance);
+ Spectrum transmittance;
+ Spectrum pdf = subsurface_random_walk_pdf(sigma_t, t, hit, &transmittance);
if (bounce > 0) {
/* Compute PDF just like we do for classic sampling, but with the stretched sigma_t. */
- float3 guided_pdf = subsurface_random_walk_pdf(forward_stretching * sigma_t, t, hit, NULL);
+ Spectrum guided_pdf = subsurface_random_walk_pdf(forward_stretching * sigma_t, t, hit, NULL);
if (have_opposite_interface) {
/* First step of MIS: Depending on geometry we might have two methods for guided
* sampling, so perform MIS between them. */
- float3 back_pdf = subsurface_random_walk_pdf(backward_stretching * sigma_t, t, hit, NULL);
+ Spectrum back_pdf = subsurface_random_walk_pdf(
+ backward_stretching * sigma_t, t, hit, NULL);
guided_pdf = mix(
guided_pdf * forward_pdf_factor, back_pdf * backward_pdf_factor, backward_fraction);
}
@@ -430,9 +423,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
/* If we hit the surface, we are done. */
break;
}
- else if (throughput.x < VOLUME_THROUGHPUT_EPSILON &&
- throughput.y < VOLUME_THROUGHPUT_EPSILON &&
- throughput.z < VOLUME_THROUGHPUT_EPSILON) {
+ else if (reduce_max(throughput) < VOLUME_THROUGHPUT_EPSILON) {
/* Avoid unnecessary work and precision issue when throughput gets really small. */
break;
}
diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h
index 2e309cee43f..4195675dd13 100644
--- a/intern/cycles/kernel/light/sample.h
+++ b/intern/cycles/kernel/light/sample.h
@@ -14,7 +14,7 @@
CCL_NAMESPACE_BEGIN
/* Evaluate shader on light. */
-ccl_device_noinline_cpu float3
+ccl_device_noinline_cpu Spectrum
light_sample_shader_eval(KernelGlobals kg,
IntegratorState state,
ccl_private ShaderData *ccl_restrict emission_sd,
@@ -22,7 +22,7 @@ light_sample_shader_eval(KernelGlobals kg,
float time)
{
/* setup shading at emitter */
- float3 eval = zero_float3();
+ Spectrum eval = zero_spectrum();
if (shader_constant_emission_eval(kg, ls->shader, &eval)) {
if ((ls->prim != PRIM_NONE) && dot(ls->Ng, ls->D) > 0.0f) {
@@ -82,7 +82,8 @@ light_sample_shader_eval(KernelGlobals kg,
if (ls->lamp != LAMP_NONE) {
ccl_global const KernelLight *klight = &kernel_data_fetch(lights, ls->lamp);
- eval *= make_float3(klight->strength[0], klight->strength[1], klight->strength[2]);
+ eval *= rgb_to_spectrum(
+ make_float3(klight->strength[0], klight->strength[1], klight->strength[2]));
}
return eval;
diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp
index 865ff4ddc6d..4b5a2686117 100644
--- a/intern/cycles/kernel/osl/background.cpp
+++ b/intern/cycles/kernel/osl/background.cpp
@@ -14,8 +14,12 @@
// clang-format off
#include "kernel/device/cpu/compat.h"
+#include "kernel/device/cpu/globals.h"
+
#include "kernel/closure/alloc.h"
#include "kernel/closure/emissive.h"
+
+#include "kernel/util/color.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@@ -32,7 +36,7 @@ class GenericBackgroundClosure : public CClosurePrimitive {
public:
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
{
- background_setup(sd, weight);
+ background_setup(sd, rgb_to_spectrum(weight));
}
};
@@ -47,7 +51,7 @@ class HoldoutClosure : CClosurePrimitive {
public:
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
{
- closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, weight);
+ closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight));
sd->flag |= SD_HOLDOUT;
}
};
diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
index 39fcee1ac0d..667207ec6bf 100644
--- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
@@ -14,10 +14,15 @@
#include "kernel/osl/closures.h"
// clang-format off
+#include "kernel/device/cpu/compat.h"
+#include "kernel/device/cpu/globals.h"
+
#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_diffuse_ramp.h"
#include "kernel/closure/bsdf_util.h"
+
+#include "kernel/util/color.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@@ -34,7 +39,7 @@ class DiffuseRampClosure : public CBSDFClosure {
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
DiffuseRampBsdf *bsdf = (DiffuseRampBsdf *)bsdf_alloc_osl(
- sd, sizeof(DiffuseRampBsdf), weight, &params);
+ sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight), &params);
if (bsdf) {
bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
index 972ed7e4a6d..6f54a96e542 100644
--- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
@@ -14,10 +14,15 @@
#include "kernel/osl/closures.h"
// clang-format off
+#include "kernel/device/cpu/compat.h"
+#include "kernel/device/cpu/globals.h"
+
#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/bsdf_phong_ramp.h"
#include "kernel/closure/bsdf_util.h"
+
+#include "kernel/util/color.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@@ -34,7 +39,7 @@ class PhongRampClosure : public CBSDFClosure {
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl(
- sd, sizeof(PhongRampBsdf), weight, &params);
+ sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight), &params);
if (bsdf) {
bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp
index 4b282fddad3..3054946ba5a 100644
--- a/intern/cycles/kernel/osl/bssrdf.cpp
+++ b/intern/cycles/kernel/osl/bssrdf.cpp
@@ -12,6 +12,9 @@
#include "kernel/osl/closures.h"
// clang-format off
+#include "kernel/device/cpu/compat.h"
+#include "kernel/device/cpu/globals.h"
+
#include "kernel/types.h"
#include "kernel/closure/alloc.h"
@@ -19,6 +22,8 @@
#include "kernel/closure/bsdf_diffuse.h"
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/bssrdf.h"
+
+#include "kernel/util/color.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@@ -59,14 +64,14 @@ class CBSSRDFClosure : public CClosurePrimitive {
void alloc(ShaderData *sd, uint32_t path_flag, float3 weight, ClosureType type)
{
- Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
+ Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(weight));
if (bssrdf) {
/* 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) {
- params.radius = make_float3(0.0f, 0.0f, 0.0f);
+ params.radius = zero_spectrum();
}
/* create one closure per color channel */
diff --git a/intern/cycles/kernel/osl/closures.cpp b/intern/cycles/kernel/osl/closures.cpp
index 7c6b48154e4..8766fb73dbb 100644
--- a/intern/cycles/kernel/osl/closures.cpp
+++ b/intern/cycles/kernel/osl/closures.cpp
@@ -38,6 +38,8 @@
#include "kernel/closure/bsdf_principled_diffuse.h"
#include "kernel/closure/bsdf_principled_sheen.h"
#include "kernel/closure/volume.h"
+
+#include "kernel/util/color.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@@ -183,7 +185,7 @@ class PrincipledSheenClosure : public CBSDFClosure {
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc_osl(
- sd, sizeof(PrincipledSheenBsdf), weight, &params);
+ sd, sizeof(PrincipledSheenBsdf), rgb_to_spectrum(weight), &params);
sd->flag |= (bsdf) ? bsdf_principled_sheen_setup(sd, bsdf) : 0;
}
}
@@ -207,7 +209,7 @@ class PrincipledHairClosure : public CBSDFClosure {
PrincipledHairBSDF *alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
{
PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc_osl(
- sd, sizeof(PrincipledHairBSDF), weight, &params);
+ sd, sizeof(PrincipledHairBSDF), rgb_to_spectrum(weight), &params);
if (!bsdf) {
return NULL;
}
@@ -263,7 +265,7 @@ class PrincipledClearcoatClosure : public CBSDFClosure {
MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
{
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
- sd, sizeof(MicrofacetBsdf), weight, &params);
+ sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), &params);
if (!bsdf) {
return NULL;
}
@@ -273,13 +275,13 @@ class PrincipledClearcoatClosure : public CBSDFClosure {
return NULL;
}
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->extra = extra;
bsdf->ior = 1.5f;
bsdf->alpha_x = clearcoat_roughness;
bsdf->alpha_y = clearcoat_roughness;
- bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
+ bsdf->extra->color = zero_spectrum();
+ bsdf->extra->cspec0 = make_spectrum(0.04f);
bsdf->extra->clearcoat = clearcoat;
return bsdf;
}
@@ -511,7 +513,7 @@ class MicrofacetClosure : public CBSDFClosure {
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
- sd, sizeof(MicrofacetBsdf), weight, &params);
+ sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), &params);
if (!bsdf) {
return;
@@ -586,7 +588,7 @@ class MicrofacetFresnelClosure : public CBSDFClosure {
}
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
- sd, sizeof(MicrofacetBsdf), weight, &params);
+ sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), &params);
if (!bsdf) {
return NULL;
}
@@ -597,8 +599,8 @@ class MicrofacetFresnelClosure : public CBSDFClosure {
}
bsdf->extra = extra;
- bsdf->extra->color = color;
- bsdf->extra->cspec0 = cspec0;
+ bsdf->extra->color = rgb_to_spectrum(color);
+ bsdf->extra->cspec0 = rgb_to_spectrum(cspec0);
bsdf->extra->clearcoat = 0.0f;
return bsdf;
}
@@ -615,7 +617,7 @@ class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure {
return;
}
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->alpha_y = bsdf->alpha_x;
sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
}
@@ -684,7 +686,7 @@ class MicrofacetMultiClosure : public CBSDFClosure {
}
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
- sd, sizeof(MicrofacetBsdf), weight, &params);
+ sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), &params);
if (!bsdf) {
return NULL;
}
@@ -695,8 +697,8 @@ class MicrofacetMultiClosure : public CBSDFClosure {
}
bsdf->extra = extra;
- bsdf->extra->color = color;
- bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->color = rgb_to_spectrum(color);
+ bsdf->extra->cspec0 = zero_spectrum();
bsdf->extra->clearcoat = 0.0f;
return bsdf;
}
@@ -714,7 +716,7 @@ class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure {
}
bsdf->ior = 0.0f;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->alpha_y = bsdf->alpha_x;
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
}
@@ -777,7 +779,7 @@ class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure {
return;
}
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->alpha_y = bsdf->alpha_x;
sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
}
@@ -814,7 +816,7 @@ class MicrofacetMultiFresnelClosure : public CBSDFClosure {
}
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
- sd, sizeof(MicrofacetBsdf), weight, &params);
+ sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), &params);
if (!bsdf) {
return NULL;
}
@@ -825,8 +827,8 @@ class MicrofacetMultiFresnelClosure : public CBSDFClosure {
}
bsdf->extra = extra;
- bsdf->extra->color = color;
- bsdf->extra->cspec0 = cspec0;
+ bsdf->extra->color = rgb_to_spectrum(color);
+ bsdf->extra->cspec0 = rgb_to_spectrum(cspec0);
bsdf->extra->clearcoat = 0.0f;
return bsdf;
}
@@ -843,7 +845,7 @@ class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure {
return;
}
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->alpha_y = bsdf->alpha_x;
sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
}
@@ -911,7 +913,7 @@ class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosu
return;
}
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->alpha_y = bsdf->alpha_x;
sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
}
@@ -941,7 +943,7 @@ class TransparentClosure : public CBSDFClosure {
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
- bsdf_transparent_setup(sd, weight, path_flag);
+ bsdf_transparent_setup(sd, rgb_to_spectrum(weight), path_flag);
}
};
@@ -960,7 +962,7 @@ class VolumeAbsorptionClosure : public CBSDFClosure {
public:
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
- volume_extinction_setup(sd, weight);
+ volume_extinction_setup(sd, rgb_to_spectrum(weight));
}
};
@@ -979,10 +981,10 @@ class VolumeHenyeyGreensteinClosure : public CBSDFClosure {
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
{
- volume_extinction_setup(sd, weight);
+ volume_extinction_setup(sd, rgb_to_spectrum(weight));
HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc_osl(
- sd, sizeof(HenyeyGreensteinVolume), weight, &params);
+ sd, sizeof(HenyeyGreensteinVolume), rgb_to_spectrum(weight), &params);
if (!volume) {
return;
}
diff --git a/intern/cycles/kernel/osl/closures.h b/intern/cycles/kernel/osl/closures.h
index e10a3d88a04..97666be7a1e 100644
--- a/intern/cycles/kernel/osl/closures.h
+++ b/intern/cycles/kernel/osl/closures.h
@@ -115,7 +115,8 @@ class CBSDFClosure : public CClosurePrimitive {
{ \
if (!skip(sd, path_flag, TYPE)) { \
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); \
- structname *bsdf = (structname *)bsdf_alloc_osl(sd, sizeof(structname), weight, &params); \
+ structname *bsdf = (structname *)bsdf_alloc_osl( \
+ sd, sizeof(structname), rgb_to_spectrum(weight), &params); \
sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \
} \
} \
diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp
index 1a01b215836..8d1928d0126 100644
--- a/intern/cycles/kernel/osl/emissive.cpp
+++ b/intern/cycles/kernel/osl/emissive.cpp
@@ -14,9 +14,13 @@
// clang-format off
#include "kernel/device/cpu/compat.h"
+#include "kernel/device/cpu/globals.h"
+
#include "kernel/types.h"
#include "kernel/closure/alloc.h"
#include "kernel/closure/emissive.h"
+
+#include "kernel/util/color.h"
// clang-format on
CCL_NAMESPACE_BEGIN
@@ -34,7 +38,7 @@ class GenericEmissiveClosure : public CClosurePrimitive {
public:
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
{
- emission_setup(sd, weight);
+ emission_setup(sd, rgb_to_spectrum(weight));
}
};
diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h
index 99a8fdd3be9..5e8ef69fd15 100644
--- a/intern/cycles/kernel/svm/closure.h
+++ b/intern/cycles/kernel/svm/closure.h
@@ -3,6 +3,8 @@
#pragma once
+#include "kernel/util/color.h"
+
CCL_NAMESPACE_BEGIN
/* Closure Nodes */
@@ -183,7 +185,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
}
float3 subsurface_radius = stack_valid(data_cn_ssr.y) ?
stack_load_float3(stack, data_cn_ssr.y) :
- make_float3(1.0f, 1.0f, 1.0f);
+ one_float3();
float subsurface_ior = stack_valid(data_cn_ssr.z) ? stack_load_float(stack, data_cn_ssr.z) :
1.4f;
float subsurface_anisotropy = stack_valid(data_cn_ssr.w) ?
@@ -198,12 +200,12 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
__uint_as_float(data_subsurface_color.z),
__uint_as_float(data_subsurface_color.w));
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
# ifdef __SUBSURFACE__
float3 mixed_ss_base_color = subsurface_color * subsurface +
base_color * (1.0f - subsurface);
- float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight;
+ Spectrum subsurf_weight = weight * rgb_to_spectrum(mixed_ss_base_color) * diffuse_weight;
/* disable in case of diffuse ancestor, can't see it well then and
* adds considerably noise due to probabilities of continuing path
@@ -220,7 +222,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
/* diffuse */
if (fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) {
if (subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
- float3 diff_weight = weight * base_color * diffuse_weight;
+ 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);
@@ -237,8 +239,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight);
if (bssrdf) {
- bssrdf->radius = subsurface_radius * subsurface;
- bssrdf->albedo = mixed_ss_base_color;
+ bssrdf->radius = rgb_to_spectrum(subsurface_radius * subsurface);
+ bssrdf->albedo = rgb_to_spectrum(mixed_ss_base_color);
bssrdf->N = N;
bssrdf->roughness = roughness;
@@ -254,7 +256,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
# else
/* diffuse */
if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
- float3 diff_weight = weight * base_color * diffuse_weight;
+ 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);
@@ -272,15 +274,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
/* sheen */
if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
float m_cdlum = linear_rgb_to_gray(kg, base_color);
- float3 m_ctint = m_cdlum > 0.0f ?
- base_color / m_cdlum :
- make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
+ float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum :
+ one_float3(); // normalize lum. to isolate hue+sat
/* color of the sheen component */
- float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) +
- m_ctint * sheen_tint;
+ float3 sheen_color = make_float3(1.0f - sheen_tint) + m_ctint * sheen_tint;
- float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight;
+ Spectrum sheen_weight = weight * sheen * rgb_to_spectrum(sheen_color) * diffuse_weight;
ccl_private PrincipledSheenBsdf *bsdf = (ccl_private PrincipledSheenBsdf *)bsdf_alloc(
sd, sizeof(PrincipledSheenBsdf), sheen_weight);
@@ -299,7 +299,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
# endif
if (specular_weight > CLOSURE_WEIGHT_CUTOFF &&
(specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) {
- float3 spec_weight = weight * specular_weight;
+ Spectrum spec_weight = weight * specular_weight;
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), spec_weight);
@@ -322,16 +322,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
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 :
- make_float3(
- 1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat
- float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) +
- m_ctint * specular_tint;
-
- bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) +
- base_color * metallic;
- bsdf->extra->color = base_color;
+ 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;
+
+ bsdf->extra->cspec0 = rgb_to_spectrum(
+ (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic);
+ bsdf->extra->color = rgb_to_spectrum(base_color);
bsdf->extra->clearcoat = 0.0f;
/* setup bsdf */
@@ -352,9 +349,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
# endif
if (final_transmission > CLOSURE_WEIGHT_CUTOFF) {
- float3 glass_weight = weight * final_transmission;
- float3 cspec0 = base_color * specular_tint +
- make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint);
+ Spectrum glass_weight = weight * final_transmission;
+ float3 cspec0 = base_color * specular_tint + make_float3(1.0f - specular_tint);
if (roughness <= 5e-2f ||
distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
@@ -374,15 +370,15 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (bsdf && extra) {
bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->extra = extra;
bsdf->alpha_x = refl_roughness * refl_roughness;
bsdf->alpha_y = refl_roughness * refl_roughness;
bsdf->ior = ior;
- bsdf->extra->color = base_color;
- bsdf->extra->cspec0 = cspec0;
+ bsdf->extra->color = rgb_to_spectrum(base_color);
+ bsdf->extra->cspec0 = rgb_to_spectrum(cspec0);
bsdf->extra->clearcoat = 0.0f;
/* setup bsdf */
@@ -398,10 +394,12 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
/* This is to prevent MNEE from receiving a null BSDF. */
float refraction_fresnel = fmaxf(0.0001f, 1.0f - fresnel);
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
- sd, sizeof(MicrofacetBsdf), base_color * glass_weight * refraction_fresnel);
+ sd,
+ sizeof(MicrofacetBsdf),
+ rgb_to_spectrum(base_color) * glass_weight * refraction_fresnel);
if (bsdf) {
bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->extra = NULL;
if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID)
@@ -430,14 +428,14 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (bsdf && extra) {
bsdf->N = N;
bsdf->extra = extra;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->alpha_x = roughness * roughness;
bsdf->alpha_y = roughness * roughness;
bsdf->ior = ior;
- bsdf->extra->color = base_color;
- bsdf->extra->cspec0 = cspec0;
+ bsdf->extra->color = rgb_to_spectrum(base_color);
+ bsdf->extra->cspec0 = rgb_to_spectrum(cspec0);
bsdf->extra->clearcoat = 0.0f;
/* setup bsdf */
@@ -463,15 +461,15 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (bsdf && extra) {
bsdf->N = clearcoat_normal;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->ior = 1.5f;
bsdf->extra = extra;
bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness;
bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness;
- bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
- bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
+ bsdf->extra->color = zero_spectrum();
+ bsdf->extra->cspec0 = make_spectrum(0.04f);
bsdf->extra->clearcoat = clearcoat;
/* setup bsdf */
@@ -486,7 +484,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
}
#endif /* __PRINCIPLED__ */
case CLOSURE_BSDF_DIFFUSE_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private OrenNayarBsdf *bsdf = (ccl_private OrenNayarBsdf *)bsdf_alloc(
sd, sizeof(OrenNayarBsdf), weight);
@@ -506,7 +504,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
break;
}
case CLOSURE_BSDF_TRANSLUCENT_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), weight);
@@ -517,7 +515,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
break;
}
case CLOSURE_BSDF_TRANSPARENT_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
bsdf_transparent_setup(sd, weight, path_flag);
break;
}
@@ -530,7 +528,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), weight);
@@ -545,7 +543,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bsdf->extra = NULL;
if (data_node.y == SVM_STACK_INVALID) {
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
}
@@ -581,8 +579,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bsdf->extra = (ccl_private MicrofacetExtra *)closure_alloc_extra(sd,
sizeof(MicrofacetExtra));
if (bsdf->extra) {
- bsdf->extra->color = stack_load_float3(stack, data_node.w);
- bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->color = rgb_to_spectrum(stack_load_float3(stack, data_node.w));
+ bsdf->extra->cspec0 = zero_spectrum();
bsdf->extra->clearcoat = 0.0f;
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
}
@@ -600,13 +598,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), weight);
if (bsdf) {
bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->extra = NULL;
float eta = fmaxf(param2, 1e-5f);
@@ -644,7 +642,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
break;
}
#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
/* index of refraction */
float eta = fmaxf(param2, 1e-5f);
@@ -665,7 +663,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (bsdf) {
bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->extra = NULL;
svm_node_glass_setup(sd, bsdf, type, eta, roughness, false);
}
@@ -683,7 +681,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (bsdf) {
bsdf->N = N;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
bsdf->extra = NULL;
svm_node_glass_setup(sd, bsdf, type, eta, roughness, true);
}
@@ -697,7 +695,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), weight);
if (!bsdf) {
@@ -712,7 +710,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bsdf->N = N;
bsdf->extra = extra;
- bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->T = zero_float3();
float roughness = sqr(param1);
bsdf->alpha_x = roughness;
@@ -721,8 +719,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
kernel_assert(stack_valid(data_node.z));
- bsdf->extra->color = stack_load_float3(stack, data_node.z);
- bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
+ bsdf->extra->color = rgb_to_spectrum(stack_load_float3(stack, data_node.z));
+ bsdf->extra->cspec0 = zero_spectrum();
bsdf->extra->clearcoat = 0.0f;
/* setup bsdf */
@@ -730,7 +728,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
break;
}
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private VelvetBsdf *bsdf = (ccl_private VelvetBsdf *)bsdf_alloc(
sd, sizeof(VelvetBsdf), weight);
@@ -749,7 +747,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
ATTR_FALLTHROUGH;
#endif
case CLOSURE_BSDF_DIFFUSE_TOON_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private ToonBsdf *bsdf = (ccl_private ToonBsdf *)bsdf_alloc(
sd, sizeof(ToonBsdf), weight);
@@ -771,7 +769,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
uint4 data_node3 = read_node(kg, &offset);
uint4 data_node4 = read_node(kg, &offset);
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
uint offset_ofs, ior_ofs, color_ofs, parametrization;
svm_unpack_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, &parametrization);
@@ -829,7 +827,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
switch (parametrization) {
case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: {
float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs);
- bsdf->sigma = absorption_coefficient;
+ bsdf->sigma = rgb_to_spectrum(absorption_coefficient);
break;
}
case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: {
@@ -849,20 +847,21 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
/* Benedikt Bitterli's melanin ratio remapping. */
float eumelanin = melanin * (1.0f - melanin_redness);
float pheomelanin = melanin * melanin_redness;
- float3 melanin_sigma = bsdf_principled_hair_sigma_from_concentration(eumelanin,
- pheomelanin);
+ Spectrum melanin_sigma = bsdf_principled_hair_sigma_from_concentration(eumelanin,
+ pheomelanin);
/* Optional tint. */
float3 tint = stack_load_float3(stack, tint_ofs);
- float3 tint_sigma = bsdf_principled_hair_sigma_from_reflectance(tint,
- radial_roughness);
+ Spectrum tint_sigma = bsdf_principled_hair_sigma_from_reflectance(
+ rgb_to_spectrum(tint), radial_roughness);
bsdf->sigma = melanin_sigma + tint_sigma;
break;
}
case NODE_PRINCIPLED_HAIR_REFLECTANCE: {
float3 color = stack_load_float3(stack, color_ofs);
- bsdf->sigma = bsdf_principled_hair_sigma_from_reflectance(color, radial_roughness);
+ bsdf->sigma = bsdf_principled_hair_sigma_from_reflectance(rgb_to_spectrum(color),
+ radial_roughness);
break;
}
default: {
@@ -879,7 +878,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
}
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private HairBsdf *bsdf = (ccl_private HairBsdf *)bsdf_alloc(
sd, sizeof(HairBsdf), weight);
@@ -916,7 +915,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
case CLOSURE_BSSRDF_BURLEY_ID:
case CLOSURE_BSSRDF_RANDOM_WALK_ID:
case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: {
- float3 weight = sd->svm_closure_weight * mix_weight;
+ Spectrum weight = sd->svm_closure_weight * mix_weight;
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
if (bssrdf) {
@@ -926,7 +925,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
param1 = 0.0f;
- bssrdf->radius = stack_load_float3(stack, data_node.z) * param1;
+ bssrdf->radius = rgb_to_spectrum(stack_load_float3(stack, data_node.z) * param1);
bssrdf->albedo = sd->svm_closure_weight;
bssrdf->N = N;
bssrdf->roughness = FLT_MAX;
@@ -976,10 +975,10 @@ ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg,
density = mix_weight * fmaxf(density, 0.0f);
/* Compute scattering coefficient. */
- float3 weight = sd->svm_closure_weight;
+ Spectrum weight = sd->svm_closure_weight;
if (type == CLOSURE_VOLUME_ABSORPTION_ID) {
- weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
+ weight = one_spectrum() - weight;
}
weight *= density;
@@ -1047,11 +1046,11 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
if (density > CLOSURE_WEIGHT_CUTOFF) {
/* Compute scattering color. */
- float3 color = sd->svm_closure_weight;
+ Spectrum color = sd->svm_closure_weight;
const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y);
if (attr_color.offset != ATTR_STD_NOT_FOUND) {
- color *= primitive_volume_attribute_float3(kg, sd, attr_color);
+ color *= rgb_to_spectrum(primitive_volume_attribute_float3(kg, sd, attr_color));
}
/* Add closure for volume scattering. */
@@ -1066,10 +1065,13 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
}
/* Add extinction weight. */
- float3 zero = make_float3(0.0f, 0.0f, 0.0f);
- float3 one = make_float3(1.0f, 1.0f, 1.0f);
- float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero);
- float3 absorption = max(one - color, zero) * max(one - absorption_color, zero);
+ float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)),
+ zero_float3());
+
+ Spectrum zero = zero_spectrum();
+ Spectrum one = one_spectrum();
+ Spectrum absorption = max(one - color, zero) *
+ max(one - rgb_to_spectrum(absorption_color), zero);
volume_extinction_setup(sd, (color + absorption) * density);
}
@@ -1089,7 +1091,7 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
if (emission > CLOSURE_WEIGHT_CUTOFF) {
float3 emission_color = stack_load_float3(stack, emission_color_offset);
- emission_setup(sd, emission * emission_color);
+ emission_setup(sd, rgb_to_spectrum(emission * emission_color));
}
if (blackbody > CLOSURE_WEIGHT_CUTOFF) {
@@ -1113,7 +1115,7 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg,
float3 blackbody_tint = stack_load_float3(stack, node.w);
float3 bb = blackbody_tint * intensity *
rec709_to_rgb(kg, svm_math_blackbody_color_rec709(T));
- emission_setup(sd, bb);
+ emission_setup(sd, rgb_to_spectrum(bb));
}
}
#endif
@@ -1125,7 +1127,7 @@ ccl_device_noinline void svm_node_closure_emission(ccl_private ShaderData *sd,
uint4 node)
{
uint mix_weight_offset = node.y;
- float3 weight = sd->svm_closure_weight;
+ Spectrum weight = sd->svm_closure_weight;
if (stack_valid(mix_weight_offset)) {
float mix_weight = stack_load_float(stack, mix_weight_offset);
@@ -1144,7 +1146,7 @@ ccl_device_noinline void svm_node_closure_background(ccl_private ShaderData *sd,
uint4 node)
{
uint mix_weight_offset = node.y;
- float3 weight = sd->svm_closure_weight;
+ Spectrum weight = sd->svm_closure_weight;
if (stack_valid(mix_weight_offset)) {
float mix_weight = stack_load_float(stack, mix_weight_offset);
@@ -1181,14 +1183,15 @@ ccl_device_noinline void svm_node_closure_holdout(ccl_private ShaderData *sd,
/* Closure Nodes */
-ccl_device_inline void svm_node_closure_store_weight(ccl_private ShaderData *sd, float3 weight)
+ccl_device_inline void svm_node_closure_store_weight(ccl_private ShaderData *sd, Spectrum weight)
{
sd->svm_closure_weight = weight;
}
ccl_device void svm_node_closure_set_weight(ccl_private ShaderData *sd, uint r, uint g, uint b)
{
- float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b));
+ Spectrum weight = rgb_to_spectrum(
+ make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)));
svm_node_closure_store_weight(sd, weight);
}
@@ -1196,7 +1199,7 @@ ccl_device void svm_node_closure_weight(ccl_private ShaderData *sd,
ccl_private float *stack,
uint weight_offset)
{
- float3 weight = stack_load_float3(stack, weight_offset);
+ Spectrum weight = rgb_to_spectrum(stack_load_float3(stack, weight_offset));
svm_node_closure_store_weight(sd, weight);
}
@@ -1209,7 +1212,7 @@ ccl_device_noinline void svm_node_emission_weight(KernelGlobals kg,
uint strength_offset = node.z;
float strength = stack_load_float(stack, strength_offset);
- float3 weight = stack_load_float3(stack, color_offset) * strength;
+ Spectrum weight = rgb_to_spectrum(stack_load_float3(stack, color_offset)) * strength;
svm_node_closure_store_weight(sd, weight);
}
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index 7762c95275e..252c27a40f0 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -413,9 +413,9 @@ typedef enum CryptomatteType {
} CryptomatteType;
typedef struct BsdfEval {
- float3 diffuse;
- float3 glossy;
- float3 sum;
+ Spectrum diffuse;
+ Spectrum glossy;
+ Spectrum sum;
} BsdfEval;
/* Closure Filter */
@@ -709,7 +709,7 @@ typedef struct AttributeMap {
* padded to be 16 bytes, while it's only 12 bytes on the GPU. */
#define SHADER_CLOSURE_BASE \
- float3 weight; \
+ Spectrum weight; \
ClosureType type; \
float sample_weight; \
float3 N
@@ -718,10 +718,9 @@ typedef struct ccl_align(16) ShaderClosure
{
SHADER_CLOSURE_BASE;
-#ifndef __KERNEL_GPU__
- float pad[2];
-#endif
- float data[10];
+ /* Extra space for closures to store data, somewhat arbitrary but closures
+ * assert that their size fits. */
+ char pad[sizeof(Spectrum) * 2 + sizeof(float) * 4];
}
ShaderClosure;
@@ -912,12 +911,12 @@ typedef struct ccl_align(16) ShaderData
/* Closure data, we store a fixed array of closures */
int num_closure;
int num_closure_left;
- float3 svm_closure_weight;
+ Spectrum svm_closure_weight;
/* Closure weights summed directly, so we can evaluate
* emission and shadow transparency with MAX_CLOSURE 0. */
- float3 closure_emission_background;
- float3 closure_transparent_extinction;
+ Spectrum closure_emission_background;
+ Spectrum closure_transparent_extinction;
/* At the end so we can adjust size in ShaderDataTinyStorage. */
struct ShaderClosure closure[MAX_CLOSURE];
@@ -948,7 +947,7 @@ ShaderDataCausticsStorage;
* Used for decoupled direct/indirect light closure storage. */
typedef struct ShaderVolumeClosure {
- float3 weight;
+ Spectrum weight;
float sample_weight;
float g;
} ShaderVolumeClosure;
diff --git a/intern/cycles/kernel/util/color.h b/intern/cycles/kernel/util/color.h
index c85ef262d88..4983b9048d4 100644
--- a/intern/cycles/kernel/util/color.h
+++ b/intern/cycles/kernel/util/color.h
@@ -33,4 +33,19 @@ ccl_device float linear_rgb_to_gray(KernelGlobals kg, float3 c)
return dot(c, float4_to_float3(kernel_data.film.rgb_to_y));
}
+ccl_device_inline Spectrum rgb_to_spectrum(float3 rgb)
+{
+ return rgb;
+}
+
+ccl_device_inline float3 spectrum_to_rgb(Spectrum s)
+{
+ return s;
+}
+
+ccl_device float spectrum_to_gray(KernelGlobals kg, Spectrum c)
+{
+ return linear_rgb_to_gray(kg, spectrum_to_rgb(c));
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/scene/image_oiio.cpp b/intern/cycles/scene/image_oiio.cpp
index 500e53ed763..8792393e5a1 100644
--- a/intern/cycles/scene/image_oiio.cpp
+++ b/intern/cycles/scene/image_oiio.cpp
@@ -184,9 +184,8 @@ bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata,
ImageSpec config = ImageSpec();
/* Load without automatic OIIO alpha conversion, we do it ourselves. OIIO
- * will associate alpha in the the 8bit buffer for PNGs, which leads to too
- * much precision loss when we load it as half float to do a colorspace
- * transform. */
+ * will associate alpha in the 8bit buffer for PNGs, which leads to too
+ * much precision loss when we load it as half float to do a color-space transform. */
config.attribute("oiio:UnassociatedAlpha", 1);
if (!in->open(filepath.string(), spec, config)) {
diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp
index c94b53535a7..e5df22211e7 100644
--- a/intern/cycles/session/session.cpp
+++ b/intern/cycles/session/session.cpp
@@ -503,7 +503,9 @@ void Session::do_delayed_reset()
if (!params.background) {
progress.set_start_time();
}
+ const double time_limit = params.time_limit * ((double)tile_manager_.get_num_tiles());
progress.set_render_start_time();
+ progress.set_time_limit(time_limit);
}
void Session::reset(const SessionParams &session_params, const BufferParams &buffer_params)
@@ -598,7 +600,8 @@ double Session::get_estimated_remaining_time() const
progress.get_time(total_time, render_time);
double remaining = (1.0 - (double)completed) * (render_time / (double)completed);
- const double time_limit = render_scheduler_.get_time_limit();
+ const double time_limit = render_scheduler_.get_time_limit() *
+ ((double)tile_manager_.get_num_tiles());
if (time_limit != 0.0) {
remaining = min(remaining, max(time_limit - render_time, 0.0));
}
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index f3fc7739f66..81a7607baab 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -118,6 +118,7 @@ set(SRC_HEADERS
types_int3_impl.h
types_int4.h
types_int4_impl.h
+ types_spectrum.h
types_uchar2.h
types_uchar2_impl.h
types_uchar3.h
@@ -131,8 +132,6 @@ set(SRC_HEADERS
types_uint4.h
types_uint4_impl.h
types_ushort4.h
- types_vector3.h
- types_vector3_impl.h
unique_ptr.h
vector.h
version.h
diff --git a/intern/cycles/util/debug.cpp b/intern/cycles/util/debug.cpp
index faa54a92c24..8210e21f951 100644
--- a/intern/cycles/util/debug.cpp
+++ b/intern/cycles/util/debug.cpp
@@ -13,7 +13,6 @@
CCL_NAMESPACE_BEGIN
DebugFlags::CPU::CPU()
- : avx2(true), avx(true), sse41(true), sse3(true), sse2(true), bvh_layout(BVH_LAYOUT_AUTO)
{
reset();
}
@@ -41,17 +40,17 @@ void DebugFlags::CPU::reset()
bvh_layout = BVH_LAYOUT_AUTO;
}
-DebugFlags::CUDA::CUDA() : adaptive_compile(false)
+DebugFlags::CUDA::CUDA()
{
reset();
}
-DebugFlags::HIP::HIP() : adaptive_compile(false)
+DebugFlags::HIP::HIP()
{
reset();
}
-DebugFlags::Metal::Metal() : adaptive_compile(false)
+DebugFlags::Metal::Metal()
{
reset();
}
@@ -84,14 +83,13 @@ void DebugFlags::OptiX::reset()
use_debug = false;
}
-DebugFlags::DebugFlags() : viewport_static_bvh(false), running_inside_blender(false)
+DebugFlags::DebugFlags()
{
/* Nothing for now. */
}
void DebugFlags::reset()
{
- viewport_static_bvh = false;
cpu.reset();
cuda.reset();
optix.reset();
diff --git a/intern/cycles/util/debug.h b/intern/cycles/util/debug.h
index 3565fdea17f..ab200649f59 100644
--- a/intern/cycles/util/debug.h
+++ b/intern/cycles/util/debug.h
@@ -17,11 +17,6 @@ CCL_NAMESPACE_BEGIN
*/
class DebugFlags {
public:
- /* Use static BVH in viewport, to match final render exactly. */
- bool viewport_static_bvh;
-
- bool running_inside_blender;
-
/* Descriptor of CPU feature-set to be used. */
struct CPU {
CPU();
@@ -30,11 +25,11 @@ class DebugFlags {
void reset();
/* Flags describing which instructions sets are allowed for use. */
- bool avx2;
- bool avx;
- bool sse41;
- bool sse3;
- bool sse2;
+ bool avx2 = true;
+ bool avx = true;
+ bool sse41 = true;
+ bool sse3 = true;
+ bool sse2 = true;
/* Check functions to see whether instructions up to the given one
* are allowed for use.
@@ -65,7 +60,7 @@ class DebugFlags {
* By default the fastest will be used. For debugging the BVH used by other
* CPUs and GPUs can be selected here instead.
*/
- BVHLayout bvh_layout;
+ BVHLayout bvh_layout = BVH_LAYOUT_AUTO;
};
/* Descriptor of CUDA feature-set to be used. */
@@ -77,7 +72,7 @@ class DebugFlags {
/* Whether adaptive feature based runtime compile is enabled or not.
* Requires the CUDA Toolkit and only works on Linux at the moment. */
- bool adaptive_compile;
+ bool adaptive_compile = false;
};
/* Descriptor of HIP feature-set to be used. */
@@ -88,7 +83,7 @@ class DebugFlags {
void reset();
/* Whether adaptive feature based runtime compile is enabled or not. */
- bool adaptive_compile;
+ bool adaptive_compile = false;
};
/* Descriptor of OptiX feature-set to be used. */
@@ -100,7 +95,7 @@ class DebugFlags {
/* Load OptiX module with debug capabilities. Will lower logging verbosity level, enable
* validations, and lower optimization level. */
- bool use_debug;
+ bool use_debug = false;
};
/* Descriptor of Metal feature-set to be used. */
@@ -111,7 +106,7 @@ class DebugFlags {
void reset();
/* Whether adaptive feature based runtime compile is enabled or not. */
- bool adaptive_compile;
+ bool adaptive_compile = false;
};
/* Get instance of debug flags registry. */
@@ -142,15 +137,9 @@ class DebugFlags {
private:
DebugFlags();
-#if (__cplusplus > 199711L)
public:
explicit DebugFlags(DebugFlags const & /*other*/) = delete;
void operator=(DebugFlags const & /*other*/) = delete;
-#else
- private:
- explicit DebugFlags(DebugFlags const & /*other*/);
- void operator=(DebugFlags const & /*other*/);
-#endif
};
typedef DebugFlags &DebugFlagsRef;
diff --git a/intern/cycles/util/defines.h b/intern/cycles/util/defines.h
index d0df1a221fc..c7118ca09c9 100644
--- a/intern/cycles/util/defines.h
+++ b/intern/cycles/util/defines.h
@@ -136,4 +136,7 @@ template<typename T> static inline T decltype_helper(T x)
# define util_assert(statement)
#endif
+#define CONCAT_HELPER(a, ...) a##__VA_ARGS__
+#define CONCAT(a, ...) CONCAT_HELPER(a, __VA_ARGS__)
+
#endif /* __UTIL_DEFINES_H__ */
diff --git a/intern/cycles/util/math.h b/intern/cycles/util/math.h
index f6400cb879f..0585dcc8ad5 100644
--- a/intern/cycles/util/math.h
+++ b/intern/cycles/util/math.h
@@ -595,26 +595,26 @@ ccl_device_inline void make_orthonormals(const float3 N,
/* Color division */
-ccl_device_inline float3 safe_invert_color(float3 a)
+ccl_device_inline Spectrum safe_invert_color(Spectrum a)
{
- float x, y, z;
-
- x = (a.x != 0.0f) ? 1.0f / a.x : 0.0f;
- y = (a.y != 0.0f) ? 1.0f / a.y : 0.0f;
- z = (a.z != 0.0f) ? 1.0f / a.z : 0.0f;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ GET_SPECTRUM_CHANNEL(a, i) = (GET_SPECTRUM_CHANNEL(a, i) != 0.0f) ?
+ 1.0f / GET_SPECTRUM_CHANNEL(a, i) :
+ 0.0f;
+ }
- return make_float3(x, y, z);
+ return a;
}
-ccl_device_inline float3 safe_divide_color(float3 a, float3 b)
+ccl_device_inline Spectrum safe_divide_color(Spectrum a, Spectrum b)
{
- float x, y, z;
-
- x = (b.x != 0.0f) ? a.x / b.x : 0.0f;
- y = (b.y != 0.0f) ? a.y / b.y : 0.0f;
- z = (b.z != 0.0f) ? a.z / b.z : 0.0f;
+ FOREACH_SPECTRUM_CHANNEL (i) {
+ GET_SPECTRUM_CHANNEL(a, i) = (GET_SPECTRUM_CHANNEL(b, i) != 0.0f) ?
+ GET_SPECTRUM_CHANNEL(a, i) / GET_SPECTRUM_CHANNEL(b, i) :
+ 0.0f;
+ }
- return make_float3(x, y, z);
+ return a;
}
ccl_device_inline float3 safe_divide_even_color(float3 a, float3 b)
diff --git a/intern/cycles/util/progress.h b/intern/cycles/util/progress.h
index 37eafd57491..586979d2021 100644
--- a/intern/cycles/util/progress.h
+++ b/intern/cycles/util/progress.h
@@ -28,6 +28,7 @@ class Progress {
denoised_tiles = 0;
start_time = time_dt();
render_start_time = time_dt();
+ time_limit = 0.0;
end_time = 0.0;
status = "Initializing";
substatus = "";
@@ -68,6 +69,7 @@ class Progress {
denoised_tiles = 0;
start_time = time_dt();
render_start_time = time_dt();
+ time_limit = 0.0;
end_time = 0.0;
status = "Initializing";
substatus = "";
@@ -145,6 +147,13 @@ class Progress {
render_start_time = time_dt();
}
+ void set_time_limit(double time_limit_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ time_limit = time_limit_;
+ }
+
void add_skip_time(const scoped_timer &start_timer, bool only_render)
{
double skip_time = time_dt() - start_timer.get_start();
@@ -191,8 +200,13 @@ class Progress {
{
thread_scoped_lock lock(progress_mutex);
- if (total_pixel_samples > 0) {
- return ((double)pixel_samples) / (double)total_pixel_samples;
+ if (pixel_samples > 0) {
+ double progress_percent = (double)pixel_samples / (double)total_pixel_samples;
+ if (time_limit != 0.0) {
+ double time_since_render_start = time_dt() - render_start_time;
+ progress_percent = max(progress_percent, time_since_render_start / time_limit);
+ }
+ return min(1.0, progress_percent);
}
return 0.0;
}
@@ -335,7 +349,7 @@ class Progress {
* in which case the current_tile_sample is displayed. */
int rendered_tiles, denoised_tiles;
- double start_time, render_start_time;
+ double start_time, render_start_time, time_limit;
/* End time written when render is done, so it doesn't keep increasing on redraws. */
double end_time;
diff --git a/intern/cycles/util/types.h b/intern/cycles/util/types.h
index 031c2f7c4c1..1ab6f76f9bc 100644
--- a/intern/cycles/util/types.h
+++ b/intern/cycles/util/types.h
@@ -12,6 +12,7 @@
#if !defined(__KERNEL_GPU__)
# include <stdint.h>
+# include <stdio.h>
#endif
#include "util/defines.h"
@@ -70,6 +71,24 @@ ccl_device_inline bool is_power_of_two(size_t x)
CCL_NAMESPACE_END
+/* Device side printf only tested on CUDA, may work on more GPU devices. */
+#if !defined(__KERNEL_GPU__) || defined(__KERNEL_CUDA__)
+# define __KERNEL_PRINTF__
+#endif
+
+ccl_device_inline void print_float(ccl_private const char *label, const float a)
+{
+#ifdef __KERNEL_PRINTF__
+ printf("%s: %.8f\n", label, (double)a);
+#endif
+}
+
+/* Most GPU APIs matching native vector types, so we only need to implement them for
+ * CPU and oneAPI. */
+#if defined(__KERNEL_GPU__) && !defined(__KERNEL_ONEAPI__)
+# define __KERNEL_NATIVE_VECTOR_TYPES__
+#endif
+
/* Vectorized types declaration. */
#include "util/types_uchar2.h"
#include "util/types_uchar3.h"
@@ -90,7 +109,7 @@ CCL_NAMESPACE_END
#include "util/types_float4.h"
#include "util/types_float8.h"
-#include "util/types_vector3.h"
+#include "util/types_spectrum.h"
/* Vectorized types implementation. */
#include "util/types_uchar2_impl.h"
@@ -110,8 +129,6 @@ CCL_NAMESPACE_END
#include "util/types_float4_impl.h"
#include "util/types_float8_impl.h"
-#include "util/types_vector3_impl.h"
-
/* SSE types. */
#ifndef __KERNEL_GPU__
# include "util/sseb.h"
diff --git a/intern/cycles/util/types_float2.h b/intern/cycles/util/types_float2.h
index 07b9ec0986b..ea510ef832c 100644
--- a/intern/cycles/util/types_float2.h
+++ b/intern/cycles/util/types_float2.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_FLOAT2_H__
-#define __UTIL_TYPES_FLOAT2_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,18 +9,19 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct float2 {
float x, y;
+# ifndef __KERNEL_GPU__
__forceinline float operator[](int i) const;
__forceinline float &operator[](int i);
+# endif
};
ccl_device_inline float2 make_float2(float x, float y);
-ccl_device_inline void print_float2(const char *label, const float2 &a);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
-CCL_NAMESPACE_END
+ccl_device_inline void print_float2(ccl_private const char *label, const float2 a);
-#endif /* __UTIL_TYPES_FLOAT2_H__ */
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_float2_impl.h b/intern/cycles/util/types_float2_impl.h
index 45fc90c52bd..7ba7dee2e3a 100644
--- a/intern/cycles/util/types_float2_impl.h
+++ b/intern/cycles/util/types_float2_impl.h
@@ -1,20 +1,16 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_FLOAT2_IMPL_H__
-#define __UTIL_TYPES_FLOAT2_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
#endif
-#ifndef __KERNEL_GPU__
-# include <cstdio>
-#endif
-
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifndef __KERNEL_GPU__
__forceinline float float2::operator[](int i) const
{
util_assert(i >= 0);
@@ -28,19 +24,20 @@ __forceinline float &float2::operator[](int i)
util_assert(i < 2);
return *(&x + i);
}
+# endif
ccl_device_inline float2 make_float2(float x, float y)
{
float2 a = {x, y};
return a;
}
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
-ccl_device_inline void print_float2(const char *label, const float2 &a)
+ccl_device_inline void print_float2(ccl_private const char *label, const float2 a)
{
+#ifdef __KERNEL_PRINTF__
printf("%s: %.8f %.8f\n", label, (double)a.x, (double)a.y);
+#endif
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_FLOAT2_IMPL_H__ */
diff --git a/intern/cycles/util/types_float3.h b/intern/cycles/util/types_float3.h
index c7900acaa69..87c6b1d3654 100644
--- a/intern/cycles/util/types_float3.h
+++ b/intern/cycles/util/types_float3.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_FLOAT3_H__
-#define __UTIL_TYPES_FLOAT3_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,17 +9,28 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct ccl_try_align(16) float3
{
-# ifdef __KERNEL_SSE__
+# ifdef __KERNEL_GPU__
+ /* Compact structure for GPU. */
+ float x, y, z;
+# else
+ /* SIMD aligned structure for CPU. */
+# ifdef __KERNEL_SSE__
union {
__m128 m128;
struct {
float x, y, z, w;
};
};
+# else
+ float x, y, z, w;
+# endif
+# endif
+# ifdef __KERNEL_SSE__
+ /* Convenient constructors and operators for SIMD, otherwise default is enough. */
__forceinline float3();
__forceinline float3(const float3 &a);
__forceinline explicit float3(const __m128 &a);
@@ -29,18 +39,19 @@ struct ccl_try_align(16) float3
__forceinline operator __m128 &();
__forceinline float3 &operator=(const float3 &a);
-# else /* __KERNEL_SSE__ */
- float x, y, z, w;
-# endif /* __KERNEL_SSE__ */
+# endif
+# ifndef __KERNEL_GPU__
__forceinline float operator[](int i) const;
__forceinline float &operator[](int i);
+# endif
};
-ccl_device_inline float3 make_float3(float f);
ccl_device_inline float3 make_float3(float x, float y, float z);
-ccl_device_inline void print_float3(const char *label, const float3 &a);
-#endif /* !defined(__KERNEL_GPU__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
+
+ccl_device_inline float3 make_float3(float f);
+ccl_device_inline void print_float3(ccl_private const char *label, const float3 a);
/* Smaller float3 for storage. For math operations this must be converted to float3, so that on the
* CPU SIMD instructions can be used. */
@@ -78,5 +89,3 @@ struct packed_float3 {
static_assert(sizeof(packed_float3) == 12, "packed_float3 expected to be exactly 12 bytes");
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_FLOAT3_H__ */
diff --git a/intern/cycles/util/types_float3_impl.h b/intern/cycles/util/types_float3_impl.h
index 2e6e864c8ea..da76ab2ab2a 100644
--- a/intern/cycles/util/types_float3_impl.h
+++ b/intern/cycles/util/types_float3_impl.h
@@ -1,20 +1,15 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_FLOAT3_IMPL_H__
-#define __UTIL_TYPES_FLOAT3_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
#endif
-#ifndef __KERNEL_GPU__
-# include <cstdio>
-#endif
-
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
# ifdef __KERNEL_SSE__
__forceinline float3::float3()
{
@@ -45,6 +40,7 @@ __forceinline float3 &float3::operator=(const float3 &a)
}
# endif /* __KERNEL_SSE__ */
+# ifndef __KERNEL_GPU__
__forceinline float float3::operator[](int i) const
{
util_assert(i >= 0);
@@ -58,33 +54,37 @@ __forceinline float &float3::operator[](int i)
util_assert(i < 3);
return *(&x + i);
}
+# endif
-ccl_device_inline float3 make_float3(float f)
+ccl_device_inline float3 make_float3(float x, float y, float z)
{
-# ifdef __KERNEL_SSE__
- float3 a(_mm_set1_ps(f));
+# if defined(__KERNEL_GPU__)
+ return {x, y, z};
+# elif defined(__KERNEL_SSE__)
+ return float3(_mm_set_ps(0.0f, z, y, x));
# else
- float3 a = {f, f, f, f};
+ return {x, y, z, 0.0f};
# endif
- return a;
}
-ccl_device_inline float3 make_float3(float x, float y, float z)
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
+
+ccl_device_inline float3 make_float3(float f)
{
-# ifdef __KERNEL_SSE__
- float3 a(_mm_set_ps(0.0f, z, y, x));
-# else
- float3 a = {x, y, z, 0.0f};
-# endif
- return a;
+#if defined(__KERNEL_GPU__)
+ return make_float3(f, f, f);
+#elif defined(__KERNEL_SSE__)
+ return float3(_mm_set1_ps(f));
+#else
+ return {f, f, f, f};
+#endif
}
-ccl_device_inline void print_float3(const char *label, const float3 &a)
+ccl_device_inline void print_float3(ccl_private const char *label, const float3 a)
{
+#ifdef __KERNEL_PRINTF__
printf("%s: %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z);
+#endif
}
-#endif /* !defined(__KERNEL_GPU__) */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_FLOAT3_IMPL_H__ */
diff --git a/intern/cycles/util/types_float4.h b/intern/cycles/util/types_float4.h
index 27453bf39e4..a347cfce9a1 100644
--- a/intern/cycles/util/types_float4.h
+++ b/intern/cycles/util/types_float4.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_FLOAT4_H__
-#define __UTIL_TYPES_FLOAT4_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,7 +9,7 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct int4;
struct ccl_try_align(16) float4
@@ -35,16 +34,17 @@ struct ccl_try_align(16) float4
float x, y, z, w;
# endif /* __KERNEL_SSE__ */
+# ifndef __KERNEL_GPU__
__forceinline float operator[](int i) const;
__forceinline float &operator[](int i);
+# endif
};
-ccl_device_inline float4 make_float4(float f);
ccl_device_inline float4 make_float4(float x, float y, float z, float w);
-ccl_device_inline float4 make_float4(const int4 &i);
-ccl_device_inline void print_float4(const char *label, const float4 &a);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
-CCL_NAMESPACE_END
+ccl_device_inline float4 make_float4(float f);
+ccl_device_inline float4 make_float4(const int4 i);
+ccl_device_inline void print_float4(ccl_private const char *label, const float4 a);
-#endif /* __UTIL_TYPES_FLOAT4_H__ */
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_float4_impl.h b/intern/cycles/util/types_float4_impl.h
index d7858f744e3..420d9316926 100644
--- a/intern/cycles/util/types_float4_impl.h
+++ b/intern/cycles/util/types_float4_impl.h
@@ -1,20 +1,15 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_FLOAT4_IMPL_H__
-#define __UTIL_TYPES_FLOAT4_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
#endif
-#ifndef __KERNEL_GPU__
-# include <cstdio>
-#endif
-
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
# ifdef __KERNEL_SSE__
__forceinline float4::float4()
{
@@ -41,6 +36,7 @@ __forceinline float4 &float4::operator=(const float4 &a)
}
# endif /* __KERNEL_SSE__ */
+# ifndef __KERNEL_GPU__
__forceinline float float4::operator[](int i) const
{
util_assert(i >= 0);
@@ -54,43 +50,42 @@ __forceinline float &float4::operator[](int i)
util_assert(i < 4);
return *(&x + i);
}
+# endif
-ccl_device_inline float4 make_float4(float f)
+ccl_device_inline float4 make_float4(float x, float y, float z, float w)
{
# ifdef __KERNEL_SSE__
- float4 a(_mm_set1_ps(f));
+ return float4(_mm_set_ps(w, z, y, x));
# else
- float4 a = {f, f, f, f};
+ return {x, y, z, w};
# endif
- return a;
}
-ccl_device_inline float4 make_float4(float x, float y, float z, float w)
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
+
+ccl_device_inline float4 make_float4(float f)
{
-# ifdef __KERNEL_SSE__
- float4 a(_mm_set_ps(w, z, y, x));
-# else
- float4 a = {x, y, z, w};
-# endif
- return a;
+#ifdef __KERNEL_SSE__
+ return float4(_mm_set1_ps(f));
+#else
+ return make_float4(f, f, f, f);
+#endif
}
-ccl_device_inline float4 make_float4(const int4 &i)
+ccl_device_inline float4 make_float4(const int4 i)
{
-# ifdef __KERNEL_SSE__
- float4 a(_mm_cvtepi32_ps(i.m128));
-# else
- float4 a = {(float)i.x, (float)i.y, (float)i.z, (float)i.w};
-# endif
- return a;
+#ifdef __KERNEL_SSE__
+ return float4(_mm_cvtepi32_ps(i.m128));
+#else
+ return make_float4((float)i.x, (float)i.y, (float)i.z, (float)i.w);
+#endif
}
-ccl_device_inline void print_float4(const char *label, const float4 &a)
+ccl_device_inline void print_float4(ccl_private const char *label, const float4 a)
{
+#ifdef __KERNEL_PRINTF__
printf("%s: %.8f %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z, (double)a.w);
+#endif
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_FLOAT4_IMPL_H__ */
diff --git a/intern/cycles/util/types_float8.h b/intern/cycles/util/types_float8.h
index bb9798932ac..29fd632f08e 100644
--- a/intern/cycles/util/types_float8.h
+++ b/intern/cycles/util/types_float8.h
@@ -2,8 +2,7 @@
* Original code Copyright 2017, Intel Corporation
* Modifications Copyright 2018-2022 Blender Foundation. */
-#ifndef __UTIL_TYPES_FLOAT8_H__
-#define __UTIL_TYPES_FLOAT8_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -12,7 +11,7 @@
CCL_NAMESPACE_BEGIN
/* float8 is a reserved type in Metal that has not been implemented. For
- * that reason this is named float8_t. */
+ * that reason this is named float8_t and not using native vector types. */
#ifdef __KERNEL_GPU__
struct float8_t
@@ -52,5 +51,3 @@ ccl_device_inline float8_t
make_float8_t(float a, float b, float c, float d, float e, float f, float g, float h);
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_FLOAT8_H__ */
diff --git a/intern/cycles/util/types_float8_impl.h b/intern/cycles/util/types_float8_impl.h
index 2ab464a791b..e8576cdaf70 100644
--- a/intern/cycles/util/types_float8_impl.h
+++ b/intern/cycles/util/types_float8_impl.h
@@ -2,17 +2,12 @@
* Original code Copyright 2017, Intel Corporation
* Modifications Copyright 2018-2022 Blender Foundation. */
-#ifndef __UTIL_TYPES_FLOAT8_IMPL_H__
-#define __UTIL_TYPES_FLOAT8_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
#endif
-#ifndef __KERNEL_GPU__
-# include <cstdio>
-#endif
-
CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_AVX2__
@@ -83,5 +78,3 @@ make_float8_t(float a, float b, float c, float d, float e, float f, float g, flo
}
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_FLOAT8_IMPL_H__ */
diff --git a/intern/cycles/util/types_int2.h b/intern/cycles/util/types_int2.h
index bf69cddc653..604713dffcd 100644
--- a/intern/cycles/util/types_int2.h
+++ b/intern/cycles/util/types_int2.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_INT2_H__
-#define __UTIL_TYPES_INT2_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,17 +9,17 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct int2 {
int x, y;
+# ifndef __KERNEL_GPU__
__forceinline int operator[](int i) const;
__forceinline int &operator[](int i);
+# endif
};
ccl_device_inline int2 make_int2(int x, int y);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_INT2_H__ */
diff --git a/intern/cycles/util/types_int2_impl.h b/intern/cycles/util/types_int2_impl.h
index 7bdc77369ee..f48c6f46729 100644
--- a/intern/cycles/util/types_int2_impl.h
+++ b/intern/cycles/util/types_int2_impl.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_INT2_IMPL_H__
-#define __UTIL_TYPES_INT2_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,7 +9,8 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifndef __KERNEL_GPU__
int int2::operator[](int i) const
{
util_assert(i >= 0);
@@ -24,14 +24,13 @@ int &int2::operator[](int i)
util_assert(i < 2);
return *(&x + i);
}
+# endif
ccl_device_inline int2 make_int2(int x, int y)
{
int2 a = {x, y};
return a;
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_INT2_IMPL_H__ */
diff --git a/intern/cycles/util/types_int3.h b/intern/cycles/util/types_int3.h
index f88ff22ac35..e059ddd3660 100644
--- a/intern/cycles/util/types_int3.h
+++ b/intern/cycles/util/types_int3.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_INT3_H__
-#define __UTIL_TYPES_INT3_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,10 +9,15 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct ccl_try_align(16) int3
{
-# ifdef __KERNEL_SSE__
+# ifdef __KERNEL_GPU__
+ /* Compact structure on the GPU. */
+ int x, y, z;
+# else
+ /* SIMD aligned structure for CPU. */
+# ifdef __KERNEL_SSE__
union {
__m128i m128;
struct {
@@ -29,19 +33,21 @@ struct ccl_try_align(16) int3
__forceinline operator __m128i &();
__forceinline int3 &operator=(const int3 &a);
-# else /* __KERNEL_SSE__ */
+# else /* __KERNEL_SSE__ */
int x, y, z, w;
-# endif /* __KERNEL_SSE__ */
+# endif /* __KERNEL_SSE__ */
+# endif
+# ifndef __KERNEL_GPU__
__forceinline int operator[](int i) const;
__forceinline int &operator[](int i);
+# endif
};
-ccl_device_inline int3 make_int3(int i);
ccl_device_inline int3 make_int3(int x, int y, int z);
-ccl_device_inline void print_int3(const char *label, const int3 &a);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
-CCL_NAMESPACE_END
+ccl_device_inline int3 make_int3(int i);
+ccl_device_inline void print_int3(ccl_private const char *label, const int3 a);
-#endif /* __UTIL_TYPES_INT3_H__ */
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_int3_impl.h b/intern/cycles/util/types_int3_impl.h
index 1c49e97ad32..830dfa3c658 100644
--- a/intern/cycles/util/types_int3_impl.h
+++ b/intern/cycles/util/types_int3_impl.h
@@ -1,20 +1,15 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_INT3_IMPL_H__
-#define __UTIL_TYPES_INT3_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
#endif
-#ifndef __KERNEL_GPU__
-# include <cstdio>
-#endif
-
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
# ifdef __KERNEL_SSE__
__forceinline int3::int3()
{
@@ -45,6 +40,7 @@ __forceinline int3 &int3::operator=(const int3 &a)
}
# endif /* __KERNEL_SSE__ */
+# ifndef __KERNEL_GPU__
__forceinline int int3::operator[](int i) const
{
util_assert(i >= 0);
@@ -58,34 +54,37 @@ __forceinline int &int3::operator[](int i)
util_assert(i < 3);
return *(&x + i);
}
-
-ccl_device_inline int3 make_int3(int i)
-{
-# ifdef __KERNEL_SSE__
- int3 a(_mm_set1_epi32(i));
-# else
- int3 a = {i, i, i, i};
# endif
- return a;
-}
ccl_device_inline int3 make_int3(int x, int y, int z)
{
-# ifdef __KERNEL_SSE__
- int3 a(_mm_set_epi32(0, z, y, x));
+# if defined(__KERNEL_GPU__)
+ return {x, y, z};
+# elif defined(__KERNEL_SSE__)
+ return int3(_mm_set_epi32(0, z, y, x));
# else
- int3 a = {x, y, z, 0};
+ return {x, y, z, 0};
# endif
+}
- return a;
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
+
+ccl_device_inline int3 make_int3(int i)
+{
+#if defined(__KERNEL_GPU__)
+ return make_int3(i, i, i);
+#elif defined(__KERNEL_SSE__)
+ return int3(_mm_set1_epi32(i));
+#else
+ return {i, i, i, i};
+#endif
}
-ccl_device_inline void print_int3(const char *label, const int3 &a)
+ccl_device_inline void print_int3(ccl_private const char *label, const int3 a)
{
+#ifdef __KERNEL_PRINTF__
printf("%s: %d %d %d\n", label, a.x, a.y, a.z);
+#endif
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_INT3_IMPL_H__ */
diff --git a/intern/cycles/util/types_int4.h b/intern/cycles/util/types_int4.h
index 9d557c01344..1a13c03e60e 100644
--- a/intern/cycles/util/types_int4.h
+++ b/intern/cycles/util/types_int4.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_INT4_H__
-#define __UTIL_TYPES_INT4_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,7 +9,7 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct float3;
struct float4;
@@ -37,17 +36,18 @@ struct ccl_try_align(16) int4
int x, y, z, w;
# endif /* __KERNEL_SSE__ */
+# ifndef __KERNEL_GPU__
__forceinline int operator[](int i) const;
__forceinline int &operator[](int i);
+# endif
};
-ccl_device_inline int4 make_int4(int i);
ccl_device_inline int4 make_int4(int x, int y, int z, int w);
-ccl_device_inline int4 make_int4(const float3 &f);
-ccl_device_inline int4 make_int4(const float4 &f);
-ccl_device_inline void print_int4(const char *label, const int4 &a);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
-CCL_NAMESPACE_END
+ccl_device_inline int4 make_int4(int i);
+ccl_device_inline int4 make_int4(const float3 f);
+ccl_device_inline int4 make_int4(const float4 f);
+ccl_device_inline void print_int4(ccl_private const char *label, const int4 a);
-#endif /* __UTIL_TYPES_INT4_H__ */
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_int4_impl.h b/intern/cycles/util/types_int4_impl.h
index 11e1ede6705..067794e67b4 100644
--- a/intern/cycles/util/types_int4_impl.h
+++ b/intern/cycles/util/types_int4_impl.h
@@ -1,20 +1,15 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_INT4_IMPL_H__
-#define __UTIL_TYPES_INT4_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
#endif
-#ifndef __KERNEL_GPU__
-# include <cstdio>
-#endif
-
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
# ifdef __KERNEL_SSE__
__forceinline int4::int4()
{
@@ -45,6 +40,7 @@ __forceinline int4 &int4::operator=(const int4 &a)
}
# endif /* __KERNEL_SSE__ */
+# ifndef __KERNEL_GPU__
__forceinline int int4::operator[](int i) const
{
util_assert(i >= 0);
@@ -58,55 +54,53 @@ __forceinline int &int4::operator[](int i)
util_assert(i < 4);
return *(&x + i);
}
+# endif
-ccl_device_inline int4 make_int4(int i)
+ccl_device_inline int4 make_int4(int x, int y, int z, int w)
{
# ifdef __KERNEL_SSE__
- int4 a(_mm_set1_epi32(i));
+ return int4(_mm_set_epi32(w, z, y, x));
# else
- int4 a = {i, i, i, i};
+ return {x, y, z, w};
# endif
- return a;
}
-ccl_device_inline int4 make_int4(int x, int y, int z, int w)
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
+
+ccl_device_inline int4 make_int4(int i)
{
-# ifdef __KERNEL_SSE__
- int4 a(_mm_set_epi32(w, z, y, x));
-# else
- int4 a = {x, y, z, w};
-# endif
- return a;
+#ifdef __KERNEL_SSE__
+ return int4(_mm_set1_epi32(i));
+#else
+ return make_int4(i, i, i, i);
+#endif
}
-ccl_device_inline int4 make_int4(const float3 &f)
+ccl_device_inline int4 make_int4(const float3 f)
{
-# ifdef __KERNEL_SSE__
- int4 a(_mm_cvtps_epi32(f.m128));
-# elif defined(__KERNEL_ONEAPI__)
- int4 a = {(int)f.x, (int)f.y, (int)f.z, 0};
-# else
- int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w};
-# endif
- return a;
+#if defined(__KERNEL_GPU__)
+ return make_int4((int)f.x, (int)f.y, (int)f.z, 0);
+#elif defined(__KERNEL_SSE__)
+ return int4(_mm_cvtps_epi32(f.m128));
+#else
+ return make_int4((int)f.x, (int)f.y, (int)f.z, (int)f.w);
+#endif
}
-ccl_device_inline int4 make_int4(const float4 &f)
+ccl_device_inline int4 make_int4(const float4 f)
{
-# ifdef __KERNEL_SSE__
- int4 a(_mm_cvtps_epi32(f.m128));
-# else
- int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w};
-# endif
- return a;
+#ifdef __KERNEL_SSE__
+ return int4(_mm_cvtps_epi32(f.m128));
+#else
+ return make_int4((int)f.x, (int)f.y, (int)f.z, (int)f.w);
+#endif
}
-ccl_device_inline void print_int4(const char *label, const int4 &a)
+ccl_device_inline void print_int4(ccl_private const char *label, const int4 a)
{
+#ifdef __KERNEL_PRINTF__
printf("%s: %d %d %d %d\n", label, a.x, a.y, a.z, a.w);
+#endif
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_INT4_IMPL_H__ */
diff --git a/intern/cycles/util/types_spectrum.h b/intern/cycles/util/types_spectrum.h
new file mode 100644
index 00000000000..c59230b83ae
--- /dev/null
+++ b/intern/cycles/util/types_spectrum.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2022 Blender Foundation */
+
+#ifndef __UTIL_TYPES_SPECTRUM_H__
+#define __UTIL_TYPES_SPECTRUM_H__
+
+#ifndef __UTIL_TYPES_H__
+# error "Do not include this file directly, include util/types.h instead."
+#endif
+
+CCL_NAMESPACE_BEGIN
+
+#define SPECTRUM_CHANNELS 3
+#define SPECTRUM_DATA_TYPE float3
+#define PACKED_SPECTRUM_DATA_TYPE packed_float3
+
+using Spectrum = SPECTRUM_DATA_TYPE;
+using PackedSpectrum = PACKED_SPECTRUM_DATA_TYPE;
+
+#define make_spectrum(f) CONCAT(make_, SPECTRUM_DATA_TYPE(f))
+#define load_spectrum(f) CONCAT(load_, SPECTRUM_DATA_TYPE(f))
+#define store_spectrum(s, f) CONCAT(store_, SPECTRUM_DATA_TYPE((s), (f)))
+
+#define zero_spectrum CONCAT(zero_, SPECTRUM_DATA_TYPE)
+#define one_spectrum CONCAT(one_, SPECTRUM_DATA_TYPE)
+
+#define FOREACH_SPECTRUM_CHANNEL(counter) \
+ for (int counter = 0; counter < SPECTRUM_CHANNELS; counter++)
+
+#define GET_SPECTRUM_CHANNEL(v, i) (((ccl_private float *)(&(v)))[i])
+
+CCL_NAMESPACE_END
+
+#endif /* __UTIL_TYPES_SPECTRUM_H__ */
diff --git a/intern/cycles/util/types_uchar2.h b/intern/cycles/util/types_uchar2.h
index 0b3c9bd0331..ce617248e6e 100644
--- a/intern/cycles/util/types_uchar2.h
+++ b/intern/cycles/util/types_uchar2.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_UCHAR2_H__
-#define __UTIL_TYPES_UCHAR2_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,17 +9,17 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct uchar2 {
uchar x, y;
+# ifndef __KERNEL_GPU__
__forceinline uchar operator[](int i) const;
__forceinline uchar &operator[](int i);
+# endif
};
ccl_device_inline uchar2 make_uchar2(uchar x, uchar y);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_UCHAR2_H__ */
diff --git a/intern/cycles/util/types_uchar2_impl.h b/intern/cycles/util/types_uchar2_impl.h
index a7254d5eaf2..9f3f3a4efb9 100644
--- a/intern/cycles/util/types_uchar2_impl.h
+++ b/intern/cycles/util/types_uchar2_impl.h
@@ -10,7 +10,8 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifndef __KERNEL_GPU__
uchar uchar2::operator[](int i) const
{
util_assert(i >= 0);
@@ -24,13 +25,14 @@ uchar &uchar2::operator[](int i)
util_assert(i < 2);
return *(&x + i);
}
+# endif
ccl_device_inline uchar2 make_uchar2(uchar x, uchar y)
{
uchar2 a = {x, y};
return a;
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_uchar3.h b/intern/cycles/util/types_uchar3.h
index fc213502ada..aed04c4775e 100644
--- a/intern/cycles/util/types_uchar3.h
+++ b/intern/cycles/util/types_uchar3.h
@@ -10,16 +10,18 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct uchar3 {
uchar x, y, z;
+# ifndef __KERNEL_GPU__
__forceinline uchar operator[](int i) const;
__forceinline uchar &operator[](int i);
+# endif
};
ccl_device_inline uchar3 make_uchar3(uchar x, uchar y, uchar z);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_uchar3_impl.h b/intern/cycles/util/types_uchar3_impl.h
index 0c24ffb488a..83eb3c99b3c 100644
--- a/intern/cycles/util/types_uchar3_impl.h
+++ b/intern/cycles/util/types_uchar3_impl.h
@@ -10,7 +10,8 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifndef __KERNEL_GPU__
uchar uchar3::operator[](int i) const
{
util_assert(i >= 0);
@@ -24,13 +25,14 @@ uchar &uchar3::operator[](int i)
util_assert(i < 3);
return *(&x + i);
}
+# endif
ccl_device_inline uchar3 make_uchar3(uchar x, uchar y, uchar z)
{
uchar3 a = {x, y, z};
return a;
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_uchar4.h b/intern/cycles/util/types_uchar4.h
index a2a2c945aaa..fb13a98875e 100644
--- a/intern/cycles/util/types_uchar4.h
+++ b/intern/cycles/util/types_uchar4.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_UCHAR4_H__
-#define __UTIL_TYPES_UCHAR4_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,17 +9,17 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct uchar4 {
uchar x, y, z, w;
+# ifndef __KERNEL_GPU__
__forceinline uchar operator[](int i) const;
__forceinline uchar &operator[](int i);
+# endif
};
ccl_device_inline uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_UCHAR4_H__ */
diff --git a/intern/cycles/util/types_uchar4_impl.h b/intern/cycles/util/types_uchar4_impl.h
index 8ec6213a37d..244bb98f883 100644
--- a/intern/cycles/util/types_uchar4_impl.h
+++ b/intern/cycles/util/types_uchar4_impl.h
@@ -10,7 +10,8 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifndef __KERNEL_GPU__
uchar uchar4::operator[](int i) const
{
util_assert(i >= 0);
@@ -24,13 +25,14 @@ uchar &uchar4::operator[](int i)
util_assert(i < 4);
return *(&x + i);
}
+# endif
ccl_device_inline uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w)
{
uchar4 a = {x, y, z, w};
return a;
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/types_uint2.h b/intern/cycles/util/types_uint2.h
index faa0955f903..4d76b628088 100644
--- a/intern/cycles/util/types_uint2.h
+++ b/intern/cycles/util/types_uint2.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_UINT2_H__
-#define __UTIL_TYPES_UINT2_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,17 +9,17 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct uint2 {
uint x, y;
+# ifndef __KERNEL_GPU__
__forceinline uint operator[](uint i) const;
__forceinline uint &operator[](uint i);
+# endif
};
ccl_device_inline uint2 make_uint2(uint x, uint y);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_UINT2_H__ */
diff --git a/intern/cycles/util/types_uint2_impl.h b/intern/cycles/util/types_uint2_impl.h
index cac0ba6b531..b508aaf2543 100644
--- a/intern/cycles/util/types_uint2_impl.h
+++ b/intern/cycles/util/types_uint2_impl.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_UINT2_IMPL_H__
-#define __UTIL_TYPES_UINT2_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,7 +9,8 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifndef __KERNEL_GPU__
__forceinline uint uint2::operator[](uint i) const
{
util_assert(i < 2);
@@ -22,14 +22,13 @@ __forceinline uint &uint2::operator[](uint i)
util_assert(i < 2);
return *(&x + i);
}
+# endif
ccl_device_inline uint2 make_uint2(uint x, uint y)
{
uint2 a = {x, y};
return a;
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_UINT2_IMPL_H__ */
diff --git a/intern/cycles/util/types_uint3.h b/intern/cycles/util/types_uint3.h
index 3ff87bfc791..b1571716fc7 100644
--- a/intern/cycles/util/types_uint3.h
+++ b/intern/cycles/util/types_uint3.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_UINT3_H__
-#define __UTIL_TYPES_UINT3_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,17 +9,17 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct uint3 {
uint x, y, z;
+# ifndef __KERNEL_GPU__
__forceinline uint operator[](uint i) const;
__forceinline uint &operator[](uint i);
+# endif
};
ccl_device_inline uint3 make_uint3(uint x, uint y, uint z);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_UINT3_H__ */
diff --git a/intern/cycles/util/types_uint3_impl.h b/intern/cycles/util/types_uint3_impl.h
index 221883a1adb..d36c9f52de9 100644
--- a/intern/cycles/util/types_uint3_impl.h
+++ b/intern/cycles/util/types_uint3_impl.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_UINT3_IMPL_H__
-#define __UTIL_TYPES_UINT3_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,7 +9,8 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifndef __KERNEL_GPU__
__forceinline uint uint3::operator[](uint i) const
{
util_assert(i < 3);
@@ -22,14 +22,13 @@ __forceinline uint &uint3::operator[](uint i)
util_assert(i < 3);
return *(&x + i);
}
+# endif
ccl_device_inline uint3 make_uint3(uint x, uint y, uint z)
{
uint3 a = {x, y, z};
return a;
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_UINT3_IMPL_H__ */
diff --git a/intern/cycles/util/types_uint4.h b/intern/cycles/util/types_uint4.h
index 504095b2383..4982b30f577 100644
--- a/intern/cycles/util/types_uint4.h
+++ b/intern/cycles/util/types_uint4.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_UINT4_H__
-#define __UTIL_TYPES_UINT4_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,17 +9,17 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct uint4 {
uint x, y, z, w;
+# ifndef __KERNEL_GPU__
__forceinline uint operator[](uint i) const;
__forceinline uint &operator[](uint i);
+# endif
};
ccl_device_inline uint4 make_uint4(uint x, uint y, uint z, uint w);
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_UINT4_H__ */
diff --git a/intern/cycles/util/types_uint4_impl.h b/intern/cycles/util/types_uint4_impl.h
index d78db944a1f..1cfdb9e0992 100644
--- a/intern/cycles/util/types_uint4_impl.h
+++ b/intern/cycles/util/types_uint4_impl.h
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
-#ifndef __UTIL_TYPES_UINT4_IMPL_H__
-#define __UTIL_TYPES_UINT4_IMPL_H__
+#pragma once
#ifndef __UTIL_TYPES_H__
# error "Do not include this file directly, include util/types.h instead."
@@ -10,7 +9,8 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
+# ifndef __KERNEL_GPU__
__forceinline uint uint4::operator[](uint i) const
{
util_assert(i < 3);
@@ -22,14 +22,13 @@ __forceinline uint &uint4::operator[](uint i)
util_assert(i < 3);
return *(&x + i);
}
+# endif
ccl_device_inline uint4 make_uint4(uint x, uint y, uint z, uint w)
{
uint4 a = {x, y, z, w};
return a;
}
-#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */
+#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */
CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_UINT4_IMPL_H__ */
diff --git a/intern/cycles/util/types_ushort4.h b/intern/cycles/util/types_ushort4.h
index 9a6e12095ba..aef36f63285 100644
--- a/intern/cycles/util/types_ushort4.h
+++ b/intern/cycles/util/types_ushort4.h
@@ -10,7 +10,7 @@
CCL_NAMESPACE_BEGIN
-#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__)
+#ifndef __KERNEL_NATIVE_VECTOR_TYPES__
struct ushort4 {
uint16_t x, y, z, w;
diff --git a/intern/cycles/util/types_vector3.h b/intern/cycles/util/types_vector3.h
deleted file mode 100644
index 2e0d68e1bd0..00000000000
--- a/intern/cycles/util/types_vector3.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2022 Blender Foundation */
-
-#ifndef __UTIL_TYPES_VECTOR3_H__
-#define __UTIL_TYPES_VECTOR3_H__
-
-#ifndef __UTIL_TYPES_H__
-# error "Do not include this file directly, include util/types.h instead."
-#endif
-
-CCL_NAMESPACE_BEGIN
-
-#ifndef __KERNEL_GPU__
-template<typename T> class vector3 {
- public:
- T x, y, z;
-
- __forceinline vector3();
- __forceinline vector3(const T &a);
- __forceinline vector3(const T &x, const T &y, const T &z);
-};
-#endif /* __KERNEL_GPU__ */
-
-CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_VECTOR3_H__ */
diff --git a/intern/cycles/util/types_vector3_impl.h b/intern/cycles/util/types_vector3_impl.h
deleted file mode 100644
index a765780e2d3..00000000000
--- a/intern/cycles/util/types_vector3_impl.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2022 Blender Foundation */
-
-#ifndef __UTIL_TYPES_VECTOR3_IMPL_H__
-#define __UTIL_TYPES_VECTOR3_IMPL_H__
-
-#ifndef __UTIL_TYPES_H__
-# error "Do not include this file directly, include util/types.h instead."
-#endif
-
-CCL_NAMESPACE_BEGIN
-
-#ifndef __KERNEL_GPU__
-template<typename T> ccl_always_inline vector3<T>::vector3()
-{
-}
-
-template<typename T> ccl_always_inline vector3<T>::vector3(const T &a) : x(a), y(a), z(a)
-{
-}
-
-template<typename T>
-ccl_always_inline vector3<T>::vector3(const T &x, const T &y, const T &z) : x(x), y(y), z(z)
-{
-}
-#endif /* __KERNEL_GPU__ */
-
-CCL_NAMESPACE_END
-
-#endif /* __UTIL_TYPES_VECTOR3_IMPL_H__ */
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index c681dc368bb..0ac3a234946 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -5,6 +5,7 @@ set(INC
.
../clog
../glew-mx
+ ../../source/blender/blenlib
../../source/blender/imbuf
../../source/blender/makesdna
)
@@ -25,6 +26,7 @@ set(SRC
intern/GHOST_ISystemPaths.cpp
intern/GHOST_ModifierKeys.cpp
intern/GHOST_Path-api.cpp
+ intern/GHOST_PathUtils.cpp
intern/GHOST_Rect.cpp
intern/GHOST_System.cpp
intern/GHOST_TimerManager.cpp
@@ -59,6 +61,7 @@ set(SRC
intern/GHOST_EventTrackpad.h
intern/GHOST_EventWheel.h
intern/GHOST_ModifierKeys.h
+ intern/GHOST_PathUtils.h
intern/GHOST_System.h
intern/GHOST_SystemPaths.h
intern/GHOST_TimerManager.h
diff --git a/intern/ghost/intern/GHOST_Context.cpp b/intern/ghost/intern/GHOST_Context.cpp
index f9aa80dc13d..f4b3d08ffc5 100644
--- a/intern/ghost/intern/GHOST_Context.cpp
+++ b/intern/ghost/intern/GHOST_Context.cpp
@@ -35,7 +35,7 @@ bool win32_silent_chk(bool result)
bool win32_chk(bool result, const char *file, int line, const char *text)
{
if (!result) {
- LPTSTR formattedMsg = NULL;
+ LPTSTR formattedMsg = nullptr;
DWORD error = GetLastError();
@@ -87,12 +87,12 @@ bool win32_chk(bool result, const char *file, int line, const char *text)
default: {
count = FormatMessage((FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS),
- NULL,
+ nullptr,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)(&formattedMsg),
0,
- NULL);
+ nullptr);
msg = count > 0 ? formattedMsg : "<no system message>\n";
break;
@@ -113,8 +113,9 @@ bool win32_chk(bool result, const char *file, int line, const char *text)
SetLastError(NO_ERROR);
- if (count != 0)
+ if (count != 0) {
LocalFree(formattedMsg);
+ }
}
return result;
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp
index 252a8bfd095..4da3c7c996d 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp
@@ -7,6 +7,7 @@
#include "GHOST_DropTargetX11.h"
#include "GHOST_Debug.h"
+#include "GHOST_PathUtils.h"
#include "GHOST_utildefines.h"
#include <cassert>
@@ -97,89 +98,10 @@ GHOST_DropTargetX11::~GHOST_DropTargetX11()
}
}
-/* Based on: https://stackoverflow.com/a/2766963/432509 */
-
-using DecodeState_e = enum DecodeState_e {
- /** Searching for an ampersand to convert. */
- STATE_SEARCH = 0,
- /** Convert the two proceeding characters from hex. */
- STATE_CONVERTING
-};
-
-void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn)
-{
- unsigned int i;
- unsigned int len = strlen(encodedIn);
- DecodeState_e state = STATE_SEARCH;
- int j;
- unsigned int asciiCharacter;
- char tempNumBuf[3] = {0};
- bool bothDigits = true;
-
- memset(decodedOut, 0, bufferSize);
-
- for (i = 0; i < len; ++i) {
- switch (state) {
- case STATE_SEARCH:
- if (encodedIn[i] != '%') {
- strncat(decodedOut, &encodedIn[i], 1);
- assert((int)strlen(decodedOut) < bufferSize);
- break;
- }
-
- /* We are now converting */
- state = STATE_CONVERTING;
- break;
-
- case STATE_CONVERTING:
- bothDigits = true;
-
- /* Create a buffer to hold the hex. For example, if %20, this
- * buffer would hold 20 (in ASCII) */
- memset(tempNumBuf, 0, sizeof(tempNumBuf));
-
- /* Conversion complete (i.e. don't convert again next iter) */
- state = STATE_SEARCH;
-
- strncpy(tempNumBuf, &encodedIn[i], 2);
-
- /* Ensure both characters are hexadecimal */
-
- for (j = 0; j < 2; ++j) {
- if (!isxdigit(tempNumBuf[j])) {
- bothDigits = false;
- }
- }
-
- if (!bothDigits) {
- break;
- }
- /* Convert two hexadecimal characters into one character */
- sscanf(tempNumBuf, "%x", &asciiCharacter);
-
- /* Ensure we aren't going to overflow */
- assert((int)strlen(decodedOut) < bufferSize);
-
- /* Concatenate this character onto the output */
- strncat(decodedOut, (char *)&asciiCharacter, 1);
-
- /* Skip the next character */
- i++;
- break;
- }
- }
-}
-
char *GHOST_DropTargetX11::FileUrlDecode(char *fileUrl)
{
if (strncmp(fileUrl, "file://", 7) == 0) {
- /* assume one character of encoded URL can be expanded to 4 chars max */
- int decodedSize = 4 * strlen(fileUrl) + 1;
- char *decodedPath = (char *)malloc(decodedSize);
-
- UrlDecode(decodedPath, decodedSize, fileUrl + 7);
-
- return decodedPath;
+ return GHOST_URL_decode_alloc(fileUrl + 7);
}
return nullptr;
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.h b/intern/ghost/intern/GHOST_DropTargetX11.h
index f0ef27697e1..db73ddff70f 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.h
+++ b/intern/ghost/intern/GHOST_DropTargetX11.h
@@ -65,14 +65,6 @@ class GHOST_DropTargetX11 {
void *getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize);
/**
- * Decode URL (i.e. converts `file:///a%20b/test` to `file:///a b/test`)
- * \param decodedOut: - buffer for decoded URL.
- * \param bufferSize: - size of output buffer.
- * \param encodedIn: - input encoded buffer to be decoded.
- */
- void UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn);
-
- /**
* Fully decode file URL (i.e. converts `file:///a%20b/test` to `/a b/test`)
* \param fileUrl: - file path URL to be fully decoded.
* \return decoded file path (result should be free-d).
diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h
index 0813378a819..1e1c428e2ae 100644
--- a/intern/ghost/intern/GHOST_Event.h
+++ b/intern/ghost/intern/GHOST_Event.h
@@ -22,7 +22,7 @@ class GHOST_Event : public GHOST_IEvent {
* \param window: The generating window (or NULL if system event).
*/
GHOST_Event(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window)
- : m_type(type), m_time(msec), m_window(window), m_data(NULL)
+ : m_type(type), m_time(msec), m_window(window), m_data(nullptr)
{
}
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index d58fb90f63e..746e3532b03 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -411,8 +411,9 @@ static bool nearHomePosition(GHOST_TEventNDOFMotionData *ndof, float threshold)
bool GHOST_NDOFManager::sendMotionEvent()
{
- if (!m_motionEventPending)
+ if (!m_motionEventPending) {
return false;
+ }
m_motionEventPending = false; /* Any pending motion is handled right now. */
diff --git a/intern/ghost/intern/GHOST_Path-api.cpp b/intern/ghost/intern/GHOST_Path-api.cpp
index 1b1c72d8a4b..58f36dc096d 100644
--- a/intern/ghost/intern/GHOST_Path-api.cpp
+++ b/intern/ghost/intern/GHOST_Path-api.cpp
@@ -49,10 +49,10 @@ const char *GHOST_getBinaryDir()
return systemPaths ? systemPaths->getBinaryDir() : nullptr;
}
-void GHOST_addToSystemRecentFiles(const char *filename)
+void GHOST_addToSystemRecentFiles(const char *filepath)
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
if (systemPaths) {
- systemPaths->addToSystemRecentFiles(filename);
+ systemPaths->addToSystemRecentFiles(filepath);
}
}
diff --git a/intern/ghost/intern/GHOST_PathUtils.cpp b/intern/ghost/intern/GHOST_PathUtils.cpp
new file mode 100644
index 00000000000..3b57480039a
--- /dev/null
+++ b/intern/ghost/intern/GHOST_PathUtils.cpp
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2010 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup GHOST
+ */
+
+#include <cassert>
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include "GHOST_PathUtils.h"
+#include "GHOST_Types.h"
+
+/* Based on: https://stackoverflow.com/a/2766963/432509 */
+
+using DecodeState_e = enum DecodeState_e {
+ /** Searching for an ampersand to convert. */
+ STATE_SEARCH = 0,
+ /** Convert the two proceeding characters from hex. */
+ STATE_CONVERTING
+};
+
+void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src)
+{
+ const unsigned int buf_src_len = strlen(buf_src);
+ DecodeState_e state = STATE_SEARCH;
+ unsigned int ascii_character;
+ char temp_num_buf[3] = {0};
+
+ memset(buf_dst, 0, buf_dst_size);
+
+ for (unsigned int i = 0; i < buf_src_len; i++) {
+ switch (state) {
+ case STATE_SEARCH: {
+ if (buf_src[i] != '%') {
+ strncat(buf_dst, &buf_src[i], 1);
+ assert((int)strlen(buf_dst) < buf_dst_size);
+ break;
+ }
+
+ /* We are now converting. */
+ state = STATE_CONVERTING;
+ break;
+ }
+ case STATE_CONVERTING: {
+ bool both_digits = true;
+
+ /* Create a buffer to hold the hex. For example, if `%20`,
+ * this buffer would hold 20 (in ASCII). */
+ memset(temp_num_buf, 0, sizeof(temp_num_buf));
+
+ /* Conversion complete (i.e. don't convert again next iteration). */
+ state = STATE_SEARCH;
+
+ strncpy(temp_num_buf, &buf_src[i], 2);
+
+ /* Ensure both characters are hexadecimal. */
+ for (int j = 0; j < 2; j++) {
+ if (!isxdigit(temp_num_buf[j])) {
+ both_digits = false;
+ }
+ }
+
+ if (!both_digits) {
+ break;
+ }
+ /* Convert two hexadecimal characters into one character. */
+ sscanf(temp_num_buf, "%x", &ascii_character);
+
+ /* Ensure we aren't going to overflow. */
+ assert((int)strlen(buf_dst) < buf_dst_size);
+
+ /* Concatenate this character onto the output. */
+ strncat(buf_dst, (char *)&ascii_character, 1);
+
+ /* Skip the next character. */
+ i++;
+ break;
+ }
+ }
+ }
+}
+
+char *GHOST_URL_decode_alloc(const char *buf_src)
+{
+ /* Assume one character of encoded URL can be expanded to 4 chars max. */
+ const size_t decoded_size_max = 4 * strlen(buf_src) + 1;
+ char *buf_dst = (char *)malloc(decoded_size_max);
+ GHOST_URL_decode(buf_dst, decoded_size_max, buf_src);
+ const size_t decoded_size = strlen(buf_dst) + 1;
+ if (decoded_size != decoded_size_max) {
+ char *buf_dst_trim = (char *)malloc(decoded_size);
+ memcpy(buf_dst_trim, buf_dst, decoded_size);
+ free(buf_dst);
+ buf_dst = buf_dst_trim;
+ }
+ return buf_dst;
+}
diff --git a/intern/ghost/intern/GHOST_PathUtils.h b/intern/ghost/intern/GHOST_PathUtils.h
new file mode 100644
index 00000000000..26a31d1f5c6
--- /dev/null
+++ b/intern/ghost/intern/GHOST_PathUtils.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2010 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup GHOST
+ */
+
+#pragma once
+
+/**
+ * Decode URL (i.e. converts `file:///a%20b/test` to `file:///a b/test`)
+ *
+ * \param buf_dst: Buffer for decoded URL.
+ * \param buf_dst_maxlen: Size of output buffer.
+ * \param buf_src: Input encoded buffer to be decoded.
+ */
+void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src);
+/**
+ * A version of #GHOST_URL_decode that allocates the string & returns it.
+ *
+ * \param buf_src: Input encoded buffer to be decoded.
+ * \return The decoded output buffer.
+ */
+char *GHOST_URL_decode_alloc(const char *buf_src);
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index ebb52bf08cb..18d91d43057 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -11,7 +11,9 @@
#include "GHOST_EventDragnDrop.h"
#include "GHOST_EventKey.h"
#include "GHOST_EventWheel.h"
+#include "GHOST_PathUtils.h"
#include "GHOST_TimerManager.h"
+#include "GHOST_WaylandUtils.h"
#include "GHOST_WindowManager.h"
#include "GHOST_utildefines.h"
@@ -82,6 +84,10 @@ static void output_handle_done(void *data, struct wl_output *wl_output);
static bool use_gnome_confine_hack = false;
#endif
+#define XKB_STATE_MODS_ALL \
+ (enum xkb_state_component)(XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED | \
+ XKB_STATE_MODS_LOCKED | XKB_STATE_MODS_EFFECTIVE)
+
/* -------------------------------------------------------------------- */
/** \name Inline Event Codes
*
@@ -306,6 +312,20 @@ struct input_t {
*/
struct xkb_state *xkb_state_empty_with_numlock = nullptr;
+ /**
+ * Cache result of `xkb_keymap_mod_get_index`
+ * so every time a modifier is accessed a string lookup isn't required.
+ * Be sure to check for #XKB_MOD_INVALID before using.
+ */
+ struct {
+ xkb_mod_index_t shift; /* #XKB_MOD_NAME_SHIFT */
+ xkb_mod_index_t caps; /* #XKB_MOD_NAME_CAPS */
+ xkb_mod_index_t ctrl; /* #XKB_MOD_NAME_CTRL */
+ xkb_mod_index_t alt; /* #XKB_MOD_NAME_ALT */
+ xkb_mod_index_t num; /* #XKB_MOD_NAME_NUM */
+ xkb_mod_index_t logo; /* #XKB_MOD_NAME_LOGO */
+ } xkb_keymap_mod_index;
+
struct {
/** Key repetition in character per second. */
int32_t rate = 0;
@@ -1138,6 +1158,7 @@ static void data_device_handle_enter(void *data,
input_t *input = static_cast<input_t *>(data);
std::lock_guard lock{input->data_offer_dnd_mutex};
+ delete input->data_offer_dnd;
input->data_offer_dnd = static_cast<data_offer_t *>(wl_data_offer_get_user_data(id));
data_offer_t *data_offer = input->data_offer_dnd;
@@ -1197,8 +1218,6 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
input_t *input = static_cast<input_t *>(data);
std::lock_guard lock{input->data_offer_dnd_mutex};
- CLOG_INFO(LOG, 2, "drop");
-
data_offer_t *data_offer = input->data_offer_dnd;
const std::string mime_receive = *std::find_first_of(mime_preference_order.begin(),
@@ -1206,6 +1225,8 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
data_offer->types.begin(),
data_offer->types.end());
+ CLOG_INFO(LOG, 2, "drop mime_recieve=%s", mime_receive.c_str());
+
auto read_uris_fn = [](input_t *const input,
data_offer_t *data_offer,
wl_surface *surface,
@@ -1214,9 +1235,15 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
const std::string data = read_pipe(data_offer, mime_receive, nullptr);
+ CLOG_INFO(
+ LOG, 2, "drop_read_uris mime_receive=%s, data=%s", mime_receive.c_str(), data.c_str());
+
wl_data_offer_finish(data_offer->id);
wl_data_offer_destroy(data_offer->id);
+ if (input->data_offer_dnd == data_offer) {
+ input->data_offer_dnd = nullptr;
+ }
delete data_offer;
data_offer = nullptr;
@@ -1224,7 +1251,9 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
if (mime_receive == mime_text_uri) {
static constexpr const char *file_proto = "file://";
- static constexpr const char *crlf = "\r\n";
+ /* NOTE: some applications CRLF (`\r\n`) GTK3 for e.g. & others don't `pcmanfm-qt`.
+ * So support both, once `\n` is found, strip the preceding `\r` if found. */
+ static constexpr const char *lf = "\n";
GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface);
std::vector<std::string> uris;
@@ -1233,13 +1262,18 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
while (true) {
pos = data.find(file_proto, pos);
const size_t start = pos + sizeof(file_proto) - 1;
- pos = data.find(crlf, pos);
- const size_t end = pos;
+ pos = data.find(lf, pos);
if (pos == std::string::npos) {
break;
}
+ /* Account for 'CRLF' case. */
+ size_t end = pos;
+ if (data[end - 1] == '\r') {
+ end -= 1;
+ }
uris.push_back(data.substr(start, end - start));
+ CLOG_INFO(LOG, 2, "drop_read_uris pos=%zu, text_uri=\"%s\"", start, uris.back().c_str());
}
GHOST_TStringArray *flist = static_cast<GHOST_TStringArray *>(
@@ -1247,10 +1281,10 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
flist->count = int(uris.size());
flist->strings = static_cast<uint8_t **>(malloc(uris.size() * sizeof(uint8_t *)));
for (size_t i = 0; i < uris.size(); i++) {
- flist->strings[i] = static_cast<uint8_t *>(malloc((uris[i].size() + 1) * sizeof(uint8_t)));
- memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1);
+ flist->strings[i] = (uint8_t *)GHOST_URL_decode_alloc(uris[i].c_str());
}
+ CLOG_INFO(LOG, 2, "drop_read_uris_fn file_count=%d", flist->count);
const wl_fixed_t scale = win->scale();
system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
GHOST_kEventDraggingDropDone,
@@ -1263,12 +1297,13 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
else if (ELEM(mime_receive, mime_text_plain, mime_text_utf8)) {
/* TODO: enable use of internal functions 'txt_insert_buf' and
* 'text_update_edited' to behave like dropped text was pasted. */
+ CLOG_INFO(LOG, 2, "drop_read_uris_fn (text_plain, text_utf8), unhandled!");
}
wl_display_roundtrip(system->display());
};
/* Pass in `input->focus_dnd` instead of accessing it from `input` since the leave callback
- * (#data_device_leave) will clear the value once this function starts. */
+ * (#data_device_handle_leave) will clear the value once this function starts. */
std::thread read_thread(read_uris_fn, input, data_offer, input->focus_dnd, mime_receive);
read_thread.detach();
}
@@ -2086,6 +2121,13 @@ static void keyboard_handle_keymap(void *data,
}
}
+ input->xkb_keymap_mod_index.shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
+ input->xkb_keymap_mod_index.caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
+ input->xkb_keymap_mod_index.ctrl = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
+ input->xkb_keymap_mod_index.alt = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT);
+ input->xkb_keymap_mod_index.num = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM);
+ input->xkb_keymap_mod_index.logo = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
+
xkb_keymap_unref(keymap);
}
@@ -2099,7 +2141,7 @@ static void keyboard_handle_enter(void *data,
struct wl_keyboard * /*wl_keyboard*/,
const uint32_t serial,
struct wl_surface *surface,
- struct wl_array * /*keys*/)
+ struct wl_array *keys)
{
if (!ghost_wl_surface_own(surface)) {
CLOG_INFO(LOG, 2, "enter (skipped)");
@@ -2110,6 +2152,49 @@ static void keyboard_handle_enter(void *data,
input_t *input = static_cast<input_t *>(data);
input->keyboard.serial = serial;
input->keyboard.wl_surface = surface;
+
+ if (keys->size != 0) {
+ /* If there are any keys held when activating the window,
+ * modifiers will be compared against the input state,
+ * only enabling modifiers that were previously disabled. */
+
+ const xkb_mod_mask_t state = xkb_state_serialize_mods(input->xkb_state, XKB_STATE_MODS_ALL);
+ uint32_t *key;
+ WL_ARRAY_FOR_EACH (key, keys) {
+ const xkb_keycode_t key_code = *key + EVDEV_OFFSET;
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(input->xkb_state, key_code);
+ GHOST_TKey gkey = GHOST_kKeyUnknown;
+
+#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod)))
+#define MOD_TEST_CASE(xkb_key, ghost_key, mod_index) \
+ case xkb_key: \
+ if (!MOD_TEST(state, input->xkb_keymap_mod_index.mod_index)) { \
+ gkey = ghost_key; \
+ } \
+ break
+
+ switch (sym) {
+ MOD_TEST_CASE(XKB_KEY_Shift_L, GHOST_kKeyLeftShift, shift);
+ MOD_TEST_CASE(XKB_KEY_Shift_R, GHOST_kKeyRightShift, shift);
+ MOD_TEST_CASE(XKB_KEY_Control_L, GHOST_kKeyLeftControl, ctrl);
+ MOD_TEST_CASE(XKB_KEY_Control_R, GHOST_kKeyRightControl, ctrl);
+ MOD_TEST_CASE(XKB_KEY_Alt_L, GHOST_kKeyLeftAlt, alt);
+ MOD_TEST_CASE(XKB_KEY_Alt_R, GHOST_kKeyRightAlt, alt);
+ MOD_TEST_CASE(XKB_KEY_Super_L, GHOST_kKeyOS, logo);
+ MOD_TEST_CASE(XKB_KEY_Super_R, GHOST_kKeyOS, logo);
+ }
+
+#undef MOD_TEST
+#undef MOD_TEST_CASE
+
+ if (gkey != GHOST_kKeyUnknown) {
+ GHOST_IWindow *win = ghost_wl_surface_user_data(surface);
+ GHOST_SystemWayland *system = input->system;
+ input->system->pushEvent(
+ new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyDown, win, gkey, false));
+ }
+ }
+ }
}
/**
@@ -2336,7 +2421,13 @@ static void keyboard_handle_modifiers(void *data,
const uint32_t mods_locked,
const uint32_t group)
{
- CLOG_INFO(LOG, 2, "modifiers");
+ CLOG_INFO(LOG,
+ 2,
+ "modifiers (depressed=%u, latched=%u, locked=%u, group=%u)",
+ mods_depressed,
+ mods_latched,
+ mods_locked,
+ group);
input_t *input = static_cast<input_t *>(data);
xkb_state_update_mask(input->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
@@ -2473,7 +2564,7 @@ static void xdg_output_handle_logical_size(void *data,
* done (we can't match exactly because fractional scaling can't be
* detected otherwise), then override if necessary. */
if ((output->size_logical[0] == width) && (output->scale_fractional == wl_fixed_from_int(1))) {
- GHOST_PRINT("xdg_output scale did not match, overriding with wl_output scale");
+ GHOST_PRINT("xdg_output scale did not match, overriding with wl_output scale\n");
#ifdef USE_GNOME_CONFINE_HACK
/* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue
@@ -2923,32 +3014,36 @@ GHOST_TSuccess GHOST_SystemWayland::getModifierKeys(GHOST_ModifierKeys &keys) co
return GHOST_kFailure;
}
- static const xkb_state_component mods_all = xkb_state_component(
- XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED | XKB_STATE_MODS_LOCKED |
- XKB_STATE_MODS_EFFECTIVE);
+ input_t *input = d->inputs[0];
bool val;
- /* NOTE: XKB doesn't seem to differentiate between left/right modifiers. */
+ /* NOTE: XKB doesn't differentiate between left/right modifiers
+ * for it's internal modifier state storage. */
+ const xkb_mod_mask_t state = xkb_state_serialize_mods(input->xkb_state, XKB_STATE_MODS_ALL);
+
+#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod)))
- val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_SHIFT, mods_all) == 1;
+ val = MOD_TEST(state, input->xkb_keymap_mod_index.shift);
keys.set(GHOST_kModifierKeyLeftShift, val);
keys.set(GHOST_kModifierKeyRightShift, val);
- val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_ALT, mods_all) == 1;
+ val = MOD_TEST(state, input->xkb_keymap_mod_index.alt);
keys.set(GHOST_kModifierKeyLeftAlt, val);
keys.set(GHOST_kModifierKeyRightAlt, val);
- val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_CTRL, mods_all) == 1;
+ val = MOD_TEST(state, input->xkb_keymap_mod_index.ctrl);
keys.set(GHOST_kModifierKeyLeftControl, val);
keys.set(GHOST_kModifierKeyRightControl, val);
- val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_LOGO, mods_all) == 1;
+ val = MOD_TEST(state, input->xkb_keymap_mod_index.logo);
keys.set(GHOST_kModifierKeyOS, val);
- val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_NUM, mods_all) == 1;
+ val = MOD_TEST(state, input->xkb_keymap_mod_index.num);
keys.set(GHOST_kModifierKeyNum, val);
+#undef MOD_TEST
+
return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 00cc5f3af8f..0494e462bfc 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -287,7 +287,7 @@ uint8_t GHOST_SystemX11::getNumDisplays() const
void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const
{
if (m_display) {
- /* NOTE(campbell): for this to work as documented,
+ /* NOTE(@campbellbarton): for this to work as documented,
* we would need to use Xinerama check r54370 for code that did this,
* we've since removed since its not worth the extra dependency. */
getAllDisplayDimensions(width, height);
@@ -514,8 +514,9 @@ static void destroyIMCallback(XIM /*xim*/, XPointer ptr, XPointer /*data*/)
bool GHOST_SystemX11::openX11_IM()
{
- if (!m_display)
+ if (!m_display) {
return false;
+ }
/* set locale modifiers such as `@im=ibus` specified by XMODIFIERS. */
XSetLocaleModifiers("");
@@ -585,7 +586,7 @@ struct init_timestamp_data {
Time timestamp;
};
-static Bool init_timestamp_scanner(Display *, XEvent *event, XPointer arg)
+static Bool init_timestamp_scanner(Display * /*display*/, XEvent *event, XPointer arg)
{
init_timestamp_data *data = reinterpret_cast<init_timestamp_data *>(arg);
switch (event->type) {
@@ -673,11 +674,12 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window);
if (window && !window->getX11_XIC() && window->createX11_XIC()) {
GHOST_PRINT("XIM input context created\n");
- if (xevent.type == KeyPress)
+ if (xevent.type == KeyPress) {
/* we can assume the window has input focus
* here, because key events are received only
* when the window is focused. */
XSetICFocus(window->getX11_XIC());
+ }
}
}
}
@@ -1321,10 +1323,12 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
XIC xic = window->getX11_XIC();
if (xic) {
- if (xe->type == FocusIn)
+ if (xe->type == FocusIn) {
XSetICFocus(xic);
- else
+ }
+ else {
XUnsetICFocus(xic);
+ }
}
#endif
@@ -2381,10 +2385,11 @@ class DialogData {
/* Is the mouse inside the given button */
bool isInsideButton(XEvent &e, uint button_num)
{
- return ((e.xmotion.y > height - padding_y - button_height) &&
- (e.xmotion.y < height - padding_y) &&
- (e.xmotion.x > width - (padding_x + button_width) * button_num) &&
- (e.xmotion.x < width - padding_x - (padding_x + button_width) * (button_num - 1)));
+ return (
+ (e.xmotion.y > (int)(height - padding_y - button_height)) &&
+ (e.xmotion.y < (int)(height - padding_y)) &&
+ (e.xmotion.x > (int)(width - (padding_x + button_width) * button_num)) &&
+ (e.xmotion.x < (int)(width - padding_x - (padding_x + button_width) * (button_num - 1))));
}
};
diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp
index 504cdbfb6c8..e54c2515029 100644
--- a/intern/ghost/intern/GHOST_TimerManager.cpp
+++ b/intern/ghost/intern/GHOST_TimerManager.cpp
@@ -71,10 +71,11 @@ uint64_t GHOST_TimerManager::nextFireTime()
TTimerVector::iterator iter;
for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) {
- uint64_t next = (*iter)->getNext();
+ const uint64_t next = (*iter)->getNext();
- if (next < smallest)
+ if (next < smallest) {
smallest = next;
+ }
}
return smallest;
@@ -86,8 +87,9 @@ bool GHOST_TimerManager::fireTimers(uint64_t time)
bool anyProcessed = false;
for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) {
- if (fireTimer(time, *iter))
+ if (fireTimer(time, *iter)) {
anyProcessed = true;
+ }
}
return anyProcessed;
@@ -113,9 +115,7 @@ bool GHOST_TimerManager::fireTimer(uint64_t time, GHOST_TimerTask *task)
return true;
}
- else {
- return false;
- }
+ return false;
}
void GHOST_TimerManager::disposeTimers()
diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h
index 090a84d1f14..4458a107190 100644
--- a/intern/ghost/intern/GHOST_TimerManager.h
+++ b/intern/ghost/intern/GHOST_TimerManager.h
@@ -87,7 +87,7 @@ class GHOST_TimerManager {
*/
void disposeTimers();
- typedef std::vector<GHOST_TimerTask *> TTimerVector;
+ using TTimerVector = std::vector<GHOST_TimerTask *>;
/** The list with event consumers. */
TTimerVector m_timers;
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 2276e90387b..83c608435b0 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -147,16 +147,19 @@ static XVisualInfo *x11_visualinfo_from_glx(Display *display,
/* take a frame buffer config that has alpha cap */
for (int i = 0; i < nbfbconfig; i++) {
XVisualInfo *visual = (XVisualInfo *)glXGetVisualFromFBConfig(display, fbconfigs[i]);
- if (!visual)
+ if (!visual) {
continue;
+ }
/* if we don't need a alpha background, the first config will do, otherwise
* test the alphaMask as it won't necessarily be present */
if (needAlpha) {
XRenderPictFormat *pict_format = XRenderFindVisualFormat(display, visual->visual);
- if (!pict_format)
+ if (!pict_format) {
continue;
- if (pict_format->direct.alphaMask <= 0)
+ }
+ if (pict_format->direct.alphaMask <= 0) {
continue;
+ }
}
*fbconfig = fbconfigs[i];
@@ -487,8 +490,9 @@ static Bool destroyICCallback(XIC /*xic*/, XPointer ptr, XPointer /*data*/)
bool GHOST_WindowX11::createX11_XIC()
{
XIM xim = m_system->getX11_XIM();
- if (!xim)
+ if (!xim) {
return false;
+ }
XICCallback destroy;
destroy.callback = (XICProc)destroyICCallback;
@@ -536,17 +540,21 @@ void GHOST_WindowX11::refreshXInputDevices()
XEventClass ev;
DeviceMotionNotify(xtablet.Device, xtablet.MotionEvent, ev);
- if (ev)
+ if (ev) {
xevents.push_back(ev);
+ }
DeviceButtonPress(xtablet.Device, xtablet.PressEvent, ev);
- if (ev)
+ if (ev) {
xevents.push_back(ev);
+ }
ProximityIn(xtablet.Device, xtablet.ProxInEvent, ev);
- if (ev)
+ if (ev) {
xevents.push_back(ev);
+ }
ProximityOut(xtablet.Device, xtablet.ProxOutEvent, ev);
- if (ev)
+ if (ev) {
xevents.push_back(ev);
+ }
}
XSelectExtensionEvent(m_display, m_window, xevents.data(), (int)xevents.size());
diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp
index 5a43543d163..f5ef2527d75 100644
--- a/intern/ghost/test/gears/GHOST_Test.cpp
+++ b/intern/ghost/test/gears/GHOST_Test.cpp
@@ -559,10 +559,12 @@ bool Application::processEvent(GHOST_IEvent *event)
break;
case GHOST_kKeyS: // toggle mono and stereo
- if (stereo)
+ if (stereo) {
stereo = false;
- else
+ }
+ else {
stereo = true;
+ }
break;
case GHOST_kKeyT:
@@ -680,8 +682,9 @@ int main(int /*argc*/, char ** /*argv*/)
if (lresult == ERROR_SUCCESS)
printf("Successfully set value for key\n");
regkey.Close();
- if (lresult == ERROR_SUCCESS)
+ if (lresult == ERROR_SUCCESS) {
printf("Successfully closed key\n");
+ }
// regkey.Write("2");
}
#endif // WIN32
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
index 157e4f1b0f2..99b88dfb525 100644
--- a/intern/ghost/test/multitest/MultiTest.c
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -179,37 +179,44 @@ static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press)
{
switch (key) {
case GHOST_kKeyC:
- if (press)
+ if (press) {
GHOST_SetCursorShape(mw->win,
(GHOST_TStandardCursor)(rand() % (GHOST_kStandardCursorNumCursors)));
+ }
break;
case GHOST_kKeyLeftBracket:
- if (press)
+ if (press) {
GHOST_SetCursorVisibility(mw->win, 0);
+ }
break;
case GHOST_kKeyRightBracket:
- if (press)
+ if (press) {
GHOST_SetCursorVisibility(mw->win, 1);
+ }
break;
case GHOST_kKeyE:
- if (press)
+ if (press) {
multitestapp_toggle_extra_window(mw->app);
+ }
break;
case GHOST_kKeyQ:
- if (press)
+ if (press) {
multitestapp_exit(mw->app);
+ }
break;
case GHOST_kKeyT:
- if (press)
+ if (press) {
mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/");
+ }
break;
case GHOST_kKeyR:
if (press) {
int i;
mainwindow_log(mw, "Invalidating window 10 times");
- for (i = 0; i < 10; i++)
+ for (i = 0; i < 10; i++) {
GHOST_InvalidateWindow(mw->win);
+ }
}
break;
case GHOST_kKeyF11:
@@ -328,9 +335,7 @@ MainWindow *mainwindow_new(MultiTestApp *app)
return mw;
}
- else {
- return NULL;
- }
+ return NULL;
}
void mainwindow_free(MainWindow *mw)
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index fca19fb9731..64987548a11 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -199,6 +199,15 @@ extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
#ifndef NDEBUG
extern const char *(*MEM_name_ptr)(void *vmemh);
+/**
+ * Change the debugging name/string assigned to the memory allocated at \a vmemh. Only affects the
+ * guarded allocator. The name must be a static string, because only a pointer to it is stored!
+ *
+ * Handy when debugging leaking memory allocated by some often called, generic function with a
+ * unspecific name. A caller with more info can set a more specific name, and see which call to the
+ * generic function allocates the leaking memory.
+ */
+extern void (*MEM_name_ptr_set)(void *vmemh, const char *str) ATTR_NONNULL();
#endif
/**
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index f7979168799..63f06ced31d 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -49,6 +49,7 @@ size_t (*MEM_get_peak_memory)(void) = MEM_lockfree_get_peak_memory;
#ifndef NDEBUG
const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr;
+void (*MEM_name_ptr_set)(void *vmemh, const char *str) = MEM_lockfree_name_ptr_set;
#endif
void *aligned_malloc(size_t size, size_t alignment)
@@ -128,6 +129,7 @@ void MEM_use_lockfree_allocator(void)
#ifndef NDEBUG
MEM_name_ptr = MEM_lockfree_name_ptr;
+ MEM_name_ptr_set = MEM_lockfree_name_ptr_set;
#endif
}
@@ -159,5 +161,6 @@ void MEM_use_guarded_allocator(void)
#ifndef NDEBUG
MEM_name_ptr = MEM_guarded_name_ptr;
+ MEM_name_ptr_set = MEM_guarded_name_ptr_set;
#endif
}
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index 8bf1680e6f8..cd4b99ecde8 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -1199,4 +1199,18 @@ const char *MEM_guarded_name_ptr(void *vmemh)
return "MEM_guarded_name_ptr(NULL)";
}
+
+void MEM_guarded_name_ptr_set(void *vmemh, const char *str)
+{
+ if (!vmemh) {
+ return;
+ }
+
+ MemHead *memh = vmemh;
+ memh--;
+ memh->name = str;
+ if (memh->prev) {
+ MEMNEXT(memh->prev)->nextname = str;
+ }
+}
#endif /* NDEBUG */
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
index f8b16ff6ddf..ce5683a04ae 100644
--- a/intern/guardedalloc/intern/mallocn_intern.h
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -131,6 +131,7 @@ void MEM_lockfree_reset_peak_memory(void);
size_t MEM_lockfree_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
#ifndef NDEBUG
const char *MEM_lockfree_name_ptr(void *vmemh);
+void MEM_lockfree_name_ptr_set(void *vmemh, const char *str);
#endif
/* Prototypes for fully guarded allocator functions */
@@ -174,6 +175,7 @@ void MEM_guarded_reset_peak_memory(void);
size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
#ifndef NDEBUG
const char *MEM_guarded_name_ptr(void *vmemh);
+void MEM_guarded_name_ptr_set(void *vmemh, const char *str);
#endif
#ifdef __cplusplus
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index 300e2000a14..b5ee539ff4d 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -426,4 +426,8 @@ const char *MEM_lockfree_name_ptr(void *vmemh)
return "MEM_lockfree_name_ptr(NULL)";
}
+
+void MEM_lockfree_name_ptr_set(void *UNUSED(vmemh), const char *UNUSED(str))
+{
+}
#endif /* NDEBUG */
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index fc14c909f4d..f5f22dc700b 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -626,7 +626,7 @@ static void manta_python_main_module_restore(PyObject *main_mod)
* access these variables, the same __main__ module has to be used every time.
*
* Unfortunately, we also depend on the fact that mantaflow dumps variables into this module using
- * PyRun_SimpleString. So we can't easily create a separate module without changing mantaflow.
+ * #PyRun_String. So we can't easily create a separate module without changing mantaflow.
*/
static PyObject *manta_main_module = nullptr;
@@ -1161,7 +1161,7 @@ string MANTA::parseScript(const string &setup_string, FluidModifierData *fmd)
return res.str();
}
-/* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */
+/** Dirty hack: Needed to format paths from python code that is run via #PyRun_String. */
static string escapePath(string const &s)
{
string result = "";