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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2013-12-26 17:40:09 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2013-12-26 17:58:18 +0400
commitde479f51b62ebed3800a5aa7203f1bfd70c3508a (patch)
treec7f6c1eb7f86fa8a395ffd07d16cc1b8eab8e173
parentbdf527bfec47a55d3a5a75a57f59ce53c641666e (diff)
Cycles Volume: implement volume absorption node.
This is the transparent volume node renamed, currently it is basically the same as a scatter volume node with anisotropy 1, so it scatters light perfectly forward. This also does some tweaks to the henyey-greenstein closure code to avoid division by zero and to make eval/sample consistent in some corner cases, and some other code cleanup related to volume shaders.
-rw-r--r--intern/cycles/blender/blender_shader.cpp4
-rw-r--r--intern/cycles/kernel/closure/bsdf.h5
-rw-r--r--intern/cycles/kernel/closure/volume.h139
-rw-r--r--intern/cycles/kernel/kernel_shader.h6
-rw-r--r--intern/cycles/kernel/kernel_types.h18
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp9
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h34
-rw-r--r--intern/cycles/kernel/shaders/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/shaders/node_absorption_volume.osl26
-rw-r--r--intern/cycles/kernel/shaders/node_scatter_volume.osl4
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h4
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h6
-rw-r--r--intern/cycles/kernel/svm/svm_types.h2
-rw-r--r--intern/cycles/render/nodes.cpp12
-rw-r--r--intern/cycles/render/nodes.h4
m---------release/scripts/addons0
m---------release/scripts/addons_contrib0
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/intern/node.c2
-rw-r--r--source/blender/nodes/CMakeLists.txt2
-rw-r--r--source/blender/nodes/NOD_shader.h2
-rw-r--r--source/blender/nodes/NOD_static_types.h2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_absorption.c (renamed from source/blender/nodes/shader/nodes/node_shader_volume_transparent.c)14
23 files changed, 158 insertions, 140 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 8c4e83baadb..be57b1d7a61 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -425,8 +425,8 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
node = new ScatterVolumeNode();
}
- else if (b_node.is_a(&RNA_ShaderNodeVolumeTransparent)) {
- node = new TransparentVolumeNode();
+ else if (b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
+ node = new AbsorptionVolumeNode();
}
else if (b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
node = new GeometryNode();
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index ff2afd067e4..221225984f8 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -146,9 +146,10 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
#endif
#ifdef __VOLUME__
- // need this to keep logic in kernel_emission.h direct light in case of volume particle
+ /* need this to keep logic in kernel_emission.h direct light in case of volume particle */
+ /* todo: restructure code so this is handled better */
if (CLOSURE_IS_VOLUME(sc->type))
- return volume_eval_phase(kg, sc, sd->I, omega_in, pdf);
+ return volume_eval_phase(sc, sd->I, omega_in, pdf);
#endif
if(dot(sd->Ng, omega_in) >= 0.0f) {
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index 4b4cfd01889..1e31c5a9cc7 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -21,111 +21,116 @@ CCL_NAMESPACE_BEGIN
/* HENYEY-GREENSTEIN CLOSURE */
-/* Given cosine between rays, return probability density that photon bounce to that direction
- * g parameter controls how far it difference from uniform sphere. g=0 uniform diffusion-like, g=1 - very close to sharp single ray. */
-
-ccl_device float single_peaked_henyey_greenstein(float cos_theta, float m_g)
+/* Given cosine between rays, return probability density that a photon bounces
+ * to that direction. The g parameter controls how different it is from the
+ * uniform sphere. g=0 uniform diffuse-like, g=1 close to sharp single ray. */
+ccl_device float single_peaked_henyey_greenstein(float cos_theta, float g)
{
- float p = (1.0f - m_g * m_g) / pow(1.0f + m_g * m_g - 2.0f * m_g * cos_theta, 1.5f) / 4.0f / M_PI_F;
-
- return p;
+ if(fabsf(g) < 1e-3f)
+ return M_1_PI_F * 0.25f;
+
+ return ((1.0f - g * g) / safe_powf(1.0f + g * g - 2.0f * g * cos_theta, 1.5f)) * (M_1_PI_F * 0.25f);
};
ccl_device int volume_henyey_greenstein_setup(ShaderClosure *sc)
{
sc->type = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
+
+ /* positive density */
+ sc->data0 = max(sc->data0, 0.0f);
+ /* clamp anisotropy to avoid delta function */
+ sc->data1 = signf(sc->data1) * min(fabsf(sc->data1), 1.0f - 1e-3f);
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
-// just return bsdf at input vector
ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
{
- float m_g = sc->data1;
- const float magic_eps = 0.001f;
+ float g = sc->data1;
-// WARNING! I point in backward direction!
-// float cos_theta = dot(I, omega_in);
+ /* note that I points towards the viewer */
float cos_theta = dot(-I, omega_in);
- if(fabsf(m_g) < magic_eps)
- *pdf = M_1_PI_F * 0.25f; // ?? double check it
- else
- *pdf = single_peaked_henyey_greenstein(cos_theta, m_g);
+ *pdf = single_peaked_henyey_greenstein(cos_theta, g);
return make_float3(*pdf, *pdf, *pdf);
}
-ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
+ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc, 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)
{
- float m_g = sc->data1;
- const float magic_eps = 0.001f;
+ float g = sc->data1;
+ float cos_phi, sin_phi, cos_theta;
- // WARNING! I point in backward direction!
-
- if(fabsf(m_g) < magic_eps) {
- *omega_in = sample_uniform_sphere(randu, randv);
- *pdf = M_1_PI_F * 0.25f; // ?? double check it
+ /* match pdf for small g */
+ if(fabsf(g) < 1e-3f) {
+ cos_theta = (1.0f - 2.0f * randu);
}
else {
- float cos_phi, sin_phi, cos_theta;
-
- if(fabsf(m_g) < magic_eps)
- cos_theta = (1.0f - 2.0f * randu);
- else {
- float k = (1.0f - m_g * m_g) / (1.0f - m_g + 2.0f * m_g * randu);
- cos_theta = (1.0f + m_g * m_g - k * k) / (2.0f * m_g);
- // float cos_theta = 1.0f / (2.0f * m_g) * (1.0f + m_g * m_g - k*k);
- // float cos_theta = (1.0f - 2.0f * randu);
- // float cos_theta = randu;
- }
- float sin_theta = sqrt(1 - cos_theta * cos_theta);
-
- float3 T, B;
- make_orthonormals(-I, &T, &B);
- float phi = M_2PI_F * randv;
- cos_phi = cosf(phi);
- sin_phi = sinf(phi);
- *omega_in = sin_theta * cos_phi * T + sin_theta * sin_phi * B + cos_theta * (-I);
- *pdf = single_peaked_henyey_greenstein(cos_theta, m_g);
+ float k = (1.0f - g * g) / (1.0f - g + 2.0f * g * randu);
+ cos_theta = (1.0f + g * g - k * k) / (2.0f * g);
}
- *eval = make_float3(*pdf, *pdf, *pdf); // perfect importance sampling
+ float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
+
+ float phi = M_2PI_F * randv;
+ cos_phi = cosf(phi);
+ sin_phi = sinf(phi);
+
+ /* note that I points towards the viewer and so is used negated */
+ float3 T, B;
+ make_orthonormals(-I, &T, &B);
+ *omega_in = sin_theta * cos_phi * T + sin_theta * sin_phi * B + cos_theta * (-I);
+
+ *pdf = single_peaked_henyey_greenstein(cos_theta, g);
+ *eval = make_float3(*pdf, *pdf, *pdf); /* perfect importance sampling */
+
#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(Ng, dIdx)) * Ng - dIdx;
- *domega_in_dy = (2 * dot(Ng, dIdy)) * Ng - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
+ /* todo: implement ray differential estimation */
+ *domega_in_dx = make_float3(0.0f, 0.0f, 0.0f);
+ *domega_in_dy = make_float3(0.0f, 0.0f, 0.0f);
#endif
- return LABEL_REFLECT|LABEL_DIFFUSE;
+
+ /* todo: do we need a separate light path state for volume scatter? */
+ return LABEL_DIFFUSE;
}
-/* TRANSPARENT VOLUME CLOSURE */
+/* ABSORPTION VOLUME CLOSURE */
-ccl_device int volume_transparent_setup(ShaderClosure *sc)
+ccl_device int volume_absorption_setup(ShaderClosure *sc)
{
- sc->type = CLOSURE_VOLUME_TRANSPARENT_ID;
+ sc->type = CLOSURE_VOLUME_ABSORPTION_ID;
+
+ /* positive density */
+ sc->data0 = max(sc->data0, 0.0f);
return SD_VOLUME;
}
-ccl_device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
+ccl_device float3 volume_absorption_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
{
- return make_float3(1.0f, 1.0f, 1.0f);
+ /* eval to zero for delta functions */
+ return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int volume_transparent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
+ccl_device int volume_absorption_sample(const ShaderClosure *sc, 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)
{
- /* XXX Implement */
- return LABEL_REFLECT|LABEL_DIFFUSE;
+ *omega_in = -I;
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = -dIdx;
+ *domega_in_dy = -dIdy;
+#endif
+
+ *pdf = 1.0f;
+ *eval = make_float3(1.0f, 1.0f, 1.0f);
+
+ return LABEL_TRANSMIT|LABEL_TRANSPARENT;
}
/* VOLUME CLOSURE */
-ccl_device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
+ccl_device float3 volume_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
{
float3 eval;
@@ -133,8 +138,8 @@ ccl_device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc,
case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
eval = volume_henyey_greenstein_eval_phase(sc, I, omega_in, pdf);
break;
- case CLOSURE_VOLUME_TRANSPARENT_ID:
- eval = volume_transparent_eval_phase(sc, I, omega_in, pdf);
+ case CLOSURE_VOLUME_ABSORPTION_ID:
+ eval = volume_absorption_eval_phase(sc, I, omega_in, pdf);
break;
default:
eval = make_float3(0.0f, 0.0f, 0.0f);
@@ -144,17 +149,17 @@ ccl_device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc,
return eval;
}
-ccl_device int volume_sample(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, float randu,
+ccl_device int volume_sample(const ShaderData *sd, const ShaderClosure *sc, float randu,
float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
{
int label;
switch(sc->type) {
case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
- label = volume_henyey_greenstein_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = volume_henyey_greenstein_sample(sc, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
- case CLOSURE_VOLUME_TRANSPARENT_ID:
- label = volume_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ case CLOSURE_VOLUME_ABSORPTION_ID:
+ label = volume_absorption_sample(sc, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
default:
*eval = make_float3(0.0f, 0.0f, 0.0f);
@@ -162,8 +167,6 @@ ccl_device int volume_sample(KernelGlobals *kg, const ShaderData *sd, const Shad
break;
}
-// *eval *= sd->svm_closure_weight;
-
return label;
}
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 7b73fd39d2f..f98b626dee1 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -1025,7 +1025,7 @@ ccl_device int shader_volume_bsdf_sample(KernelGlobals *kg, const ShaderData *sd
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
*pdf = 0.0f;
- label = volume_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ label = volume_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
if(*pdf != 0.0f) {
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
@@ -1041,14 +1041,14 @@ ccl_device int shader_volume_bsdf_sample(KernelGlobals *kg, const ShaderData *sd
/* sample the single closure that we picked */
*pdf = 0.0f;
#if 0
- int label = volume_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
+ int label = volume_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
*bsdf_eval *= sd->closure.weight;
#else
const ShaderClosure *sc = &sd->closure;
int label;
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- label = volume_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ label = volume_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
#endif
return label;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 30937edcfca..02a1197c2e3 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -237,18 +237,12 @@ enum PathRayFlag {
typedef enum ClosureLabel {
LABEL_NONE = 0,
- LABEL_CAMERA = 1,
- LABEL_LIGHT = 2,
- LABEL_BACKGROUND = 4,
- LABEL_TRANSMIT = 8,
- LABEL_REFLECT = 16,
- LABEL_VOLUME = 32,
- LABEL_OBJECT = 64,
- LABEL_DIFFUSE = 128,
- LABEL_GLOSSY = 256,
- LABEL_SINGULAR = 512,
- LABEL_TRANSPARENT = 1024,
- LABEL_STOP = 2048
+ LABEL_TRANSMIT = 1,
+ LABEL_REFLECT = 2,
+ LABEL_DIFFUSE = 4,
+ LABEL_GLOSSY = 8,
+ LABEL_SINGULAR = 16,
+ LABEL_TRANSPARENT = 32,
} ClosureLabel;
/* Render Passes */
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 20c696cb628..9ad7e09ec83 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -170,12 +170,15 @@ BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, hair_transmission,
#endif
BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
-VOLUME_CLOSURE_CLASS_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein, henyey_greenstein)
- CLOSURE_FLOAT3_PARAM(VolumeHenyeyGreensteinClosure, sc.N),
+VOLUME_CLOSURE_CLASS_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein, LABEL_DIFFUSE)
CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, sc.data0),
CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, sc.data1),
VOLUME_CLOSURE_CLASS_END(VolumeHenyeyGreenstein, henyey_greenstein)
+VOLUME_CLOSURE_CLASS_BEGIN(VolumeAbsorption, absorption, LABEL_SINGULAR)
+ CLOSURE_FLOAT_PARAM(VolumeAbsorptionClosure, sc.data0),
+VOLUME_CLOSURE_CLASS_END(VolumeAbsorption, absorption)
+
/* Registration */
static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, OSL::ClosureParam *params, OSL::PrepareClosureFunc prepare)
@@ -258,6 +261,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
register_closure(ss, "henyey_greenstein", id++,
volume_henyey_greenstein_params(), volume_henyey_greenstein_prepare);
+ register_closure(ss, "absorption_volume", id++,
+ volume_absorption_params(), volume_absorption_prepare);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index 5ac15b373f9..8029d933c7a 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -191,36 +191,35 @@ CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure)
/* Volume */
-class CVolumeClosure : public OSL::ClosurePrimitive {
+class CVolumeClosure : public CClosurePrimitive {
public:
ShaderClosure sc;
- CVolumeClosure() : OSL::ClosurePrimitive(Volume),
- m_shaderdata_flag(0)
+ CVolumeClosure(int scattering) : CClosurePrimitive(Volume),
+ m_scattering_label(scattering), m_shaderdata_flag(0)
{ memset(&sc, 0, sizeof(sc)); }
~CVolumeClosure() { }
+ int scattering() const { return m_scattering_label; }
int shaderdata_flag() const { return m_shaderdata_flag; }
virtual float3 eval_phase(const float3 &omega_out, const float3 &omega_in, float& pdf) const = 0;
- virtual int sample(const float3 &Ng,
- const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ virtual int sample(const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
float randu, float randv,
float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
float &pdf, float3 &eval) const = 0;
protected:
+ int m_scattering_label;
int m_shaderdata_flag;
};
-#define VOLUME_CLOSURE_CLASS_BEGIN(Upper, lower, svmlower) \
+#define VOLUME_CLOSURE_CLASS_BEGIN(Upper, lower, TYPE) \
\
class Upper##Closure : public CVolumeClosure { \
public: \
- Upper##Closure() : CVolumeClosure() {} \
- size_t memsize() const { return sizeof(*this); } \
- const char *name() const { return #lower; } \
+ Upper##Closure() : CVolumeClosure(TYPE) {} \
\
void setup() \
{ \
@@ -228,28 +227,17 @@ public: \
m_shaderdata_flag = volume_##lower##_setup(&sc); \
} \
\
- bool mergeable(const ClosurePrimitive *other) const \
- { \
- return false; \
- } \
- \
- void print_on(std::ostream &out) const \
- { \
- out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))"; \
- } \
-\
float3 eval_phase(const float3 &omega_out, const float3 &omega_in, float& pdf) const \
{ \
- return volume_##svmlower##_eval_phase(&sc, omega_out, omega_in, &pdf); \
+ return volume_##lower##_eval_phase(&sc, omega_out, omega_in, &pdf); \
} \
\
- int sample(const float3 &Ng, \
- const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, \
+ int sample(const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, \
float randu, float randv, \
float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, \
float &pdf, float3 &eval) const \
{ \
- return volume_##svmlower##_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy, \
+ return volume_##lower##_sample(&sc, omega_out, domega_out_dx, domega_out_dy, \
randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); \
} \
\
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 1cc2eb84f8a..045abdb80af 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -30,6 +30,7 @@ set(SRC_OSL
node_gradient_texture.osl
node_hair_info.osl
node_scatter_volume.osl
+ node_absorption_volume.osl
node_holdout.osl
node_hsv.osl
node_image_texture.osl
diff --git a/intern/cycles/kernel/shaders/node_absorption_volume.osl b/intern/cycles/kernel/shaders/node_absorption_volume.osl
new file mode 100644
index 00000000000..f72615c8cc9
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_absorption_volume.osl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2011-2013 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
+ */
+
+#include "stdosl.h"
+
+shader node_absorption_volume(
+ color Color = color(0.8, 0.8, 0.8),
+ float Density = 1.0,
+ output closure color Volume = 0)
+{
+ Volume = Color * absorption_volume(Density);
+}
+
diff --git a/intern/cycles/kernel/shaders/node_scatter_volume.osl b/intern/cycles/kernel/shaders/node_scatter_volume.osl
index 12f2cb29134..523912c81aa 100644
--- a/intern/cycles/kernel/shaders/node_scatter_volume.osl
+++ b/intern/cycles/kernel/shaders/node_scatter_volume.osl
@@ -20,8 +20,8 @@ shader node_scatter_volume(
color Color = color(0.8, 0.8, 0.8),
float Density = 1.0,
float Anisotropy = 0.0,
- normal Normal = N,
output closure color Volume = 0)
{
- Volume = Color * henyey_greenstein(Normal, Density, Anisotropy);
+ Volume = Color * henyey_greenstein(Density, Anisotropy);
}
+
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index a7a311b013d..afa6e626e41 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -497,11 +497,13 @@ closure color ambient_occlusion() BUILTIN;
closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN;
closure color bssrdf_gaussian(normal N, vector radius, float texture_blur) BUILTIN;
+// Hair
closure color hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
closure color hair_transmission(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
// Volume
-closure color henyey_greenstein(normal N, float Density, float g) BUILTIN;
+closure color henyey_greenstein(float density, float g) BUILTIN;
+closure color absorption_volume(float density) BUILTIN;
// Backwards compatibility
closure color bssrdf_cubic(normal N, vector radius) BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index cf94f17ef1d..5dc93ad3c12 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -476,18 +476,16 @@ ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float
float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
switch(type) {
-#if 0 /* XXX unused */
- case CLOSURE_VOLUME_TRANSPARENT_ID: {
+ case CLOSURE_VOLUME_ABSORPTION_ID: {
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
if(sc) {
float density = param1;
sc->data0 = density;
- sd->flag |= volume_transparent_setup(sc);
+ sd->flag |= volume_absorption_setup(sc);
}
break;
}
-#endif
case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID: {
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 0dbbe1bd67f..e16c488c1f3 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -389,7 +389,7 @@ typedef enum ClosureType {
/* Volume */
CLOSURE_VOLUME_ID,
- CLOSURE_VOLUME_TRANSPARENT_ID,
+ CLOSURE_VOLUME_ABSORPTION_ID,
CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID,
NBUILTIN_CLOSURES
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index f8434e0bf11..68af81a6358 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1995,21 +1995,21 @@ void VolumeNode::compile(OSLCompiler& compiler)
assert(0);
}
-/* Transparent Volume Closure */
+/* Absorption Volume Closure */
-TransparentVolumeNode::TransparentVolumeNode()
+AbsorptionVolumeNode::AbsorptionVolumeNode()
{
- closure = CLOSURE_VOLUME_TRANSPARENT_ID;
+ closure = CLOSURE_VOLUME_ABSORPTION_ID;
}
-void TransparentVolumeNode::compile(SVMCompiler& compiler)
+void AbsorptionVolumeNode::compile(SVMCompiler& compiler)
{
VolumeNode::compile(compiler, input("Density"), NULL);
}
-void TransparentVolumeNode::compile(OSLCompiler& compiler)
+void AbsorptionVolumeNode::compile(OSLCompiler& compiler)
{
- compiler.add(this, "node_transparent_volume");
+ compiler.add(this, "node_absorption_volume");
}
/* Scatter Volume Closure */
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index cbb99ebc532..36348044bbc 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -316,9 +316,9 @@ public:
ClosureType closure;
};
-class TransparentVolumeNode : public VolumeNode {
+class AbsorptionVolumeNode : public VolumeNode {
public:
- SHADER_NODE_CLASS(TransparentVolumeNode)
+ SHADER_NODE_CLASS(AbsorptionVolumeNode)
};
class ScatterVolumeNode : public VolumeNode {
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 92a03a1b94b4fae0b6c04d3c4fa2bdcd4df8a08
+Subproject c50944e808d6c74148237e85866e893628f0fee
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
-Subproject 941d5d1857a13766fb39db1757659dc7a9e6127
+Subproject 31545d25c9cb41d271a3f3ef84d327708572290
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 0c777028b01..e3af696c8a9 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -717,7 +717,7 @@ struct ShadeResult;
#define SH_NODE_OUTPUT_TEXTURE 158
#define SH_NODE_HOLDOUT 159
#define SH_NODE_LAYER_WEIGHT 160
-#define SH_NODE_VOLUME_TRANSPARENT 161
+#define SH_NODE_VOLUME_ABSORPTION 161
#define SH_NODE_VOLUME_SCATTER 162
#define SH_NODE_GAMMA 163
#define SH_NODE_TEX_CHECKER 164
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 58b3337785c..db96e1c960d 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3494,7 +3494,7 @@ static void registerShaderNodes(void)
register_node_type_sh_bsdf_hair();
register_node_type_sh_emission();
register_node_type_sh_holdout();
- //register_node_type_sh_volume_transparent();
+ register_node_type_sh_volume_absorption();
register_node_type_sh_volume_scatter();
register_node_type_sh_subsurface_scattering();
register_node_type_sh_mix_shader();
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index d7e72130c52..16671e84da0 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -198,7 +198,7 @@ set(SRC
shader/nodes/node_shader_tex_voronoi.c
shader/nodes/node_shader_tex_wave.c
shader/nodes/node_shader_volume_scatter.c
- shader/nodes/node_shader_volume_transparent.c
+ shader/nodes/node_shader_volume_absorption.c
shader/node_shader_tree.c
shader/node_shader_util.c
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index fcbc85a584f..0f388a890a4 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -105,7 +105,7 @@ void register_node_type_sh_bsdf_toon(void);
void register_node_type_sh_bsdf_anisotropic(void);
void register_node_type_sh_emission(void);
void register_node_type_sh_holdout(void);
-void register_node_type_sh_volume_transparent(void);
+void register_node_type_sh_volume_absorption(void);
void register_node_type_sh_volume_scatter(void);
void register_node_type_sh_bsdf_hair(void);
void register_node_type_sh_subsurface_scattering(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index d8e72b85099..260323d368c 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -88,7 +88,7 @@ DefNode( ShaderNode, SH_NODE_BSDF_VELVET, 0, "BS
DefNode( ShaderNode, SH_NODE_BSDF_TOON, def_toon, "BSDF_TOON", BsdfToon, "Toon BSDF", "" )
DefNode( ShaderNode, SH_NODE_BSDF_HAIR, def_hair, "BSDF_HAIR", BsdfHair, "Hair BSDF", "" )
DefNode( ShaderNode, SH_NODE_SUBSURFACE_SCATTERING, def_sh_subsurface, "SUBSURFACE_SCATTERING",SubsurfaceScattering,"Subsurface Scattering","")
-DefNode( ShaderNode, SH_NODE_VOLUME_TRANSPARENT, 0, "VOLUME_TRANSPARENT", VolumeTransparent,"Transparent Volume","" )
+DefNode( ShaderNode, SH_NODE_VOLUME_ABSORPTION, 0, "VOLUME_ABSORPTION", VolumeAbsorption, "Volume Absorption", "" )
DefNode( ShaderNode, SH_NODE_VOLUME_SCATTER, 0, "VOLUME_SCATTER", VolumeScatter, "Volume Scatter", "" )
DefNode( ShaderNode, SH_NODE_EMISSION, 0, "EMISSION", Emission, "Emission", "" )
DefNode( ShaderNode, SH_NODE_NEW_GEOMETRY, 0, "NEW_GEOMETRY", NewGeometry, "Geometry", "" )
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_transparent.c b/source/blender/nodes/shader/nodes/node_shader_volume_absorption.c
index 31009a3585a..a271162bd19 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_transparent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_absorption.c
@@ -29,33 +29,33 @@
/* **************** OUTPUT ******************** */
-static bNodeSocketTemplate sh_node_volume_transparent_in[] = {
+static bNodeSocketTemplate sh_node_volume_absorption_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Density"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
{ -1, 0, "" }
};
-static bNodeSocketTemplate sh_node_volume_transparent_out[] = {
+static bNodeSocketTemplate sh_node_volume_absorption_out[] = {
{ SOCK_SHADER, 0, N_("Volume")},
{ -1, 0, "" }
};
-static int node_shader_gpu_volume_transparent(GPUMaterial *UNUSED(mat), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *UNUSED(in), GPUNodeStack *UNUSED(out))
+static int node_shader_gpu_volume_absorption(GPUMaterial *UNUSED(mat), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *UNUSED(in), GPUNodeStack *UNUSED(out))
{
return 0;
}
/* node type definition */
-void register_node_type_sh_volume_transparent(void)
+void register_node_type_sh_volume_absorption(void)
{
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VOLUME_TRANSPARENT, "Transparent Volume", NODE_CLASS_SHADER, 0);
+ sh_node_type_base(&ntype, SH_NODE_VOLUME_ABSORPTION, "Volume Absorption", NODE_CLASS_SHADER, 0);
node_type_compatibility(&ntype, NODE_NEW_SHADING);
- node_type_socket_templates(&ntype, sh_node_volume_transparent_in, sh_node_volume_transparent_out);
+ node_type_socket_templates(&ntype, sh_node_volume_absorption_in, sh_node_volume_absorption_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_volume_transparent);
+ node_type_gpu(&ntype, node_shader_gpu_volume_absorption);
nodeRegisterType(&ntype);
}