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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h37
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h5
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse_ramp.h6
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h4
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h12
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h10
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h16
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_volume.h1
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h10
-rw-r--r--intern/cycles/kernel/geom/geom_volume.h12
-rw-r--r--intern/cycles/kernel/kernel_bake.h8
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h105
-rw-r--r--intern/cycles/kernel/kernel_light.h196
-rw-r--r--intern/cycles/kernel/kernel_path_surface.h9
-rw-r--r--intern/cycles/kernel/kernel_path_volume.h20
-rw-r--r--intern/cycles/kernel/kernel_shader.h2
-rw-r--r--intern/cycles/kernel/kernel_types.h150
-rw-r--r--intern/cycles/kernel/kernel_volume.h61
-rw-r--r--intern/cycles/kernel/osl/SConscript11
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp6
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp53
-rw-r--r--intern/cycles/kernel/osl/osl_services.h88
-rw-r--r--intern/cycles/kernel/shaders/node_combine_hsv.osl3
-rw-r--r--intern/cycles/kernel/shaders/node_hsv.osl5
-rw-r--r--intern/cycles/kernel/shaders/node_normal.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_separate_hsv.osl2
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h41
-rw-r--r--intern/cycles/kernel/svm/svm.h1
-rw-r--r--intern/cycles/kernel/svm/svm_hsv.h5
-rw-r--r--intern/cycles/kernel/svm/svm_math.h50
-rw-r--r--intern/cycles/kernel/svm/svm_math_util.h70
-rw-r--r--intern/cycles/kernel/svm/svm_sepcomb_hsv.h5
33 files changed, 662 insertions, 345 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index c521e1383a4..0ff227938ae 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -91,6 +91,7 @@ set(SRC_SVM_HEADERS
svm/svm_magic.h
svm/svm_mapping.h
svm/svm_math.h
+ svm/svm_math_util.h
svm/svm_mix.h
svm/svm_musgrave.h
svm/svm_noise.h
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index ad7864cb8ea..b94bdeeb23f 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2013 Blender Foundation
+ * Copyright 2011-2014 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,24 +33,20 @@ CCL_NAMESPACE_BEGIN
ccl_device int bsdf_ashikhmin_shirley_setup(ShaderClosure *sc)
{
- /* store roughness. could already convert to exponent to save some cycles
- * in eval, but this is more consistent with other bsdfs and shader_blur. */
sc->data0 = clamp(sc->data0, 1e-4f, 1.0f);
sc->data1 = sc->data0;
sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_ashikhmin_shirley_aniso_setup(ShaderClosure *sc)
{
- /* store roughness. could already convert to exponent to save some cycles
- * in eval, but this is more consistent with other bsdfs and shader_blur. */
sc->data0 = clamp(sc->data0, 1e-4f, 1.0f);
sc->data1 = clamp(sc->data1, 1e-4f, 1.0f);
sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_ashikhmin_shirley_blur(ShaderClosure *sc, float roughness)
@@ -73,7 +69,7 @@ ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, c
float out = 0.0f;
- if (NdotI > 0.0f && NdotO > 0.0f) {
+ if(NdotI > 0.0f && NdotO > 0.0f) {
NdotI = fmaxf(NdotI, 1e-6f);
NdotO = fmaxf(NdotO, 1e-6f);
float3 H = normalize(omega_in + I);
@@ -86,7 +82,8 @@ ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, c
float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0);
float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1);
- if (n_x == n_y) { /* => isotropic case */
+ if(n_x == n_y) {
+ /* isotropic */
float e = n_x;
float lobe = powf(HdotN, e);
float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
@@ -94,7 +91,8 @@ ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, c
out = NdotO * norm * lobe * pump;
*pdf = norm * lobe / HdotI; /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper) */
}
- else { /* => ANisotropic case */
+ else {
+ /* anisotropic */
float3 X, Y;
make_orthonormals_tangent(N, sc->T, &X, &Y);
@@ -130,7 +128,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
float3 N = sc->N;
float NdotI = dot(N, I);
- if (NdotI > 0.0f) {
+ if(NdotI > 0.0f) {
float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0);
float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1);
@@ -146,21 +144,23 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
/* sample spherical coords for h in tangent space */
float phi;
float cos_theta;
- if (n_x == n_y) { /* => simple isotropic sampling */
+ if(n_x == n_y) {
+ /* isotropic sampling */
phi = M_2PI_F * randu;
cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
}
- else { /* => more complex anisotropic sampling */
- if (randu < 0.25f) { /* first quadrant */
+ else {
+ /* anisotropic sampling */
+ if(randu < 0.25f) { /* first quadrant */
float remapped_randu = 4.0f * randu;
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
}
- else if (randu < 0.5f) { /* second quadrant */
+ else if(randu < 0.5f) { /* second quadrant */
float remapped_randu = 4.0f * (.5f - randu);
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
phi = M_PI_F - phi;
}
- else if (randu < 0.75f) { /* third quadrant */
+ else if(randu < 0.75f) { /* third quadrant */
float remapped_randu = 4.0f * (randu - 0.5f);
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
phi = M_PI_F + phi;
@@ -185,13 +185,12 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
/* half vector to world space */
float3 H = h.x*X + h.y*Y + h.z*N;
float HdotI = dot(H, I);
- if (HdotI < 0.0f) H = -H;
+ if(HdotI < 0.0f) H = -H;
/* reflect I on H to get omega_in */
*omega_in = -I + (2.0f * HdotI) * H;
/* leave the rest to eval_reflect */
- /* (could maybe optimize a few things by manual inlining, but I doubt it would make much difference) */
*eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf);
#ifdef __RAY_DIFFERENTIALS__
@@ -201,7 +200,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
#endif
}
- return LABEL_REFLECT | LABEL_GLOSSY;
+ return LABEL_REFLECT|LABEL_GLOSSY;
}
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index 949fe869549..371f467000c 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -108,11 +108,6 @@ ccl_device float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc, const
return make_float3 (cos_pi, cos_pi, cos_pi);
}
-ccl_device float bsdf_translucent_albedo(const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
ccl_device int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float3 N = sc->N;
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
index b856774375f..cdaf84f1750 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -41,9 +41,9 @@ ccl_device float3 bsdf_diffuse_ramp_get_color(const ShaderClosure *sc, const flo
float npos = pos * (float)(MAXCOLORS - 1);
int ipos = float_to_int(npos);
- if (ipos < 0)
+ if(ipos < 0)
return colors[0];
- if (ipos >= (MAXCOLORS - 1))
+ if(ipos >= (MAXCOLORS - 1))
return colors[MAXCOLORS - 1];
float offset = npos - (float)ipos;
return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
@@ -52,7 +52,7 @@ ccl_device float3 bsdf_diffuse_ramp_get_color(const ShaderClosure *sc, const flo
ccl_device int bsdf_diffuse_ramp_setup(ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_DIFFUSE_RAMP_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_diffuse_ramp_blur(ShaderClosure *sc, float roughness)
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index e0b5454592b..4f4fd5d26b8 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -49,7 +49,7 @@ ccl_device int bsdf_hair_reflection_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_HAIR_REFLECTION_ID;
sc->data0 = clamp(sc->data0, 0.001f, 1.0f);
sc->data1 = clamp(sc->data1, 0.001f, 1.0f);
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_hair_transmission_setup(ShaderClosure *sc)
@@ -57,7 +57,7 @@ ccl_device int bsdf_hair_transmission_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
sc->data0 = clamp(sc->data0, 0.001f, 1.0f);
sc->data1 = clamp(sc->data1, 0.001f, 1.0f);
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 8737b0e2d94..9561885525f 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -305,7 +305,7 @@ ccl_device int bsdf_microfacet_ggx_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_aniso_setup(ShaderClosure *sc)
@@ -315,7 +315,7 @@ ccl_device int bsdf_microfacet_ggx_aniso_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc)
@@ -325,7 +325,7 @@ ccl_device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness)
@@ -657,7 +657,7 @@ ccl_device int bsdf_microfacet_beckmann_setup(ShaderClosure *sc)
sc->data1 = sc->data0; /* alpha_y */
sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_beckmann_aniso_setup(ShaderClosure *sc)
@@ -666,7 +666,7 @@ ccl_device int bsdf_microfacet_beckmann_aniso_setup(ShaderClosure *sc)
sc->data1 = clamp(sc->data1, 0.0f, 1.0f); /* alpha_y */
sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc)
@@ -675,7 +675,7 @@ ccl_device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc)
sc->data1 = sc->data0; /* alpha_y */
sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness)
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index 6f685d5eeea..6d3b915c24a 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -25,7 +25,7 @@ ccl_device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3
float nv = max(dot(n, v), 0.0f);
float t = dot(l, v) - nl * nv;
- if (t > 0.0f)
+ if(t > 0.0f)
t /= max(nl, nv) + FLT_MIN;
float is = nl * (sc->data0 + sc->data1 * t);
return make_float3(is, is, is);
@@ -44,7 +44,7 @@ ccl_device int bsdf_oren_nayar_setup(ShaderClosure *sc)
sc->data0 = 1.0f * div;
sc->data1 = sigma * div;
- return SD_BSDF | SD_BSDF_HAS_EVAL;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_oren_nayar_blur(ShaderClosure *sc, float roughness)
@@ -53,7 +53,7 @@ ccl_device void bsdf_oren_nayar_blur(ShaderClosure *sc, float roughness)
ccl_device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- if (dot(sc->N, omega_in) > 0.0f) {
+ if(dot(sc->N, omega_in) > 0.0f) {
*pdf = 0.5f * M_1_PI_F;
return bsdf_oren_nayar_get_intensity(sc, sc->N, I, omega_in);
}
@@ -72,7 +72,7 @@ ccl_device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3
{
sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf);
- if (dot(Ng, *omega_in) > 0.0f) {
+ if(dot(Ng, *omega_in) > 0.0f) {
*eval = bsdf_oren_nayar_get_intensity(sc, sc->N, I, *omega_in);
#ifdef __RAY_DIFFERENTIALS__
@@ -86,7 +86,7 @@ ccl_device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3
*eval = make_float3(0.0f, 0.0f, 0.0f);
}
- return LABEL_REFLECT | LABEL_DIFFUSE;
+ 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 2b4e1c68640..f9f263719e9 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -41,9 +41,9 @@ ccl_device float3 bsdf_phong_ramp_get_color(const ShaderClosure *sc, const float
float npos = pos * (float)(MAXCOLORS - 1);
int ipos = float_to_int(npos);
- if (ipos < 0)
+ if(ipos < 0)
return colors[0];
- if (ipos >= (MAXCOLORS - 1))
+ if(ipos >= (MAXCOLORS - 1))
return colors[MAXCOLORS - 1];
float offset = npos - (float)ipos;
return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
@@ -54,7 +54,7 @@ ccl_device int bsdf_phong_ramp_setup(ShaderClosure *sc)
sc->data0 = max(sc->data0, 0.0f);
sc->type = CLOSURE_BSDF_PHONG_RAMP_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_phong_ramp_blur(ShaderClosure *sc, float roughness)
@@ -67,11 +67,11 @@ ccl_device float3 bsdf_phong_ramp_eval_reflect(const ShaderClosure *sc, const fl
float cosNI = dot(sc->N, omega_in);
float cosNO = dot(sc->N, I);
- if (cosNI > 0 && cosNO > 0) {
+ if(cosNI > 0 && cosNO > 0) {
// reflect the view vector
float3 R = (2 * cosNO) * sc->N - I;
float cosRI = dot(R, omega_in);
- if (cosRI > 0) {
+ if(cosRI > 0) {
float cosp = powf(cosRI, m_exponent);
float common = 0.5f * M_1_PI_F * cosp;
float out = cosNI * (m_exponent + 2) * common;
@@ -93,7 +93,7 @@ ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colo
float cosNO = dot(sc->N, I);
float m_exponent = sc->data0;
- if (cosNO > 0) {
+ if(cosNO > 0) {
// reflect the view vector
float3 R = (2 * cosNO) * sc->N - I;
@@ -111,12 +111,12 @@ ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colo
*omega_in = (cosf(phi) * sinTheta) * T +
(sinf(phi) * sinTheta) * B +
( cosTheta) * R;
- if (dot(Ng, *omega_in) > 0.0f)
+ if(dot(Ng, *omega_in) > 0.0f)
{
// common terms for pdf and eval
float cosNI = dot(sc->N, *omega_in);
// make sure the direction we chose is still in the right hemisphere
- if (cosNI > 0)
+ if(cosNI > 0)
{
float cosp = powf(cosTheta, m_exponent);
float common = 0.5f * M_1_PI_F * cosp;
diff --git a/intern/cycles/kernel/geom/geom_bvh_volume.h b/intern/cycles/kernel/geom/geom_bvh_volume.h
index 9dd8d226f5b..16c16beee39 100644
--- a/intern/cycles/kernel/geom/geom_bvh_volume.h
+++ b/intern/cycles/kernel/geom/geom_bvh_volume.h
@@ -277,6 +277,7 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
}
else {
/* pop */
+ object = OBJECT_NONE;
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index 5df6c75df86..207d5066fb2 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -144,7 +144,8 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
float3 center;
#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_CURVE) {
+ bool is_curve_primitive = sd->type & PRIMITIVE_ALL_CURVE;
+ if(is_curve_primitive) {
center = curve_motion_center_location(kg, sd);
if(!(sd->flag & SD_TRANSFORM_APPLIED))
@@ -170,6 +171,13 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
motion_pre = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
motion_post = primitive_attribute_float3(kg, sd, elem, offset_next, NULL, NULL);
+
+#ifdef __HAIR__
+ if(is_curve_primitive && (sd->flag & SD_OBJECT_HAS_VERTEX_MOTION) == 0) {
+ object_position_transform(kg, sd, &motion_pre);
+ object_position_transform(kg, sd, &motion_post);
+ }
+#endif
}
/* object motion. note that depending on the mesh having motion vectors, this
diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h
index 33a20494966..3cb6d168f80 100644
--- a/intern/cycles/kernel/geom/geom_volume.h
+++ b/intern/cycles/kernel/geom/geom_volume.h
@@ -52,7 +52,11 @@ ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd,
#ifdef __KERNEL_GPU__
float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
#else
- float4 r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
+ float4 r;
+ if(sd->flag & SD_VOLUME_CUBIC)
+ r = kernel_tex_image_interp_3d_ex(id, P.x, P.y, P.z, INTERPOLATION_CUBIC);
+ else
+ r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
#endif
if(dx) *dx = 0.0f;
@@ -68,7 +72,11 @@ ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *s
#ifdef __KERNEL_GPU__
float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
#else
- float4 r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
+ float4 r;
+ if(sd->flag & SD_VOLUME_CUBIC)
+ r = kernel_tex_image_interp_3d_ex(id, P.x, P.y, P.z, INTERPOLATION_CUBIC);
+ else
+ r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
#endif
if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index a1ec080e3d3..e80bfb32e89 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -198,10 +198,10 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
int num_samples = kernel_data.integrator.aa_samples;
/* random number generator */
- RNG rng = cmj_hash(offset + i, 0);
+ RNG rng = cmj_hash(offset + i, kernel_data.integrator.seed);
#if 0
- uint rng_state = cmj_hash(i, 0);
+ uint rng_state = cmj_hash(i, kernel_data.integrator.seed);
float filter_x, filter_y;
path_rng_init(kg, &rng_state, sample, num_samples, &rng, 0, 0, &filter_x, &filter_y);
@@ -253,6 +253,10 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
/* data passes */
case SHADER_EVAL_NORMAL:
{
+ if ((sd.flag & SD_HAS_BUMP)) {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ }
+
/* compression: normal = (2 * color) - 1 */
out = sd.N * 0.5f + make_float3(0.5f, 0.5f, 0.5f);
break;
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index 403fd0a67f7..08c8bdd369d 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -25,10 +25,12 @@
#include "util_half.h"
#include "util_types.h"
-/* On 64bit linux single precision exponent is really slow comparing to the
- * double precision version, even with float<->double conversion involved.
+/* On x86_64, versions of glibc < 2.16 have an issue where expf is
+ * much slower than the double version. This was fixed in glibc 2.16.
*/
-#if !defined(__KERNEL_GPU__) && defined(__linux__) && defined(__x86_64__)
+#if !defined(__KERNEL_GPU__) && defined(__x86_64__) && defined(__x86_64__) && \
+ defined(__GNU_LIBRARY__) && defined(__GLIBC__ ) && defined(__GLIBC_MINOR__) && \
+ (__GLIBC__ <= 2 && __GLIBC_MINOR__ < 16)
# define expf(x) ((float)exp((double)(x)))
#endif
@@ -151,6 +153,13 @@ template<typename T> struct texture_image {
ccl_always_inline float4 interp_3d(float x, float y, float z, bool periodic = false)
{
+ return interp_3d_ex(x, y, z, interpolation, periodic);
+ }
+
+ ccl_always_inline float4 interp_3d_ex(float x, float y, float z,
+ int interpolation = INTERPOLATION_LINEAR,
+ bool periodic = false)
+ {
if(UNLIKELY(!data))
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
@@ -174,7 +183,7 @@ template<typename T> struct texture_image {
return read(data[ix + iy*width + iz*width*height]);
}
- else {
+ else if(interpolation == INTERPOLATION_LINEAR) {
float tx = frac(x*(float)width - 0.5f, &ix);
float ty = frac(y*(float)height - 0.5f, &iy);
float tz = frac(z*(float)depth - 0.5f, &iz);
@@ -212,6 +221,93 @@ template<typename T> struct texture_image {
return r;
}
+ else {
+ /* Tricubic b-spline interpolation. */
+ const float tx = frac(x*(float)width - 0.5f, &ix);
+ const float ty = frac(y*(float)height - 0.5f, &iy);
+ const float tz = frac(z*(float)depth - 0.5f, &iz);
+ int pix, piy, piz, nnix, nniy, nniz;
+
+ if(periodic) {
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ iz = wrap_periodic(iz, depth);
+
+ pix = wrap_periodic(ix-1, width);
+ piy = wrap_periodic(iy-1, height);
+ piz = wrap_periodic(iz-1, depth);
+
+ nix = wrap_periodic(ix+1, width);
+ niy = wrap_periodic(iy+1, height);
+ niz = wrap_periodic(iz+1, depth);
+
+ nnix = wrap_periodic(ix+2, width);
+ nniy = wrap_periodic(iy+2, height);
+ nniz = wrap_periodic(iz+2, depth);
+ }
+ else {
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ iz = wrap_clamp(iz, depth);
+
+ pix = wrap_clamp(ix-1, width);
+ piy = wrap_clamp(iy-1, height);
+ piz = wrap_clamp(iz-1, depth);
+
+ nix = wrap_clamp(ix+1, width);
+ niy = wrap_clamp(iy+1, height);
+ niz = wrap_clamp(iz+1, depth);
+
+ nnix = wrap_clamp(ix+2, width);
+ nniy = wrap_clamp(iy+2, height);
+ nniz = wrap_clamp(iz+2, depth);
+ }
+
+ const int xc[4] = {pix, ix, nix, nnix};
+ const int yc[4] = {width * piy,
+ width * iy,
+ width * niy,
+ width * nniy};
+ const int zc[4] = {width * height * piz,
+ width * height * iz,
+ width * height * niz,
+ width * height * nniz};
+ float u[4], v[4], w[4];
+
+ /* Some helper macro to keep code reasonable size,
+ * let compiler to inline all the matrix multiplications.
+ */
+#define SET_SPLINE_WEIGHTS(u, t) \
+ { \
+ u[0] = (((-1.0f/6.0f)* t + 0.5f) * t - 0.5f) * t + (1.0f/6.0f); \
+ u[1] = (( 0.5f * t - 1.0f) * t ) * t + (2.0f/3.0f); \
+ u[2] = (( -0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f/6.0f); \
+ u[3] = (1.0f / 6.0f) * t * t * t; \
+ } (void)0
+#define DATA(x, y, z) (read(data[xc[x] + yc[y] + zc[z]]))
+#define COL_TERM(col, row) \
+ (v[col] * (u[0] * DATA(0, col, row) + \
+ u[1] * DATA(1, col, row) + \
+ u[2] * DATA(2, col, row) + \
+ u[3] * DATA(3, col, row)))
+#define ROW_TERM(row) \
+ (w[row] * (COL_TERM(0, row) + \
+ COL_TERM(1, row) + \
+ COL_TERM(2, row) + \
+ COL_TERM(3, row)))
+
+ SET_SPLINE_WEIGHTS(u, tx);
+ SET_SPLINE_WEIGHTS(v, ty);
+ SET_SPLINE_WEIGHTS(w, tz);
+
+ /* Actual interpolation. */
+ return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
+
+#undef COL_TERM
+#undef ROW_TERM
+#undef DATA
+#undef SET_SPLINE_WEIGHTS
+ }
}
ccl_always_inline void dimensions_set(int width_, int height_, int depth_)
@@ -244,6 +340,7 @@ typedef texture_image<uchar4> texture_image_uchar4;
#define kernel_tex_lookup(tex, t, offset, size) (kg->tex.lookup(t, offset, size))
#define kernel_tex_image_interp(tex, x, y) ((tex < MAX_FLOAT_IMAGES) ? kg->texture_float_images[tex].interp(x, y) : kg->texture_byte_images[tex - MAX_FLOAT_IMAGES].interp(x, y))
#define kernel_tex_image_interp_3d(tex, x, y, z) ((tex < MAX_FLOAT_IMAGES) ? kg->texture_float_images[tex].interp_3d(x, y, z) : kg->texture_byte_images[tex - MAX_FLOAT_IMAGES].interp_3d(x, y, z))
+#define kernel_tex_image_interp_3d_ex(tex, x, y, z, interpolation) ((tex < MAX_FLOAT_IMAGES) ? kg->texture_float_images[tex].interp_3d_ex(x, y, z, interpolation) : kg->texture_byte_images[tex - MAX_FLOAT_IMAGES].interp_3d_ex(x, y, z, interpolation))
#define kernel_data (kg->__data)
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index e7f62f230f8..9dfbfd91881 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -167,12 +167,143 @@ ccl_device float3 sphere_light_sample(float3 P, float3 center, float radius, flo
return disk_light_sample(normalize(P - center), randu, randv)*radius;
}
-ccl_device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
+/* Uses the following paper:
+ *
+ * Carlos Urena et al.
+ * An Area-Preserving Parametrization for Spherical Rectangles.
+ *
+ * https://www.solidangle.com/research/egsr2013_spherical_rectangle.pdf
+ */
+ccl_device float3 area_light_sample(float3 P,
+ float3 light_p,
+ float3 axisu, float3 axisv,
+ float randu, float randv,
+ float *pdf)
{
- randu = randu - 0.5f;
- randv = randv - 0.5f;
+ /* In our name system we're using P for the center,
+ * which is o in the paper.
+ */
+
+ float3 corner = light_p - axisu * 0.5f - axisv * 0.5f;
+ float axisu_len, axisv_len;
+ /* Compute local reference system R. */
+ float3 x = normalize_len(axisu, &axisu_len);
+ float3 y = normalize_len(axisv, &axisv_len);
+ float3 z = cross(x, y);
+ /* Compute rectangle coords in local reference system. */
+ float3 dir = corner - P;
+ float z0 = dot(dir, z);
+ /* Flip 'z' to make it point against Q. */
+ if(z0 > 0.0f) {
+ z *= -1.0f;
+ z0 *= -1.0f;
+ }
+ float z0sq = z0 * z0;
+ float x0 = dot(dir, x);
+ float y0 = dot(dir, y);
+ float x1 = x0 + axisu_len;
+ float y1 = y0 + axisv_len;
+ float y0sq = y0 * y0;
+ float y1sq = y1 * y1;
+ /* Create vectors to four vertices. */
+ float3 v00 = make_float3(x0, y0, z0);
+ float3 v01 = make_float3(x0, y1, z0);
+ float3 v10 = make_float3(x1, y0, z0);
+ float3 v11 = make_float3(x1, y1, z0);
+ /* Compute normals to edges. */
+ float3 n0 = normalize(cross(v00, v10));
+ float3 n1 = normalize(cross(v10, v11));
+ float3 n2 = normalize(cross(v11, v01));
+ float3 n3 = normalize(cross(v01, v00));
+ /* Compute internal angles (gamma_i). */
+ float g0 = safe_acosf(-dot(n0, n1));
+ float g1 = safe_acosf(-dot(n1, n2));
+ float g2 = safe_acosf(-dot(n2, n3));
+ float g3 = safe_acosf(-dot(n3, n0));
+ /* Compute predefined constants. */
+ float b0 = n0.z;
+ float b1 = n2.z;
+ float b0sq = b0 * b0;
+ float k = M_2PI_F - g2 - g3;
+ /* Compute solid angle from internal angles. */
+ float S = g0 + g1 - k;
+
+ /* Compute cu. */
+ float au = randu * S + k;
+ float fu = (cosf(au) * b0 - b1) / sinf(au);
+ float cu = 1.0f / sqrtf(fu * fu + b0sq) * (fu > 0.0f ? 1.0f : -1.0f);
+ cu = clamp(cu, -1.0f, 1.0f);
+ /* Compute xu. */
+ float xu = -(cu * z0) / sqrtf(1.0f - cu * cu);
+ xu = clamp(xu, x0, x1);
+ /* Compute yv. */
+ float d = sqrtf(xu * xu + z0sq);
+ float h0 = y0 / sqrtf(d * d + y0sq);
+ float h1 = y1 / sqrtf(d * d + y1sq);
+ float hv = h0 + randv * (h1 - h0), hv2 = hv * hv;
+ float yv = (hv2 < 1.0f - 1e-6f) ? (hv * d) / sqrtf(1.0f - hv2) : y1;
+
+ if(S != 0.0f)
+ *pdf = 1.0f / S;
+ else
+ *pdf = 0.0f;
+
+ /* Transform (xu, yv, z0) to world coords. */
+ return P + xu * x + yv * y + z0 * z;
+}
- return axisu*randu + axisv*randv;
+/* TODO(sergey): This is actually a duplicated code from above, but how to avoid
+ * this without having some nasty function with loads of parameters?
+ */
+ccl_device float area_light_pdf(float3 P,
+ float3 light_p,
+ float3 axisu, float3 axisv)
+{
+ /* In our name system we're using P for the center,
+ * which is o in the paper.
+ */
+
+ float3 corner = light_p - axisu * 0.5f - axisv * 0.5f;
+ float axisu_len, axisv_len;
+ /* Compute local reference system R. */
+ float3 x = normalize_len(axisu, &axisu_len);
+ float3 y = normalize_len(axisv, &axisv_len);
+ float3 z = cross(x, y);
+ /* Compute rectangle coords in local reference system. */
+ float3 dir = corner - P;
+ float z0 = dot(dir, z);
+ /* Flip 'z' to make it point against Q. */
+ if(z0 > 0.0f) {
+ z *= -1.0f;
+ z0 *= -1.0f;
+ }
+ float x0 = dot(dir, x);
+ float y0 = dot(dir, y);
+ float x1 = x0 + axisu_len;
+ float y1 = y0 + axisv_len;
+ /* Create vectors to four vertices. */
+ float3 v00 = make_float3(x0, y0, z0);
+ float3 v01 = make_float3(x0, y1, z0);
+ float3 v10 = make_float3(x1, y0, z0);
+ float3 v11 = make_float3(x1, y1, z0);
+ /* Compute normals to edges. */
+ float3 n0 = normalize(cross(v00, v10));
+ float3 n1 = normalize(cross(v10, v11));
+ float3 n2 = normalize(cross(v11, v01));
+ float3 n3 = normalize(cross(v01, v00));
+ /* Compute internal angles (gamma_i). */
+ float g0 = safe_acosf(-dot(n0, n1));
+ float g1 = safe_acosf(-dot(n1, n2));
+ float g2 = safe_acosf(-dot(n2, n3));
+ float g3 = safe_acosf(-dot(n3, n0));
+ /* Compute predefined constants. */
+ float k = M_2PI_F - g2 - g3;
+ /* Compute solid angle from internal angles. */
+ float S = g0 + g1 - k;
+ if(S != 0.0f)
+ return 1.0f / S;
+ else
+ return 0.0f;
}
ccl_device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls)
@@ -276,6 +407,7 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
}
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
else {
/* area light */
@@ -286,18 +418,22 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
float3 axisv = make_float3(data2.y, data2.z, data2.w);
float3 D = make_float3(data3.y, data3.z, data3.w);
- ls->P += area_light_sample(axisu, axisv, randu, randv);
+ ls->P = area_light_sample(P, ls->P,
+ axisu, axisv,
+ randu, randv,
+ &ls->pdf);
+
ls->Ng = D;
ls->D = normalize_len(ls->P - P, &ls->t);
float invarea = data2.x;
-
ls->eval_fac = 0.25f*invarea;
- ls->pdf = invarea;
+
+ if(dot(ls->D, D) > 0.0f)
+ ls->pdf = 0.0f;
}
ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
}
@@ -355,6 +491,7 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
ls->D = D;
ls->t = FLT_MAX;
+ /* compute pdf */
float invarea = data1.w;
ls->pdf = invarea/(costheta*costheta*costheta);
ls->eval_fac = ls->pdf;
@@ -386,6 +523,10 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
if(ls->eval_fac == 0.0f)
return false;
}
+
+ /* compute pdf */
+ if(ls->t != FLT_MAX)
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
else if(type == LIGHT_AREA) {
/* area light */
@@ -412,16 +553,12 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
ls->D = D;
ls->Ng = Ng;
- ls->pdf = invarea;
- ls->eval_fac = 0.25f*ls->pdf;
+ ls->pdf = area_light_pdf(P, ls->P, axisu, axisv);
+ ls->eval_fac = 0.25f*invarea;
}
else
return false;
- /* compute pdf */
- if(ls->t != FLT_MAX)
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
-
return true;
}
@@ -514,7 +651,13 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float randt)
/* Generic Light */
-ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
+ccl_device bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce)
+{
+ float4 data4 = kernel_tex_fetch(__light_data, index*LIGHT_SIZE + 4);
+ return (bounce > __float_as_int(data4.x));
+}
+
+ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, int bounce, LightSample *ls)
{
/* sample index */
int index = light_distribution_sample(kg, randt);
@@ -536,6 +679,12 @@ ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float
}
else {
int lamp = -prim-1;
+
+ if(UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) {
+ ls->pdf = 0.0f;
+ return;
+ }
+
lamp_light_sample(kg, lamp, randu, randv, P, ls);
}
}
@@ -546,22 +695,5 @@ ccl_device int light_select_num_samples(KernelGlobals *kg, int index)
return __float_as_int(data3.x);
}
-ccl_device int lamp_light_eval_sample(KernelGlobals *kg, float randt)
-{
- /* sample index */
- int index = light_distribution_sample(kg, randt);
-
- /* fetch light data */
- float4 l = kernel_tex_fetch(__light_distribution, index);
- int prim = __float_as_int(l.y);
-
- if(prim < 0) {
- int lamp = -prim-1;
- return lamp;
- }
- else
- return LAMP_NONE;
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h
index 9553c2da0df..e5ba1f41c47 100644
--- a/intern/cycles/kernel/kernel_path_surface.h
+++ b/intern/cycles/kernel/kernel_path_surface.h
@@ -38,6 +38,9 @@ ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
if(sample_all_lights) {
/* lamp sampling */
for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+ if(UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
+ continue;
+
int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
RNG lamp_rng = cmj_hash(*rng, i);
@@ -82,7 +85,7 @@ ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
light_t = 0.5f*light_t;
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
@@ -103,7 +106,7 @@ ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
/* sample random light */
if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
@@ -200,7 +203,7 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG
#endif
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h
index da2d5e6eca8..11d3d94657b 100644
--- a/intern/cycles/kernel/kernel_path_volume.h
+++ b/intern/cycles/kernel/kernel_path_volume.h
@@ -40,7 +40,7 @@ ccl_device void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
light_ray.time = sd->time;
#endif
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(ls.pdf == 0.0f)
return;
@@ -56,7 +56,12 @@ ccl_device void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
#endif
}
-ccl_device bool kernel_path_volume_bounce(KernelGlobals *kg, RNG *rng,
+#ifdef __KERNEL_GPU__
+ccl_device_noinline
+#else
+ccl_device
+#endif
+bool kernel_path_volume_bounce(KernelGlobals *kg, RNG *rng,
ShaderData *sd, float3 *throughput, PathState *state, PathRadiance *L, Ray *ray)
{
/* sample phase function */
@@ -119,6 +124,9 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
if(sample_all_lights) {
/* lamp sampling */
for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+ if(UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
+ continue;
+
int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
RNG lamp_rng = cmj_hash(*rng, i);
@@ -183,7 +191,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
light_t = 0.5f*light_t;
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
float3 tp = throughput;
@@ -198,7 +206,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
kernel_assert(result == VOLUME_PATH_SCATTERED);
/* todo: split up light_sample so we don't have to call it again with new position */
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(ls.pdf == 0.0f)
continue;
@@ -222,7 +230,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
float3 tp = throughput;
@@ -237,7 +245,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
kernel_assert(result == VOLUME_PATH_SCATTERED);
/* todo: split up light_sample so we don't have to call it again with new position */
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(ls.pdf == 0.0f)
return;
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index db08c328d7e..65089740ef9 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -681,7 +681,7 @@ ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSSRDF(sc->type))
+ if(CLOSURE_IS_BSSRDF(sc->type) || CLOSURE_IS_BSDF_BSSRDF(sc->type))
eval += sc->weight;
}
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index ca1210f2d80..460ca7b68eb 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN
/* constants */
#define OBJECT_SIZE 11
#define OBJECT_VECTOR_SIZE 6
-#define LIGHT_SIZE 4
+#define LIGHT_SIZE 5
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
#define PARTICLE_SIZE 5
@@ -291,34 +291,34 @@ typedef enum ClosureLabel {
typedef enum PassType {
PASS_NONE = 0,
- PASS_COMBINED = 1,
- PASS_DEPTH = 2,
- PASS_NORMAL = 4,
- PASS_UV = 8,
- PASS_OBJECT_ID = 16,
- PASS_MATERIAL_ID = 32,
- PASS_DIFFUSE_COLOR = 64,
- PASS_GLOSSY_COLOR = 128,
- PASS_TRANSMISSION_COLOR = 256,
- PASS_DIFFUSE_INDIRECT = 512,
- PASS_GLOSSY_INDIRECT = 1024,
- PASS_TRANSMISSION_INDIRECT = 2048,
- PASS_DIFFUSE_DIRECT = 4096,
- PASS_GLOSSY_DIRECT = 8192,
- PASS_TRANSMISSION_DIRECT = 16384,
- PASS_EMISSION = 32768,
- PASS_BACKGROUND = 65536,
- PASS_AO = 131072,
- PASS_SHADOW = 262144,
- PASS_MOTION = 524288,
- PASS_MOTION_WEIGHT = 1048576,
- PASS_MIST = 2097152,
- PASS_SUBSURFACE_DIRECT = 4194304,
- PASS_SUBSURFACE_INDIRECT = 8388608,
- PASS_SUBSURFACE_COLOR = 16777216,
- PASS_LIGHT = 33554432, /* no real pass, used to force use_light_pass */
+ PASS_COMBINED = (1 << 0),
+ PASS_DEPTH = (1 << 1),
+ PASS_NORMAL = (1 << 2),
+ PASS_UV = (1 << 3),
+ PASS_OBJECT_ID = (1 << 4),
+ PASS_MATERIAL_ID = (1 << 5),
+ PASS_DIFFUSE_COLOR = (1 << 6),
+ PASS_GLOSSY_COLOR = (1 << 7),
+ PASS_TRANSMISSION_COLOR = (1 << 8),
+ PASS_DIFFUSE_INDIRECT = (1 << 9),
+ PASS_GLOSSY_INDIRECT = (1 << 10),
+ PASS_TRANSMISSION_INDIRECT = (1 << 11),
+ PASS_DIFFUSE_DIRECT = (1 << 12),
+ PASS_GLOSSY_DIRECT = (1 << 13),
+ PASS_TRANSMISSION_DIRECT = (1 << 14),
+ PASS_EMISSION = (1 << 15),
+ PASS_BACKGROUND = (1 << 16),
+ PASS_AO = (1 << 17),
+ PASS_SHADOW = (1 << 18),
+ PASS_MOTION = (1 << 19),
+ PASS_MOTION_WEIGHT = (1 << 20),
+ PASS_MIST = (1 << 21),
+ PASS_SUBSURFACE_DIRECT = (1 << 22),
+ PASS_SUBSURFACE_INDIRECT = (1 << 23),
+ PASS_SUBSURFACE_COLOR = (1 << 24),
+ PASS_LIGHT = (1 << 25), /* no real pass, used to force use_light_pass */
#ifdef __KERNEL_DEBUG__
- PASS_BVH_TRAVERSAL_STEPS = 67108864,
+ PASS_BVH_TRAVERSAL_STEPS = (1 << 26),
#endif
} PassType;
@@ -539,34 +539,25 @@ typedef enum AttributeStandard {
#define MAX_CLOSURE 1
#endif
-/* TODO(sergey): This is rather nasty bug happening in here, which
- * could be simply a compilers bug for which we can't find a generic
- * platform independent workaround. Also even if it's a compiler
- * issue, it's not so simple to upgrade the compiler in the release
- * environment for linux and doing it so closer to the release is
- * rather a risky business.
- *
- * For this release it's probably safer to stick with such a rather
- * dirty solution, and look for a cleaner fix during the next release
- * cycle.
+/* This struct is to be 16 bytes aligned, we also keep some extra precautions:
+ * - All the float3 members are in the beginning of the struct, so compiler
+ * does not put own padding trying to align this members.
+ * - We make sure OSL pointer is also 16 bytes aligned.
*/
typedef struct ShaderClosure {
- ClosureType type;
float3 weight;
-#ifndef __APPLE__
+ float3 N;
+ float3 T;
+
+ ClosureType type;
float sample_weight;
-#endif
float data0;
float data1;
float data2;
+ int pad1, pad2, pad3;
- float3 N;
- float3 T;
-#ifdef __APPLE__
- float sample_weight;
-#endif
#ifdef __OSL__
- void *prim;
+ void *prim, *pad4;
#endif
} ShaderClosure;
@@ -591,43 +582,46 @@ typedef enum ShaderContext {
enum ShaderDataFlag {
/* runtime flags */
- SD_BACKFACING = 1, /* backside of surface? */
- SD_EMISSION = 2, /* have emissive closure? */
- SD_BSDF = 4, /* have bsdf closure? */
- SD_BSDF_HAS_EVAL = 8, /* have non-singular bsdf closure? */
- SD_PHASE_HAS_EVAL = 8, /* have non-singular phase closure? */
- SD_BSDF_GLOSSY = 16, /* have glossy bsdf */
- SD_BSSRDF = 32, /* have bssrdf */
- SD_HOLDOUT = 64, /* have holdout closure? */
- SD_ABSORPTION = 128, /* have volume absorption closure? */
- SD_SCATTER = 256, /* have volume phase closure? */
- SD_AO = 512, /* have ao closure? */
- SD_TRANSPARENT = 1024, /* have transparent closure? */
-
- SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY|
- SD_BSSRDF|SD_HOLDOUT|SD_ABSORPTION|SD_SCATTER|SD_AO),
+ SD_BACKFACING = (1 << 0), /* backside of surface? */
+ SD_EMISSION = (1 << 1), /* have emissive closure? */
+ SD_BSDF = (1 << 2), /* have bsdf closure? */
+ SD_BSDF_HAS_EVAL = (1 << 3), /* have non-singular bsdf closure? */
+ SD_PHASE_HAS_EVAL = (1 << 3), /* have non-singular phase closure? */
+ SD_BSSRDF = (1 << 4), /* have bssrdf */
+ SD_HOLDOUT = (1 << 5), /* have holdout closure? */
+ SD_ABSORPTION = (1 << 6), /* have volume absorption closure? */
+ SD_SCATTER = (1 << 7), /* have volume phase closure? */
+ SD_AO = (1 << 8), /* have ao closure? */
+ SD_TRANSPARENT = (1 << 9), /* have transparent closure? */
+
+ SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF|
+ SD_HOLDOUT|SD_ABSORPTION|SD_SCATTER|SD_AO),
/* shader flags */
- SD_USE_MIS = 2048, /* direct light sample */
- SD_HAS_TRANSPARENT_SHADOW = 4096, /* has transparent shadow */
- SD_HAS_VOLUME = 8192, /* has volume shader */
- SD_HAS_ONLY_VOLUME = 16384, /* has only volume shader, no surface */
- SD_HETEROGENEOUS_VOLUME = 32768, /* has heterogeneous volume */
- SD_HAS_BSSRDF_BUMP = 65536, /* bssrdf normal uses bump */
- SD_VOLUME_EQUIANGULAR = 131072, /* use equiangular sampling */
- SD_VOLUME_MIS = 262144, /* use multiple importance sampling */
+ SD_USE_MIS = (1 << 10), /* direct light sample */
+ SD_HAS_TRANSPARENT_SHADOW = (1 << 11), /* has transparent shadow */
+ SD_HAS_VOLUME = (1 << 12), /* has volume shader */
+ SD_HAS_ONLY_VOLUME = (1 << 13), /* has only volume shader, no surface */
+ SD_HETEROGENEOUS_VOLUME = (1 << 14), /* has heterogeneous volume */
+ SD_HAS_BSSRDF_BUMP = (1 << 15), /* bssrdf normal uses bump */
+ SD_VOLUME_EQUIANGULAR = (1 << 16), /* use equiangular sampling */
+ SD_VOLUME_MIS = (1 << 17), /* use multiple importance sampling */
+ SD_VOLUME_CUBIC = (1 << 18), /* use cubic interpolation for voxels */
+ SD_HAS_BUMP = (1 << 19), /* has data connected to the displacement input */
SD_SHADER_FLAGS = (SD_USE_MIS|SD_HAS_TRANSPARENT_SHADOW|SD_HAS_VOLUME|
SD_HAS_ONLY_VOLUME|SD_HETEROGENEOUS_VOLUME|
- SD_HAS_BSSRDF_BUMP|SD_VOLUME_EQUIANGULAR|SD_VOLUME_MIS),
+ SD_HAS_BSSRDF_BUMP|SD_VOLUME_EQUIANGULAR|SD_VOLUME_MIS|
+ SD_VOLUME_CUBIC|SD_HAS_BUMP),
/* object flags */
- SD_HOLDOUT_MASK = 524288, /* holdout for camera rays */
- SD_OBJECT_MOTION = 1048576, /* has object motion blur */
- SD_TRANSFORM_APPLIED = 2097152, /* vertices have transform applied */
- SD_NEGATIVE_SCALE_APPLIED = 4194304, /* vertices have negative scale applied */
- SD_OBJECT_HAS_VOLUME = 8388608, /* object has a volume shader */
- SD_OBJECT_INTERSECTS_VOLUME = 16777216, /* object intersects AABB of an object with volume shader */
+ SD_HOLDOUT_MASK = (1 << 20), /* holdout for camera rays */
+ SD_OBJECT_MOTION = (1 << 21), /* has object motion blur */
+ SD_TRANSFORM_APPLIED = (1 << 22), /* vertices have transform applied */
+ SD_NEGATIVE_SCALE_APPLIED = (1 << 23), /* vertices have negative scale applied */
+ SD_OBJECT_HAS_VOLUME = (1 << 24), /* object has a volume shader */
+ SD_OBJECT_INTERSECTS_VOLUME = (1 << 25), /* object intersects AABB of an object with volume shader */
+ SD_OBJECT_HAS_VERTEX_MOTION = (1 << 21), /* has position for motion vertices */
SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED|
SD_NEGATIVE_SCALE_APPLIED|SD_OBJECT_HAS_VOLUME|
@@ -994,7 +988,7 @@ typedef struct KernelData {
#ifdef __KERNEL_DEBUG__
typedef struct DebugData {
- // Total number of BVH node travesal steps and primitives intersections
+ // Total number of BVH node traversal steps and primitives intersections
// for the camera rays.
int num_bvh_traversal_steps;
} DebugData;
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 93cb4c120ea..6a39ba928f0 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -581,7 +581,8 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals
* through a volume. This can then latter be used for decoupled sampling as in:
* "Importance Sampling Techniques for Path Tracing in Participating Media"
*
- * On the GPU this is only supported for homogeneous volumes (1 step), due to
+ * On the GPU this is only supported (but currently not enabled)
+ * for homogeneous volumes (1 step), due to
* no support for malloc/free and too much stack usage with a fix size array. */
typedef struct VolumeStep {
@@ -595,6 +596,7 @@ typedef struct VolumeStep {
} VolumeStep;
typedef struct VolumeSegment {
+ VolumeStep stack_step; /* stack storage for homogeneous step, to avoid malloc */
VolumeStep *steps; /* recorded steps */
int numsteps; /* number of steps */
int closure_flag; /* accumulated closure flags from all steps */
@@ -627,11 +629,13 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
/* compute exact steps in advance for malloc */
max_steps = max((int)ceilf(ray->t/step_size), 1);
+ segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
}
else {
max_steps = 1;
step_size = ray->t;
random_jitter_offset = 0.0f;
+ segment->steps = &segment->stack_step;
}
/* init accumulation variables */
@@ -640,10 +644,8 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
float3 cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
float t = 0.0f;
- segment->closure_flag = 0;
segment->numsteps = 0;
-
- segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
+ segment->closure_flag = 0;
VolumeStep *step = segment->steps;
@@ -729,16 +731,13 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
ccl_device void kernel_volume_decoupled_free(KernelGlobals *kg, VolumeSegment *segment)
{
- free(segment->steps);
+ if(segment->steps != &segment->stack_step)
+ free(segment->steps);
}
/* scattering for homogeneous and heterogeneous volumes, using decoupled ray
- * marching. unlike the non-decoupled functions, these do not do probalistic
- * scattering, they always scatter if there is any non-zero scattering
- * coefficient.
+ * marching. this function does not do emission or modify throughput.
*
- * these also do not do emission or modify throughput.
- *
* function is expected to return VOLUME_PATH_SCATTERED when probalistic_scatter is false */
ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd,
@@ -958,7 +957,7 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg,
Ray *ray,
VolumeStack *stack)
{
- /* NULL ray happens in the baker, does it need proper initializetion of
+ /* NULL ray happens in the baker, does it need proper initialization of
* camera in volume?
*/
if(!kernel_data.cam.is_inside_volume || ray == NULL) {
@@ -992,31 +991,29 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg,
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &volume_ray, 0, 0);
- if(sd.flag & SD_HAS_VOLUME) {
- if(sd.flag & SD_BACKFACING) {
- /* If ray exited the volume and never entered to that volume
- * it means that camera is inside such a volume.
- */
- bool is_enclosed = false;
- for(int i = 0; i < enclosed_index; ++i) {
- if(enclosed_volumes[i] == sd.object) {
- is_enclosed = true;
- break;
- }
- }
- if(is_enclosed == false) {
- stack[stack_index].object = sd.object;
- stack[stack_index].shader = sd.shader;
- ++stack_index;
+ if(sd.flag & SD_BACKFACING) {
+ /* If ray exited the volume and never entered to that volume
+ * it means that camera is inside such a volume.
+ */
+ bool is_enclosed = false;
+ for(int i = 0; i < enclosed_index; ++i) {
+ if(enclosed_volumes[i] == sd.object) {
+ is_enclosed = true;
+ break;
}
}
- else {
- /* If ray from camera enters the volume, this volume shouldn't
- * be added to the stak on exit.
- */
- enclosed_volumes[enclosed_index++] = sd.object;
+ if(is_enclosed == false) {
+ stack[stack_index].object = sd.object;
+ stack[stack_index].shader = sd.shader;
+ ++stack_index;
}
}
+ else {
+ /* If ray from camera enters the volume, this volume shouldn't
+ * be added to the stack on exit.
+ */
+ enclosed_volumes[enclosed_index++] = sd.object;
+ }
/* Move ray forward. */
volume_ray.P = ray_offset(sd.P, -sd.Ng);
diff --git a/intern/cycles/kernel/osl/SConscript b/intern/cycles/kernel/osl/SConscript
index d721edbaf6e..0a21d3e6819 100644
--- a/intern/cycles/kernel/osl/SConscript
+++ b/intern/cycles/kernel/osl/SConscript
@@ -38,6 +38,7 @@ incs.append(env['BF_OIIO_INC'])
incs.append(env['BF_BOOST_INC'])
incs.append(env['BF_OSL_INC'])
incs.append(env['BF_OPENEXR_INC'].split())
+incs.append('#/intern/atomic')
defs.append('CCL_NAMESPACE_BEGIN=namespace ccl {')
defs.append('CCL_NAMESPACE_END=}')
@@ -46,6 +47,16 @@ defs.append('WITH_OSL')
if env['WITH_BF_CYCLES_DEBUG']:
defs.append('WITH_CYCLES_DEBUG')
+if env['WITH_BF_CYCLES_LOGGING']:
+ defs.append('WITH_CYCLES_LOGGING')
+ defs.append('GOOGLE_GLOG_DLL_DECL=')
+ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+ incs.append('#extern/libmv/third_party/glog/src/windows')
+ incs.append('#extern/libmv/third_party/gflags')
+ else:
+ incs.append('#extern/libmv/third_party/glog/src')
+ incs.append('#extern/libmv/third_party/gflags')
+
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
cxxflags.append('-DBOOST_NO_RTTI -DBOOST_NO_TYPEID /fp:fast'.split())
incs.append(env['BF_PTHREADS_INC'])
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index cc9942b024e..1d99f1d2682 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -189,11 +189,7 @@ static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, O
/* optimization: it's possible to not use a prepare function at all and
* only initialize the actual class when accessing the closure component
* data, but then we need to map the id to the class somehow */
-#ifdef CLOSURE_PREPARE
- ss->register_closure(name, id, params, prepare, NULL, NULL);
-#else
- ss->register_closure(name, id, params, prepare, NULL);
-#endif
+ ss->register_closure(name, id, params, prepare, NULL, 16);
}
void OSLShader::register_closures(OSLShadingSystem *ss_)
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index a9694651e14..7a93aa05222 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -834,7 +834,7 @@ bool OSLRenderServices::has_userdata(ustring name, TypeDesc type, OSL::ShaderGlo
bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg,
float s, float t, float dsdx, float dtdx,
- float dsdy, float dtdy, float *result)
+ float dsdy, float dtdy, int nchannels, float *result)
{
OSL::TextureSystem *ts = osl_ts;
ShaderData *sd = (ShaderData *)(sg->renderstate);
@@ -869,9 +869,9 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
PtexFilter::Options opts(PtexFilter::f_bicubic, mipmaplerp, sharpness);
PtexPtr<PtexFilter> f(PtexFilter::getFilter(r, opts));
- f->eval(result, options.firstchannel, options.nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);
+ f->eval(result, options.firstchannel, nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);
- for(int c = r->numChannels(); c < options.nchannels; c++)
+ for(int c = r->numChannels(); c < nchannels; c++)
result[c] = result[0];
return true;
@@ -880,15 +880,15 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
bool status;
if(filename[0] == '@' && filename.find('.') == -1) {
- int slot = atoi(filename.c_str() + 1);
+ int slot = atoi(filename.c_str() + 1);
float4 rgba = kernel_tex_image_interp(slot, s, 1.0f - t);
result[0] = rgba[0];
- if(options.nchannels > 1)
+ if(nchannels > 1)
result[1] = rgba[1];
- if(options.nchannels > 2)
+ if(nchannels > 2)
result[2] = rgba[2];
- if(options.nchannels > 3)
+ if(nchannels > 3)
result[3] = rgba[3];
status = true;
}
@@ -898,17 +898,24 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);
+#if OIIO_VERSION < 10500
status = ts->texture(th, thread_info,
- options, s, t, dsdx, dtdx, dsdy, dtdy, result);
+ options, s, t, dsdx, dtdx, dsdy, dtdy,
+ result);
+#else
+ status = ts->texture(th, thread_info,
+ options, s, t, dsdx, dtdx, dsdy, dtdy,
+ nchannels, result);
+#endif
}
if(!status) {
- if(options.nchannels == 3 || options.nchannels == 4) {
+ if(nchannels == 3 || nchannels == 4) {
result[0] = 1.0f;
result[1] = 0.0f;
result[2] = 1.0f;
- if(options.nchannels == 4)
+ if(nchannels == 4)
result[3] = 1.0f;
}
}
@@ -919,7 +926,7 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
- const OSL::Vec3 &dPdz, float *result)
+ const OSL::Vec3 &dPdz, int nchannels, float *result)
{
OSL::TextureSystem *ts = osl_ts;
ShaderData *sd = (ShaderData *)(sg->renderstate);
@@ -929,16 +936,22 @@ bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);
+#if OIIO_VERSION < 10500
bool status = ts->texture3d(th, thread_info,
options, P, dPdx, dPdy, dPdz, result);
+#else
+ bool status = ts->texture3d(th, thread_info,
+ options, P, dPdx, dPdy, dPdz,
+ nchannels, result);
+#endif
if(!status) {
- if(options.nchannels == 3 || options.nchannels == 4) {
+ if(nchannels == 3 || nchannels == 4) {
result[0] = 1.0f;
result[1] = 0.0f;
result[2] = 1.0f;
- if(options.nchannels == 4)
+ if(nchannels == 4)
result[3] = 1.0f;
}
@@ -949,7 +962,8 @@ bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
bool OSLRenderServices::environment(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
- const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result)
+ const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy,
+ int nchannels, float *result)
{
OSL::TextureSystem *ts = osl_ts;
ShaderData *sd = (ShaderData *)(sg->renderstate);
@@ -958,16 +972,23 @@ bool OSLRenderServices::environment(ustring filename, TextureOpt &options,
OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info;
OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);
+
+#if OIIO_VERSION < 10500
bool status = ts->environment(th, thread_info,
options, R, dRdx, dRdy, result);
+#else
+ bool status = ts->environment(th, thread_info,
+ options, R, dRdx, dRdy,
+ nchannels, result);
+#endif
if(!status) {
- if(options.nchannels == 3 || options.nchannels == 4) {
+ if(nchannels == 3 || nchannels == 4) {
result[0] = 1.0f;
result[1] = 0.0f;
result[2] = 1.0f;
- if(options.nchannels == 4)
+ if(nchannels == 4)
result[3] = 1.0f;
}
}
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index 6f928a0d103..e9026d95f34 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -97,16 +97,17 @@ public:
bool texture(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg,
float s, float t, float dsdx, float dtdx,
- float dsdy, float dtdy, float *result);
+ float dsdy, float dtdy, int nchannels, float *result);
bool texture3d(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
- const OSL::Vec3 &dPdz, float *result);
+ const OSL::Vec3 &dPdz, int nchannels, float *result);
bool environment(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
- const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result);
+ const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy,
+ int nchannels, float *result);
bool get_texture_info(OSL::ShaderGlobals *sg, ustring filename, int subimage,
ustring dataname, TypeDesc datatype, void *data);
@@ -159,70 +160,37 @@ public:
static ustring u_v;
static ustring u_empty;
-#if OSL_LIBRARY_VERSION_CODE < 10500
- bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) {
- return get_matrix(NULL, result, xform, time);
- }
-
- bool get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) {
- return get_inverse_matrix(NULL, result, xform, time);
- }
-
- bool get_matrix(OSL::Matrix44 &result, ustring from, float time) {
- return get_matrix(NULL, result, from, time);
- }
-
- bool get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time) {
- return get_inverse_matrix(NULL, result, to, time);
- }
-
- bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform) {
- return get_matrix(NULL, result, xform);
- }
-
- bool get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform) {
- return get_inverse_matrix(NULL, result, xform);
- }
+ /* Code to make OSL versions transition smooth. */
- bool get_matrix(OSL::Matrix44 &result, ustring from) {
- return get_matrix(NULL, result, from);
+#if OSL_LIBRARY_VERSION_CODE < 10600
+ inline bool texture(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ float s, float t, float dsdx, float dtdx,
+ float dsdy, float dtdy, float *result)
+ {
+ return texture(filename, options, sg, s, t, dsdx, dtdx, dsdy, dtdy,
+ options.nchannels, result);
}
- bool get_inverse_matrix(OSL::Matrix44 &result, ustring to) {
- return get_inverse_matrix(NULL, result, to);
+ inline bool texture3d(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
+ const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
+ const OSL::Vec3 &dPdz, float *result)
+ {
+ return texture3d(filename, options, sg, P, dPdx, dPdy, dPdz,
+ options.nchannels, result);
}
- bool get_array_attribute(void *renderstate, bool derivatives,
- ustring object, TypeDesc type, ustring name,
- int index, void *val) {
- OSL::ShaderGlobals sg;
- sg.renderstate = renderstate;
- return get_array_attribute(&sg, derivatives,
- object, type, name,
- index, val);
- }
-
- bool get_attribute(void *renderstate, bool derivatives, ustring object_name,
- TypeDesc type, ustring name, void *val) {
- OSL::ShaderGlobals sg;
- sg.renderstate = renderstate;
- return get_attribute(&sg, derivatives, object_name, type, name, val);
- }
-
- bool has_userdata(ustring name, TypeDesc type, void *renderstate) {
- return has_userdata(name, type, (OSL::ShaderGlobals *) renderstate);
- }
-
- bool get_userdata(bool derivatives, ustring name, TypeDesc type,
- void *renderstate, void *val) {
- return get_userdata(derivatives, name, type, (OSL::ShaderGlobals *) renderstate, val);
- }
-
- bool get_texture_info(ustring filename, int subimage,
- ustring dataname, TypeDesc datatype, void *data) {
- return get_texture_info(NULL, filename, subimage, dataname, datatype, data);
+ inline bool environment(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
+ const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy,
+ float *result)
+ {
+ return environment(filename, options, sg, R, dRdx, dRdy,
+ options.nchannels, result);
}
#endif
+
private:
KernelGlobals *kernel_globals;
OSL::TextureSystem *osl_ts;
diff --git a/intern/cycles/kernel/shaders/node_combine_hsv.osl b/intern/cycles/kernel/shaders/node_combine_hsv.osl
index 010773acc5c..574bad30b14 100644
--- a/intern/cycles/kernel/shaders/node_combine_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_combine_hsv.osl
@@ -15,6 +15,7 @@
*/
#include "stdosl.h"
+#include "node_color.h"
shader node_combine_hsv(
float H = 0.0,
@@ -22,6 +23,6 @@ shader node_combine_hsv(
float V = 0.0,
output color Color = 0.8)
{
- Color = color("hsv", H, S, V);
+ Color = color_srgb_to_scene_linear(color("hsv", H, S, V));
}
diff --git a/intern/cycles/kernel/shaders/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl
index 4722bde4cd7..5f4300ee31d 100644
--- a/intern/cycles/kernel/shaders/node_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_hsv.osl
@@ -35,6 +35,11 @@ shader node_hsv(
Color = hsv_to_rgb(Color);
+ // Clamp color to prevent negative values cauzed by oversaturation.
+ Color[0] = max(Color[0], 0.0);
+ Color[1] = max(Color[1], 0.0);
+ Color[2] = max(Color[2], 0.0);
+
ColorOut = mix(ColorIn, Color, Fac);
}
diff --git a/intern/cycles/kernel/shaders/node_normal.osl b/intern/cycles/kernel/shaders/node_normal.osl
index 14af044e0c0..002eddb574c 100644
--- a/intern/cycles/kernel/shaders/node_normal.osl
+++ b/intern/cycles/kernel/shaders/node_normal.osl
@@ -23,6 +23,6 @@ shader node_normal(
output float Dot = 1.0)
{
NormalOut = normalize(Direction);
- Dot = dot(NormalOut, NormalIn);
+ Dot = dot(NormalOut, normalize(NormalIn));
}
diff --git a/intern/cycles/kernel/shaders/node_separate_hsv.osl b/intern/cycles/kernel/shaders/node_separate_hsv.osl
index 94fc5de9122..8bfb04aea1c 100644
--- a/intern/cycles/kernel/shaders/node_separate_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_separate_hsv.osl
@@ -23,7 +23,7 @@ shader node_separate_hsv(
output float S = 0.0,
output float V = 0.0)
{
- color col = rgb_to_hsv(Color);
+ color col = rgb_to_hsv(color_scene_linear_to_srgb(Color));
H = col[0];
S = col[1];
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 1ff8f363b49..6babe98717c 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -505,6 +505,47 @@ closure color hair_transmission(normal N, float roughnessu, float roughnessv, ve
closure color henyey_greenstein(float g) BUILTIN;
closure color absorption() BUILTIN;
+// OSL 1.5 Microfacet functions
+closure color microfacet(string distribution, normal N, vector U, float xalpha, float yalpha, float eta, int refract) {
+ /* GGX */
+ if (distribution == "ggx" || distribution == "default") {
+ if (!refract) {
+ if (xalpha == yalpha) {
+ /* Isotropic */
+ return microfacet_ggx(N, xalpha);
+ }
+ else {
+ /* Anisotropic */
+ return microfacet_ggx_aniso(N, U, xalpha, yalpha);
+ }
+ }
+ else {
+ return microfacet_ggx_refraction(N, xalpha, eta);
+ }
+ }
+ /* Beckmann */
+ else {
+ if (!refract) {
+ if (xalpha == yalpha) {
+ /* Isotropic */
+ return microfacet_beckmann(N, xalpha);
+ }
+ else {
+ /* Anisotropic */
+ return microfacet_beckmann_aniso(N, U, xalpha, yalpha);
+ }
+ }
+ else {
+ return microfacet_beckmann_refraction(N, xalpha, eta);
+ }
+ }
+}
+
+closure color microfacet (string distribution, normal N, float alpha, float eta, int refract) {
+ return microfacet(distribution, N, vector(0), alpha, alpha, eta, refract);
+}
+
+
// Renderer state
int backfacing () BUILTIN;
int raytype (string typename) BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index c13eae813d6..5acfbbf972b 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -164,6 +164,7 @@ CCL_NAMESPACE_END
#include "svm_mapping.h"
#include "svm_normal.h"
#include "svm_wave.h"
+#include "svm_math_util.h"
#include "svm_math.h"
#include "svm_mix.h"
#include "svm_ramp.h"
diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h
index 11dfc4f096b..a02d853be1a 100644
--- a/intern/cycles/kernel/svm/svm_hsv.h
+++ b/intern/cycles/kernel/svm/svm_hsv.h
@@ -46,6 +46,11 @@ ccl_device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, ui
color.y = fac*color.y + (1.0f - fac)*in_color.y;
color.z = fac*color.z + (1.0f - fac)*in_color.z;
+ /* Clamp color to prevent negative values cauzed by oversaturation. */
+ color.x = max(color.x, 0.0f);
+ color.y = max(color.y, 0.0f);
+ color.z = max(color.z, 0.0f);
+
if (stack_valid(out_color_offset))
stack_store_float3(stack, out_color_offset, color);
}
diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h
index 1ce9386e40e..e3d8c1f3242 100644
--- a/intern/cycles/kernel/svm/svm_math.h
+++ b/intern/cycles/kernel/svm/svm_math.h
@@ -16,56 +16,6 @@
CCL_NAMESPACE_BEGIN
-ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
-{
- float Fac;
-
- if(type == NODE_MATH_ADD)
- Fac = Fac1 + Fac2;
- else if(type == NODE_MATH_SUBTRACT)
- Fac = Fac1 - Fac2;
- else if(type == NODE_MATH_MULTIPLY)
- Fac = Fac1*Fac2;
- else if(type == NODE_MATH_DIVIDE)
- Fac = safe_divide(Fac1, Fac2);
- else if(type == NODE_MATH_SINE)
- Fac = sinf(Fac1);
- else if(type == NODE_MATH_COSINE)
- Fac = cosf(Fac1);
- else if(type == NODE_MATH_TANGENT)
- Fac = tanf(Fac1);
- else if(type == NODE_MATH_ARCSINE)
- Fac = safe_asinf(Fac1);
- else if(type == NODE_MATH_ARCCOSINE)
- Fac = safe_acosf(Fac1);
- else if(type == NODE_MATH_ARCTANGENT)
- Fac = atanf(Fac1);
- else if(type == NODE_MATH_POWER)
- Fac = safe_powf(Fac1, Fac2);
- else if(type == NODE_MATH_LOGARITHM)
- Fac = safe_logf(Fac1, Fac2);
- else if(type == NODE_MATH_MINIMUM)
- Fac = fminf(Fac1, Fac2);
- else if(type == NODE_MATH_MAXIMUM)
- Fac = fmaxf(Fac1, Fac2);
- else if(type == NODE_MATH_ROUND)
- Fac = floorf(Fac1 + 0.5f);
- else if(type == NODE_MATH_LESS_THAN)
- Fac = Fac1 < Fac2;
- else if(type == NODE_MATH_GREATER_THAN)
- Fac = Fac1 > Fac2;
- else if(type == NODE_MATH_MODULO)
- Fac = safe_modulo(Fac1, Fac2);
- else if(type == NODE_MATH_ABSOLUTE)
- Fac = fabsf(Fac1);
- else if(type == NODE_MATH_CLAMP)
- Fac = clamp(Fac1, 0.0f, 1.0f);
- else
- Fac = 0.0f;
-
- return Fac;
-}
-
ccl_device float average_fac(float3 v)
{
return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f;
diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h
new file mode 100644
index 00000000000..b813bf531dc
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_math_util.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011-2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
+{
+ float Fac;
+
+ if(type == NODE_MATH_ADD)
+ Fac = Fac1 + Fac2;
+ else if(type == NODE_MATH_SUBTRACT)
+ Fac = Fac1 - Fac2;
+ else if(type == NODE_MATH_MULTIPLY)
+ Fac = Fac1*Fac2;
+ else if(type == NODE_MATH_DIVIDE)
+ Fac = safe_divide(Fac1, Fac2);
+ else if(type == NODE_MATH_SINE)
+ Fac = sinf(Fac1);
+ else if(type == NODE_MATH_COSINE)
+ Fac = cosf(Fac1);
+ else if(type == NODE_MATH_TANGENT)
+ Fac = tanf(Fac1);
+ else if(type == NODE_MATH_ARCSINE)
+ Fac = safe_asinf(Fac1);
+ else if(type == NODE_MATH_ARCCOSINE)
+ Fac = safe_acosf(Fac1);
+ else if(type == NODE_MATH_ARCTANGENT)
+ Fac = atanf(Fac1);
+ else if(type == NODE_MATH_POWER)
+ Fac = safe_powf(Fac1, Fac2);
+ else if(type == NODE_MATH_LOGARITHM)
+ Fac = safe_logf(Fac1, Fac2);
+ else if(type == NODE_MATH_MINIMUM)
+ Fac = fminf(Fac1, Fac2);
+ else if(type == NODE_MATH_MAXIMUM)
+ Fac = fmaxf(Fac1, Fac2);
+ else if(type == NODE_MATH_ROUND)
+ Fac = floorf(Fac1 + 0.5f);
+ else if(type == NODE_MATH_LESS_THAN)
+ Fac = Fac1 < Fac2;
+ else if(type == NODE_MATH_GREATER_THAN)
+ Fac = Fac1 > Fac2;
+ else if(type == NODE_MATH_MODULO)
+ Fac = safe_modulo(Fac1, Fac2);
+ else if(type == NODE_MATH_ABSOLUTE)
+ Fac = fabsf(Fac1);
+ else if(type == NODE_MATH_CLAMP)
+ Fac = clamp(Fac1, 0.0f, 1.0f);
+ else
+ Fac = 0.0f;
+
+ return Fac;
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
index 111d5d47988..abf75b62bd5 100644
--- a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
+++ b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
@@ -26,7 +26,8 @@ ccl_device void svm_node_combine_hsv(KernelGlobals *kg, ShaderData *sd, float *s
float value = stack_load_float(stack, value_in);
/* Combine, and convert back to RGB */
- float3 color = hsv_to_rgb(make_float3(hue, saturation, value));
+ float3 color = color_srgb_to_scene_linear(
+ hsv_to_rgb(make_float3(hue, saturation, value)));
if (stack_valid(color_out))
stack_store_float3(stack, color_out, color);
@@ -40,7 +41,7 @@ ccl_device void svm_node_separate_hsv(KernelGlobals *kg, ShaderData *sd, float *
float3 color = stack_load_float3(stack, color_in);
/* Convert to HSV */
- color = rgb_to_hsv(color);
+ color = rgb_to_hsv(color_scene_linear_to_srgb(color));
if (stack_valid(hue_out))
stack_store_float(stack, hue_out, color.x);