For the record, Lukas Tönne contributed to OSL Volume support as well. :)

Am 28.12.2013 17:40, schrieb Brecht Van Lommel:
> Commit: a35db17cee5a9b47dc9624f7dfcb41f5fc185b33
> Author: Brecht Van Lommel
> Date:   Sat Dec 28 01:54:44 2013 +0100
> https://developer.blender.org/rBa35db17cee5a9b47dc9624f7dfcb41f5fc185b33
>
> Cycles Volume Render: work on nodes and closures.
>
> * Henyey-Greenstein scattering closure implementation.
> * Rename transparent to absorption node and isotropic to scatter node.
> * Volume density is folded into the closure weights.
> * OSL support for volume closures and nodes.
> * This commit has no user visible changes, there is no volume render code yet.
>
> This is work by "storm", Stuart Broadfoot, Thomas Dinges and myself.
>
> ===================================================================
>
> M     intern/cycles/app/cycles_xml.cpp
> M     intern/cycles/blender/blender_shader.cpp
> M     intern/cycles/kernel/closure/volume.h
> M     intern/cycles/kernel/kernel_shader.h
> M     intern/cycles/kernel/kernel_types.h
> M     intern/cycles/kernel/osl/osl_closures.cpp
> M     intern/cycles/kernel/osl/osl_closures.h
> M     intern/cycles/kernel/osl/osl_shader.cpp
> M     intern/cycles/kernel/shaders/CMakeLists.txt
> A     intern/cycles/kernel/shaders/node_absorption_volume.osl
> M     intern/cycles/kernel/shaders/node_light_path.osl
> A     intern/cycles/kernel/shaders/node_scatter_volume.osl
> M     intern/cycles/kernel/shaders/stdosl.h
> M     intern/cycles/kernel/svm/svm_closure.h
> M     intern/cycles/kernel/svm/svm_light_path.h
> M     intern/cycles/kernel/svm/svm_types.h
> M     intern/cycles/render/nodes.cpp
> M     intern/cycles/render/nodes.h
> M     intern/cycles/render/osl.cpp
> M     release/scripts/addons
> M     release/scripts/addons_contrib
> M     source/blender/blenkernel/BKE_node.h
> M     source/blender/blenkernel/intern/node.c
> M     source/blender/nodes/CMakeLists.txt
> M     source/blender/nodes/NOD_shader.h
> M     source/blender/nodes/NOD_static_types.h
> A     source/blender/nodes/shader/nodes/node_shader_volume_absorption.c
> D     source/blender/nodes/shader/nodes/node_shader_volume_isotropic.c
> A     source/blender/nodes/shader/nodes/node_shader_volume_scatter.c
> D     source/blender/nodes/shader/nodes/node_shader_volume_transparent.c
>
> ===================================================================
>
> diff --git a/intern/cycles/app/cycles_xml.cpp 
> b/intern/cycles/app/cycles_xml.cpp
> index df187f0..a483c76 100644
> --- a/intern/cycles/app/cycles_xml.cpp
> +++ b/intern/cycles/app/cycles_xml.cpp
> @@ -452,11 +452,11 @@ static void xml_read_shader_graph(const XMLReadState& 
> state, Shader *shader, pug
>               else if(string_iequals(node.name(), "background")) {
>                       snode = new BackgroundNode();
>               }
> -             else if(string_iequals(node.name(), "transparent_volume")) {
> -                     snode = new TransparentVolumeNode();
> +             else if(string_iequals(node.name(), "absorption_volume")) {
> +                     snode = new AbsorptionVolumeNode();
>               }
> -             else if(string_iequals(node.name(), "isotropic_volume")) {
> -                     snode = new IsotropicVolumeNode();
> +             else if(string_iequals(node.name(), "scatter_volume")) {
> +                     snode = new ScatterVolumeNode();
>               }
>               else if(string_iequals(node.name(), "geometry")) {
>                       snode = new GeometryNode();
> diff --git a/intern/cycles/blender/blender_shader.cpp 
> b/intern/cycles/blender/blender_shader.cpp
> index a6d2b53..0c3a32a 100644
> --- a/intern/cycles/blender/blender_shader.cpp
> +++ b/intern/cycles/blender/blender_shader.cpp
> @@ -422,11 +422,11 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData 
> b_data, BL::Scene b_scen
>       else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
>               node = new AmbientOcclusionNode();
>       }
> -     else if (b_node.is_a(&RNA_ShaderNodeVolumeIsotropic)) {
> -             node = new IsotropicVolumeNode();
> +     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/volume.h 
> b/intern/cycles/kernel/closure/volume.h
> index f493256..dae24fb 100644
> --- a/intern/cycles/kernel/closure/volume.h
> +++ b/intern/cycles/kernel/closure/volume.h
> @@ -14,53 +14,102 @@
>    * limitations under the License
>    */
>   
> +#ifndef __VOLUME_H__
> +#define __VOLUME_H__
> +
>   CCL_NAMESPACE_BEGIN
>   
> -/* note: the interfaces here are just as an example, need to figure
> - * out the right functions and parameters to use */
> +/* HENYEY-GREENSTEIN CLOSURE */
>   
> -/* ISOTROPIC VOLUME CLOSURE */
> +/* 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)
> +{
> +     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_isotropic_setup(ShaderClosure *sc, float density)
> +ccl_device int volume_henyey_greenstein_setup(ShaderClosure *sc)
>   {
> -     sc->type = CLOSURE_VOLUME_ISOTROPIC_ID;
> -     sc->data0 = density;
> +     sc->type = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
> +     
> +     /* clamp anisotropy to avoid delta function */
> +     sc->data0 = signf(sc->data0) * min(fabsf(sc->data0), 1.0f - 1e-3f);
>   
> -     return SD_VOLUME;
> +     return SD_BSDF|SD_BSDF_HAS_EVAL;
>   }
>   
> -ccl_device float3 volume_isotropic_eval_phase(const ShaderClosure *sc, const 
> float3 omega_in, const float3 omega_out)
> +ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure 
> *sc, const float3 I, float3 omega_in, float *pdf)
>   {
> -     return make_float3(1.0f, 1.0f, 1.0f);
> -}
> +     float g = sc->data0;
>   
> -/* TRANSPARENT VOLUME CLOSURE */
> +     /* note that I points towards the viewer */
> +     float cos_theta = dot(-I, omega_in);
>   
> -ccl_device int volume_transparent_setup(ShaderClosure *sc, float density)
> +     *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 I, float3 dIdx, float3 dIdy, float randu, float randv,
> +     float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 
> *domega_in_dy, float *pdf)
>   {
> -     sc->type = CLOSURE_VOLUME_TRANSPARENT_ID;
> -     sc->data0 = density;
> +     float g = sc->data0;
> +     float cos_phi, sin_phi, cos_theta;
>   
> -     return SD_VOLUME;
> +     /* match pdf for small g */
> +     if(fabsf(g) < 1e-3f) {
> +             cos_theta = (1.0f - 2.0f * randu);
> +     }
> +     else {
> +             float k = (1.0f - g * g) / (1.0f - g + 2.0f * g * randu);
> +             cos_theta = (1.0f + g * g - k * k) / (2.0f * g);
> +     }
> +
> +     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: 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_VOLUME_SCATTER;
>   }
>   
> -ccl_device float3 volume_transparent_eval_phase(const ShaderClosure *sc, 
> const float3 omega_in, const float3 omega_out)
> +/* ABSORPTION VOLUME CLOSURE */
> +
> +ccl_device int volume_absorption_setup(ShaderClosure *sc)
>   {
> -     return make_float3(1.0f, 1.0f, 1.0f);
> +     sc->type = CLOSURE_VOLUME_ABSORPTION_ID;
> +
> +     return SD_VOLUME;
>   }
>   
>   /* VOLUME CLOSURE */
>   
> -ccl_device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure 
> *sc, const float3 omega_in, const float3 omega_out)
> +ccl_device float3 volume_eval_phase(const ShaderClosure *sc, const float3 I, 
> float3 omega_in, float *pdf)
>   {
>       float3 eval;
>   
>       switch(sc->type) {
> -             case CLOSURE_VOLUME_ISOTROPIC_ID:
> -                     eval = volume_isotropic_eval_phase(sc, omega_in, 
> omega_out);
> -                     break;
> -             case CLOSURE_VOLUME_TRANSPARENT_ID:
> -                     eval = volume_transparent_eval_phase(sc, omega_in, 
> omega_out);
> +             case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
> +                     eval = volume_henyey_greenstein_eval_phase(sc, I, 
> omega_in, pdf);
>                       break;
>               default:
>                       eval = make_float3(0.0f, 0.0f, 0.0f);
> @@ -70,5 +119,24 @@ ccl_device float3 volume_eval_phase(KernelGlobals *kg, 
> const ShaderClosure *sc,
>       return eval;
>   }
>   
> +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->I, 
> sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, 
> &domega_in->dy, pdf);
> +                     break;
> +             default:
> +                     *eval = make_float3(0.0f, 0.0f, 0.0f);
> +                     label = LABEL_NONE;
> +                     break;
> +     }
> +
> +     return label;
> +}
> +
>   CCL_NAMESPACE_END
>   
> +#endif
> diff --git a/intern/cycles/kernel/kernel_shader.h 
> b/intern/cycles/kernel/kernel_shader.h
> index 457a7f7..012aa4a 100644
> --- a/intern/cycles/kernel/kernel_shader.h
> +++ b/intern/cycles/kernel/kernel_shader.h
> @@ -868,17 +868,19 @@ ccl_device float3 
> shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
>   {
>   #ifdef __MULTI_CLOSURE__
>       float3 eval = make_float3(0.0f, 0.0f, 0.0f);
> +     float pdf;
>   
>       for(int i = 0; i< sd->num_closure; i++) {
>               const ShaderClosure *sc = &sd->closure[i];
>   
>               if(CLOSURE_IS_VOLUME(sc->type))
> -                     eval += volume_eval_phase(kg, sc, omega_in, omega_out);
> +                     eval += volume_eval_phase(sc, omega_in, omega_out, 
> &pdf);
>       }
>   
>       return eval;
>   #else
> -     return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
> +     float pdf;
> +     return volume_eval_phase(&sd->closure, omega_in, omega_out, &pdf);
>   #endif
>   }
>   
> diff --git a/intern/cycles/kernel/kernel_types.h 
> b/intern/cycles/kernel/kernel_types.h
> index 9b1893e..4821a1b 100644
> --- a/intern/cycles/kernel/kernel_types.h
> +++ b/intern/cycles/kernel/kernel_types.h
> @@ -201,6 +201,7 @@ enum PathRayFlag {
>       PATH_RAY_GLOSSY = 16,
>       PATH_RAY_SINGULAR = 32,
>       PATH_RAY_TRANSPARENT = 64,
> +     PATH_RAY_VOLUME_SCATTER = 128,
>   
>       PATH_RAY_SHADOW_OPAQUE = 128,
>       PATH_RAY_SHADOW_TRANSPARENT = 256,
> @@ -224,18 +225,13 @@ 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,
> +     LABEL_VOLUME_SCATTER = 64,
>   } ClosureLabel;
>   
>   /* Render Passes */
> diff --git a/intern/cycles/kernel/osl/osl_closures.cpp 
> b/intern/cycles/kernel/osl/osl_closures.cpp
> index 340e449..a96c0e2 100644
> --- a/intern/cycles/kernel/osl/osl_closures.cpp
> +++ b/intern/cycles/kernel/osl/osl_closures.cpp
> @@ -55,6 +55,7 @@
>   #include "closure/bsdf_westin.h"
>   #include "closure/bsdf_toon.h"
>   #include "closure/bsdf_hair.h"
> +#include "closure/volume.h"
>   
>   CCL_NAMESPACE_BEGIN
>   
> @@ -169,6 +170,13 @@ BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, 
> hair_transmission, hair_transmission,
>   #endif
>   BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
>   
> +VOLUME_CLOSURE_CLASS_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein, 
> LABEL_VOLUME_SCATTER)
> +     CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, sc.data0),
> +VOLUME_CLOSURE_CLASS_END(VolumeHenyeyGreenstein, henyey_greenstein)
> +
> +VOLUME_CLOSURE_CLASS_BEGIN(VolumeAbsorption, absorption, LABEL_SINGULAR)
> +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)
> @@ -248,6 +256,11 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
>               bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
>       register_closure(ss, "hair_transmission", id++,
>               bsdf_hair_transmission_params(), 
> bsdf_hair_transmission_prepare);
> +
> +     register_closure(ss, "henyey_greenstein", id++,
> +             volume_henyey_greenstein_params(), 
> volume_henyey_greenstein_prepare);
> +     register_closure(ss, "absorption", id++,
> +             volume_absorption_params(), volume_
>

_______________________________________________
Bf-committers mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-committers

Reply via email to